94 lines
2.6 KiB
Nim
94 lines
2.6 KiB
Nim
import
|
|
os,
|
|
stew/byteutils, stew/ranges/ptr_arith
|
|
|
|
type
|
|
SomePrimitives* = SomeInteger | enum | bool | SomeFloat | char
|
|
|
|
proc setValue*[T: SomePrimitives](key: string, val: openArray[T]) =
|
|
os.putEnv(key, byteutils.toHex(makeOpenArray(val[0].unsafeAddr, byte, val.len*sizeof(T))))
|
|
|
|
proc setValue*(key: string, val: SomePrimitives) =
|
|
os.putEnv(key, byteutils.toHex(makeOpenArray(val.unsafeAddr, byte, sizeof(val))))
|
|
|
|
proc decodePaddedHex(hex: string, res: ptr UncheckedArray[byte], outputLen: int) =
|
|
# make it an even length
|
|
let
|
|
inputLen = hex.len and not 0x01
|
|
numHex = inputLen div 2
|
|
maxLen = min(outputLen, numHex)
|
|
|
|
var
|
|
offI = hex.len - maxLen * 2
|
|
offO = outputLen - maxLen
|
|
|
|
for i in 0 ..< maxLen:
|
|
res[i + offO] = hex[2*i + offI].readHexChar shl 4 or hex[2*i + 1 + offI].readHexChar
|
|
|
|
# write single nibble from odd length hex
|
|
if (offO > 0) and (offI > 0):
|
|
res[offO-1] = hex[offI-1].readHexChar
|
|
|
|
proc getValue*(key: string, outVal: var string) =
|
|
let hex = os.getEnv(key)
|
|
let size = (hex.len div 2) + (hex.len and 0x01)
|
|
outVal.setLen(size)
|
|
decodePaddedHex(hex, cast[ptr UncheckedArray[byte]](outVal[0].addr), size)
|
|
|
|
proc getValue*[T: SomePrimitives](key: string, outVal: var seq[T]) =
|
|
let hex = os.getEnv(key)
|
|
let byteSize = (hex.len div 2) + (hex.len and 0x01)
|
|
let size = (byteSize + sizeof(T) - 1) div sizeof(T)
|
|
outVal.setLen(size)
|
|
decodePaddedHex(hex, cast[ptr UncheckedArray[byte]](outVal[0].addr), size * sizeof(T))
|
|
|
|
proc getValue*[N, T: SomePrimitives](key: string, outVal: var array[N, T]) =
|
|
let hex = os.getEnv(key)
|
|
decodePaddedHex(hex, cast[ptr UncheckedArray[byte]](outVal[0].addr), sizeof(outVal))
|
|
|
|
proc getValue*(key: string, outVal: var SomePrimitives) =
|
|
let hex = os.getEnv(key)
|
|
decodePaddedHex(hex, cast[ptr UncheckedArray[byte]](outVal.addr), sizeof(outVal))
|
|
|
|
template uTypeIsPrimitives*[T](_: type seq[T]): bool =
|
|
when T is SomePrimitives:
|
|
true
|
|
else:
|
|
false
|
|
|
|
template uTypeIsPrimitives*[N, T](_: type array[N, T]): bool =
|
|
when T is SomePrimitives:
|
|
true
|
|
else:
|
|
false
|
|
|
|
template uTypeIsPrimitives*[T](_: type openArray[T]): bool =
|
|
when T is SomePrimitives:
|
|
true
|
|
else:
|
|
false
|
|
|
|
template uTypeIsRecord*(_: typed): bool =
|
|
false
|
|
|
|
template uTypeIsRecord*[T](_: type seq[T]): bool =
|
|
when T is (object or tuple):
|
|
true
|
|
else:
|
|
false
|
|
|
|
template uTypeIsRecord*[N, T](_: type array[N, T]): bool =
|
|
when T is (object or tuple):
|
|
true
|
|
else:
|
|
false
|
|
|
|
func constructKey*(prefix: string, keys: openArray[string]): string =
|
|
var size = prefix.len
|
|
for i in 0..<keys.len:
|
|
inc(size, keys[i].len)
|
|
result = newStringOfCap(size)
|
|
result.add prefix
|
|
for x in keys:
|
|
result.add x
|