| ... | @@ -439,6 +439,7 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T { | ... | @@ -439,6 +439,7 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T { |
| 439 | return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes)); | 439 | return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes)); |
| 440 | } | 440 | } |
| 441 | assert(bytes.len == @sizeOf(T)); | 441 | assert(bytes.len == @sizeOf(T)); |
| | 442 | if (T == u8) return bytes[0]; |
| 442 | var result: T = 0; | 443 | var result: T = 0; |
| 443 | { | 444 | { |
| 444 | comptime var i = 0; | 445 | comptime var i = 0; |
| ... | @@ -456,6 +457,7 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T { | ... | @@ -456,6 +457,7 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T { |
| 456 | return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes)); | 457 | return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes)); |
| 457 | } | 458 | } |
| 458 | assert(bytes.len == @sizeOf(T)); | 459 | assert(bytes.len == @sizeOf(T)); |
| | 460 | if (T == u8) return bytes[0]; |
| 459 | var result: T = 0; | 461 | var result: T = 0; |
| 460 | { | 462 | { |
| 461 | comptime var i = 0; | 463 | comptime var i = 0; |
| ... | @@ -492,6 +494,84 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void { | ... | @@ -492,6 +494,84 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void { |
| 492 | assert(bits == 0); | 494 | assert(bits == 0); |
| 493 | } | 495 | } |
| 494 | | 496 | |
| | 497 | pub fn writeIntBE(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void { |
| | 498 | assert(T.bit_count % 8 == 0); |
| | 499 | const uint = @IntType(false, T.bit_count); |
| | 500 | if (uint == u0) { |
| | 501 | return; |
| | 502 | } |
| | 503 | var bits = @bitCast(uint, value); |
| | 504 | if (uint == u8) { |
| | 505 | buf[0] = bits; |
| | 506 | return; |
| | 507 | } |
| | 508 | var index: usize = buf.len; |
| | 509 | while (index != 0) { |
| | 510 | index -= 1; |
| | 511 | |
| | 512 | buf[index] = @truncate(u8, bits); |
| | 513 | bits >>= 8; |
| | 514 | } |
| | 515 | assert(bits == 0); |
| | 516 | } |
| | 517 | |
| | 518 | pub fn writeIntLE(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void { |
| | 519 | assert(T.bit_count % 8 == 0); |
| | 520 | const uint = @IntType(false, T.bit_count); |
| | 521 | if (uint == u0) { |
| | 522 | return; |
| | 523 | } |
| | 524 | var bits = @bitCast(uint, value); |
| | 525 | if (uint == u8) { |
| | 526 | buf[0] = bits; |
| | 527 | return; |
| | 528 | } |
| | 529 | // FIXME: this should just be for (buf). |
| | 530 | // See https://github.com/ziglang/zig/issues/1663 |
| | 531 | for (buf.*) |*b| { |
| | 532 | b.* = @truncate(u8, bits); |
| | 533 | bits >>= 8; |
| | 534 | } |
| | 535 | assert(bits == 0); |
| | 536 | } |
| | 537 | |
| | 538 | test "writeIntBE/LE" { |
| | 539 | var buf0: [0]u8 = undefined; |
| | 540 | var buf1: [1]u8 = undefined; |
| | 541 | var buf2: [2]u8 = undefined; |
| | 542 | var buf9: [9]u8 = undefined; |
| | 543 | |
| | 544 | writeIntBE(u0, &buf0, 0x0); |
| | 545 | assert(eql_slice_u8(buf0[0..], []u8{})); |
| | 546 | writeIntLE(u0, &buf0, 0x0); |
| | 547 | assert(eql_slice_u8(buf0[0..], []u8{})); |
| | 548 | |
| | 549 | writeIntBE(u8, &buf1, 0x12); |
| | 550 | assert(eql_slice_u8(buf1[0..], []u8{0x12})); |
| | 551 | writeIntLE(u8, &buf1, 0x34); |
| | 552 | assert(eql_slice_u8(buf1[0..], []u8{0x34})); |
| | 553 | |
| | 554 | writeIntBE(u16, &buf2, 0x1234); |
| | 555 | assert(eql_slice_u8(buf2[0..], []u8{ 0x12, 0x34 })); |
| | 556 | writeIntLE(u16, &buf2, 0x5678); |
| | 557 | assert(eql_slice_u8(buf2[0..], []u8{ 0x78, 0x56 })); |
| | 558 | |
| | 559 | writeIntBE(u72, &buf9, 0x123456789abcdef024); |
| | 560 | assert(eql_slice_u8(buf9[0..], []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 })); |
| | 561 | writeIntLE(u72, &buf9, 0xfedcba9876543210ec); |
| | 562 | assert(eql_slice_u8(buf9[0..], []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe })); |
| | 563 | |
| | 564 | writeIntBE(i8, &buf1, -1); |
| | 565 | assert(eql_slice_u8(buf1[0..], []u8{0xff})); |
| | 566 | writeIntLE(i8, &buf1, -2); |
| | 567 | assert(eql_slice_u8(buf1[0..], []u8{0xfe})); |
| | 568 | |
| | 569 | writeIntBE(i16, &buf2, -3); |
| | 570 | assert(eql_slice_u8(buf2[0..], []u8{ 0xff, 0xfd })); |
| | 571 | writeIntLE(i16, &buf2, -4); |
| | 572 | assert(eql_slice_u8(buf2[0..], []u8{ 0xfc, 0xff })); |
| | 573 | } |
| | 574 | |
| 495 | pub fn hash_slice_u8(k: []const u8) u32 { | 575 | pub fn hash_slice_u8(k: []const u8) u32 { |
| 496 | // FNV 32-bit hash | 576 | // FNV 32-bit hash |
| 497 | var h: u32 = 2166136261; | 577 | var h: u32 = 2166136261; |