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" {...@@ -180,6 +180,7 @@ test "mem.indexOf" {
180/// Reads an integer from memory with size equal to bytes.len.180/// Reads an integer from memory with size equal to bytes.len.
181/// T specifies the return type, which must be large enough to store181/// T specifies the return type, which must be large enough to store
182/// the result.182/// the result.
183/// See also ::readIntBE or ::readIntLE.
183pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {184pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {
184 if (T.bit_count == 8) {185 if (T.bit_count == 8) {
185 return bytes[0];186 return bytes[0];
...@@ -198,6 +199,34 @@ pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {...@@ -198,6 +199,34 @@ pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {
198 return result;199 return result;
199}200}
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
201/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes230/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes
202/// to fill the entire buffer provided.231/// to fill the entire buffer provided.
203/// value must be an integer.232/// value must be an integer.
...@@ -348,8 +377,12 @@ test "testReadInt" {...@@ -348,8 +377,12 @@ test "testReadInt" {
348fn testReadIntImpl() {377fn testReadIntImpl() {
349 {378 {
350 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };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 assert(readInt(bytes, u32, false) == 0x78563412);383 assert(readInt(bytes, u32, false) == 0x78563412);
384 assert(readIntLE(u32, bytes) == 0x78563412);
385 assert(readIntLE(i32, bytes) == 0x78563412);
353 }386 }
354 {387 {
355 const buf = []u8{0x00, 0x00, 0x12, 0x34};388 const buf = []u8{0x00, 0x00, 0x12, 0x34};
...@@ -361,6 +394,13 @@ fn testReadIntImpl() {...@@ -361,6 +394,13 @@ fn testReadIntImpl() {
361 const answer = readInt(buf, u64, false);394 const answer = readInt(buf, u64, false);
362 assert(answer == 0x00003412);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}
365405
366test "testWriteInt" {406test "testWriteInt" {