mirror of
https://github.com/status-im/nim-stint.git
synced 2025-02-22 03:48:20 +00:00
more endians2 implementation and tests
This commit is contained in:
parent
80ccea2643
commit
867739d2ca
78
stint/io.nim
78
stint/io.nim
@ -378,19 +378,85 @@ func readUintBE*[bits: static[int]](ba: openArray[byte]): StUint[bits] {.noinit,
|
|||||||
result = (typeof result).fromBytesBE(ba)
|
result = (typeof result).fromBytesBE(ba)
|
||||||
|
|
||||||
func toByteArrayBE*[bits: static[int]](n: StUint[bits]): array[bits div 8, byte] {.noinit, inline.}=
|
func toByteArrayBE*[bits: static[int]](n: StUint[bits]): array[bits div 8, byte] {.noinit, inline.}=
|
||||||
## Convert a uint[bits] to to a big-endian array of bits div 8 bytes
|
## Convert a Uint[bits] to to a big-endian array of bits div 8 bytes
|
||||||
## Input:
|
## Input:
|
||||||
## - an unsigned integer
|
## - an unsigned integer
|
||||||
## Returns:
|
## Returns:
|
||||||
## - a big-endian array of the same size
|
## - a big-endian array of the same size
|
||||||
result = n.toBytesBE()
|
result = n.toBytesBE()
|
||||||
|
|
||||||
func fromBytesBE*(T: type StUint, ba: openArray[byte], allowPadding: static[bool] = true): T {.noinit, inline.}=
|
func fromBytesBE*(T: type StUint, ba: openArray[byte]): T {.noinit, inline.}=
|
||||||
result = readUintBE[T.bits](ba)
|
result = readUintBE[T.bits](ba)
|
||||||
#when allowPadding:
|
|
||||||
# result = result shl (((sizeof(T) - ba.len) * 8) - 1)
|
|
||||||
|
|
||||||
template initFromBytesBE*(x: var StUint, ba: openArray[byte], allowPadding: static[bool] = true) =
|
template initFromBytesBE*(x: var StUint, ba: openArray[byte]) =
|
||||||
x = fromBytesBE(type x, ba, allowPadding)
|
x = fromBytesBE(type x, ba)
|
||||||
|
|
||||||
|
func readUintLE*[bits: static[int]](ba: openArray[byte]): StUint[bits] {.noinit, inline.}=
|
||||||
|
## Convert a lettle-endian array of (bits div 8) Bytes to an UInt[bits] (in native host endianness)
|
||||||
|
## Input:
|
||||||
|
## - a little-endian openArray of size (bits div 8) at least
|
||||||
|
## Returns:
|
||||||
|
## - A unsigned integer of the same size with `bits` bits
|
||||||
|
result = (typeof result).fromBytesLE(ba)
|
||||||
|
|
||||||
|
func toByteArrayLE*[bits: static[int]](n: StUint[bits]): array[bits div 8, byte] {.noinit, inline.}=
|
||||||
|
## Convert a Uint[bits] to to a little-endian array of bits div 8 bytes
|
||||||
|
## Input:
|
||||||
|
## - an unsigned integer
|
||||||
|
## Returns:
|
||||||
|
## - a little-endian array of the same size
|
||||||
|
result = n.toBytesLE()
|
||||||
|
|
||||||
|
func fromBytesLE*(T: type StUint, ba: openArray[byte]): T {.noinit, inline.}=
|
||||||
|
result = readUintLE[T.bits](ba)
|
||||||
|
|
||||||
|
template initFromBytesLE*(x: var StUint, ba: openArray[byte]) =
|
||||||
|
x = fromBytesLE(type x, ba)
|
||||||
|
|
||||||
|
#---------------Byte Serialization of Signed Integer ---------------------------
|
||||||
|
|
||||||
|
func readIntBE*[bits: static[int]](ba: openArray[byte]): StInt[bits] {.noinit, inline.}=
|
||||||
|
## Convert a big-endian array of (bits div 8) Bytes to an Int[bits] (in native host endianness)
|
||||||
|
## Input:
|
||||||
|
## - a big-endian openArray of size (bits div 8) at least
|
||||||
|
## Returns:
|
||||||
|
## - A signed integer of the same size with `bits` bits
|
||||||
|
result.impl = (typeof result.impl).fromBytesBE(ba)
|
||||||
|
|
||||||
|
func toByteArrayBE*[bits: static[int]](n: StInt[bits]): array[bits div 8, byte] {.noinit, inline.}=
|
||||||
|
## Convert a Int[bits] to to a big-endian array of bits div 8 bytes
|
||||||
|
## Input:
|
||||||
|
## - a signed integer
|
||||||
|
## Returns:
|
||||||
|
## - a big-endian array of the same size
|
||||||
|
result = n.impl.toBytesBE()
|
||||||
|
|
||||||
|
func fromBytesBE*(T: type StInt, ba: openArray[byte]): T {.noinit, inline.}=
|
||||||
|
result = readIntBE[T.bits](ba)
|
||||||
|
|
||||||
|
template initFromBytesBE*(x: var StInt, ba: openArray[byte]) =
|
||||||
|
x = fromBytesBE(type x, ba)
|
||||||
|
|
||||||
|
func readIntLE*[bits: static[int]](ba: openArray[byte]): StInt[bits] {.noinit, inline.}=
|
||||||
|
## Convert a lettle-endian array of (bits div 8) Bytes to an Int[bits] (in native host endianness)
|
||||||
|
## Input:
|
||||||
|
## - a little-endian openArray of size (bits div 8) at least
|
||||||
|
## Returns:
|
||||||
|
## - A signed integer of the same size with `bits` bits
|
||||||
|
result.impl = (typeof result.impl).fromBytesLE(ba)
|
||||||
|
|
||||||
|
func toByteArrayLE*[bits: static[int]](n: StInt[bits]): array[bits div 8, byte] {.noinit, inline.}=
|
||||||
|
## Convert a Int[bits] to to a little-endian array of bits div 8 bytes
|
||||||
|
## Input:
|
||||||
|
## - an signed integer
|
||||||
|
## Returns:
|
||||||
|
## - a little-endian array of the same size
|
||||||
|
result = n.impl.toBytesLE()
|
||||||
|
|
||||||
|
func fromBytesLE*(T: type StInt, ba: openArray[byte]): T {.noinit, inline.}=
|
||||||
|
result = readIntLE[T.bits](ba)
|
||||||
|
|
||||||
|
template initFromBytesLE*(x: var StInt, ba: openArray[byte]) =
|
||||||
|
x = fromBytesLE(type x, ba)
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
@ -54,7 +54,6 @@ template chkStintToStuint(chk, handleErr: untyped, N, bits: static[int]) =
|
|||||||
|
|
||||||
template chkStintToStint(chk, handleErr: untyped, N, bits: static[int]) =
|
template chkStintToStint(chk, handleErr: untyped, N, bits: static[int]) =
|
||||||
block:
|
block:
|
||||||
# TODO add low value tests if bug #92 fixed
|
|
||||||
let y = stint(0, N)
|
let y = stint(0, N)
|
||||||
let z = stint(1, N)
|
let z = stint(1, N)
|
||||||
let v = stint(-1, N)
|
let v = stint(-1, N)
|
||||||
|
80
tests/test_int_endians2.nim
Normal file
80
tests/test_int_endians2.nim
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Stint
|
||||||
|
# Copyright 2018 Status Research & Development GmbH
|
||||||
|
# Licensed under either of
|
||||||
|
#
|
||||||
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||||
|
#
|
||||||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
import ../stint, unittest, stew/byteutils, test_helpers
|
||||||
|
|
||||||
|
template chkToBytesLE(chk: untyped, bits: int, hex: string) =
|
||||||
|
let x = fromHex(StInt[bits], hex)
|
||||||
|
chk toBytes(x, littleEndian).toHex() == x.dumpHex(littleEndian)
|
||||||
|
|
||||||
|
template chkToBytesBE(chk: untyped, bits: int, hex: string) =
|
||||||
|
let x = fromHex(StInt[bits], hex)
|
||||||
|
chk toBytes(x, bigEndian).toHex() == x.dumpHex(bigEndian)
|
||||||
|
|
||||||
|
|
||||||
|
template chkFromBytesBE(chk: untyped, bits: int, hex: string) =
|
||||||
|
let x = fromHex(StInt[bits], hex)
|
||||||
|
let z = fromBytesBE(StInt[bits], toByteArrayBE(x))
|
||||||
|
chk z == x
|
||||||
|
|
||||||
|
template chkFromBytesLE(chk: untyped, bits: int, hex: string) =
|
||||||
|
let x = fromHex(StInt[bits], hex)
|
||||||
|
let z = fromBytesLE(StInt[bits], toByteArrayLE(x))
|
||||||
|
chk z == x
|
||||||
|
|
||||||
|
template chkEndians(chkFunc, tst, name: untyped) =
|
||||||
|
tst astToStr(name).substr(3):
|
||||||
|
name(chkFunc, 64, "abcdef1234567890")
|
||||||
|
name(chkFunc, 128, "abcdef1234567890abcdef1234567890")
|
||||||
|
name(chkFunc, 256, "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890")
|
||||||
|
|
||||||
|
template testEndians(chkFunc, tst: untyped) =
|
||||||
|
chkEndians(chkFunc, tst, chkToBytesLE)
|
||||||
|
chkEndians(chkFunc, tst, chkToBytesBE)
|
||||||
|
chkEndians(chkFunc, tst, chkFromBytesLE)
|
||||||
|
chkEndians(chkFunc, tst, chkFromBytesBE)
|
||||||
|
|
||||||
|
static:
|
||||||
|
testEndians(ctCheck, ctTest)
|
||||||
|
|
||||||
|
suite "Testing endians":
|
||||||
|
test "Endians give sane results":
|
||||||
|
|
||||||
|
check:
|
||||||
|
1.i128.toByteArrayBE() ==
|
||||||
|
[0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
||||||
|
|
||||||
|
1.i128.toByteArrayLE() ==
|
||||||
|
[1'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
1.i128 == Int128.fromBytesBE(
|
||||||
|
[0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
|
||||||
|
|
||||||
|
1.i128 == Int128.fromBytesLE(
|
||||||
|
[1'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||||
|
|
||||||
|
-1.i128.toByteArrayBE() ==
|
||||||
|
[255'u8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
|
||||||
|
|
||||||
|
-2.i128.toByteArrayBE() ==
|
||||||
|
[255'u8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254]
|
||||||
|
|
||||||
|
-1.i128.toByteArrayLE() ==
|
||||||
|
[255'u8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
|
||||||
|
|
||||||
|
-2.i128.toByteArrayLE() ==
|
||||||
|
[254'u8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
|
||||||
|
|
||||||
|
-2.i128 == Int128.fromBytesBE(
|
||||||
|
[255'u8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254])
|
||||||
|
|
||||||
|
-2.i128 == Int128.fromBytesLE(
|
||||||
|
[254'u8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255])
|
||||||
|
|
||||||
|
testEndians(check, test)
|
@ -9,18 +9,6 @@
|
|||||||
|
|
||||||
import ../stint, unittest, stew/byteutils, test_helpers
|
import ../stint, unittest, stew/byteutils, test_helpers
|
||||||
|
|
||||||
|
|
||||||
template chkSwapBytes(chk: untyped, bits: int, hex: string) =
|
|
||||||
# dumpHex already do the job to swap the output if
|
|
||||||
# we use `littleEndian` on both platform
|
|
||||||
# bigEndian: B to B, B to L, L to B
|
|
||||||
# littleEndian: B to L, L to B, B to B
|
|
||||||
chk swapBytes(fromHex(StUint[bits], hex)).dumpHex(littleEndian) == hex
|
|
||||||
|
|
||||||
template chkToBytes(chk: untyped, bits: int, hex: string) =
|
|
||||||
let x = fromHex(StUint[bits], hex)
|
|
||||||
chk toBytes(x).toHex() == x.dumpHex(system.cpuEndian)
|
|
||||||
|
|
||||||
template chkToBytesLE(chk: untyped, bits: int, hex: string) =
|
template chkToBytesLE(chk: untyped, bits: int, hex: string) =
|
||||||
let x = fromHex(StUint[bits], hex)
|
let x = fromHex(StUint[bits], hex)
|
||||||
chk toBytes(x, littleEndian).toHex() == x.dumpHex(littleEndian)
|
chk toBytes(x, littleEndian).toHex() == x.dumpHex(littleEndian)
|
||||||
@ -29,10 +17,6 @@ template chkToBytesBE(chk: untyped, bits: int, hex: string) =
|
|||||||
let x = fromHex(StUint[bits], hex)
|
let x = fromHex(StUint[bits], hex)
|
||||||
chk toBytes(x, bigEndian).toHex() == x.dumpHex(bigEndian)
|
chk toBytes(x, bigEndian).toHex() == x.dumpHex(bigEndian)
|
||||||
|
|
||||||
template chkFromBytes(chk: untyped, bits: int, hex: string) =
|
|
||||||
let x = fromHex(StUint[bits], hex)
|
|
||||||
let z = fromBytes(StUint[bits], toBytes(x))
|
|
||||||
chk z == x
|
|
||||||
|
|
||||||
template chkFromBytesBE(chk: untyped, bits: int, hex: string) =
|
template chkFromBytesBE(chk: untyped, bits: int, hex: string) =
|
||||||
let x = fromHex(StUint[bits], hex)
|
let x = fromHex(StUint[bits], hex)
|
||||||
@ -41,38 +25,20 @@ template chkFromBytesBE(chk: untyped, bits: int, hex: string) =
|
|||||||
|
|
||||||
template chkFromBytesLE(chk: untyped, bits: int, hex: string) =
|
template chkFromBytesLE(chk: untyped, bits: int, hex: string) =
|
||||||
let x = fromHex(StUint[bits], hex)
|
let x = fromHex(StUint[bits], hex)
|
||||||
let z = fromBytesLE(StUint[bits], toBytesLE(x))
|
let z = fromBytesLE(StUint[bits], toByteArrayLE(x))
|
||||||
chk z == x
|
|
||||||
|
|
||||||
template chkFromToLE(chk: untyped, bits: int, hex: string) =
|
|
||||||
let x = fromHex(StUint[bits], hex)
|
|
||||||
let z = x.fromLE.toLE
|
|
||||||
chk z == x
|
|
||||||
|
|
||||||
template chkFromToBE(chk: untyped, bits: int, hex: string) =
|
|
||||||
let x = fromHex(StUint[bits], hex)
|
|
||||||
let z = x.fromBytesBE.toByteArrayBE
|
|
||||||
chk z == x
|
chk z == x
|
||||||
|
|
||||||
template chkEndians(chkFunc, tst, name: untyped) =
|
template chkEndians(chkFunc, tst, name: untyped) =
|
||||||
tst astToStr(name).substr(3):
|
tst astToStr(name).substr(3):
|
||||||
#name(chkFunc, 8, "ab")
|
name(chkFunc, 64, "abcdef1234567890")
|
||||||
#name(chkFunc, 16, "abcd")
|
|
||||||
#name(chkFunc, 32, "abcdef12")
|
|
||||||
#name(chkFunc, 64, "abcdef1234567890")
|
|
||||||
name(chkFunc, 128, "abcdef1234567890abcdef1234567890")
|
name(chkFunc, 128, "abcdef1234567890abcdef1234567890")
|
||||||
name(chkFunc, 256, "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890")
|
name(chkFunc, 256, "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890")
|
||||||
|
|
||||||
template testEndians(chkFunc, tst: untyped) =
|
template testEndians(chkFunc, tst: untyped) =
|
||||||
#chkEndians(chkFunc, tst, chkSwapBytes)
|
chkEndians(chkFunc, tst, chkToBytesLE)
|
||||||
#chkEndians(chkFunc, tst, chkToBytes)
|
|
||||||
#chkEndians(chkFunc, tst, chkToBytesLE)
|
|
||||||
chkEndians(chkFunc, tst, chkToBytesBE)
|
chkEndians(chkFunc, tst, chkToBytesBE)
|
||||||
#chkEndians(chkFunc, tst, chkFromBytes)
|
chkEndians(chkFunc, tst, chkFromBytesLE)
|
||||||
#chkEndians(chkFunc, tst, chkFromBytesLE)
|
chkEndians(chkFunc, tst, chkFromBytesBE)
|
||||||
#chkEndians(chkFunc, tst, chkFromBytesBE)
|
|
||||||
#chkEndians(chkFunc, tst, chkFromToLE)
|
|
||||||
#chkEndians(chkFunc, tst, chkFromToBE)
|
|
||||||
|
|
||||||
static:
|
static:
|
||||||
testEndians(ctCheck, ctTest)
|
testEndians(ctCheck, ctTest)
|
||||||
@ -84,13 +50,13 @@ suite "Testing endians":
|
|||||||
1.u128.toByteArrayBE() ==
|
1.u128.toByteArrayBE() ==
|
||||||
[0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
[0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
||||||
|
|
||||||
#1.u128.toBytesLE() ==
|
1.u128.toByteArrayLE() ==
|
||||||
# [1'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
[1'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
1.u128 == UInt128.fromBytesBE(
|
1.u128 == UInt128.fromBytesBE(
|
||||||
[0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
|
[0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
|
||||||
|
|
||||||
#1.u128 == UInt128.fromBytesLE(
|
1.u128 == UInt128.fromBytesLE(
|
||||||
# [1'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
[1'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||||
|
|
||||||
testEndians(check, test)
|
testEndians(check, test)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user