mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
lib::std::core::bitorder: add read and write
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
committed by
Christoffer Lerno
parent
57424d8b6b
commit
f439539c6e
@@ -87,3 +87,91 @@ bitstruct UInt128LE : uint128 @littleendian
|
||||
uint128 val : 0..127;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require is_array_or_sub_of_char(bytes) "argument must be an array, a pointer to an array or a subarray of char"
|
||||
* @require is_bitorder($Type) "type must be a bitorder integer"
|
||||
**/
|
||||
macro read(bytes, $Type)
|
||||
{
|
||||
char[] s;
|
||||
$switch ($typeof(bytes).kindof)
|
||||
$case POINTER:
|
||||
s = (*bytes)[:$Type.sizeof];
|
||||
$default:
|
||||
s = bytes[:$Type.sizeof];
|
||||
$endswitch
|
||||
return bitcast(*(char[$Type.sizeof]*)s.ptr, $Type).val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require is_arrayptr_or_sub_of_char(bytes) "argument must be a pointer to an array or a subarray of char"
|
||||
* @require is_bitorder($Type) "type must be a bitorder integer"
|
||||
**/
|
||||
macro write(x, bytes, $Type)
|
||||
{
|
||||
char[] s;
|
||||
$switch ($typeof(bytes).kindof)
|
||||
$case POINTER:
|
||||
s = (*bytes)[:$Type.sizeof];
|
||||
$default:
|
||||
s = bytes[:$Type.sizeof];
|
||||
$endswitch
|
||||
*($typeof(x)*)s.ptr = bitcast(x, $Type).val;
|
||||
}
|
||||
|
||||
macro is_bitorder($Type)
|
||||
{
|
||||
$switch ($Type)
|
||||
$case UShortLE:
|
||||
$case ShortLE:
|
||||
$case UIntLE:
|
||||
$case IntLE:
|
||||
$case ULongLE:
|
||||
$case LongLE:
|
||||
$case UInt128LE:
|
||||
$case Int128LE:
|
||||
$case UShortBE:
|
||||
$case ShortBE:
|
||||
$case UIntBE:
|
||||
$case IntBE:
|
||||
$case ULongBE:
|
||||
$case LongBE:
|
||||
$case UInt128BE:
|
||||
$case Int128BE:
|
||||
return true;
|
||||
$endswitch
|
||||
return false;
|
||||
}
|
||||
|
||||
macro bool is_array_or_sub_of_char(bytes)
|
||||
{
|
||||
$switch ($typeof(bytes).kindof)
|
||||
$case POINTER:
|
||||
var $Inner = $typefrom($typeof(bytes).inner);
|
||||
$if $Inner.kindof == ARRAY:
|
||||
var $Inner2 = $typefrom($Inner.inner);
|
||||
return $Inner2.typeid == char.typeid;
|
||||
$endif
|
||||
$case ARRAY:
|
||||
$case SUBARRAY:
|
||||
var $Inner = $typefrom($typeof(bytes).inner);
|
||||
return $Inner.typeid == char.typeid;
|
||||
$endswitch
|
||||
return false;
|
||||
}
|
||||
|
||||
macro bool is_arrayptr_or_sub_of_char(bytes)
|
||||
{
|
||||
$switch ($typeof(bytes).kindof)
|
||||
$case POINTER:
|
||||
var $Inner = $typefrom($typeof(bytes).inner);
|
||||
$if $Inner.kindof == ARRAY:
|
||||
var $Inner2 = $typefrom($Inner.inner);
|
||||
return $Inner2.typeid == char.typeid;
|
||||
$endif
|
||||
$case SUBARRAY:
|
||||
var $Inner = $typefrom($typeof(bytes).inner);
|
||||
return $Inner.typeid == char.typeid;
|
||||
$endswitch
|
||||
return false;
|
||||
}
|
||||
45
test/unit/stdlib/core/bitorder.c3
Normal file
45
test/unit/stdlib/core/bitorder.c3
Normal file
@@ -0,0 +1,45 @@
|
||||
module std::core::bitorder @test;
|
||||
|
||||
fn void! test_read()
|
||||
{
|
||||
char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
|
||||
assert(bitorder::read(bytes, UShortBE) == 0x0102);
|
||||
assert(bitorder::read(bytes, UShortLE) == 0x0201);
|
||||
assert(bitorder::read(bytes, UIntBE) == 0x01020304);
|
||||
assert(bitorder::read(bytes, UIntLE) == 0x04030201);
|
||||
assert(bitorder::read(bytes, ULongBE) == 0x0102030405060708);
|
||||
assert(bitorder::read(bytes, ULongLE) == 0x0807060504030201);
|
||||
|
||||
assert(bitorder::read(&bytes, UShortBE) == 0x0102);
|
||||
assert(bitorder::read(&bytes, UShortLE) == 0x0201);
|
||||
assert(bitorder::read(&bytes, UIntBE) == 0x01020304);
|
||||
assert(bitorder::read(&bytes, UIntLE) == 0x04030201);
|
||||
assert(bitorder::read(&bytes, ULongBE) == 0x0102030405060708);
|
||||
assert(bitorder::read(&bytes, ULongLE) == 0x0807060504030201);
|
||||
|
||||
assert(bitorder::read(bytes[:], UShortBE) == 0x0102);
|
||||
assert(bitorder::read(bytes[:], UShortLE) == 0x0201);
|
||||
assert(bitorder::read(bytes[:], UIntBE) == 0x01020304);
|
||||
assert(bitorder::read(bytes[:], UIntLE) == 0x04030201);
|
||||
assert(bitorder::read(bytes[:], ULongBE) == 0x0102030405060708);
|
||||
assert(bitorder::read(bytes[:], ULongLE) == 0x0807060504030201);
|
||||
}
|
||||
|
||||
fn void! test_write()
|
||||
{
|
||||
char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
char[8] buf;
|
||||
|
||||
ushort x1 = bitorder::read(bytes, UShortBE);
|
||||
bitorder::write(x1, &buf, UShortBE);
|
||||
assert(bitorder::read(buf, UShortBE) == x1);
|
||||
|
||||
uint x2 = bitorder::read(bytes, UIntBE);
|
||||
bitorder::write(x2, buf[:], UIntBE);
|
||||
assert(bitorder::read(buf, UIntBE) == x2);
|
||||
|
||||
ulong x3 = bitorder::read(bytes, ULongBE);
|
||||
bitorder::write(x3, buf[:], ULongBE);
|
||||
assert(bitorder::read(buf, ULongBE) == x3);
|
||||
}
|
||||
Reference in New Issue
Block a user