mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Add read/write to stream with big endian ints.
- Move accidently hidden "wrap_bytes".
This commit is contained in:
@@ -402,10 +402,3 @@ fn File* stdin()
|
|||||||
return &stdin_file;
|
return &stdin_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap bytes for reading using io functions.
|
|
||||||
**/
|
|
||||||
fn ByteReader wrap_bytes(char[] bytes)
|
|
||||||
{
|
|
||||||
return { bytes, 0 };
|
|
||||||
}
|
|
||||||
@@ -241,4 +241,205 @@ macro usz! write_varint(stream, x)
|
|||||||
}
|
}
|
||||||
buffer[i] = (char)x;
|
buffer[i] = (char)x;
|
||||||
return write_all(stream, buffer[:i + 1]);
|
return write_all(stream, buffer[:i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro ushort! read_be_ushort(stream)
|
||||||
|
{
|
||||||
|
char hi_byte = stream.read_byte()!;
|
||||||
|
char lo_byte = stream.read_byte()!;
|
||||||
|
return (ushort)(hi_byte << 8 | lo_byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro short! read_be_short(stream)
|
||||||
|
{
|
||||||
|
return read_be_ushort(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_outstream(stream)
|
||||||
|
**/
|
||||||
|
macro void! write_be_short(stream, ushort s)
|
||||||
|
{
|
||||||
|
stream.write_byte((char)(s >> 8))!;
|
||||||
|
stream.write_byte((char)s)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro uint! read_be_uint(stream)
|
||||||
|
{
|
||||||
|
uint val = stream.read_byte()! << 24;
|
||||||
|
val += stream.read_byte()! << 16;
|
||||||
|
val += stream.read_byte()! << 8;
|
||||||
|
return val + stream.read_byte()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro int! read_be_int(stream)
|
||||||
|
{
|
||||||
|
return read_be_uint(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_outstream(stream)
|
||||||
|
**/
|
||||||
|
macro void! write_be_int(stream, uint s)
|
||||||
|
{
|
||||||
|
stream.write_byte((char)(s >> 24))!;
|
||||||
|
stream.write_byte((char)(s >> 16))!;
|
||||||
|
stream.write_byte((char)(s >> 8))!;
|
||||||
|
stream.write_byte((char)s)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro ulong! read_be_ulong(stream)
|
||||||
|
{
|
||||||
|
ulong val = (ulong)stream.read_byte()! << 56;
|
||||||
|
val += (ulong)stream.read_byte()! << 48;
|
||||||
|
val += (ulong)stream.read_byte()! << 40;
|
||||||
|
val += (ulong)stream.read_byte()! << 32;
|
||||||
|
val += (ulong)stream.read_byte()! << 24;
|
||||||
|
val += (ulong)stream.read_byte()! << 16;
|
||||||
|
val += (ulong)stream.read_byte()! << 8;
|
||||||
|
return val + stream.read_byte()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro long! read_be_long(stream)
|
||||||
|
{
|
||||||
|
return read_be_ulong(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_outstream(stream)
|
||||||
|
**/
|
||||||
|
macro void! write_be_long(stream, ulong s)
|
||||||
|
{
|
||||||
|
stream.write_byte((char)(s >> 56))!;
|
||||||
|
stream.write_byte((char)(s >> 48))!;
|
||||||
|
stream.write_byte((char)(s >> 40))!;
|
||||||
|
stream.write_byte((char)(s >> 32))!;
|
||||||
|
stream.write_byte((char)(s >> 24))!;
|
||||||
|
stream.write_byte((char)(s >> 16))!;
|
||||||
|
stream.write_byte((char)(s >> 8))!;
|
||||||
|
stream.write_byte((char)s)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro uint128! read_be_uint128(stream)
|
||||||
|
{
|
||||||
|
uint128 val = (uint128)stream.read_byte()! << 120;
|
||||||
|
val += (uint128)stream.read_byte()! << 112;
|
||||||
|
val += (uint128)stream.read_byte()! << 104;
|
||||||
|
val += (uint128)stream.read_byte()! << 96;
|
||||||
|
val += (uint128)stream.read_byte()! << 88;
|
||||||
|
val += (uint128)stream.read_byte()! << 80;
|
||||||
|
val += (uint128)stream.read_byte()! << 72;
|
||||||
|
val += (uint128)stream.read_byte()! << 64;
|
||||||
|
val += (uint128)stream.read_byte()! << 56;
|
||||||
|
val += (uint128)stream.read_byte()! << 48;
|
||||||
|
val += (uint128)stream.read_byte()! << 40;
|
||||||
|
val += (uint128)stream.read_byte()! << 32;
|
||||||
|
val += (uint128)stream.read_byte()! << 24;
|
||||||
|
val += (uint128)stream.read_byte()! << 16;
|
||||||
|
val += (uint128)stream.read_byte()! << 8;
|
||||||
|
return val + stream.read_byte()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro int128! read_be_int128(stream)
|
||||||
|
{
|
||||||
|
return read_be_uint128(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_outstream(stream)
|
||||||
|
**/
|
||||||
|
macro void! write_be_int128(stream, uint128 s)
|
||||||
|
{
|
||||||
|
stream.write_byte((char)(s >> 120))!;
|
||||||
|
stream.write_byte((char)(s >> 112))!;
|
||||||
|
stream.write_byte((char)(s >> 104))!;
|
||||||
|
stream.write_byte((char)(s >> 96))!;
|
||||||
|
stream.write_byte((char)(s >> 88))!;
|
||||||
|
stream.write_byte((char)(s >> 80))!;
|
||||||
|
stream.write_byte((char)(s >> 72))!;
|
||||||
|
stream.write_byte((char)(s >> 64))!;
|
||||||
|
stream.write_byte((char)(s >> 56))!;
|
||||||
|
stream.write_byte((char)(s >> 48))!;
|
||||||
|
stream.write_byte((char)(s >> 40))!;
|
||||||
|
stream.write_byte((char)(s >> 32))!;
|
||||||
|
stream.write_byte((char)(s >> 24))!;
|
||||||
|
stream.write_byte((char)(s >> 16))!;
|
||||||
|
stream.write_byte((char)(s >> 8))!;
|
||||||
|
stream.write_byte((char)s)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_outstream(stream)
|
||||||
|
* @require data.len < 256 "Data exceeded 255"
|
||||||
|
**/
|
||||||
|
macro usz! write_tiny_bytearray(stream, char[] data)
|
||||||
|
{
|
||||||
|
stream.write_byte((char)data.len)!;
|
||||||
|
return stream.write(data) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro char[]! read_tiny_bytearray(stream, Allocator allocator)
|
||||||
|
{
|
||||||
|
int len = stream.read_byte()!;
|
||||||
|
if (!len) return {};
|
||||||
|
char[] data = allocator::alloc_array(allocator, char, len);
|
||||||
|
io::read_all(stream, data)!;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_outstream(stream)
|
||||||
|
* @require data.len < 0x1000 "Data exceeded 65535"
|
||||||
|
**/
|
||||||
|
macro usz! write_short_bytearray(stream, char[] data)
|
||||||
|
{
|
||||||
|
io::write_be_short(stream, (ushort)data.len)!;
|
||||||
|
return stream.write(data) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @require @is_instream(stream)
|
||||||
|
**/
|
||||||
|
macro char[]! read_short_bytearray(stream, Allocator allocator)
|
||||||
|
{
|
||||||
|
int len = io::read_be_ushort(stream)!;
|
||||||
|
if (!len) return {};
|
||||||
|
char[] data = allocator::alloc_array(allocator, char, len);
|
||||||
|
io::read_all(stream, data)!;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap bytes for reading using io functions.
|
||||||
|
**/
|
||||||
|
fn ByteReader wrap_bytes(char[] bytes)
|
||||||
|
{
|
||||||
|
return { bytes, 0 };
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Remove unintended print of `char[]` as String
|
- Remove unintended print of `char[]` as String
|
||||||
|
- Add read/write to stream with big endian ints.
|
||||||
|
- Move accidently hidden "wrap_bytes".
|
||||||
|
|
||||||
## 0.6.3 Change list
|
## 0.6.3 Change list
|
||||||
|
|
||||||
|
|||||||
87
test/unit/stdlib/io/stream.c3
Normal file
87
test/unit/stdlib/io/stream.c3
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
module std::io @test;
|
||||||
|
|
||||||
|
fn void read_ushort_test()
|
||||||
|
{
|
||||||
|
ByteReader reader = io::wrap_bytes({0x34, 0x8a});
|
||||||
|
assert(io::read_be_ushort(&reader)!! == 0x348a);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void read_uint_test()
|
||||||
|
{
|
||||||
|
ByteReader reader = io::wrap_bytes({0x34, 0x8a, 0xef, 0xcc});
|
||||||
|
assert(io::read_be_uint(&reader)!! == 0x348aefcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void read_ulong_test()
|
||||||
|
{
|
||||||
|
ByteReader reader = io::wrap_bytes({0x34, 0x8a, 0xef, 0xcc, 0x34, 0x8a, 0xef, 0xcc});
|
||||||
|
assert(io::read_be_ulong(&reader)!! == 0x348aefcc348aefcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void read_uint128_test()
|
||||||
|
{
|
||||||
|
ByteReader reader = io::wrap_bytes({0x34, 0x8a, 0xef, 0xcc, 0x34, 0x8a, 0xef, 0xcc, 0x34, 0x8a, 0xef, 0xcc, 0x34, 0x8a, 0xef, 0xcc});
|
||||||
|
assert(io::read_be_uint128(&reader)!! == 0x348aefcc348aefcc348aefcc348aefcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void write_ushort_test()
|
||||||
|
{
|
||||||
|
ByteWriter bw;
|
||||||
|
bw.temp_init();
|
||||||
|
io::write_be_short(&bw, 0x348a)!!;
|
||||||
|
assert(bw.str_view() == &&x'348a');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void write_uint_test()
|
||||||
|
{
|
||||||
|
ByteWriter bw;
|
||||||
|
bw.temp_init();
|
||||||
|
io::write_be_int(&bw, 0x3421348a)!!;
|
||||||
|
assert(bw.str_view() == &&x'3421348a');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void write_ulong_test()
|
||||||
|
{
|
||||||
|
ByteWriter bw;
|
||||||
|
bw.temp_init();
|
||||||
|
io::write_be_long(&bw, 0xaabbccdd3421348a)!!;
|
||||||
|
assert(bw.str_view() == &&x'aabbccdd3421348a');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void write_uint128_test()
|
||||||
|
{
|
||||||
|
ByteWriter bw;
|
||||||
|
bw.temp_init();
|
||||||
|
io::write_be_int128(&bw, 0xaabbccdd3421348aaabbccdd3421348a)!!;
|
||||||
|
assert(bw.str_view() == &&x'aabbccdd3421348aaabbccdd3421348a');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void write_tiny_bytearray_test()
|
||||||
|
{
|
||||||
|
ByteWriter bw;
|
||||||
|
bw.temp_init();
|
||||||
|
io::write_tiny_bytearray(&bw, &&x"aabbcc00112233")!!;
|
||||||
|
assert(bw.str_view() == &&x'07aabbcc00112233');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void write_short_bytearray_test()
|
||||||
|
{
|
||||||
|
ByteWriter bw;
|
||||||
|
bw.temp_init();
|
||||||
|
io::write_short_bytearray(&bw, &&x"aabbcc00112233")!!;
|
||||||
|
assert(bw.str_view() == &&x'0007aabbcc00112233');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void read_tiny_bytearray_test()
|
||||||
|
{
|
||||||
|
ByteReader reader = io::wrap_bytes(&&x'07aabbcc00112233');
|
||||||
|
char[] read = io::read_tiny_bytearray(&reader, allocator: allocator::heap())!;
|
||||||
|
assert(read == &&x'aabbcc00112233');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void read_short_bytearray_test()
|
||||||
|
{
|
||||||
|
ByteReader reader = io::wrap_bytes(&&x'0007aabbcc00112233');
|
||||||
|
char[] read = io::read_short_bytearray(&reader, allocator: allocator::heap())!;
|
||||||
|
assert(read == &&x'aabbcc00112233');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user