summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorflywind <43030857+xflywind@users.noreply.github.com>2021-01-25 00:39:25 -0600
committerGitHub <noreply@github.com>2021-01-25 07:39:25 +0100
commit8d3e0c7b9bb1289c249b2f009089326794a8a74a (patch)
tree7ed83f6170f436055abfab3d8b05ce2f56a11418 /lib/pure
parentd99ea0082944918f23534cb291f6e6d18e5224b7 (diff)
downloadNim-8d3e0c7b9bb1289c249b2f009089326794a8a74a.tar.gz
make oids module better (#16704)
* make oids modules better

* Update lib/pure/oids.nim

* fix
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/oids.nim64
1 files changed, 38 insertions, 26 deletions
diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index 957a8193a..1373d2da6 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -13,9 +13,10 @@
 ## from the Mongodb interface and it thus binary compatible with a Mongo OID.
 ##
 ## This implementation calls `initRand()` for the first call of
-## ``genOid``.
+## `genOid`.
 
-import hashes, times, endians, random
+import std/[hashes, times, endians, random]
+from std/private/decode_helpers import handleHexChar
 
 type
   Oid* = object  ## An OID.
@@ -23,9 +24,9 @@ type
     fuzz: int32  ##
     count: int32 ##
 
-proc `==`*(oid1: Oid, oid2: Oid): bool =
+proc `==`*(oid1: Oid, oid2: Oid): bool {.inline.} =
   ## Compares two Mongo Object IDs for equality.
-  return (oid1.time == oid2.time) and (oid1.fuzz == oid2.fuzz) and
+  result = (oid1.time == oid2.time) and (oid1.fuzz == oid2.fuzz) and
           (oid1.count == oid2.count)
 
 proc hash*(oid: Oid): Hash =
@@ -36,12 +37,8 @@ proc hash*(oid: Oid): Hash =
   h = h !& hash(oid.count)
   result = !$h
 
-proc hexbyte*(hex: char): int =
-  case hex
-  of '0'..'9': result = (ord(hex) - ord('0'))
-  of 'a'..'f': result = (ord(hex) - ord('a') + 10)
-  of 'A'..'F': result = (ord(hex) - ord('A') + 10)
-  else: discard
+proc hexbyte*(hex: char): int {.inline.} =
+  result = handleHexChar(hex)
 
 proc parseOid*(str: cstring): Oid =
   ## Parses an OID.
@@ -51,45 +48,60 @@ proc parseOid*(str: cstring): Oid =
     bytes[i] = chr((hexbyte(str[2 * i]) shl 4) or hexbyte(str[2 * i + 1]))
     inc(i)
 
-proc oidToString*(oid: Oid, str: cstring) =
-  ## Converts an oid to `str` which must have space allocated for 25 elements.
+template toStringImpl[T: string | cstring](result: var T, oid: Oid) =
+  ## Stringifies `oid`.
   const hex = "0123456789abcdef"
-  # work around a compiler bug:
-  var str = str
+  const N = 24
+
+  when T is string:
+    result.setLen N
+
   var o = oid
   var bytes = cast[cstring](addr(o))
   var i = 0
   while i < 12:
     let b = bytes[i].ord
-    str[2 * i] = hex[(b and 0xF0) shr 4]
-    str[2 * i + 1] = hex[b and 0xF]
+    result[2 * i] = hex[(b and 0xF0) shr 4]
+    result[2 * i + 1] = hex[b and 0xF]
     inc(i)
-  str[24] = '\0'
+  when T is cstring:
+    result[N] = '\0'
+
+proc oidToString*(oid: Oid, str: cstring) {.deprecated: "unsafe; use `$`".} =
+  ## Converts an oid to `str` 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 string.
-  result = newString(24)
-  oidToString(oid, result)
+  toStringImpl(result, oid)
 
 
-var
+let
   t = getTime().toUnix.int32
+
+var
   seed = initRand(t)
   incr: int = seed.rand(int.high)
 
 let fuzz = cast[int32](seed.rand(high(int)))
 
+
+template genOid(result: var Oid, incr: var int, fuzz: int32) =
+  var time = getTime().toUnix.int32
+  var i = cast[int32](atomicInc(incr))
+
+  bigEndian32(addr result.time, addr(time))
+  result.fuzz = fuzz
+  bigEndian32(addr result.count, addr(i))
+
 proc genOid*(): Oid =
   ## Generates a new OID.
   runnableExamples:
     doAssert ($genOid()).len == 24
     if false: doAssert $genOid() == "5fc7f546ddbbc84800006aaf"
-  t = getTime().toUnix.int32
-  var i = cast[int32](atomicInc(incr))
-
-  bigEndian32(addr result.time, addr(t))
-  result.fuzz = fuzz
-  bigEndian32(addr result.count, addr(i))
+  genOid(result, incr, fuzz)
 
 proc generatedTime*(oid: Oid): Time =
   ## Returns the generated timestamp of the OID.