From 6aeef5e4db0c08faf968fe35bbc0951d5fa9d2ff Mon Sep 17 00:00:00 2001 From: Ivan Vatlin Date: Tue, 10 Sep 2024 20:22:34 +0300 Subject: [PATCH] encoding.binary: add `u16`/`u32`/`u64` -> `[]u8` conversion functions (#22193) --- vlib/encoding/binary/big_endian.v | 32 +++++++++++++++++++++++ vlib/encoding/binary/big_endian_test.v | 23 ++++++++++++++++ vlib/encoding/binary/little_endian.v | 32 +++++++++++++++++++++++ vlib/encoding/binary/little_endian_test.v | 23 ++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/vlib/encoding/binary/big_endian.v b/vlib/encoding/binary/big_endian.v index 6d893b73a..e32efac6c 100644 --- a/vlib/encoding/binary/big_endian.v +++ b/vlib/encoding/binary/big_endian.v @@ -47,6 +47,14 @@ pub fn big_endian_put_u16_end(mut b []u8, v u16) { big_endian_put_u16_at(mut b, v, b.len - 2) } +// big_endian_get_u16 creates u8 array from the unsigned 16-bit integer v in big endian order. +pub fn big_endian_get_u16(v u16) []u8 { + mut b := []u8{cap: 2} + b << u8(v >> u16(8)) + b << u8(v) + return b +} + // big_endian_u32 creates a u32 from four bytes in the array b in big endian order. @[direct_array_access; inline] pub fn big_endian_u32(b []u8) u32 { @@ -95,6 +103,16 @@ pub fn big_endian_put_u32_end(mut b []u8, v u32) { big_endian_put_u32_at(mut b, v, b.len - 4) } +// big_endian_get_u32 creates u8 array from the unsigned 32-bit integer v in big endian order. +pub fn big_endian_get_u32(v u32) []u8 { + mut b := []u8{cap: 4} + b << u8(v >> u32(24)) + b << u8(v >> u32(16)) + b << u8(v >> u32(8)) + b << u8(v) + return b +} + // big_endian_u64 creates a u64 from the first eight bytes in the array b in big endian order. @[direct_array_access; inline] pub fn big_endian_u64(b []u8) u64 { @@ -151,3 +169,17 @@ pub fn big_endian_put_u64_at(mut b []u8, v u64, o int) { pub fn big_endian_put_u64_end(mut b []u8, v u64) { big_endian_put_u64_at(mut b, v, b.len - 8) } + +// big_endian_get_u64 creates u8 array from the unsigned 64-bit integer v in big endian order. +pub fn big_endian_get_u64(v u64) []u8 { + mut b := []u8{cap: 8} + b << u8(v >> u64(56)) + b << u8(v >> u64(48)) + b << u8(v >> u64(40)) + b << u8(v >> u64(32)) + b << u8(v >> u64(24)) + b << u8(v >> u64(16)) + b << u8(v >> u64(8)) + b << u8(v) + return b +} diff --git a/vlib/encoding/binary/big_endian_test.v b/vlib/encoding/binary/big_endian_test.v index d2c07bfaf..c06ddeee6 100644 --- a/vlib/encoding/binary/big_endian_test.v +++ b/vlib/encoding/binary/big_endian_test.v @@ -46,6 +46,13 @@ fn test_big_endian_put_u16_at() { assert buf == [u8(0), 0xfd, 0xff, 0] } +fn test_big_endian_get_u16() { + assert big_endian_get_u16(u16(1)) == [u8(0), 1] + assert big_endian_get_u16(u16(0x0504)) == [u8(5), 4] + assert big_endian_get_u16(u16(0x3557)) == [u8(0x35), 0x57] + assert big_endian_get_u16(u16(0x5735)) != [u8(0x35), 0x57] +} + fn test_big_endian_u32() { assert big_endian_u32([u8(0), 0, 0, 1]) == u32(1) assert big_endian_u32([u8(5), 4, 9, 1]) == u32(0x05040901) @@ -105,6 +112,13 @@ fn test_big_endian_put_u32_end() { assert buf == [u8(0), 0, 0, 0, 0xfd, 0xf2, 0xe6, 0x8f] } +fn test_big_endian_get_u32() { + assert big_endian_get_u32(u32(1)) == [u8(0), 0, 0, 1] + assert big_endian_get_u32(u32(0x05040901)) == [u8(5), 4, 9, 1] + assert big_endian_get_u32(u32(0xf8a29e21)) == [u8(0xf8), 0xa2, 0x9e, 0x21] + assert big_endian_get_u32(u32(0x2192a2f8)) != [u8(0xf8), 0xa2, 0x9e, 0x21] +} + fn test_big_endian_u64() { assert big_endian_u64([u8(0), 0, 0, 0, 0, 0, 0, 1]) == u64(1) assert big_endian_u64([u8(5), 4, 9, 1, 7, 3, 6, 8]) == u64(0x0504090107030608) @@ -167,3 +181,12 @@ fn test_big_endian_put_u64_end() { big_endian_put_u64_end(mut buf, 0xfdf2e68f8e9f7f21) assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 0xfd, 0xf2, 0xe6, 0x8f, 0x8e, 0x9f, 0x7f, 0x21] } + +fn test_big_endian_get_u64() { + assert big_endian_get_u64(u64(1)) == [u8(0), 0, 0, 0, 0, 0, 0, 1] + assert big_endian_get_u64(u64(0x0504090107030608)) == [u8(5), 4, 9, 1, 7, 3, 6, 8] + assert big_endian_get_u64(u64(0xf8a29e217f9f8e8f)) == [u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, + 0x8e, 0x8f] + assert big_endian_get_u64(u64(0x8f8e9f7f219ea2f8)) != [u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, + 0x8e, 0x8f] +} diff --git a/vlib/encoding/binary/little_endian.v b/vlib/encoding/binary/little_endian.v index 8aa0f745c..5cfb48b45 100644 --- a/vlib/encoding/binary/little_endian.v +++ b/vlib/encoding/binary/little_endian.v @@ -47,6 +47,14 @@ pub fn little_endian_put_u16_end(mut b []u8, v u16) { little_endian_put_u16_at(mut b, v, b.len - 2) } +// little_endian_get_u16 creates u8 array from the unsigned 16-bit integer v in little endian order. +pub fn little_endian_get_u16(v u16) []u8 { + mut b := []u8{cap: 2} + b << u8(v) + b << u8(v >> u16(8)) + return b +} + // little_endian_u32 creates a u32 from the first four bytes in the array b in little endian order. @[direct_array_access; inline] pub fn little_endian_u32(b []u8) u32 { @@ -95,6 +103,16 @@ pub fn little_endian_put_u32_end(mut b []u8, v u32) { little_endian_put_u32_at(mut b, v, b.len - 4) } +// little_endian_get_u32 creates u8 array from the unsigned 32-bit integer v in little endian order. +pub fn little_endian_get_u32(v u32) []u8 { + mut b := []u8{cap: 4} + b << u8(v) + b << u8(v >> u32(8)) + b << u8(v >> u32(16)) + b << u8(v >> u32(24)) + return b +} + // little_endian_u64 creates a u64 from the first eight bytes in the array b in little endian order. @[direct_array_access; inline] pub fn little_endian_u64(b []u8) u64 { @@ -161,3 +179,17 @@ pub fn little_endian_f32_at(b []u8, o int) f32 { return *(&f32(&u)) } } + +// little_endian_get_u64 creates u8 array from the unsigned 64-bit integer v in little endian order. +pub fn little_endian_get_u64(v u64) []u8 { + mut b := []u8{cap: 8} + b << u8(v) + b << u8(v >> u64(8)) + b << u8(v >> u64(16)) + b << u8(v >> u64(24)) + b << u8(v >> u64(32)) + b << u8(v >> u64(40)) + b << u8(v >> u64(48)) + b << u8(v >> u64(56)) + return b +} diff --git a/vlib/encoding/binary/little_endian_test.v b/vlib/encoding/binary/little_endian_test.v index 6ed87a2ab..9372f0c12 100644 --- a/vlib/encoding/binary/little_endian_test.v +++ b/vlib/encoding/binary/little_endian_test.v @@ -61,6 +61,13 @@ fn test_little_endian_put_u16_end() { assert buf == [u8(0), 0, 0xff, 0xfd] } +fn test_little_endian_get_u16() { + assert little_endian_get_u16(u16(256)) == [u8(0), 1] + assert little_endian_get_u16(u16(0x0405)) == [u8(5), 4] + assert little_endian_get_u16(u16(0x5735)) == [u8(0x35), 0x57] + assert little_endian_get_u16(u16(0x3557)) != [u8(0x35), 0x57] +} + fn test_little_endian_u32() { assert little_endian_u32([u8(0), 0, 0, 0]) == u32(0) assert little_endian_u32([u8(5), 4, 9, 1]) == u32(0x01090405) @@ -122,6 +129,13 @@ fn test_little_endian_put_u32_end() { assert buf == [u8(0), 0, 0, 0, 0x8f, 0xe6, 0xf2, 0xfd] } +fn test_little_endian_get_u32() { + assert little_endian_get_u32(u32(16777216)) == [u8(0), 0, 0, 1] + assert little_endian_get_u32(u32(0x01090405)) == [u8(5), 4, 9, 1] + assert little_endian_get_u32(u32(0x2192a2f8)) == [u8(0xf8), 0xa2, 0x92, 0x21] + assert little_endian_get_u32(u32(0xf8a29e21)) != [u8(0xf8), 0xa2, 0x9e, 0x21] +} + fn test_little_endian_u64() { assert little_endian_u64([u8(0), 0, 0, 0, 0, 0, 0, 0]) == u64(0) assert little_endian_u64([u8(5), 4, 9, 1, 7, 3, 6, 8]) == u64(0x0806030701090405) @@ -195,3 +209,12 @@ fn test_little_endian_put_u64_end() { little_endian_put_u64_end(mut buf, 0xfdf2e68f8e9f7f21) assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0xe6, 0xf2, 0xfd] } + +fn test_little_endian_get_u64() { + assert little_endian_get_u64(u64(72057594037927936)) == [u8(0), 0, 0, 0, 0, 0, 0, 1] + assert little_endian_get_u64(u64(0x0806030701090405)) == [u8(5), 4, 9, 1, 7, 3, 6, 8] + assert little_endian_get_u64(u64(0x8f8e9f7f219ea2f8)) == [u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, + 0x9f, 0x8e, 0x8f] + assert little_endian_get_u64(u64(0xf8a29e217f9f8e8f)) != [u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, + 0x9f, 0x8e, 0x8f] +} -- 2.39.5