diff options
author | bptato <nincsnevem662@gmail.com> | 2022-02-08 22:24:07 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-02-08 22:24:07 +0100 |
commit | 445c7341c85c94c4fa891f49ff6f4eb87e34b722 (patch) | |
tree | 30e6616c050e1d180f8f4219b79b2bb42110ffc0 /src/data | |
parent | c065b4c384e6178d8ca85dd80c40e6da35e6cf4d (diff) | |
download | chawan-445c7341c85c94c4fa891f49ff6f4eb87e34b722.tar.gz |
Cleanup idna code a bit
Diffstat (limited to 'src/data')
-rw-r--r-- | src/data/idna.nim | 185 |
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] |