Created
May 17, 2018 23:33
-
-
Save treeform/eab4d05013d0953cbec580466e1018d7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #[ | |
| kiwi is a packed key value table/dictinary/associate-arrays like objects that is packed into a single buffer. | |
| kiwis don't optimize key access, but its pretty fast to do a liner scan if your kiwi is less then 100 elements. | |
| ]# | |
| type | |
| Kiwi* = object | |
| arr: seq[uint8] | |
| proc newKiwi*(): Kiwi = | |
| result.arr = newSeq[uint8]() | |
| proc `[]=`*(kiwi: var Kiwi, key, value: string) = | |
| assert key.len <= 0xFFFF | |
| assert value.len <= 0xFFFF | |
| # pack key | |
| kiwi.arr.add(uint8(key.len and 0x00FF)) | |
| kiwi.arr.add(uint8(uint16(key.len and 0xFF00) shr 8)) | |
| for c in key: | |
| kiwi.arr.add(uint8(c)) | |
| # pack value | |
| kiwi.arr.add(uint8(value.len and 0x00FF)) | |
| kiwi.arr.add(uint8(uint16(value.len and 0xFF00) shr 8)) | |
| for c in value: | |
| kiwi.arr.add(uint8(c)) | |
| proc `[]`*(kiwi: var Kiwi, key: string): string = | |
| var i = 0 | |
| while i < kiwi.arr.len: | |
| let keyLen = int(kiwi.arr[i]) + int(kiwi.arr[i+1]) shr 8 | |
| i += 2 | |
| var | |
| j = i | |
| foundKey = true | |
| for c in key: | |
| if char(kiwi.arr[j]) != c: | |
| foundKey = false | |
| break | |
| inc j | |
| i += keylen | |
| let valueLen = int(kiwi.arr[i]) + int(kiwi.arr[i+1]) shr 8 | |
| i += 2 | |
| if foundKey: | |
| result = newStringOfCap(valueLen) | |
| for j in 0..<valueLen: | |
| result &= char(kiwi.arr[i+j]) | |
| return | |
| else: | |
| i += valueLen | |
| iterator items*(kiwi: Kiwi): tuple[k: string, v: string] = | |
| var i = 0 | |
| while i < kiwi.arr.len: | |
| let keyLen = int(kiwi.arr[i]) + int(kiwi.arr[i+1]) shr 85 | |
| i += 2 | |
| var key = newStringOfCap(keyLen) | |
| for j in 0..<keyLen: | |
| key &= char(kiwi.arr[i+j]) | |
| i += keylen | |
| let valueLen = int(kiwi.arr[i]) + int(kiwi.arr[i+1]) shr 8 | |
| i += 2 | |
| var value = newStringOfCap(valueLen) | |
| for j in 0..<valueLen: | |
| value &= char(kiwi.arr[i+j]) | |
| yield (k:key, v:value) | |
| i += valueLen | |
| proc `$`*(kiwi: Kiwi): string = | |
| result = "{" | |
| var first = true | |
| for k, v in kiwi.items: | |
| if not first: | |
| result &= ", " | |
| result &= k & ": " & v | |
| first = false | |
| result &= "}" | |
| import json | |
| proc `%`*(kiwi: Kiwi): JsonNode = | |
| result = newJObject() | |
| for k, v in kiwi.items: | |
| result[k] = newJString(v) | |
| when isMainModule: | |
| var kv = newKiwi() | |
| kv["foo"] = "bar" | |
| kv["1234"] = "abcd" | |
| echo kv["foo"] | |
| echo kv["1234"] | |
| for k, v in kv.items: | |
| echo k, ": ", v | |
| echo kv | |
| var a = "hi there" | |
| var b = a | |
| a[2] = '-' | |
| echo a | |
| echo b |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment