Permalink
Browse files

Corrected endian problem in automatic generation of ObjectIDs

  • Loading branch information...
1 parent f7671cd commit 79df094e1ec4c0b0aa69b3b6d9235c57b63be1da @idmillington idmillington committed Jun 10, 2010
Showing with 21 additions and 11 deletions.
  1. +4 −4 lib/mongodb/bson/binary_parser.js
  2. +17 −7 lib/mongodb/bson/bson.js
@@ -57,8 +57,8 @@ p.decodeFloat = function( data, precisionBits, exponentBits ){
}while( precisionBits -= startBit );
return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 );
};
-p.decodeInt = function( data, bits, signed ){
- var b = new this.Buffer( this.bigEndian, data ), x = b.readBits( 0, bits ), max = Math.pow( 2, bits );
+p.decodeInt = function( data, bits, signed, forceBigEndian ){
+ var b = new this.Buffer( this.bigEndian||forceBigEndian, data ), x = b.readBits( 0, bits ), max = Math.pow( 2, bits );
return signed && x >= max / 2 ? x - max : x;
};
p.encodeFloat = function( data, precisionBits, exponentBits ){
@@ -104,13 +104,13 @@ p.encodeFloat = function( data, precisionBits, exponentBits ){
r[r.length] = n ? String.fromCharCode( n ) : "";
return ( this.bigEndian ? r.reverse() : r ).join( "" );
};
-p.encodeInt = function( data, bits, signed ){
+p.encodeInt = function( data, bits, signed, forceBigEndian ){
var max = Math.pow( 2, bits );
( data >= max || data < -( max / 2 ) ) && this.warn( "encodeInt::overflow" ) && ( data = 0 );
data < 0 && ( data += max );
for( var r = []; data; r[r.length] = String.fromCharCode( data % 256 ), data = Math.floor( data / 256 ) );
for( bits = -( -bits >> 3 ) - r.length; bits--; r[r.length] = "\0" );
- return ( this.bigEndian ? r.reverse() : r ).join( "" );
+ return ( (this.bigEndian||forceBigEndian) ? r.reverse() : r ).join( "" );
};
p.toSmall = function( data ){ return this.decodeInt( data, 8, true ); };
p.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); };
View
@@ -491,12 +491,22 @@ ObjectID.prototype.get_inc = function() {
return exports.ObjectID.index;
};
+/* Find the machine id. */
+var MACHINE_ID = (function() {
+ // Create a random 3-byte value (i.e. unique for this
+ // process). Other drivers use a md5 of the machine id here, but
+ // that would mean an asyc call to gethostname, so we don't bother.
+ var rnd = parseInt(Math.random() * 0xffffff);
+ return rnd;
+})();
+
ObjectID.prototype.generate = function() {
- var timeInteger = BinaryParser.fromInt(((new Date()).getTime()/1000));
- var memoryInteger = BinaryParser.encodeInt(((new Date()).getTime()/1000000) * Math.random(), 24, false);
- var pidInteger = BinaryParser.fromShort(process.pid);
- var indexInteger = BinaryParser.encodeInt(this.get_inc(), 24, false);
- return timeInteger + memoryInteger + pidInteger + indexInteger;
+ var unixTime = parseInt((new Date()).getTime()/1000);
+ var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true);
+ var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false);
+ var pid2Bytes = BinaryParser.fromShort(process.pid);
+ var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true);
+ return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes;
};
ObjectID.prototype.toHexString = function() {
@@ -514,8 +524,8 @@ ObjectID.prototype.toString = function() {
};
// accurate up to number of seconds
-ObjectID.prototype.__defineGetter__("generationTime", function() {
- return BinaryParser.toInt(this.id.substring(0,4)) * 1000;
+ObjectID.prototype.__defineGetter__("generationTime", function() {
+ return BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true) * 1000;
})
ObjectID.index = 0;

0 comments on commit 79df094

Please sign in to comment.