| ... | @@ -2545,8 +2545,10 @@ pub const Storage = enum { | ... | @@ -2545,8 +2545,10 @@ pub const Storage = enum { |
| 2545 | }; | 2545 | }; |
| 2546 | } | 2546 | } |
| 2547 | | 2547 | |
| 2548 | /// The field contains a u32 length followed by that many items, each | 2548 | /// The field contains a u32 length followed by that many items. Each |
| 2549 | /// element bitcastable to u32. | 2549 | /// element needs well-defined memory layout but can otherwise be any |
| | 2550 | /// multiple of u32 length. The length is number of elements, not the |
| | 2551 | /// number of u32s. |
| 2550 | pub fn LengthPrefixedList(comptime ElemArg: type) type { | 2552 | pub fn LengthPrefixedList(comptime ElemArg: type) type { |
| 2551 | return struct { | 2553 | return struct { |
| 2552 | slice: []const Elem, | 2554 | slice: []const Elem, |
| ... | @@ -2759,19 +2761,21 @@ pub const Storage = enum { | ... | @@ -2759,19 +2761,21 @@ pub const Storage = enum { |
| 2759 | }, | 2761 | }, |
| 2760 | .extended => @compileError("TODO"), | 2762 | .extended => @compileError("TODO"), |
| 2761 | .length_prefixed_list => { | 2763 | .length_prefixed_list => { |
| | 2764 | const n = @divExact(@sizeOf(Field.Elem), @sizeOf(u32)); |
| 2762 | const data_start = i.* + 1; | 2765 | const data_start = i.* + 1; |
| 2763 | const len = buffer[data_start - 1]; | 2766 | const buf_len = buffer[data_start - 1] * n; |
| 2764 | defer i.* = data_start + len; | 2767 | defer i.* = data_start + buf_len; |
| 2765 | return .{ .slice = @ptrCast(buffer[data_start..][0..len]) }; | 2768 | return .{ .slice = @ptrCast(buffer[data_start..][0..buf_len]) }; |
| 2766 | }, | 2769 | }, |
| 2767 | .flag_length_prefixed_list => { | 2770 | .flag_length_prefixed_list => { |
| 2768 | const flags = @field(container, @tagName(Field.flags)); | 2771 | const flags = @field(container, @tagName(Field.flags)); |
| 2769 | const flag = @field(flags, @tagName(Field.flag)); | 2772 | const flag = @field(flags, @tagName(Field.flag)); |
| 2770 | if (!flag) return .{ .slice = &.{} }; | 2773 | if (!flag) return .{ .slice = &.{} }; |
| | 2774 | const n = @divExact(@sizeOf(Field.Elem), @sizeOf(u32)); |
| 2771 | const data_start = i.* + 1; | 2775 | const data_start = i.* + 1; |
| 2772 | const len = buffer[data_start - 1]; | 2776 | const buf_len = buffer[data_start - 1] * n; |
| 2773 | defer i.* = data_start + len; | 2777 | defer i.* = data_start + buf_len; |
| 2774 | return .{ .slice = @ptrCast(buffer[data_start..][0..len]) }; | 2778 | return .{ .slice = @ptrCast(buffer[data_start..][0..buf_len]) }; |
| 2775 | }, | 2779 | }, |
| 2776 | .flag_list => { | 2780 | .flag_list => { |
| 2777 | const flags = @field(container, @tagName(Field.flags)); | 2781 | const flags = @field(container, @tagName(Field.flags)); |