-
-
Notifications
You must be signed in to change notification settings - Fork 176
/
leveldown.h
155 lines (135 loc) · 5.22 KB
/
leveldown.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* Copyright (c) 2012-2013 LevelDOWN contributors
* See list at <https://github.com/rvagg/node-leveldown#contributing>
* MIT +no-false-attribs License <https://github.com/rvagg/node-leveldown/blob/master/LICENSE>
*/
#ifndef LD_LEVELDOWN_H
#define LD_LEVELDOWN_H
#include <v8.h>
namespace leveldown {
class Plugin {
public:
Plugin () {};
virtual void Init (v8::Local<v8::Object> database) =0;
virtual const char* Name () =0;
};
typedef Plugin* CreatePlugin();
} // namespace leveldown
#define LD_PLUGIN(name, clazz) \
extern "C" { \
NODE_MODULE_EXPORT leveldown::Plugin* name ## _plugin() { \
return new clazz(); \
} \
}
#define LD_SYMBOL(var, key) \
static const v8::Persistent<v8::String> var = \
v8::Persistent<v8::String>::New(v8::String::NewSymbol(#key));
#define LD_V8_METHOD(name) \
static v8::Handle<v8::Value> name (const v8::Arguments& args);
#define LD_CB_ERR_IF_NULL_OR_UNDEFINED(index, name) \
if (args[index]->IsNull() || args[index]->IsUndefined()) { \
v8::Local<v8::Value> argv[] = { \
v8::Local<v8::Value>::New(v8::Exception::Error( \
v8::String::New(#name " argument cannot be `null` or `undefined`")) \
) \
}; \
LD_RUN_CALLBACK(callback, argv, 1); \
return v8::Undefined(); \
}
#define LD_FROM_V8_STRING(to, from) \
size_t to ## Sz_; \
char* to; \
v8::Local<v8::String> to ## Str = from->ToString(); \
to ## Sz_ = to ## Str->Utf8Length(); \
to = new char[to ## Sz_ + 1]; \
to ## Str->WriteUtf8(to, -1, NULL, v8::String::NO_OPTIONS);
#define LD_STRING_OR_BUFFER_TO_SLICE(to, from, name) \
size_t to ## Sz_; \
char* to ## Ch_; \
if (node::Buffer::HasInstance(from->ToObject())) { \
to ## Sz_ = node::Buffer::Length(from->ToObject()); \
if (to ## Sz_ == 0) { \
LD_RETURN_CALLBACK_OR_ERROR(callback, #name " argument cannot be an empty Buffer") \
} \
to ## Ch_ = node::Buffer::Data(from->ToObject()); \
} else { \
v8::Local<v8::String> to ## Str = from->ToString(); \
to ## Sz_ = to ## Str->Utf8Length(); \
if (to ## Sz_ == 0) { \
LD_RETURN_CALLBACK_OR_ERROR(callback, #name " argument cannot be an empty String") \
} \
to ## Ch_ = new char[to ## Sz_]; \
to ## Str->WriteUtf8( \
to ## Ch_ \
, -1 \
, NULL, v8::String::NO_NULL_TERMINATION \
); \
} \
leveldb::Slice to(to ## Ch_, to ## Sz_);
#define LD_BOOLEAN_OPTION_VALUE(optionsObj, opt) \
bool opt = !optionsObj.IsEmpty() \
&& optionsObj->Has(option_ ## opt) \
&& optionsObj->Get(option_ ## opt)->BooleanValue();
#define LD_BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, opt) \
bool opt = optionsObj.IsEmpty() \
|| !optionsObj->Has(option_ ## opt) \
|| optionsObj->Get(option_ ## opt)->BooleanValue();
#define LD_UINT32_OPTION_VALUE(optionsObj, opt, default) \
uint32_t opt = !optionsObj.IsEmpty() \
&& optionsObj->Has(option_ ## opt) \
&& optionsObj->Get(option_ ## opt)->IsUint32() \
? optionsObj->Get(option_ ## opt)->Uint32Value() \
: default;
#define LD_RETURN_CALLBACK_OR_ERROR(callback, msg) \
if (callback->IsFunction()) { \
v8::Local<v8::Value> argv[] = { \
v8::Local<v8::Value>::New(v8::Exception::Error( \
v8::String::New(msg)) \
) \
}; \
LD_RUN_CALLBACK(callback, argv, 1) \
return v8::Undefined(); \
} \
LD_THROW_RETURN(msg)
#define LD_RUN_CALLBACK(callback, argv, length) \
v8::TryCatch try_catch; \
callback->Call(v8::Context::GetCurrent()->Global(), length, argv); \
if (try_catch.HasCaught()) { \
node::FatalException(try_catch); \
}
#define LD_THROW_RETURN(msg) \
v8::ThrowException(v8::Exception::Error(v8::String::New(#msg))); \
return v8::Undefined();
/* LD_METHOD_SETUP_COMMON setup the following objects:
* - Database* database
* - v8::Local<v8::Object> optionsObj (may be empty)
* - v8::Persistent<v8::Function> callback (won't be empty)
* Will LD_THROW_RETURN if there isn't a callback in arg 0 or 1
*/
#define LD_METHOD_SETUP_COMMON(name, optionPos, callbackPos) \
if (args.Length() == 0) { \
LD_THROW_RETURN(name() requires a callback argument) \
} \
leveldown::Database* database = \
node::ObjectWrap::Unwrap<leveldown::Database>(args.This()); \
v8::Local<v8::Object> optionsObj; \
v8::Persistent<v8::Function> callback; \
if (optionPos == -1 && args[callbackPos]->IsFunction()) { \
callback = v8::Persistent<v8::Function>::New( \
v8::Local<v8::Function>::Cast(args[callbackPos]) \
); \
} else if (optionPos != -1 && args[callbackPos - 1]->IsFunction()) { \
callback = v8::Persistent<v8::Function>::New( \
v8::Local<v8::Function>::Cast(args[callbackPos - 1]) \
); \
} else if (optionPos != -1 \
&& args[optionPos]->IsObject() \
&& args[callbackPos]->IsFunction()) { \
optionsObj = v8::Local<v8::Object>::Cast(args[optionPos]); \
callback = v8::Persistent<v8::Function>::New( \
v8::Local<v8::Function>::Cast(args[callbackPos]) \
); \
} else { \
LD_THROW_RETURN(name() requires a callback argument) \
}
#define LD_METHOD_SETUP_COMMON_ONEARG(name) LD_METHOD_SETUP_COMMON(name, -1, 0)
#endif