Skip to content
Browse files

Added support for buffers to objectId

  • Loading branch information...
1 parent 6504dda commit aa0b54597a0af28cce3530d2144af708e4b66bf0 @christkv christkv committed May 17, 2016
Showing with 92 additions and 41 deletions.
  1. +74 −23 lib/bson/objectid.js
  2. +11 −1 lib/bson/parser/serializer.js
  3. +1 −1 test/node/bson_compliance_test.js
  4. +6 −2 test/node/bson_test.js
  5. +0 −14 test/node/map_tests.js
View
97 lib/bson/objectid.js
@@ -74,6 +74,12 @@ ObjectID.prototype.toHexString = function() {
var hexString = '';
+ if(this.id instanceof _Buffer) {
+ hexString = convertToHex(this.id);
+ if(ObjectID.cacheHexString) this.__id = hexString;
+ return hexString;
+ }
+
for (var i = 0; i < this.id.length; i++) {
hexString += hexTable[this.id.charCodeAt(i)];
}
@@ -113,7 +119,7 @@ ObjectID.prototype.getInc = function() {
*/
ObjectID.prototype.generate = function(time) {
if ('number' != typeof time) {
- time = parseInt(Date.now()/1000,10);
+ time = ~~(Date.now()/1000);
}
var time4Bytes = BinaryParser.encodeInt(time, 32, true, true);
@@ -160,18 +166,22 @@ ObjectID.prototype.toJSON = function() {
* @param {object} otherID ObjectID instance to compare against.
* @return {boolean} the result of comparing two ObjectID's
*/
-ObjectID.prototype.equals = function equals (otherID) {
+ObjectID.prototype.equals = function equals (otherId) {
var id;
- if(otherID != null && (otherID instanceof ObjectID || otherID.toHexString)) {
- id = otherID.id;
- } else if(typeof otherID == 'string' && ObjectID.isValid(otherID)) {
- id = ObjectID.createFromHexString(otherID).id;
+ if(otherId instanceof ObjectID) {
+ return this.toString() == otherId.toString();
+ } else if(typeof otherId == 'string' && ObjectID.isValid(otherId) && otherId.length == 12 && this.id instanceof _Buffer) {
+ return otherId === this.id.toString('binary');
+ } else if(typeof otherId == 'string' && ObjectID.isValid(otherId) && otherId.length == 24) {
+ return otherId === this.toHexString();
+ } else if(typeof otherId == 'string' && ObjectID.isValid(otherId) && otherId.length == 12) {
+ return otherId === this.id;
+ } else if(otherId != null && (otherId instanceof ObjectID || otherId.toHexString)) {
+ return otherId.toHexString() === this.toHexString();
} else {
return false;
}
-
- return this.id === id;
}
/**
@@ -189,7 +199,7 @@ ObjectID.prototype.getTimestamp = function() {
/**
* @ignore
*/
-ObjectID.index = parseInt(Math.random() * 0xFFFFFF, 10);
+ObjectID.index = ~~(Math.random() * 0xFFFFFF);
/**
* @ignore
@@ -211,35 +221,63 @@ ObjectID.createFromTime = function createFromTime (time) {
return new ObjectID(id);
};
+// Lookup tables
+var encodeLookup = '0123456789abcdef'.split('')
+var decodeLookup = []
+var i = 0
+while (i < 10) decodeLookup[0x30 + i] = i++
+while (i < 16) decodeLookup[0x61 - 10 + i] = i++
+
+var _Buffer = Buffer;
+var convertToHex = function(bytes) {
+ return bytes.toString('hex');
+}
+
/**
* Creates an ObjectID from a hex string representation of an ObjectID.
*
* @method
* @param {string} hexString create a ObjectID from a passed in 24 byte hexstring.
* @return {ObjectID} return the created ObjectID
*/
-ObjectID.createFromHexString = function createFromHexString (hexString) {
+ObjectID.createFromHexString = function createFromHexString (string) {
// Throw an error if it's not a valid setup
- if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24)
+ if(typeof string === 'undefined' || string != null && string.length != 24)
throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters");
- var len = hexString.length;
+ var length = string.length;
- if(len > 12*2) {
+ if(length > 12*2) {
throw new Error('Id cannot be longer than 12 bytes');
}
- var result = ''
- , string
- , number;
+ // Calculate lengths
+ var sizeof = length >> 1;
+ var array = new _Buffer(sizeof);
+ var n = 0;
+ var i = 0;
- for (var index = 0; index < len; index += 2) {
- string = hexString.substr(index, 2);
- number = parseInt(string, 16);
- result += BinaryParser.fromByte(number);
+ while (i < length) {
+ array[n++] = decodeLookup[string.charCodeAt(i++)] << 4 | decodeLookup[string.charCodeAt(i++)]
}
- return new ObjectID(result, hexString);
+ // var result = array.toString('binary');
+ // console.log("!!!!!!!!!!!!!!!!!!!")
+ // console.log(array.toString('binary'))
+
+
+ // var result = ''
+ // , string
+ // , number;
+ //
+ // for (var index = 0; index < len; index += 2) {
+ // string = hexString.substr(index, 2);
+ // // number = 0 + parseInt(string, 16);
+ // number = 0 + string;
+ // result += BinaryParser.fromByte(number);
+ // }ObjectID
+
+ return new ObjectID(array);
};
/**
@@ -251,18 +289,27 @@ ObjectID.createFromHexString = function createFromHexString (hexString) {
ObjectID.isValid = function isValid(id) {
if(id == null) return false;
- if(typeof id == 'number')
+ if(typeof id == 'number') {
return true;
+ }
+
if(typeof id == 'string') {
return id.length == 12 || (id.length == 24 && checkForHexRegExp.test(id));
}
+
if(id instanceof ObjectID) {
return true;
}
+
+ if(id instanceof _Buffer) {
+ return true;
+ }
+
// Duck-Typing detection of ObjectId like objects
if(id.toHexString) {
return id.id.length == 12 || (id.id.length == 24 && checkForHexRegExp.test(id.id));
}
+
return false;
};
@@ -272,7 +319,11 @@ ObjectID.isValid = function isValid(id) {
Object.defineProperty(ObjectID.prototype, "generationTime", {
enumerable: true
, get: function () {
- return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true));
+ if(this.id instanceof _Buffer) {
+ return this.id[0] | this.id[1] << 8 | this.id[2] << 16 | this.id[3] << 24;
+ } else {
+ return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true));
+ }
}
, set: function (value) {
var value = BinaryParser.encodeInt(value, 32, true, true);
View
12 lib/bson/parser/serializer.js
@@ -15,6 +15,12 @@ var writeIEEE754 = require('../float_parser').writeIEEE754,
DBRef = require('../db_ref').DBRef,
Binary = require('../binary').Binary;
+try {
+ var _Buffer = Uint8Array;
+} catch(e) {
+ var _Buffer = Buffer;
+}
+
var regexp = /\x00/
// To ensure that 0.4 of node works correctly
@@ -239,7 +245,11 @@ var serializeObjectId = function(buffer, key, value, index) {
buffer[index++] = 0;
// Write the objectId into the shared buffer
- buffer.write(value.id, index, 'binary')
+ if(typeof value.id == 'string') {
+ buffer.write(value.id, index, 'binary')
+ } else {
+ value.id.copy(buffer, index, 0, 12);
+ }
// Ajust index
return index + 12;
View
2 test/node/bson_compliance_test.js
@@ -125,7 +125,7 @@ exports['Pass all valid BSON serialization scenarios ./compliance/valid.json'] =
// Attempt to deserialize
var object = bson.deserialize(buffer, {promoteLongs:false});
// // Validate the object
- test.deepEqual(expectedDocument, object);
+ test.deepEqual(JSON.stringify(expectedDocument), JSON.stringify(object));
});
test.done();
View
8 test/node/bson_test.js
@@ -1276,7 +1276,7 @@ exports['Should deserialize correctly'] = function(test) {
assertBuffersEqual(test, serialized_data, serialized_data2, 0);
var doc2 = new BSON.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data);
- test.deepEqual(doc, doc2)
+ test.deepEqual(JSON.stringify(doc), JSON.stringify(doc2))
test.done();
}
@@ -1296,7 +1296,10 @@ exports['Should correctly serialize and deserialize MinKey and MaxKey values'] =
assertBuffersEqual(test, serialized_data, serialized_data2, 0);
var doc2 = new BSON.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data);
- test.deepEqual(doc, doc2)
+ // Peform equality checks
+ test.equal(JSON.stringify(doc), JSON.stringify(doc2));
+ test.ok(doc._id.equals(doc2._id))
+ // process.exit(0)
test.ok(doc2.minKey instanceof MinKey);
test.ok(doc2.maxKey instanceof MaxKey);
test.done();
@@ -1744,6 +1747,7 @@ exports['Should fail to create ObjectID due to illegal hex code'] = function(tes
return tmp.toHexString();
}
};
+
test.equal(true, tmp.equals(objectIdLike));
test.equal(true, tmp.equals(new ObjectId(objectIdLike)));
test.equal(true, ObjectID.isValid(objectIdLike));
View
14 test/node/map_tests.js
@@ -104,17 +104,3 @@ exports['should serialize a map'] = function(test) {
var data = bson.serialize(m, false, true);
test.equal('13000000103100010000001030000200000000', data.toString('hex'));
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-

0 comments on commit aa0b545

Please sign in to comment.
Something went wrong with that request. Please try again.