summary refs log tree commit diff stats
path: root/lib/pure/oids.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/oids.nim')
-rw-r--r--lib/pure/oids.nim43
1 files changed, 15 insertions, 28 deletions
diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index fb70047b6..4d6ceefd7 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -9,8 +9,7 @@
 
 ## Nim OID support. An OID is a global ID that consists of a timestamp,
 ## a unique counter and a random value. This combination should suffice to
-## produce a globally distributed unique ID. This implementation was extracted
-## from the MongoDB interface and is thus binary compatible with a MongoDB OID.
+## produce a globally distributed unique ID.
 ##
 ## This implementation calls `initRand()` for the first call of
 ## `genOid`.
@@ -18,9 +17,12 @@
 import std/[hashes, times, endians, random]
 from std/private/decode_helpers import handleHexChar
 
+when defined(nimPreviewSlimSystem):
+  import std/sysatomics
+
 type
   Oid* = object ## An OID.
-    time: int32
+    time: int64
     fuzz: int32
     count: int32
 
@@ -42,44 +44,29 @@ proc hexbyte*(hex: char): int {.inline.} =
 
 proc parseOid*(str: cstring): Oid =
   ## Parses an OID.
-  var bytes = cast[cstring](addr(result.time))
+  var bytes = cast[cstring](cast[pointer](cast[int](addr(result.time)) + 4))
   var i = 0
   while i < 12:
     bytes[i] = chr((hexbyte(str[2 * i]) shl 4) or hexbyte(str[2 * i + 1]))
     inc(i)
 
-template toStringImpl[T: string | cstring](result: var T, oid: Oid) =
-  ## Stringifies `oid`.
+proc `$`*(oid: Oid): string =
+  ## Converts an OID to a string.
   const hex = "0123456789abcdef"
-  const N = 24
 
-  when T is string:
-    result.setLen N
+  result.setLen 24
 
   var o = oid
-  var bytes = cast[cstring](addr(o))
+  var bytes = cast[cstring](cast[pointer](cast[int](addr(o)) + 4))
   var i = 0
   while i < 12:
     let b = bytes[i].ord
     result[2 * i] = hex[(b and 0xF0) shr 4]
     result[2 * i + 1] = hex[b and 0xF]
     inc(i)
-  when T is cstring:
-    result[N] = '\0'
-
-proc oidToString*(oid: Oid, str: cstring) {.deprecated: "unsafe; use `$`".} =
-  ## Converts an oid to a string which must have space allocated for 25 elements.
-  # work around a compiler bug:
-  var str = str
-  toStringImpl(str, oid)
-
-proc `$`*(oid: Oid): string =
-  ## Converts an OID to a string.
-  toStringImpl(result, oid)
-
 
 let
-  t = getTime().toUnix.int32
+  t = getTime().toUnix
 
 var
   seed = initRand(t)
@@ -89,10 +76,10 @@ let fuzz = cast[int32](seed.rand(high(int)))
 
 
 template genOid(result: var Oid, incr: var int, fuzz: int32) =
-  var time = getTime().toUnix.int32
+  var time = getTime().toUnix
   var i = cast[int32](atomicInc(incr))
 
-  bigEndian32(addr result.time, addr(time))
+  bigEndian64(addr result.time, addr(time))
   result.fuzz = fuzz
   bigEndian32(addr result.count, addr(i))
 
@@ -106,7 +93,7 @@ proc genOid*(): Oid =
 
 proc generatedTime*(oid: Oid): Time =
   ## Returns the generated timestamp of the OID.
-  var tmp: int32
+  var tmp: int64
   var dummy = oid.time
-  bigEndian32(addr(tmp), addr(dummy))
+  bigEndian64(addr(tmp), addr(dummy))
   result = fromUnix(tmp)