99
1010# # Nim OID support. An OID is a global ID that consists of a timestamp,
1111# # a unique counter and a random value. This combination should suffice to
12- # # produce a globally distributed unique ID.
12+ # # produce a globally distributed unique ID. This implementation was extracted
13+ # # from the MongoDB interface and is thus binary compatible with a MongoDB OID.
1314# #
1415# # This implementation calls `initRand()` for the first call of
1516# # `genOid`.
@@ -19,7 +20,7 @@ from std/private/decode_helpers import handleHexChar
1920
2021type
2122 Oid * = object # # An OID.
22- time: int64
23+ time: int32
2324 fuzz: int32
2425 count: int32
2526
@@ -43,27 +44,37 @@ proc parseOid*(str: cstring): Oid =
4344 # # Parses an OID.
4445 var bytes = cast [cstring ](addr (result .time))
4546 var i = 0
46- while i < 16 :
47+ while i < 12 :
4748 bytes[i] = chr ((hexbyte (str[2 * i]) shl 4 ) or hexbyte (str[2 * i + 1 ]))
4849 inc (i)
4950
50- proc `$` * ( oid: Oid ): string =
51- # # Converts an OID to a string .
51+ template toStringImpl [T: string | cstring ](result: var T, oid: Oid ) =
52+ # # Stringifies `oid` .
5253 const hex = " 0123456789abcdef"
54+ const N = 24
5355
54- result .setLen 32
56+ when T is string :
57+ result .setLen N
5558
5659 var o = oid
5760 var bytes = cast [cstring ](addr (o))
5861 var i = 0
59- while i < 16 :
62+ while i < 12 :
6063 let b = bytes[i].ord
6164 result [2 * i] = hex[(b and 0x F0 ) shr 4 ]
6265 result [2 * i + 1 ] = hex[b and 0x F ]
6366 inc (i)
67+ when T is cstring :
68+ result [N] = '\0 '
69+
70+
71+ proc `$` * (oid: Oid ): string =
72+ # # Converts an OID to a string.
73+ toStringImpl (result , oid)
74+
6475
6576let
66- t = getTime ().toUnix
77+ t = getTime ().toUnix. int32
6778
6879var
6980 seed = initRand (t)
@@ -73,24 +84,24 @@ let fuzz = cast[int32](seed.rand(high(int)))
7384
7485
7586template genOid (result: var Oid , incr: var int , fuzz: int32 ) =
76- var time = getTime ().toUnix
87+ var time = getTime ().toUnix. int32
7788 var i = cast [int32 ](atomicInc (incr))
7889
79- bigEndian64 (addr result .time, addr (time))
90+ bigEndian32 (addr result .time, addr (time))
8091 result .fuzz = fuzz
8192 bigEndian32 (addr result .count, addr (i))
8293
8394proc genOid * (): Oid =
8495 # # Generates a new OID.
8596 runnableExamples:
86- doAssert ($ genOid ()).len == 32
97+ doAssert ($ genOid ()).len == 24
8798 runnableExamples (" -r:off" ):
88- echo $ genOid () # for example, "00000000632c452db08c3d19ee9073e5 "
99+ echo $ genOid () # for example, "5fc7f546ddbbc84800006aaf "
89100 genOid (result , incr, fuzz)
90101
91102proc generatedTime * (oid: Oid ): Time =
92103 # # Returns the generated timestamp of the OID.
93- var tmp: int64
104+ var tmp: int32
94105 var dummy = oid.time
95- bigEndian64 (addr (tmp), addr (dummy))
106+ bigEndian32 (addr (tmp), addr (dummy))
96107 result = fromUnix (tmp)
0 commit comments