1 |
|
2 |
|
3 | #ifndef BSON_H_
|
4 | #define BSON_H_
|
5 |
|
6 |
|
7 |
|
8 | #ifdef __arm__
|
9 | #define USE_MISALIGNED_MEMORY_ACCESS 0
|
10 | #else
|
11 | #define USE_MISALIGNED_MEMORY_ACCESS 1
|
12 | #endif
|
13 |
|
14 | using namespace v8;
|
15 | using namespace node;
|
16 |
|
17 |
|
18 |
|
19 | enum BsonType
|
20 | {
|
21 | BSON_TYPE_NUMBER = 1,
|
22 | BSON_TYPE_STRING = 2,
|
23 | BSON_TYPE_OBJECT = 3,
|
24 | BSON_TYPE_ARRAY = 4,
|
25 | BSON_TYPE_BINARY = 5,
|
26 | BSON_TYPE_UNDEFINED = 6,
|
27 | BSON_TYPE_OID = 7,
|
28 | BSON_TYPE_BOOLEAN = 8,
|
29 | BSON_TYPE_DATE = 9,
|
30 | BSON_TYPE_NULL = 10,
|
31 | BSON_TYPE_REGEXP = 11,
|
32 | BSON_TYPE_CODE = 13,
|
33 | BSON_TYPE_SYMBOL = 14,
|
34 | BSON_TYPE_CODE_W_SCOPE = 15,
|
35 | BSON_TYPE_INT = 16,
|
36 | BSON_TYPE_TIMESTAMP = 17,
|
37 | BSON_TYPE_LONG = 18,
|
38 | BSON_TYPE_MAX_KEY = 0x7f,
|
39 | BSON_TYPE_MIN_KEY = 0xff
|
40 | };
|
41 |
|
42 |
|
43 |
|
44 | template<typename T> class BSONSerializer;
|
45 |
|
46 | class BSON : public ObjectWrap {
|
47 | public:
|
48 | BSON();
|
49 | ~BSON();
|
50 |
|
51 | static void Initialize(Local<Object> target);
|
52 | static NAN_METHOD(BSONDeserializeStream);
|
53 |
|
54 |
|
55 | static NAN_METHOD(BSONSerialize);
|
56 | static NAN_METHOD(BSONDeserialize);
|
57 |
|
58 |
|
59 | static NAN_METHOD(CalculateObjectSize);
|
60 | static NAN_METHOD(SerializeWithBufferAndIndex);
|
61 |
|
62 |
|
63 | static Nan::Persistent<FunctionTemplate> constructor_template;
|
64 |
|
65 | private:
|
66 | static NAN_METHOD(New);
|
67 | static Local<Value> deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item);
|
68 |
|
69 |
|
70 | Nan::Persistent<Function> longConstructor;
|
71 | Nan::Persistent<Function> objectIDConstructor;
|
72 | Nan::Persistent<Function> binaryConstructor;
|
73 | Nan::Persistent<Function> codeConstructor;
|
74 | Nan::Persistent<Function> dbrefConstructor;
|
75 | Nan::Persistent<Function> symbolConstructor;
|
76 | Nan::Persistent<Function> doubleConstructor;
|
77 | Nan::Persistent<Function> timestampConstructor;
|
78 | Nan::Persistent<Function> minKeyConstructor;
|
79 | Nan::Persistent<Function> maxKeyConstructor;
|
80 |
|
81 |
|
82 | Nan::Persistent<String> longString;
|
83 | Nan::Persistent<String> objectIDString;
|
84 | Nan::Persistent<String> binaryString;
|
85 | Nan::Persistent<String> codeString;
|
86 | Nan::Persistent<String> dbrefString;
|
87 | Nan::Persistent<String> symbolString;
|
88 | Nan::Persistent<String> doubleString;
|
89 | Nan::Persistent<String> timestampString;
|
90 | Nan::Persistent<String> minKeyString;
|
91 | Nan::Persistent<String> maxKeyString;
|
92 |
|
93 |
|
94 | Nan::Persistent<String> _bsontypeString;
|
95 | Nan::Persistent<String> _longLowString;
|
96 | Nan::Persistent<String> _longHighString;
|
97 | Nan::Persistent<String> _objectIDidString;
|
98 | Nan::Persistent<String> _binaryPositionString;
|
99 | Nan::Persistent<String> _binarySubTypeString;
|
100 | Nan::Persistent<String> _binaryBufferString;
|
101 | Nan::Persistent<String> _doubleValueString;
|
102 | Nan::Persistent<String> _symbolValueString;
|
103 |
|
104 | Nan::Persistent<String> _dbRefRefString;
|
105 | Nan::Persistent<String> _dbRefIdRefString;
|
106 | Nan::Persistent<String> _dbRefDbRefString;
|
107 | Nan::Persistent<String> _dbRefNamespaceString;
|
108 | Nan::Persistent<String> _dbRefDbString;
|
109 | Nan::Persistent<String> _dbRefOidString;
|
110 |
|
111 | Nan::Persistent<String> _codeCodeString;
|
112 | Nan::Persistent<String> _codeScopeString;
|
113 | Nan::Persistent<String> _toBSONString;
|
114 |
|
115 | public: Local<Object> GetSerializeObject(const Local<Value>& object);
|
116 |
|
117 | template<typename T> friend class BSONSerializer;
|
118 | friend class BSONDeserializer;
|
119 | };
|
120 |
|
121 |
|
122 |
|
123 | class CountStream
|
124 | {
|
125 | public:
|
126 | CountStream() : count(0) { }
|
127 |
|
128 | void WriteByte(int value) { ++count; }
|
129 | void WriteByte(const Local<Object>&, const Local<String>&) { ++count; }
|
130 | void WriteBool(const Local<Value>& value) { ++count; }
|
131 | void WriteInt32(int32_t value) { count += 4; }
|
132 | void WriteInt32(const Local<Value>& value) { count += 4; }
|
133 | void WriteInt32(const Local<Object>& object, const Local<String>& key) { count += 4; }
|
134 | void WriteInt64(int64_t value) { count += 8; }
|
135 | void WriteInt64(const Local<Value>& value) { count += 8; }
|
136 | void WriteDouble(double value) { count += 8; }
|
137 | void WriteDouble(const Local<Value>& value) { count += 8; }
|
138 | void WriteDouble(const Local<Object>&, const Local<String>&) { count += 8; }
|
139 | void WriteUInt32String(uint32_t name) { char buffer[32]; count += sprintf(buffer, "%u", name) + 1; }
|
140 | void WriteLengthPrefixedString(const Local<String>& value) { count += value->Utf8Length()+5; }
|
141 | void WriteObjectId(const Local<Object>& object, const Local<String>& key) { count += 12; }
|
142 | void WriteString(const Local<String>& value) { count += value->Utf8Length() + 1; }
|
143 | void WriteData(const char* data, size_t length) { count += length; }
|
144 |
|
145 | void* BeginWriteType() { ++count; return NULL; }
|
146 | void CommitType(void*, BsonType) { }
|
147 | void* BeginWriteSize() { count += 4; return NULL; }
|
148 | void CommitSize(void*) { }
|
149 |
|
150 | size_t GetSerializeSize() const { return count; }
|
151 |
|
152 |
|
153 | void CheckKey(const Local<String>&) { }
|
154 |
|
155 | private:
|
156 | size_t count;
|
157 | };
|
158 |
|
159 | class DataStream
|
160 | {
|
161 | public:
|
162 | DataStream(char* aDestinationBuffer) : destinationBuffer(aDestinationBuffer), p(aDestinationBuffer) { }
|
163 |
|
164 | void WriteByte(int value) { *p++ = value; }
|
165 | void WriteByte(const Local<Object>& object, const Local<String>& key) { *p++ = object->Get(key)->Int32Value(); }
|
166 | #if USE_MISALIGNED_MEMORY_ACCESS
|
167 | void WriteInt32(int32_t value) { *reinterpret_cast<int32_t*>(p) = value; p += 4; }
|
168 | void WriteInt64(int64_t value) { *reinterpret_cast<int64_t*>(p) = value; p += 8; }
|
169 | void WriteDouble(double value) { *reinterpret_cast<double*>(p) = value; p += 8; }
|
170 | #else
|
171 | void WriteInt32(int32_t value) { memcpy(p, &value, 4); p += 4; }
|
172 | void WriteInt64(int64_t value) { memcpy(p, &value, 8); p += 8; }
|
173 | void WriteDouble(double value) { memcpy(p, &value, 8); p += 8; }
|
174 | #endif
|
175 | void WriteBool(const Local<Value>& value) { WriteByte(value->BooleanValue() ? 1 : 0); }
|
176 | void WriteInt32(const Local<Value>& value) { WriteInt32(value->Int32Value()); }
|
177 | void WriteInt32(const Local<Object>& object, const Local<String>& key) { WriteInt32(object->Get(key)); }
|
178 | void WriteInt64(const Local<Value>& value) { WriteInt64(value->IntegerValue()); }
|
179 | void WriteDouble(const Local<Value>& value) { WriteDouble(value->NumberValue()); }
|
180 | void WriteDouble(const Local<Object>& object, const Local<String>& key) { WriteDouble(object->Get(key)); }
|
181 | void WriteUInt32String(uint32_t name) { p += sprintf(p, "%u", name) + 1; }
|
182 | void WriteLengthPrefixedString(const Local<String>& value) { WriteInt32(value->Utf8Length()+1); WriteString(value); }
|
183 | void WriteObjectId(const Local<Object>& object, const Local<String>& key);
|
184 | void WriteString(const Local<String>& value) { p += value->WriteUtf8(p); }
|
185 | void WriteData(const char* data, size_t length) { memcpy(p, data, length); p += length; }
|
186 |
|
187 | void* BeginWriteType() { void* returnValue = p; p++; return returnValue; }
|
188 | void CommitType(void* beginPoint, BsonType value) { *reinterpret_cast<unsigned char*>(beginPoint) = value; }
|
189 | void* BeginWriteSize() { void* returnValue = p; p += 4; return returnValue; }
|
190 |
|
191 | #if USE_MISALIGNED_MEMORY_ACCESS
|
192 | void CommitSize(void* beginPoint) { *reinterpret_cast<int32_t*>(beginPoint) = (int32_t) (p - (char*) beginPoint); }
|
193 | #else
|
194 | void CommitSize(void* beginPoint) { int32_t value = (int32_t) (p - (char*) beginPoint); memcpy(beginPoint, &value, 4); }
|
195 | #endif
|
196 |
|
197 | size_t GetSerializeSize() const { return p - destinationBuffer; }
|
198 |
|
199 | void CheckKey(const Local<String>& keyName);
|
200 |
|
201 | protected:
|
202 | char *const destinationBuffer;
|
203 | char* p;
|
204 | };
|
205 |
|
206 | template<typename T> class BSONSerializer : public T
|
207 | {
|
208 | private:
|
209 | typedef T Inherited;
|
210 |
|
211 | public:
|
212 | BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions) : Inherited(), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { }
|
213 | BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions, char* parentParam) : Inherited(parentParam), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { }
|
214 |
|
215 | void SerializeDocument(const Local<Value>& value);
|
216 | void SerializeArray(const Local<Value>& value);
|
217 | void SerializeValue(void* typeLocation, const Local<Value>& value);
|
218 |
|
219 | private:
|
220 | bool checkKeys;
|
221 | bool serializeFunctions;
|
222 | BSON* bson;
|
223 | };
|
224 |
|
225 |
|
226 |
|
227 | class BSONDeserializer
|
228 | {
|
229 | public:
|
230 | BSONDeserializer(BSON* aBson, char* data, size_t length);
|
231 | BSONDeserializer(BSONDeserializer& parentSerializer, size_t length);
|
232 |
|
233 | Local<Value> DeserializeDocument(bool promoteLongs);
|
234 |
|
235 | bool HasMoreData() const { return p < pEnd; }
|
236 | Local<Value> ReadCString();
|
237 | uint32_t ReadIntegerString();
|
238 | int32_t ReadRegexOptions();
|
239 | Local<String> ReadString();
|
240 | Local<String> ReadObjectId();
|
241 |
|
242 | unsigned char ReadByte() { return *reinterpret_cast<unsigned char*>(p++); }
|
243 | #if USE_MISALIGNED_MEMORY_ACCESS
|
244 | int32_t ReadInt32() { int32_t returnValue = *reinterpret_cast<int32_t*>(p); p += 4; return returnValue; }
|
245 | uint32_t ReadUInt32() { uint32_t returnValue = *reinterpret_cast<uint32_t*>(p); p += 4; return returnValue; }
|
246 | int64_t ReadInt64() { int64_t returnValue = *reinterpret_cast<int64_t*>(p); p += 8; return returnValue; }
|
247 | double ReadDouble() { double returnValue = *reinterpret_cast<double*>(p); p += 8; return returnValue; }
|
248 | #else
|
249 | int32_t ReadInt32() { int32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; }
|
250 | uint32_t ReadUInt32() { uint32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; }
|
251 | int64_t ReadInt64() { int64_t returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; }
|
252 | double ReadDouble() { double returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; }
|
253 | #endif
|
254 |
|
255 | size_t GetSerializeSize() const { return p - pStart; }
|
256 |
|
257 | private:
|
258 | Local<Value> DeserializeArray(bool promoteLongs);
|
259 | Local<Value> DeserializeValue(BsonType type, bool promoteLongs);
|
260 | Local<Value> DeserializeDocumentInternal(bool promoteLongs);
|
261 | Local<Value> DeserializeArrayInternal(bool promoteLongs);
|
262 |
|
263 | BSON* bson;
|
264 | char* const pStart;
|
265 | char* p;
|
266 | char* const pEnd;
|
267 | };
|
268 |
|
269 |
|
270 |
|
271 | #endif
|
272 |
|
273 |
|