1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

encoding.binary: add functions to read/write with an offset and at the end of the array, split files by endianness (#15301)

This commit is contained in:
Nacho Verdón 2022-08-01 07:20:14 +02:00 committed by GitHub
parent dc78f1ba17
commit 9561fb406e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 663 additions and 217 deletions

View File

@ -0,0 +1,153 @@
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module binary
// big_endian_u16 creates a u16 from the first two bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_u16(b []u8) u16 {
_ = b[1] // bounds check
return u16(b[1]) | (u16(b[0]) << u16(8))
}
// big_endian_u16 creates a u16 from two bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_u16_at(b []u8, o int) u16 {
_ = b[o] // bounds check
_ = b[o + 1] // bounds check
return u16(b[o + 1]) | (u16(b[o]) << u16(8))
}
// big_endian_u16 creates a u16 from two bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_u16_end(b []u8) u16 {
return big_endian_u16_at(b, b.len - 2)
}
// big_endian_put_u16 writes a u16 to the first two bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u16(mut b []u8, v u16) {
_ = b[1] // bounds check
b[0] = u8(v >> u16(8))
b[1] = u8(v)
}
// big_endian_put_u16 writes a u16 to the two bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u16_at(mut b []u8, v u16, o int) {
_ = b[o] // bounds check
_ = b[o + 1] // bounds check
b[o] = u8(v >> u16(8))
b[o + 1] = u8(v)
}
// big_endian_put_u16 writes a u16 to the last two bytes in the array b in big endian order.
[direct_array_access; inline]
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_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 {
_ = b[3] // bounds check
return u32(b[3]) | (u32(b[2]) << u32(8)) | (u32(b[1]) << u32(16)) | (u32(b[0]) << u32(24))
}
// big_endian_u32 creates a u32 from four bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_u32_at(b []u8, o int) u32 {
_ = b[o] // bounds check
_ = b[o + 3] // bounds check
return u32(b[o + 3]) | (u32(b[o + 2]) << u32(8)) | (u32(b[o + 1]) << u32(16)) | (u32(b[o]) << u32(24))
}
// big_endian_u32 creates a u32 from the last four bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_u32_end(b []u8) u32 {
return big_endian_u32_at(b, b.len - 4)
}
// big_endian_put_u32 writes a u32 to the first four bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u32(mut b []u8, v u32) {
_ = b[3] // bounds check
b[0] = u8(v >> u32(24))
b[1] = u8(v >> u32(16))
b[2] = u8(v >> u32(8))
b[3] = u8(v)
}
// big_endian_put_u32 writes a u32 to four bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u32_at(mut b []u8, v u32, o int) {
_ = b[o] // bounds check
_ = b[o + 3] // bounds check
b[o] = u8(v >> u32(24))
b[o + 1] = u8(v >> u32(16))
b[o + 2] = u8(v >> u32(8))
b[o + 3] = u8(v)
}
// big_endian_put_u32 writes a u32 to the last four bytes in the array b in big endian order.
[direct_array_access; inline]
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_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 {
_ = b[7] // bounds check
return u64(b[7]) | (u64(b[6]) << u64(8)) | (u64(b[5]) << u64(16)) | (u64(b[4]) << u64(24)) | (u64(b[3]) << u64(32)) | (u64(b[2]) << u64(40)) | (u64(b[1]) << u64(48)) | (u64(b[0]) << u64(56))
}
// big_endian_u64 creates a u64 from eight bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_u64_at(b []u8, o int) u64 {
_ = b[o] // bounds check
_ = b[o + 7] // bounds check
return u64(b[o + 7]) | (u64(b[o + 6]) << u64(8)) | (u64(b[o + 5]) << u64(16)) | (u64(b[o + 4]) << u64(24)) | (u64(b[
o + 3]) << u64(32)) | (u64(b[o + 2]) << u64(40)) | (u64(b[o + 1]) << u64(48)) | (u64(b[o]) << u64(56))
}
// big_endian_u64 creates a u64 from the last eight bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_u64_end(b []u8) u64 {
return big_endian_u64_at(b, b.len - 8)
}
// big_endian_put_u64 writes a u64 to the first eight bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u64(mut b []u8, v u64) {
_ = b[7] // bounds check
b[0] = u8(v >> u64(56))
b[1] = u8(v >> u64(48))
b[2] = u8(v >> u64(40))
b[3] = u8(v >> u64(32))
b[4] = u8(v >> u64(24))
b[5] = u8(v >> u64(16))
b[6] = u8(v >> u64(8))
b[7] = u8(v)
}
// big_endian_put_u64 writes a u64 to eight bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u64_at(mut b []u8, v u64, o int) {
_ = b[o] // bounds check
_ = b[o + 7] // bounds check
b[o] = u8(v >> u64(56))
b[o + 1] = u8(v >> u64(48))
b[o + 2] = u8(v >> u64(40))
b[o + 3] = u8(v >> u64(32))
b[o + 4] = u8(v >> u64(24))
b[o + 5] = u8(v >> u64(16))
b[o + 6] = u8(v >> u64(8))
b[o + 7] = u8(v)
}
// big_endian_put_u64 writes a u64 to the last eight bytes in the array b at the specified offset in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u64_end(mut b []u8, v u64) {
big_endian_put_u64_at(mut b, v, b.len - 8)
}

View File

@ -0,0 +1,169 @@
module binary
// Big Endian Tests
fn test_big_endian_u16() {
assert big_endian_u16([u8(0), 1]) == u16(1)
assert big_endian_u16([u8(5), 4]) == u16(0x0504)
assert big_endian_u16([u8(0x35), 0x57]) == u16(0x3557)
assert big_endian_u16([u8(0x35), 0x57]) != u16(0x5735)
}
fn test_big_endian_u16_at() {
assert big_endian_u16_at([u8(0), 0, 1, 0], 1) == u16(1)
assert big_endian_u16_at([u8(0), 5, 4, 0], 1) == u16(0x0504)
assert big_endian_u16_at([u8(0), 0x35, 0x57, 0], 1) == u16(0x3557)
assert big_endian_u16_at([u8(0), 0x35, 0x57, 0], 1) != u16(0x5735)
}
fn test_big_endian_u16_end() {
assert big_endian_u16_end([u8(0), 0, 0, 1]) == u16(1)
assert big_endian_u16_end([u8(0), 0, 5, 4]) == u16(0x0504)
assert big_endian_u16_end([u8(0), 0, 0x35, 0x57]) == u16(0x3557)
assert big_endian_u16_end([u8(0), 0, 0x35, 0x57]) != u16(0x5735)
}
fn test_big_endian_put_u16() {
mut buf := []u8{len: 2}
big_endian_put_u16(mut buf, 0x8725)
assert buf == [u8(0x87), 0x25]
big_endian_put_u16(mut buf, 0)
assert buf == [u8(0), 0]
big_endian_put_u16(mut buf, 0xfdff)
assert buf == [u8(0xfd), 0xff]
}
fn test_big_endian_put_u16_at() {
mut buf := []u8{len: 4}
big_endian_put_u16_at(mut buf, 0x8725, 1)
assert buf == [u8(0), 0x87, 0x25, 0]
buf = []u8{len: 4}
big_endian_put_u16_at(mut buf, 1, 1)
assert buf == [u8(0), 0, 1, 0]
buf = []u8{len: 4}
big_endian_put_u16_at(mut buf, 0xfdff, 1)
assert buf == [u8(0), 0xfd, 0xff, 0]
}
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)
assert big_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) == u32(0xf8a29e21)
assert big_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) != u32(0x2192a2f8)
}
fn test_big_endian_u32_at() {
assert big_endian_u32_at([u8(0), 0, 0, 0, 1, 0, 0, 0], 1) == u32(1)
assert big_endian_u32_at([u8(0), 5, 4, 9, 1, 0, 0, 0], 1) == u32(0x05040901)
assert big_endian_u32_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0, 0, 0], 1) == u32(0xf8a29e21)
assert big_endian_u32_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0, 0, 0], 1) != u32(0x2192a2f8)
}
fn test_big_endian_u32_end() {
assert big_endian_u32_end([u8(0), 0, 0, 0, 0, 0, 1]) == u32(1)
assert big_endian_u32_end([u8(0), 0, 0, 0, 5, 4, 9, 1]) == u32(0x05040901)
assert big_endian_u32_end([u8(0), 0, 0, 0, 0xf8, 0xa2, 0x9e, 0x21]) == u32(0xf8a29e21)
assert big_endian_u32_end([u8(0), 0, 0, 0, 0xf8, 0xa2, 0x9e, 0x21]) != u32(0x2192a2f8)
}
fn test_big_endian_put_u32() {
mut buf := []u8{len: 4}
big_endian_put_u32(mut buf, 0x872fea95)
assert buf == [u8(0x87), 0x2f, 0xea, 0x95]
big_endian_put_u32(mut buf, 0)
assert buf == [u8(0), 0, 0, 0]
big_endian_put_u32(mut buf, 0xfdf2e68f)
assert buf == [u8(0xfd), 0xf2, 0xe6, 0x8f]
}
fn test_big_endian_put_u32_at() {
mut buf := []u8{len: 8}
big_endian_put_u32_at(mut buf, 0x872fea95, 1)
assert buf == [u8(0), 0x87, 0x2f, 0xea, 0x95, 0, 0, 0]
buf = []u8{len: 8}
big_endian_put_u32_at(mut buf, 1, 1)
assert buf == [u8(0), 0, 0, 0, 1, 0, 0, 0]
buf = []u8{len: 8}
big_endian_put_u32_at(mut buf, 0xfdf2e68f, 1)
assert buf == [u8(0), 0xfd, 0xf2, 0xe6, 0x8f, 0, 0, 0]
}
fn test_big_endian_put_u32_end() {
mut buf := []u8{len: 8}
big_endian_put_u32_end(mut buf, 0x872fea95)
assert buf == [u8(0), 0, 0, 0, 0x87, 0x2f, 0xea, 0x95]
buf = []u8{len: 8}
big_endian_put_u32_end(mut buf, 1)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 1]
buf = []u8{len: 8}
big_endian_put_u32_end(mut buf, 0xfdf2e68f)
assert buf == [u8(0), 0, 0, 0, 0xfd, 0xf2, 0xe6, 0x8f]
}
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)
assert big_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) == u64(0xf8a29e217f9f8e8f)
assert big_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) != u64(0x8f8e9f7f219ea2f8)
}
fn test_big_endian_u64_at() {
assert big_endian_u64_at([u8(0), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 1) == u64(1)
assert big_endian_u64_at([u8(0), 5, 4, 9, 1, 7, 3, 6, 8, 0, 0, 0, 0, 0, 0, 0], 1) == u64(0x0504090107030608)
assert big_endian_u64_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0, 0, 0, 0,
0, 0, 0], 1) == u64(0xf8a29e217f9f8e8f)
assert big_endian_u64_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0, 0, 0, 0,
0, 0, 0], 1) != u64(0x8f8e9f7f219ea2f8)
}
fn test_big_endian_u64_end() {
assert big_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) == u64(1)
assert big_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 5, 4, 9, 1, 7, 3, 6, 8]) == u64(0x0504090107030608)
assert big_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f,
0x8e, 0x8f]) == u64(0xf8a29e217f9f8e8f)
assert big_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f,
0x8e, 0x8f]) != u64(0x8f8e9f7f219ea2f8)
}
fn test_big_endian_put_u64() {
mut buf := []u8{len: 8}
big_endian_put_u64(mut buf, 0x872fea95fdf2e68f)
assert buf == [u8(0x87), 0x2f, 0xea, 0x95, 0xfd, 0xf2, 0xe6, 0x8f]
big_endian_put_u64(mut buf, 0)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0]
big_endian_put_u64(mut buf, 0xfdf2e68f8e9f7f21)
assert buf == [u8(0xfd), 0xf2, 0xe6, 0x8f, 0x8e, 0x9f, 0x7f, 0x21]
}
fn test_big_endian_put_u64_at() {
mut buf := []u8{len: 16}
big_endian_put_u64_at(mut buf, 0x872fea95fdf2e68f, 1)
assert buf == [u8(0), 0x87, 0x2f, 0xea, 0x95, 0xfd, 0xf2, 0xe6, 0x8f, 0, 0, 0, 0, 0, 0, 0]
buf = []u8{len: 16}
big_endian_put_u64_at(mut buf, 1, 1)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
buf = []u8{len: 16}
big_endian_put_u64_at(mut buf, 0xfdf2e68f8e9f7f21, 1)
assert buf == [u8(0), 0xfd, 0xf2, 0xe6, 0x8f, 0x8e, 0x9f, 0x7f, 0x21, 0, 0, 0, 0, 0, 0, 0]
}
fn test_big_endian_put_u64_end() {
mut buf := []u8{len: 16}
big_endian_put_u64_end(mut buf, 0x872fea95fdf2e68f)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 0x87, 0x2f, 0xea, 0x95, 0xfd, 0xf2, 0xe6, 0x8f]
buf = []u8{len: 16}
big_endian_put_u64_end(mut buf, 1)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
buf = []u8{len: 16}
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]
}

View File

@ -1,110 +0,0 @@
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module binary
// little_endian_u16 creates a u16 from two bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u16(b []u8) u16 {
_ = b[1] // bounds check
return u16(b[0]) | (u16(b[1]) << u16(8))
}
// little_endian_put_u16 writes a u16 to the first two bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u16(mut b []u8, v u16) {
_ = b[1] // bounds check
b[0] = u8(v)
b[1] = u8(v >> u16(8))
}
// little_endian_u32 creates a u32 from four bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u32(b []u8) u32 {
_ = b[3] // bounds check
return u32(b[0]) | (u32(b[1]) << u32(8)) | (u32(b[2]) << u32(16)) | (u32(b[3]) << u32(24))
}
// little_endian_put_u32 writes a u32 to the first four bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u32(mut b []u8, v u32) {
_ = b[3] // bounds check
b[0] = u8(v)
b[1] = u8(v >> u32(8))
b[2] = u8(v >> u32(16))
b[3] = u8(v >> u32(24))
}
// little_endian_u64 creates a u64 from eight bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u64(b []u8) u64 {
_ = b[7] // bounds check
return u64(b[0]) | (u64(b[1]) << u64(8)) | (u64(b[2]) << u64(16)) | (u64(b[3]) << u64(24)) | (u64(b[4]) << u64(32)) | (u64(b[5]) << u64(40)) | (u64(b[6]) << u64(48)) | (u64(b[7]) << u64(56))
}
// little_endian_put_u64 writes a u64 to the first eight bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u64(mut b []u8, v u64) {
_ = b[7] // bounds check
b[0] = u8(v)
b[1] = u8(v >> u64(8))
b[2] = u8(v >> u64(16))
b[3] = u8(v >> u64(24))
b[4] = u8(v >> u64(32))
b[5] = u8(v >> u64(40))
b[6] = u8(v >> u64(48))
b[7] = u8(v >> u64(56))
}
// big_endian_u16 creates a u16 from two bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_u16(b []u8) u16 {
_ = b[1] // bounds check
return u16(b[1]) | (u16(b[0]) << u16(8))
}
// big_endian_put_u16 writes a u16 to the first two bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u16(mut b []u8, v u16) {
_ = b[1] // bounds check
b[0] = u8(v >> u16(8))
b[1] = u8(v)
}
// 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 {
_ = b[3] // bounds check
return u32(b[3]) | (u32(b[2]) << u32(8)) | (u32(b[1]) << u32(16)) | (u32(b[0]) << u32(24))
}
// big_endian_put_u32 writes a u32 to the first four bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u32(mut b []u8, v u32) {
_ = b[3] // bounds check
b[0] = u8(v >> u32(24))
b[1] = u8(v >> u32(16))
b[2] = u8(v >> u32(8))
b[3] = u8(v)
}
// big_endian_u64 creates a u64 from eight bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_u64(b []u8) u64 {
_ = b[7] // bounds check
return u64(b[7]) | (u64(b[6]) << u64(8)) | (u64(b[5]) << u64(16)) | (u64(b[4]) << u64(24)) | (u64(b[3]) << u64(32)) | (u64(b[2]) << u64(40)) | (u64(b[1]) << u64(48)) | (u64(b[0]) << u64(56))
}
// big_endian_put_u64 writes a u64 to the first eight bytes in the array b in big endian order.
[direct_array_access; inline]
pub fn big_endian_put_u64(mut b []u8, v u64) {
_ = b[7] // bounds check
b[0] = u8(v >> u64(56))
b[1] = u8(v >> u64(48))
b[2] = u8(v >> u64(40))
b[3] = u8(v >> u64(32))
b[4] = u8(v >> u64(24))
b[5] = u8(v >> u64(16))
b[6] = u8(v >> u64(8))
b[7] = u8(v)
}

View File

@ -1,107 +0,0 @@
module binary
// Little Endian Tests
fn test_little_endian_u16() {
assert little_endian_u16([u8(0), 0]) == u16(0)
assert little_endian_u16([u8(5), 4]) == u16(0x0405)
assert little_endian_u16([u8(0x35), 0x57]) == u16(0x5735)
assert little_endian_u16([u8(0x35), 0x57]) != u16(0x3557)
}
fn test_little_endian_put_u16() {
mut buf := []u8{len: 2}
little_endian_put_u16(mut buf, 0x8725)
assert buf == [u8(0x25), 0x87]
little_endian_put_u16(mut buf, 0)
assert buf == [u8(0), 0]
little_endian_put_u16(mut buf, 0xfdff)
assert buf == [u8(0xff), 0xfd]
}
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)
assert little_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) == u32(0x219ea2f8)
assert little_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) != u32(0xf8a29e21)
}
fn test_little_endian_put_u32() {
mut buf := []u8{len: 4}
little_endian_put_u32(mut buf, 0x872fea95)
assert buf == [u8(0x95), 0xea, 0x2f, 0x87]
little_endian_put_u32(mut buf, 0)
assert buf == [u8(0), 0, 0, 0]
little_endian_put_u32(mut buf, 0xfdf2e68f)
assert buf == [u8(0x8f), 0xe6, 0xf2, 0xfd]
}
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)
assert little_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) == u64(0x8f8e9f7f219ea2f8)
assert little_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) != u64(0xf8a29e217f9f8e8f)
}
fn test_little_endian_put_u64() {
mut buf := []u8{len: 8}
little_endian_put_u64(mut buf, 0x872fea95fdf2e68f)
assert buf == [u8(0x8f), 0xe6, 0xf2, 0xfd, 0x95, 0xea, 0x2f, 0x87]
little_endian_put_u64(mut buf, 0)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0]
little_endian_put_u64(mut buf, 0xfdf2e68f8e9f7f21)
assert buf == [u8(0x21), 0x7f, 0x9f, 0x8e, 0x8f, 0xe6, 0xf2, 0xfd]
}
// Big Endian Tests
fn test_big_endian_u16() {
assert big_endian_u16([u8(0), 0]) == u16(0)
assert big_endian_u16([u8(5), 4]) == u16(0x0504)
assert big_endian_u16([u8(0x35), 0x57]) == u16(0x3557)
assert big_endian_u16([u8(0x35), 0x57]) != u16(0x5735)
}
fn test_big_endian_put_u16() {
mut buf := []u8{len: 2}
big_endian_put_u16(mut buf, 0x8725)
assert buf == [u8(0x87), 0x25]
big_endian_put_u16(mut buf, 0)
assert buf == [u8(0), 0]
big_endian_put_u16(mut buf, 0xfdff)
assert buf == [u8(0xfd), 0xff]
}
fn test_big_endian_u32() {
assert big_endian_u32([u8(0), 0, 0, 0]) == u32(0)
assert big_endian_u32([u8(5), 4, 9, 1]) == u32(0x05040901)
assert big_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) == u32(0xf8a29e21)
assert big_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) != u32(0x2192a2f8)
}
fn test_big_endian_put_u32() {
mut buf := []u8{len: 4}
big_endian_put_u32(mut buf, 0x872fea95)
assert buf == [u8(0x87), 0x2f, 0xea, 0x95]
big_endian_put_u32(mut buf, 0)
assert buf == [u8(0), 0, 0, 0]
big_endian_put_u32(mut buf, 0xfdf2e68f)
assert buf == [u8(0xfd), 0xf2, 0xe6, 0x8f]
}
fn test_big_endian_u64() {
assert big_endian_u64([u8(0), 0, 0, 0, 0, 0, 0, 0]) == u64(0)
assert big_endian_u64([u8(5), 4, 9, 1, 7, 3, 6, 8]) == u64(0x0504090107030608)
assert big_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) == u64(0xf8a29e217f9f8e8f)
assert big_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) != u64(0x8f8e9f7f219ea2f8)
}
fn test_big_endian_put_u64() {
mut buf := []u8{len: 8}
big_endian_put_u64(mut buf, 0x872fea95fdf2e68f)
assert buf == [u8(0x87), 0x2f, 0xea, 0x95, 0xfd, 0xf2, 0xe6, 0x8f]
big_endian_put_u64(mut buf, 0)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0]
big_endian_put_u64(mut buf, 0xfdf2e68f8e9f7f21)
assert buf == [u8(0xfd), 0xf2, 0xe6, 0x8f, 0x8e, 0x9f, 0x7f, 0x21]
}

View File

@ -0,0 +1,153 @@
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module binary
// little_endian_u16 creates a u16 from the first two bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u16(b []u8) u16 {
_ = b[1] // bounds check
return u16(b[0]) | (u16(b[1]) << u16(8))
}
// little_endian_u16 creates a u16 from two bytes in the array b at the specified offset in little endian order.
[direct_array_access; inline]
pub fn little_endian_u16_at(b []u8, o int) u16 {
_ = b[o] // bounds check
_ = b[o + 1] // bounds check
return u16(b[o]) | (u16(b[o + 1]) << u16(8))
}
// little_endian_u16 creates a u16 from the last two bytes of the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u16_end(b []u8) u16 {
return little_endian_u16_at(b, b.len - 2)
}
// little_endian_put_u16 writes a u16 to the first two bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u16(mut b []u8, v u16) {
_ = b[1] // bounds check
b[0] = u8(v)
b[1] = u8(v >> u16(8))
}
// little_endian_put_u16 writes a u16 to the two bytes in the array b at the specified offset in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u16_at(mut b []u8, v u16, o int) {
_ = b[o] // bounds check
_ = b[o + 1] // bounds check
b[o] = u8(v)
b[o + 1] = u8(v >> u16(8))
}
// little_endian_put_u16 writes a u16 to the last two bytes of the array b in little endian order.
[direct_array_access; inline]
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_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 {
_ = b[3] // bounds check
return u32(b[0]) | (u32(b[1]) << u32(8)) | (u32(b[2]) << u32(16)) | (u32(b[3]) << u32(24))
}
// little_endian_u32 creates a u32 from four bytes in the array b at the specified offset in little endian order.
[direct_array_access; inline]
pub fn little_endian_u32_at(b []u8, o int) u32 {
_ = b[o] // bounds check
_ = b[o + 3] // bounds check
return u32(b[o]) | (u32(b[o + 1]) << u32(8)) | (u32(b[o + 2]) << u32(16)) | (u32(b[o + 3]) << u32(24))
}
// little_endian_u32 creates a u32 from the last four bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u32_end(b []u8) u32 {
return little_endian_u32_at(b, b.len - 4)
}
// little_endian_put_u32 writes a u32 to the first four bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u32(mut b []u8, v u32) {
_ = b[3] // bounds check
b[0] = u8(v)
b[1] = u8(v >> u32(8))
b[2] = u8(v >> u32(16))
b[3] = u8(v >> u32(24))
}
// little_endian_put_u32 writes a u32 to the two bytes in the array b at the specified offset in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u32_at(mut b []u8, v u32, o int) {
_ = b[o] // bounds check
_ = b[o + 3] // bounds check
b[o] = u8(v)
b[o + 1] = u8(v >> u32(8))
b[o + 2] = u8(v >> u32(16))
b[o + 3] = u8(v >> u32(24))
}
// little_endian_put_u32 writes a u32 to the last two bytes in the array b in little endian order.
[direct_array_access; inline]
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_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 {
_ = b[7] // bounds check
return u64(b[0]) | (u64(b[1]) << u64(8)) | (u64(b[2]) << u64(16)) | (u64(b[3]) << u64(24)) | (u64(b[4]) << u64(32)) | (u64(b[5]) << u64(40)) | (u64(b[6]) << u64(48)) | (u64(b[7]) << u64(56))
}
// little_endian_u64 creates a u64 from eight bytes in the array b at the specified offset in little endian order.
[direct_array_access; inline]
pub fn little_endian_u64_at(b []u8, o int) u64 {
_ = b[o] // bounds check
_ = b[o + 7] // bounds check
return u64(b[o]) | (u64(b[o + 1]) << u64(8)) | (u64(b[o + 2]) << u64(16)) | (u64(b[o + 3]) << u64(24)) | (u64(b[
o + 4]) << u64(32)) | (u64(b[o + 5]) << u64(40)) | (u64(b[o + 6]) << u64(48)) | (u64(b[o + 7]) << u64(56))
}
// little_endian_u64 creates a u64 from the last eight bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_u64_end(b []u8) u64 {
return little_endian_u64_at(b, b.len - 8)
}
// little_endian_put_u64 writes a u64 to the first eight bytes in the array b in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u64(mut b []u8, v u64) {
_ = b[7] // bounds check
b[0] = u8(v)
b[1] = u8(v >> u64(8))
b[2] = u8(v >> u64(16))
b[3] = u8(v >> u64(24))
b[4] = u8(v >> u64(32))
b[5] = u8(v >> u64(40))
b[6] = u8(v >> u64(48))
b[7] = u8(v >> u64(56))
}
// little_endian_put_u64 writes a u64 to the eight bytes in the array b at the specified offset in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u64_at(mut b []u8, v u64, o int) {
_ = b[o] // bounds check
_ = b[o + 7] // bounds check
b[o] = u8(v)
b[o + 1] = u8(v >> u64(8))
b[o + 2] = u8(v >> u64(16))
b[o + 3] = u8(v >> u64(24))
b[o + 4] = u8(v >> u64(32))
b[o + 5] = u8(v >> u64(40))
b[o + 6] = u8(v >> u64(48))
b[o + 7] = u8(v >> u64(56))
}
// little_endian_put_u64 writes a u64 to the last eight bytes in the array b at in little endian order.
[direct_array_access; inline]
pub fn little_endian_put_u64_end(mut b []u8, v u64) {
little_endian_put_u64_at(mut b, v, b.len - 8)
}

View File

@ -0,0 +1,188 @@
module binary
// Little Endian Tests
fn test_little_endian_u16() {
assert little_endian_u16([u8(0), 0]) == u16(0)
assert little_endian_u16([u8(5), 4]) == u16(0x0405)
assert little_endian_u16([u8(0x35), 0x57]) == u16(0x5735)
assert little_endian_u16([u8(0x35), 0x57]) != u16(0x3557)
}
fn test_little_endian_u16_at() {
assert little_endian_u16_at([u8(1), 0, 0, 1], 1) == u16(0)
assert little_endian_u16_at([u8(5), 4, 9, 1], 1) == u16(0x0904)
assert little_endian_u16_at([u8(0xf8), 0xa2, 0x9e, 0x21], 1) == u16(0x9ea2)
assert little_endian_u16_at([u8(0xf8), 0xa2, 0x9e, 0x21], 1) != u16(0xa29e)
}
fn test_little_endian_u16_end() {
assert little_endian_u16_end([u8(1), 0, 0, 1]) == u16(0x0100)
assert little_endian_u16_end([u8(5), 4, 9, 1]) == u16(0x0109)
assert little_endian_u16_end([u8(0xf8), 0xa2, 0x9e, 0x21]) == u16(0x219e)
assert little_endian_u16_end([u8(0xf8), 0xa2, 0x9e, 0x21]) != u16(0x9e21)
}
fn test_little_endian_put_u16() {
mut buf := []u8{len: 2}
little_endian_put_u16(mut buf, 0x8725)
assert buf == [u8(0x25), 0x87]
little_endian_put_u16(mut buf, 0)
assert buf == [u8(0), 0]
little_endian_put_u16(mut buf, 0xfdff)
assert buf == [u8(0xff), 0xfd]
}
fn test_little_endian_put_u16_at() {
mut buf := []u8{len: 4}
little_endian_put_u16_at(mut buf, 0x8725, 1)
assert buf == [u8(0), 0x25, 0x87, 0]
buf = []u8{len: 4}
little_endian_put_u16_at(mut buf, 1, 1)
assert buf == [u8(0), 1, 0, 0]
buf = []u8{len: 4}
little_endian_put_u16_at(mut buf, 0xfdff, 1)
assert buf == [u8(0), 0xff, 0xfd, 0]
}
fn test_little_endian_put_u16_end() {
mut buf := []u8{len: 4}
little_endian_put_u16_end(mut buf, 0x8725)
assert buf == [u8(0), 0, 0x25, 0x87]
buf = []u8{len: 4}
little_endian_put_u16_end(mut buf, 1)
assert buf == [u8(0), 0, 1, 0]
buf = []u8{len: 4}
little_endian_put_u16_end(mut buf, 0xfdff)
assert buf == [u8(0), 0, 0xff, 0xfd]
}
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)
assert little_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) == u32(0x219ea2f8)
assert little_endian_u32([u8(0xf8), 0xa2, 0x9e, 0x21]) != u32(0xf8a29e21)
}
fn test_little_endian_u32_at() {
assert little_endian_u32_at([u8(1), 0, 0, 0, 0, 0, 0, 0], 1) == u32(0)
assert little_endian_u32_at([u8(5), 4, 9, 1, 7, 3, 6, 8], 1) == u32(0x07010904)
assert little_endian_u32_at([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f],
1) == u32(0x7f219ea2)
assert little_endian_u32_at([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f],
1) != u32(0xa29e217f)
}
fn test_little_endian_u32_end() {
assert little_endian_u32_end([u8(1), 0, 0, 0, 0, 0, 0, 0]) == u32(0)
assert little_endian_u32_end([u8(5), 4, 9, 1, 7, 3, 6, 8]) == u32(0x08060307)
assert little_endian_u32_end([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) == u32(0x8f8e9f7f)
assert little_endian_u32_end([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) != u32(0x7f9f8e8f)
}
fn test_little_endian_put_u32() {
mut buf := []u8{len: 4}
little_endian_put_u32(mut buf, 0x872fea95)
assert buf == [u8(0x95), 0xea, 0x2f, 0x87]
little_endian_put_u32(mut buf, 0)
assert buf == [u8(0), 0, 0, 0]
little_endian_put_u32(mut buf, 0xfdf2e68f)
assert buf == [u8(0x8f), 0xe6, 0xf2, 0xfd]
}
fn test_little_endian_put_u32_at() {
mut buf := []u8{len: 8}
little_endian_put_u32_at(mut buf, 0x872fea95, 1)
assert buf == [u8(0), 0x95, 0xea, 0x2f, 0x87, 0, 0, 0]
buf = []u8{len: 8}
little_endian_put_u32_at(mut buf, 1, 1)
assert buf == [u8(0), 1, 0, 0, 0, 0, 0, 0]
buf = []u8{len: 8}
little_endian_put_u32_at(mut buf, 0xfdf2e68f, 1)
assert buf == [u8(0), 0x8f, 0xe6, 0xf2, 0xfd, 0, 0, 0]
}
fn test_little_endian_put_u32_end() {
mut buf := []u8{len: 8}
little_endian_put_u32_end(mut buf, 0x872fea95)
assert buf == [u8(0), 0, 0, 0, 0x95, 0xea, 0x2f, 0x87]
buf = []u8{len: 8}
little_endian_put_u32_end(mut buf, 1)
assert buf == [u8(0), 0, 0, 0, 1, 0, 0, 0]
buf = []u8{len: 8}
little_endian_put_u32_end(mut buf, 0xfdf2e68f)
assert buf == [u8(0), 0, 0, 0, 0x8f, 0xe6, 0xf2, 0xfd]
}
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)
assert little_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) == u64(0x8f8e9f7f219ea2f8)
assert little_endian_u64([u8(0xf8), 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f]) != u64(0xf8a29e217f9f8e8f)
}
fn test_little_endian_u64_at() {
assert little_endian_u64_at([u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
1) == u64(0)
assert little_endian_u64_at([u8(0), 5, 4, 9, 1, 7, 3, 6, 8, 0, 0, 0, 0, 0, 0, 0],
1) == u64(0x0806030701090405)
assert little_endian_u64_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0, 0, 0,
0, 0, 0, 0], 1) == u64(0x8f8e9f7f219ea2f8)
assert little_endian_u64_at([u8(0), 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0, 0, 0,
0, 0, 0, 0], 1) != u64(0xf8a29e217f9f8e8f)
}
fn test_little_endian_u64_end() {
assert little_endian_u64_end([u8(1), 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]) == u64(0)
assert little_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 5, 4, 9, 1, 7, 3, 6, 8]) == u64(0x0806030701090405)
assert little_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f,
0x8e, 0x8f]) == u64(0x8f8e9f7f219ea2f8)
assert little_endian_u64_end([u8(0), 0, 0, 0, 0, 0, 0, 0, 0xf8, 0xa2, 0x9e, 0x21, 0x7f, 0x9f,
0x8e, 0x8f]) != u64(0xf8a29e217f9f8e8f)
}
fn test_little_endian_put_u64() {
mut buf := []u8{len: 8}
little_endian_put_u64(mut buf, 0x872fea95fdf2e68f)
assert buf == [u8(0x8f), 0xe6, 0xf2, 0xfd, 0x95, 0xea, 0x2f, 0x87]
little_endian_put_u64(mut buf, 0)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0]
little_endian_put_u64(mut buf, 0xfdf2e68f8e9f7f21)
assert buf == [u8(0x21), 0x7f, 0x9f, 0x8e, 0x8f, 0xe6, 0xf2, 0xfd]
}
fn test_little_endian_put_u64_at() {
mut buf := []u8{len: 16}
little_endian_put_u64_at(mut buf, 0x872fea95fdf2e68f, 1)
assert buf == [u8(0), 0x8f, 0xe6, 0xf2, 0xfd, 0x95, 0xea, 0x2f, 0x87, 0, 0, 0, 0, 0, 0, 0]
buf = []u8{len: 16}
little_endian_put_u64_at(mut buf, 1, 1)
assert buf == [u8(0), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
buf = []u8{len: 16}
little_endian_put_u64_at(mut buf, 0xfdf2e68f8e9f7f21, 1)
assert buf == [u8(0), 0x21, 0x7f, 0x9f, 0x8e, 0x8f, 0xe6, 0xf2, 0xfd, 0, 0, 0, 0, 0, 0, 0]
}
fn test_little_endian_put_u64_end() {
mut buf := []u8{len: 16}
little_endian_put_u64_end(mut buf, 0x872fea95fdf2e68f)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 0x8f, 0xe6, 0xf2, 0xfd, 0x95, 0xea, 0x2f, 0x87]
buf = []u8{len: 16}
little_endian_put_u64_end(mut buf, 1)
assert buf == [u8(0), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
buf = []u8{len: 16}
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]
}