| ... | ... | @@ -180,6 +180,7 @@ test "mem.indexOf" { |
| 180 | 180 | /// Reads an integer from memory with size equal to bytes.len. |
| 181 | 181 | /// T specifies the return type, which must be large enough to store |
| 182 | 182 | /// the result. |
| 183 | /// See also ::readIntBE or ::readIntLE. |
| 183 | 184 | pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T { |
| 184 | 185 | if (T.bit_count == 8) { |
| 185 | 186 | return bytes[0]; |
| ... | ... | @@ -198,6 +199,34 @@ pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T { |
| 198 | 199 | return result; |
| 199 | 200 | } |
| 200 | 201 | |
| 202 | /// Reads a big-endian int of type T from bytes. |
| 203 | /// bytes.len must be exactly @sizeOf(T). |
| 204 | pub fn readIntBE(comptime T: type, bytes: []const u8) -> T { |
| 205 | if (T.is_signed) { |
| 206 | return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes)); |
| 207 | } |
| 208 | assert(bytes.len == @sizeOf(T)); |
| 209 | var result: T = 0; |
| 210 | {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) { |
| 211 | result = (result << 8) | T(bytes[i]); |
| 212 | }} |
| 213 | return result; |
| 214 | } |
| 215 | |
| 216 | /// Reads a little-endian int of type T from bytes. |
| 217 | /// bytes.len must be exactly @sizeOf(T). |
| 218 | pub fn readIntLE(comptime T: type, bytes: []const u8) -> T { |
| 219 | if (T.is_signed) { |
| 220 | return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes)); |
| 221 | } |
| 222 | assert(bytes.len == @sizeOf(T)); |
| 223 | var result: T = 0; |
| 224 | {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) { |
| 225 | result |= T(bytes[i]) << i * 8; |
| 226 | }} |
| 227 | return result; |
| 228 | } |
| 229 | |
| 201 | 230 | /// Writes an integer to memory with size equal to bytes.len. Pads with zeroes |
| 202 | 231 | /// to fill the entire buffer provided. |
| 203 | 232 | /// value must be an integer. |
| ... | ... | @@ -348,8 +377,12 @@ test "testReadInt" { |
| 348 | 377 | fn testReadIntImpl() { |
| 349 | 378 | { |
| 350 | 379 | const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 }; |
| 351 | | assert(readInt(bytes, u32, true) == 0x12345678); |
| 380 | assert(readInt(bytes, u32, true) == 0x12345678); |
| 381 | assert(readIntBE(u32, bytes) == 0x12345678); |
| 382 | assert(readIntBE(i32, bytes) == 0x12345678); |
| 352 | 383 | assert(readInt(bytes, u32, false) == 0x78563412); |
| 384 | assert(readIntLE(u32, bytes) == 0x78563412); |
| 385 | assert(readIntLE(i32, bytes) == 0x78563412); |
| 353 | 386 | } |
| 354 | 387 | { |
| 355 | 388 | const buf = []u8{0x00, 0x00, 0x12, 0x34}; |
| ... | ... | @@ -361,6 +394,13 @@ fn testReadIntImpl() { |
| 361 | 394 | const answer = readInt(buf, u64, false); |
| 362 | 395 | assert(answer == 0x00003412); |
| 363 | 396 | } |
| 397 | { |
| 398 | const bytes = []u8{0xff, 0xfe}; |
| 399 | assert(readIntBE(u16, bytes) == 0xfffe); |
| 400 | assert(readIntBE(i16, bytes) == -0x0002); |
| 401 | assert(readIntLE(u16, bytes) == 0xfeff); |
| 402 | assert(readIntLE(i16, bytes) == -0x0101); |
| 403 | } |
| 364 | 404 | } |
| 365 | 405 | |
| 366 | 406 | test "testWriteInt" { |