about summary refs log tree commit diff stats
path: root/src/data
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-02-08 22:24:07 +0100
committerbptato <nincsnevem662@gmail.com>2022-02-08 22:24:07 +0100
commit445c7341c85c94c4fa891f49ff6f4eb87e34b722 (patch)
tree30e6616c050e1d180f8f4219b79b2bb42110ffc0 /src/data
parentc065b4c384e6178d8ca85dd80c40e6da35e6cf4d (diff)
downloadchawan-445c7341c85c94c4fa891f49ff6f4eb87e34b722.tar.gz
Cleanup idna code a bit
Diffstat (limited to 'src/data')
-rw-r--r--src/data/idna.nim185
1 files changed, 85 insertions, 100 deletions
diff --git a/src/data/idna.nim b/src/data/idna.nim
index 5bd38ee4..026d7942 100644
--- a/src/data/idna.nim
+++ b/src/data/idna.nim
@@ -5,41 +5,66 @@ import tables
 import sugar
 import strutils
 
-type IDNATableStatus* = enum
-  IDNA_VALID, IDNA_IGNORED, IDNA_MAPPED, IDNA_DEVIATION, IDNA_DISALLOWED
+type
+  IDNATableStatus* = enum
+    IDNA_VALID, IDNA_IGNORED, IDNA_MAPPED, IDNA_DEVIATION, IDNA_DISALLOWED
+
+type
+  LowMap[T] = seq[(uint16, T)]
+  FullMap[T] = (LowMap[T], seq[(uint32, T)])
+  FullRangeList = (seq[(uint16, uint16)], seq[(uint32, uint32)])
+  FullSet = (set[uint16], HashSet[uint32])
 
 const IdnaMappingTable = staticRead"res/IdnaMappingTable.txt"
 
-func loadStuff(s: string): (seq[(uint16, cstring)], seq[(int, cstring)],
-                            seq[(uint16, uint16)], seq[(int, int)],
-                            set[uint16], HashSet[int],
-                            set[uint16], HashSet[int],
-                            seq[(uint16, cstring)]) =
-  template add_map(i: int, str: string) =
-    if cast[uint](i) <= high(uint16):
-      result[0].add((cast[uint16](i), cstring(str)))
+func loadStuff(s: string): (FullMap[cstring], # Map
+                            FullRangeList, # Disallowed Ranges
+                            FullSet, # Disallowed
+                            FullSet, # Ignored
+                            LowMap[cstring]) = # Deviation
+  template add_map(i: uint32, str: string) =
+    if i <= high(uint16):
+      result[0][0].add((uint16(i), cstring(str)))
     else:
-      result[1].add((i, cstring(str)))
-  template add_disallow(i, j: int) =
-    if cast[uint](i) <= high(uint16):
-      result[2].add((cast[uint16](i), cast[uint16](j)))
+      result[0][1].add((i, cstring(str)))
+  template add_disallow(i, j: uint32) =
+    if i <= high(uint16):
+      result[1][0].add((uint16(i), uint16(j)))
     else:
-      result[3].add((i, j))
-  template add_disallow(i: int) =
-    if cast[uint](i) <= high(uint16):
-      result[4].incl(cast[uint16](i))
+      result[1][1].add((i, j))
+  template add_disallow(i: uint32) =
+    if i <= high(uint16):
+      result[2][0].incl(uint16(i))
     else:
-      result[5].incl(i)
-  template add_ignore(i: int) =
-    if cast[uint](i) <= high(uint16):
-      result[6].incl(cast[uint16](i))
+      result[2][1].incl(i)
+  template add_ignore(i: uint32) =
+    if i <= high(uint16):
+      result[3][0].incl(uint16(i))
     else:
-      result[7].incl(i)
-  template add_deviation(i: int, str: string) =
-    if cast[uint](i) <= high(uint16):
-      result[8].add((cast[uint16](i), cstring(str)))
+      result[3][1].incl(i)
+  template add_deviation(i: uint32, str: string) =
+    if i <= high(uint16):
+      result[4].add((uint16(i), cstring(str)))
     else:
       assert false
+  template add(firstcol: string, str: string, temp: untyped) =
+    if firstcol.contains(".."):
+      let fcs = firstcol.split("..")
+      let rstart = uint32(parseHexInt(fcs[0]))
+      let rend = uint32(parseHexInt(fcs[1]))
+      for i in rstart..rend:
+        temp(i, str)
+    else:
+      temp(uint32(parseHexInt(firstcol)), str)
+  template add(firstcol: string, temp: untyped) =
+    if firstcol.contains(".."):
+      let fcs = firstcol.split("..")
+      let rstart = uint32(parseHexInt(fcs[0]))
+      let rend = uint32(parseHexInt(fcs[1]))
+      for i in rstart..rend:
+        temp(i)
+    else:
+      temp(uint32(parseHexInt(firstcol)))
 
   for line in s.split('\n'):
     if line.len == 0 or line[0] == '#':
@@ -89,74 +114,34 @@ func loadStuff(s: string): (seq[(uint16, cstring)], seq[(int, cstring)],
       for code in codepoints:
         str &= Rune(parseHexInt(code))
 
-      if firstcol.contains(".."):
-        let fcs = firstcol.split("..")
-        let rstart = parseHexInt(fcs[0])
-        let rend = parseHexInt(fcs[1])
-        for i in rstart..rend:
-          add_map(i, str)
-      else:
-        add_map(parseHexInt(firstcol), str)
+      add(firstcol, str, add_map)
     of "deviation":
       let codepoints = thirdcol
       var str = ""
       for code in codepoints:
         str &= Rune(parseHexInt(code))
-      if firstcol.contains(".."):
-        let fcs = firstcol.split("..")
-        let rstart = parseHexInt(fcs[0])
-        let rend = parseHexInt(fcs[1])
-        for i in rstart..rend:
-          add_deviation(i, str)
-      else:
-        add_deviation(parseHexInt(firstcol), str)
+
+      add(firstcol, str, add_deviation)
     of "valid":
       if fourthcol == "NV8" or fourthcol == "XV8":
-        if firstcol.contains(".."):
-          let fcs = firstcol.split("..")
-          let rstart = parseHexInt(fcs[0])
-          let rend = parseHexInt(fcs[1])
-          add_disallow(rstart, rend)
-        else:
-          add_disallow(parseHexInt(firstcol))
+        add(firstcol, add_disallow)
     of "disallowed":
-      if firstcol.contains(".."):
-        let fcs = firstcol.split("..")
-        let rstart = parseHexInt(fcs[0])
-        let rend = parseHexInt(fcs[1])
-        add_disallow(rstart, rend)
-      else:
-        add_disallow(parseHexInt(firstcol))
+      add(firstcol, add_disallow)
     of "ignored":
-      if firstcol.contains(".."):
-        let fcs = firstcol.split("..")
-        let rstart = parseHexInt(fcs[0])
-        let rend = parseHexInt(fcs[1])
-        for i in rstart..rend:
-          add_ignore(i)
-      else:
-        add_ignore(parseHexInt(firstcol))
+      add(firstcol, add_ignore)
 
 when defined(release):
-  const (MappedMap1,
-         MappedMap2,
-         DisallowedRanges1,
-         DisallowedRanges2,
-         Disallowed1,
-         Disallowed2,
-         Ignored1,
-         Ignored2,
+  const (MappedMap,
+         DisallowedRanges,
+         Disallowed,
+         Ignored,
          Deviation) = loadStuff(IdnaMappingTable)
 else:
-  let (MappedMap1,
-         MappedMap2,
-         DisallowedRanges1,
-         DisallowedRanges2,
-         Disallowed1,
-         Disallowed2,
-         Ignored1,
-         Ignored2,
-         Deviation) = loadStuff(IdnaMappingTable)
+  let (MappedMap,
+       DisallowedRanges,
+       Disallowed,
+       Ignored,
+       Deviation) = loadStuff(IdnaMappingTable)
 
 func searchInMap[U, T](a: openarray[(U, T)], u: U): int =
   binarySearch(a, u, (x, y) => cmp(x[0], y))
@@ -168,45 +153,45 @@ func isInRange[U](a: openarray[(U, U)], u: U): bool =
   binarySearch(a, u, (x, y) => (if x[0] < y: -1 elif x[1] > y: 1 else: 0)) != -1
 
 func getIdnaTableStatus*(r: Rune): IDNATableStatus =
-  let i = int(r)
+  let i = uint32(r)
   {.cast(noSideEffect).}:
-    if cast[uint](i) <= high(uint16):
-      let u = cast[uint16](i)
-      if u in Ignored1:
+    if i <= high(uint16):
+      let u = uint16(i)
+      if u in Ignored[0]:
         return IDNA_IGNORED
-      if u in Disallowed1:
+      if u in Disallowed[0]:
         return IDNA_DISALLOWED
       for item in Deviation:
         if item[0] == u:
           return IDNA_DEVIATION
-      if DisallowedRanges1.isInRange(u):
+      if DisallowedRanges[0].isInRange(u):
         return IDNA_DISALLOWED
-      if MappedMap1.isInMap(u):
+      if MappedMap[0].isInMap(u):
         return IDNA_MAPPED
     else:
-      if i in Ignored2:
+      if i in Ignored[1]:
         return IDNA_IGNORED
-      if i in Disallowed2:
+      if i in Disallowed[1]:
         return IDNA_DISALLOWED
-      if DisallowedRanges2.isInRange(i):
+      if DisallowedRanges[1].isInRange(i):
         return IDNA_DISALLOWED
-      if MappedMap2.isInMap(i):
+      if MappedMap[1].isInMap(uint32(i)):
         return IDNA_MAPPED
     return IDNA_VALID
 
 func getIdnaMapped*(r: Rune): string =
   {.cast(noSideEffect).}:
-    let i = int(r)
-    if cast[uint](i) <= high(uint16):
-      let u = cast[uint16](i)
-      let n = MappedMap1.searchInMap(u)
+    let i = uint32(r)
+    if i <= high(uint16):
+      let u = uint16(i)
+      let n = MappedMap[0].searchInMap(u)
       if n != -1:
-        return $MappedMap1[n][1]
-    let n = MappedMap2.searchInMap(i)
-    return $MappedMap2[n][1]
+        return $MappedMap[0][n][1]
+    let n = MappedMap[1].searchInMap(i)
+    return $MappedMap[1][n][1]
 
 func getDeviationMapped*(r: Rune): string =
   {.cast(noSideEffect).}:
     for item in Deviation:
-      if item[0] == cast[uint16](r):
+      if item[0] == uint16(r):
         return $item[1]