authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-31 22:58:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-02 11:09:35-07:00
logd4bb2b1513ce63bbe02199f3eee5cd6971f1d07e
tree2dcf09d7177a2725ea0624eee851050b350c36b3
parent6123201f06e0bfb138d6dfba0b3ba9ee105062f2

std: add function for writing fixed width ULEB128


1 files changed, 44 insertions(+), 0 deletions(-)

lib/std/debug/leb128.zig+44
......@@ -159,6 +159,50 @@ pub fn writeILEB128Mem(ptr: []u8, int_value: anytype) !usize {
159159 return buf.pos;
160160}
161161
162/// This is an "advanced" function. It allows one to use a fixed amount of memory to store a
163/// ULEB128. This defeats the entire purpose of using this data encoding; it will no longer use
164/// fewer bytes to store smaller numbers. The advantage of using a fixed width is that it makes
165/// fields have a predictable size and so depending on the use case this tradeoff can be worthwhile.
166/// An example use case of this is in emitting DWARF info where one wants to make a ULEB128 field
167/// "relocatable", meaning that it becomes possible to later go back and patch the number to be a
168/// different value without shifting all the following code.
169pub fn writeUnsignedFixed(comptime l: usize, ptr: *[l]u8, int: std.meta.Int(false, l * 7)) void {
170 const T = @TypeOf(int);
171 const U = if (T.bit_count < 8) u8 else T;
172 var value = @intCast(U, int);
173
174 comptime var i = 0;
175 inline while (i < (l - 1)) : (i += 1) {
176 const byte = @truncate(u8, value) | 0b1000_0000;
177 value >>= 7;
178 ptr[i] = byte;
179 }
180 ptr[i] = @truncate(u8, value);
181}
182
183test "writeUnsignedFixed" {
184 {
185 var buf: [4]u8 = undefined;
186 writeUnsignedFixed(4, &buf, 0);
187 testing.expect((try test_read_uleb128(u64, &buf)) == 0);
188 }
189 {
190 var buf: [4]u8 = undefined;
191 writeUnsignedFixed(4, &buf, 1);
192 testing.expect((try test_read_uleb128(u64, &buf)) == 1);
193 }
194 {
195 var buf: [4]u8 = undefined;
196 writeUnsignedFixed(4, &buf, 1000);
197 testing.expect((try test_read_uleb128(u64, &buf)) == 1000);
198 }
199 {
200 var buf: [4]u8 = undefined;
201 writeUnsignedFixed(4, &buf, 10000000);
202 testing.expect((try test_read_uleb128(u64, &buf)) == 10000000);
203 }
204}
205
162206// tests
163207fn test_read_stream_ileb128(comptime T: type, encoded: []const u8) !T {
164208 var reader = std.io.fixedBufferStream(encoded);