mirror of
https://github.com/codex-storage/constantine.git
synced 2025-02-04 06:53:23 +00:00
fix little-endian parsing
This commit is contained in:
parent
2856378427
commit
059439b2c3
@ -75,12 +75,11 @@ func readDecChar(c: range['0'..'9']): int {.inline.}=
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
func parseRawUint*(
|
||||
func parseRawUintLE(
|
||||
src: openarray[byte],
|
||||
bits: static int,
|
||||
endian: static Endianness): BigInt[bits] =
|
||||
bits: static int): BigInt[bits] {.inline.}=
|
||||
## Parse an unsigned integer from its canonical
|
||||
## big-endian or little-endian unsigned representation
|
||||
## little-endian unsigned representation
|
||||
## And store it into a BigInt of size bits
|
||||
##
|
||||
## CT:
|
||||
@ -91,28 +90,39 @@ func parseRawUint*(
|
||||
acc = Word(0)
|
||||
acc_len = 0
|
||||
|
||||
template body(){.dirty.} =
|
||||
for src_idx in 0 ..< src.len:
|
||||
let src_byte = Word(src[src_idx])
|
||||
|
||||
acc = acc and (src_byte shl acc_len)
|
||||
# buffer reads
|
||||
acc = acc or (src_byte shl acc_len)
|
||||
acc_len += 8 # We count bit by bit
|
||||
|
||||
# if full, dump
|
||||
if acc_len >= WordBitSize:
|
||||
result[dst_idx] = acc and MaxWord
|
||||
inc dst_idx
|
||||
acc_len -= WordBitSize
|
||||
acc = src_byte shr (8 - acc_len)
|
||||
|
||||
when endian == bigEndian:
|
||||
for src_idx in countdown(src.high, 0):
|
||||
body()
|
||||
else:
|
||||
for src_idx in 0 ..< src.len:
|
||||
body()
|
||||
|
||||
if acc_len != 0:
|
||||
result[dst_idx] = acc
|
||||
|
||||
func parseRawUint*(
|
||||
src: openarray[byte],
|
||||
bits: static int,
|
||||
order: static Endianness): BigInt[bits] =
|
||||
## Parse an unsigned integer from its canonical
|
||||
## big-endian or little-endian unsigned representation
|
||||
## And store it into a BigInt of size bits
|
||||
##
|
||||
## CT:
|
||||
## - no leaks
|
||||
|
||||
when order == littleEndian:
|
||||
parseRawUintLE(src, bits)
|
||||
else:
|
||||
{.error: "Not implemented at the moment".}
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Serialising from internal representation to canonical format
|
||||
|
@ -31,8 +31,9 @@ suite "IO":
|
||||
T(big[0]) == 0
|
||||
T(big[1]) == 1
|
||||
|
||||
test "Parsing and dumping round-trip":
|
||||
block: # "Little-endian"
|
||||
test "Parsing and dumping round-trip on uint64":
|
||||
block:
|
||||
# "Little-endian" - 2^63
|
||||
let x = 1'u64 shl 63
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
let big = parseRawUint(x_bytes, 64, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||
@ -41,11 +42,21 @@ suite "IO":
|
||||
dumpRawUint(r_bytes, big, littleEndian)
|
||||
check: x_bytes == r_bytes
|
||||
|
||||
# block: # "Little-endian"
|
||||
# let x = uint64 rand(0..high(int))
|
||||
# let x_bytes = cast[array[8, byte]](x)
|
||||
# let big = parseRawUint(x_bytes, 64, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||
block: # "Little-endian" - single random
|
||||
let x = uint64 rand(0..high(int))
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
let big = parseRawUint(x_bytes, 64, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||
|
||||
# var r_bytes: array[8, byte]
|
||||
# dumpRawUint(r_bytes, big, littleEndian)
|
||||
# check: x_bytes == r_bytes
|
||||
var r_bytes: array[8, byte]
|
||||
dumpRawUint(r_bytes, big, littleEndian)
|
||||
check: x_bytes == r_bytes
|
||||
|
||||
block: # "Little-endian" - 10 random cases
|
||||
for _ in 0 ..< 10:
|
||||
let x = uint64 rand(0..high(int))
|
||||
let x_bytes = cast[array[8, byte]](x)
|
||||
let big = parseRawUint(x_bytes, 64, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||
|
||||
var r_bytes: array[8, byte]
|
||||
dumpRawUint(r_bytes, big, littleEndian)
|
||||
check: x_bytes == r_bytes
|
||||
|
Loading…
x
Reference in New Issue
Block a user