2023-10-31 13:40:07 +01:00
|
|
|
import ./types
|
|
|
|
|
import constantine/math/arithmetic
|
|
|
|
|
import constantine/math/io/io_bigints
|
|
|
|
|
|
2023-11-02 08:54:04 +01:00
|
|
|
func padRight(source: openArray[byte], endian: static Endianness): array[32, byte] =
|
|
|
|
|
assert source.len <= 31
|
|
|
|
|
when endian == littleEndian:
|
|
|
|
|
copyMem(addr result[0], unsafeAddr source[0], source.len)
|
|
|
|
|
when endian == bigEndian:
|
|
|
|
|
copyMem(addr result[1], unsafeAddr source[0], source.len)
|
|
|
|
|
|
2023-11-01 10:34:55 +01:00
|
|
|
func unmarshal*(
|
2023-10-31 13:40:07 +01:00
|
|
|
_: type F,
|
|
|
|
|
bytes: openArray[byte],
|
2023-11-02 08:54:04 +01:00
|
|
|
endian: static Endianness): F =
|
|
|
|
|
assert bytes.len <= 31
|
|
|
|
|
let padded = bytes.padRight(endian)
|
|
|
|
|
let bigint = B.unmarshal(padded, endian)
|
|
|
|
|
return F.fromBig(bigint)
|
|
|
|
|
|
|
|
|
|
func unmarshal*(
|
|
|
|
|
_: type seq[F],
|
|
|
|
|
bytes: openArray[byte],
|
2023-10-31 13:40:07 +01:00
|
|
|
endian: static Endianness): seq[F] =
|
|
|
|
|
const chunkLen = 31
|
|
|
|
|
var elements: seq[F]
|
2023-11-02 08:54:04 +01:00
|
|
|
var chunkStart = 0
|
|
|
|
|
while chunkStart < bytes.len:
|
|
|
|
|
let chunkEnd = min(chunkStart + 31, bytes.len)
|
|
|
|
|
let element = F.unmarshal(bytes.toOpenArray(chunkStart, chunkEnd - 1), endian)
|
2023-10-31 13:40:07 +01:00
|
|
|
elements.add(element)
|
2023-11-02 08:54:04 +01:00
|
|
|
chunkStart += chunkLen
|
2023-10-31 13:40:07 +01:00
|
|
|
return elements
|