mirror of
https://github.com/logos-storage/nim-contract-abi.git
synced 2026-01-02 13:43:12 +00:00
Support decoding of signed integers
This commit is contained in:
parent
8131170475
commit
a0fad53523
@ -62,7 +62,7 @@ func skipPadding(decoder: var AbiDecoder, amount: int): ?!void =
|
||||
let index = decoder.index
|
||||
?decoder.advance(amount)
|
||||
for i in index..<index+amount:
|
||||
if decoder.bytes[i] != 0:
|
||||
if decoder.bytes[i] notin [0x00'u8, 0xFF'u8]:
|
||||
return failure "invalid padding found"
|
||||
success()
|
||||
|
||||
@ -79,6 +79,23 @@ func read(decoder: var AbiDecoder, amount: int, padding=padLeft): ?!seq[byte] =
|
||||
func decode(decoder: var AbiDecoder, T: type UInt): ?!T =
|
||||
success T.fromBytesBE(?decoder.read(sizeof(T)))
|
||||
|
||||
template unsigned(T: type SomeSignedInt): type SomeUnsignedInt =
|
||||
when T is int8: uint8
|
||||
elif T is int16: uint16
|
||||
elif T is int32: uint32
|
||||
elif T is int64: uint64
|
||||
else: {.error "unsupported signed integer type".}
|
||||
|
||||
func decode(decoder: var AbiDecoder, T: type SomeSignedInt): ?!T =
|
||||
let bytes = ?decoder.read(sizeof(T))
|
||||
let unsigned = T.unsigned.fromBytesBE(bytes)
|
||||
let signed = cast[T](unsigned)
|
||||
success signed
|
||||
|
||||
func decode[bits](decoder: var AbiDecoder, T: type StInt[bits]): ?!T =
|
||||
let unsigned = ?decoder.read(StUint[bits])
|
||||
success cast[T](unsigned)
|
||||
|
||||
template basetype(Range: type range): untyped =
|
||||
when Range isnot SomeUnsignedInt: {.error: "only uint ranges supported".}
|
||||
elif sizeof(Range) == sizeof(uint8): uint8
|
||||
|
||||
@ -89,7 +89,7 @@ func encode[bits](encoder: var AbiEncoder, value: StInt[bits]) =
|
||||
encoder.padleft(bytes, padding)
|
||||
|
||||
func encode(encoder: var AbiEncoder, value: SomeSignedInt) =
|
||||
encoder.write(value.i256)
|
||||
encoder.write(value.to(StInt[64]))
|
||||
|
||||
func encode(encoder: var AbiEncoder, value: bool) =
|
||||
encoder.encode(if value: 1'u8 else: 0'u8)
|
||||
|
||||
@ -18,8 +18,8 @@ proc example*[T](_: type seq[T], len = 0..5): seq[T] =
|
||||
let chosenlen = rand(len)
|
||||
newSeqWith(chosenlen, T.example)
|
||||
|
||||
proc example*(_: type UInt256): UInt256 =
|
||||
UInt256.fromBytes(array[32, byte].example)
|
||||
proc example*(T: type StUint): T =
|
||||
T.fromBytes(array[sizeof(T), byte].example)
|
||||
|
||||
proc example*(_: type UInt128): UInt128 =
|
||||
UInt128.fromBytes(array[16, byte].example)
|
||||
proc example*(T: type StInt): T =
|
||||
cast[T](StUint[T.bits].example)
|
||||
|
||||
@ -20,6 +20,12 @@ suite "ABI decoding":
|
||||
checkDecode(uint32)
|
||||
checkDecode(uint64)
|
||||
|
||||
test "decodes int8, int16, int32, int64":
|
||||
checkDecode(int8)
|
||||
checkDecode(int16)
|
||||
checkDecode(int32)
|
||||
checkDecode(int64)
|
||||
|
||||
test "fails to decode when reading past end":
|
||||
var encoded = AbiEncoder.encode(uint8.example)
|
||||
encoded.delete(encoded.len-1)
|
||||
@ -75,6 +81,8 @@ suite "ABI decoding":
|
||||
test "decodes stints":
|
||||
checkDecode(UInt128)
|
||||
checkDecode(UInt256)
|
||||
checkDecode(Int128)
|
||||
checkDecode(Int256)
|
||||
|
||||
test "decodes byte arrays":
|
||||
checkDecode([1'u8, 2'u8, 3'u8])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user