UNPKG

11.3 kBtext/x-cView Raw
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
14using namespace v8;
15using namespace node;
16
17//===========================================================================
18
19enum 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
44template<typename T> class BSONSerializer;
45
46class BSON : public ObjectWrap {
47public:
48 BSON();
49 ~BSON();
50
51 static void Initialize(Local<Object> target);
52 static NAN_METHOD(BSONDeserializeStream);
53
54 // JS based objects
55 static NAN_METHOD(BSONSerialize);
56 static NAN_METHOD(BSONDeserialize);
57
58 // Calculate size of function
59 static NAN_METHOD(CalculateObjectSize);
60 static NAN_METHOD(SerializeWithBufferAndIndex);
61
62 // Constructor used for creating new BSON objects from C++
63 static Nan::Persistent<FunctionTemplate> constructor_template;
64
65private:
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 // BSON type instantiate functions
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 // Equality Objects
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 // Equality speed up comparison objects
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
115public: Local<Object> GetSerializeObject(const Local<Value>& object);
116
117 template<typename T> friend class BSONSerializer;
118 friend class BSONDeserializer;
119};
120
121//===========================================================================
122
123class CountStream
124{
125public:
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; } // This returns the number of bytes exclusive of the NULL terminator
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 // Do nothing. CheckKey is implemented for DataStream
153 void CheckKey(const Local<String>&) { }
154
155private:
156 size_t count;
157};
158
159class DataStream
160{
161public:
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); } // This returns the number of bytes inclusive of the NULL terminator.
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
201protected:
202 char *const destinationBuffer; // base, never changes
203 char* p; // cursor into buffer
204};
205
206template<typename T> class BSONSerializer : public T
207{
208private:
209 typedef T Inherited;
210
211public:
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
219private:
220 bool checkKeys;
221 bool serializeFunctions;
222 BSON* bson;
223};
224
225//===========================================================================
226
227class BSONDeserializer
228{
229public:
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
257private:
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 // BSON_H_
272
273//===========================================================================