I've been trying to extend the Schala/nim-modules github repo by adding a 
parseGuid() proc to the module which parses a GUID from a string. At first it 
seemed successful until I took a closer look:

I fed in the string "65e1d5b2-eb88-4111-b31f-792ea13afbe3" but printing it back 
out (via $parseGuid(myGuidStr)) reads 65E1D5B2-B888-4111-311F-792EA13AFBE3. As 
you can see, some of bytes don't match.

Here's the entirety of the module with my additions:
    
    
    import parseutils, random, streams, strutils
    
    type
      GuidVariant* {.pure.} = enum
        ncs, rfc4122, microsoft, future
      
      GuidVersion* {.pure.} = enum
        unknown = -1
        timeBased = 1
        dceSecurity = 2
        nameBasedMd5 = 3
        randomNumberBased = 4
        nameBasedSha1 = 5
      
      Guid* = array[0..15, uint8]
    
    proc randomGuid*(): Guid =
      randomize()
      for i in 0..15: result[i] = uint8(random(255))
      
      # variant
      result[8] = result[8] and 0xbf'u8
      result[8] = result[8] or 0x80'u8
      
      # version
      result[6] = result[6] and 0x4f'u8
      result[6] = result[6] or 0x40'u8
    
    proc nilGuid*(): Guid {.inline.} =
      zeroMem(addr(result), sizeof(Guid))
    
    proc parseGuid*(s: string, offset = 0): Guid =
      var i = 0
      var b = 0
      for j in countup(offset, offset+35, 2):
        if s[j] == '-': continue
        discard s.parseHex(b, j, 2)
        result[i] = uint8(b and 0xff)
        i.inc
    
    proc `variant`*(self: Guid): GuidVariant =
      if (self[8] and 0x80'u8) == 0'u8: return GuidVariant.ncs
      elif (self[8] and 0xc0'u8) == 0x80'u8: return GuidVariant.rfc4122
      elif (self[8] and 0xe0'u8) == 0xc0'u8: return GuidVariant.microsoft
      else: return GuidVariant.future
    
    proc `version`*(self: Guid): GuidVersion =
      case self[6] and 0xf0'u8
      of 0x10'u8: return GuidVersion.timeBased
      of 0x20'u8: return GuidVersion.dceSecurity
      of 0x30'u8: return GuidVersion.nameBasedMd5
      of 0x40'u8: return GuidVersion.randomNumberBased
      of 0x50'u8: return GuidVersion.nameBasedSha1
      else: return GuidVersion.unknown
    
    proc `==`*(lhs, rhs: Guid): bool {.inline.} =
      for i in 0..15:
        result = lhs[i] == rhs[i]
        if result == false: break
    
    proc `!=`*(lhs, rhs: Guid): bool {.inline.} =
      for i in 0..15:
        result = lhs[i] != rhs[i]
        if result == false: break
    
    proc `$`*(self: Guid): string {.inline.} =
      result = ""
      for i in 0..15:
        result = result & int(self[i]).toHex(2)
        if (i == 3) or (i == 5) or (i == 7) or (i == 9):
          result = result & '-'
    
    proc readGuid*(s: Stream): Guid {.inline.} =
      discard s.readData(addr(result), 16)
    
    proc write*(s: Stream, g: var Guid) {.inline.} =
      s.writeData(addr(g), 16)
    

Reply via email to