authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-11-30 11:20:39-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-11-30 11:20:50-07:00
log5786df933d37d52d57fef9c28acb9c2c23128d31
treec5c2924f58b1842b03c6786de3525ad82cc295af
parent210d0017c40ee24215ce705fcee342fe34b9dccb

add mem.readIntLE and readIntBE


1 files changed, 41 insertions(+), 1 deletions(-)

std/mem.zig+41-1
......@@ -180,6 +180,7 @@ test "mem.indexOf" {
180180/// Reads an integer from memory with size equal to bytes.len.
181181/// T specifies the return type, which must be large enough to store
182182/// the result.
183/// See also ::readIntBE or ::readIntLE.
183184pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {
184185 if (T.bit_count == 8) {
185186 return bytes[0];
......@@ -198,6 +199,34 @@ pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {
198199 return result;
199200}
200201
202/// Reads a big-endian int of type T from bytes.
203/// bytes.len must be exactly @sizeOf(T).
204pub 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).
218pub 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
201230/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes
202231/// to fill the entire buffer provided.
203232/// value must be an integer.
......@@ -348,8 +377,12 @@ test "testReadInt" {
348377fn testReadIntImpl() {
349378 {
350379 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);
352383 assert(readInt(bytes, u32, false) == 0x78563412);
384 assert(readIntLE(u32, bytes) == 0x78563412);
385 assert(readIntLE(i32, bytes) == 0x78563412);
353386 }
354387 {
355388 const buf = []u8{0x00, 0x00, 0x12, 0x34};
......@@ -361,6 +394,13 @@ fn testReadIntImpl() {
361394 const answer = readInt(buf, u64, false);
362395 assert(answer == 0x00003412);
363396 }
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 }
364404}
365405
366406test "testWriteInt" {