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],
|
src: openarray[byte],
|
||||||
bits: static int,
|
bits: static int): BigInt[bits] {.inline.}=
|
||||||
endian: static Endianness): BigInt[bits] =
|
|
||||||
## Parse an unsigned integer from its canonical
|
## 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
|
## And store it into a BigInt of size bits
|
||||||
##
|
##
|
||||||
## CT:
|
## CT:
|
||||||
@ -91,28 +90,39 @@ func parseRawUint*(
|
|||||||
acc = Word(0)
|
acc = Word(0)
|
||||||
acc_len = 0
|
acc_len = 0
|
||||||
|
|
||||||
template body(){.dirty.} =
|
for src_idx in 0 ..< src.len:
|
||||||
let src_byte = Word(src[src_idx])
|
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
|
acc_len += 8 # We count bit by bit
|
||||||
|
|
||||||
|
# if full, dump
|
||||||
if acc_len >= WordBitSize:
|
if acc_len >= WordBitSize:
|
||||||
result[dst_idx] = acc and MaxWord
|
result[dst_idx] = acc and MaxWord
|
||||||
inc dst_idx
|
inc dst_idx
|
||||||
acc_len -= WordBitSize
|
acc_len -= WordBitSize
|
||||||
acc = src_byte shr (8 - acc_len)
|
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:
|
if acc_len != 0:
|
||||||
result[dst_idx] = acc
|
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
|
# Serialising from internal representation to canonical format
|
||||||
|
@ -31,8 +31,9 @@ suite "IO":
|
|||||||
T(big[0]) == 0
|
T(big[0]) == 0
|
||||||
T(big[1]) == 1
|
T(big[1]) == 1
|
||||||
|
|
||||||
test "Parsing and dumping round-trip":
|
test "Parsing and dumping round-trip on uint64":
|
||||||
block: # "Little-endian"
|
block:
|
||||||
|
# "Little-endian" - 2^63
|
||||||
let x = 1'u64 shl 63
|
let x = 1'u64 shl 63
|
||||||
let x_bytes = cast[array[8, byte]](x)
|
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
|
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)
|
dumpRawUint(r_bytes, big, littleEndian)
|
||||||
check: x_bytes == r_bytes
|
check: x_bytes == r_bytes
|
||||||
|
|
||||||
# block: # "Little-endian"
|
block: # "Little-endian" - single random
|
||||||
# let x = uint64 rand(0..high(int))
|
let x = uint64 rand(0..high(int))
|
||||||
# let x_bytes = cast[array[8, byte]](x)
|
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
|
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]
|
var r_bytes: array[8, byte]
|
||||||
# dumpRawUint(r_bytes, big, littleEndian)
|
dumpRawUint(r_bytes, big, littleEndian)
|
||||||
# check: x_bytes == r_bytes
|
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