| ... | ... | @@ -159,6 +159,50 @@ pub fn writeILEB128Mem(ptr: []u8, int_value: anytype) !usize { |
| 159 | 159 | return buf.pos; |
| 160 | 160 | } |
| 161 | 161 | |
| 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. |
| 169 | pub 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 | |
| 183 | test "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 | |
| 162 | 206 | // tests |
| 163 | 207 | fn test_read_stream_ileb128(comptime T: type, encoded: []const u8) !T { |
| 164 | 208 | var reader = std.io.fixedBufferStream(encoded); |