Use proper byte ordering for internal/BSON representation of object ids.

This commit is contained in:
Jim Menard 2009-01-12 10:14:48 -05:00
parent fa171bff3b
commit 89674beb9e
2 changed files with 23 additions and 9 deletions

View File

@ -47,6 +47,14 @@ module XGen
MACHINE = ( val = rand(0x1000000); [val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff] )
PID = ( val = rand(0x10000); [val & 0xff, (val >> 8) & 0xff]; )
# The string representation of an OID is different than its internal
# and BSON byte representations. The BYTE_ORDER here maps
# internal/BSON byte position (the index in BYTE_ORDER) to the
# position of the two hex characters representing that byte in the
# string representation. For example, the 0th BSON byte corresponds to
# the (0-based) 7th pair of hex chars in the string.
BYTE_ORDER = [7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8]
LOCK = Object.new
LOCK.extend Mutex_m
@ -57,14 +65,10 @@ module XGen
# with that value.
def self.from_string(str)
data = []
byte = 0
i = str.to_i(16)
while byte < 12
data << (i & 0xff)
i >>= 8
byte += 1
end
self.new(data.reverse)
BYTE_ORDER.each_with_index { |string_position, data_index|
data[data_index] = str[string_position * 2, 2].to_i(16)
}
self.new(data)
end
# +data+ is an array of bytes. If nil, a new id will be generated.
@ -83,7 +87,11 @@ module XGen
end
def to_s
@data.collect { |b| '%02x' % b }.join
str = ' ' * 24
BYTE_ORDER.each_with_index { |string_position, data_index|
str[string_position * 2, 2] = '%02x' % @data[data_index]
}
str
end
# (Would normally be private, but isn't so we can test it.)

View File

@ -79,4 +79,10 @@ class ObjectIDTest < Test::Unit::TestCase
assert_equal hex_str, o.to_s
end
def test_byte_order
hex_str = '000102030405060708090A0B'
o = ObjectID.from_string(hex_str)
assert_equal [0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0b, 0x0a, 0x09, 0x08], o.to_a
end
end