| ... | ... | @@ -439,6 +439,7 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T { |
| 439 | 439 | return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes)); |
| 440 | 440 | } |
| 441 | 441 | assert(bytes.len == @sizeOf(T)); |
| 442 | if (T == u8) return bytes[0]; |
| 442 | 443 | var result: T = 0; |
| 443 | 444 | { |
| 444 | 445 | comptime var i = 0; |
| ... | ... | @@ -456,6 +457,7 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T { |
| 456 | 457 | return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes)); |
| 457 | 458 | } |
| 458 | 459 | assert(bytes.len == @sizeOf(T)); |
| 460 | if (T == u8) return bytes[0]; |
| 459 | 461 | var result: T = 0; |
| 460 | 462 | { |
| 461 | 463 | comptime var i = 0; |
| ... | ... | @@ -492,6 +494,84 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void { |
| 492 | 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 | 575 | pub fn hash_slice_u8(k: []const u8) u32 { |
| 496 | 576 | // FNV 32-bit hash |
| 497 | 577 | var h: u32 = 2166136261; |