| ... | ... | @@ -65,7 +65,7 @@ pub const ParseResOptions = struct { |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | 67 | /// The returned ParsedResources should be freed by calling its `deinit` function. |
| 68 | | pub fn parseRes(allocator: Allocator, reader: anytype, options: ParseResOptions) !ParsedResources { |
| 68 | pub fn parseRes(allocator: Allocator, reader: *std.Io.Reader, options: ParseResOptions) !ParsedResources { |
| 69 | 69 | var resources = ParsedResources.init(allocator); |
| 70 | 70 | errdefer resources.deinit(); |
| 71 | 71 | |
| ... | ... | @@ -74,7 +74,7 @@ pub fn parseRes(allocator: Allocator, reader: anytype, options: ParseResOptions) |
| 74 | 74 | return resources; |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | | pub fn parseResInto(resources: *ParsedResources, reader: anytype, options: ParseResOptions) !void { |
| 77 | pub fn parseResInto(resources: *ParsedResources, reader: *std.Io.Reader, options: ParseResOptions) !void { |
| 78 | 78 | const allocator = resources.allocator; |
| 79 | 79 | var bytes_remaining: u64 = options.max_size; |
| 80 | 80 | { |
| ... | ... | @@ -103,45 +103,38 @@ pub const ResourceAndSize = struct { |
| 103 | 103 | total_size: u64, |
| 104 | 104 | }; |
| 105 | 105 | |
| 106 | | pub fn parseResource(allocator: Allocator, reader: anytype, max_size: u64) !ResourceAndSize { |
| 107 | | var header_counting_reader = std.io.countingReader(reader); |
| 108 | | var buffer: [1024]u8 = undefined; |
| 109 | | var header_reader_adapter = header_counting_reader.reader().adaptToNewApi(&buffer); |
| 110 | | const header_reader = &header_reader_adapter.new_interface; |
| 111 | | const data_size = try header_reader.takeInt(u32, .little); |
| 112 | | const header_size = try header_reader.takeInt(u32, .little); |
| 106 | pub fn parseResource(allocator: Allocator, reader: *std.Io.Reader, max_size: u64) !ResourceAndSize { |
| 107 | const data_size = try reader.takeInt(u32, .little); |
| 108 | const header_size = try reader.takeInt(u32, .little); |
| 113 | 109 | const total_size: u64 = @as(u64, header_size) + data_size; |
| 114 | 110 | if (total_size > max_size) return error.ImpossibleSize; |
| 115 | 111 | |
| 116 | | var header_bytes_available = header_size -| 8; |
| 117 | | var type_reader: std.Io.Reader = .fixed(try header_reader.take(header_bytes_available)); |
| 118 | | const type_value = try parseNameOrOrdinal(allocator, &type_reader); |
| 112 | const remaining_header_bytes = try reader.take(header_size -| 8); |
| 113 | var remaining_header_reader: std.Io.Reader = .fixed(remaining_header_bytes); |
| 114 | const type_value = try parseNameOrOrdinal(allocator, &remaining_header_reader); |
| 119 | 115 | errdefer type_value.deinit(allocator); |
| 120 | 116 | |
| 121 | | header_bytes_available -|= @intCast(type_value.byteLen()); |
| 122 | | var name_reader: std.Io.Reader = .fixed(try header_reader.take(header_bytes_available)); |
| 123 | | const name_value = try parseNameOrOrdinal(allocator, &name_reader); |
| 117 | const name_value = try parseNameOrOrdinal(allocator, &remaining_header_reader); |
| 124 | 118 | errdefer name_value.deinit(allocator); |
| 125 | 119 | |
| 126 | | const padding_after_name = numPaddingBytesNeeded(@intCast(header_counting_reader.bytes_read)); |
| 127 | | try header_reader.discardAll(padding_after_name); |
| 120 | const padding_after_name = numPaddingBytesNeeded(@intCast(remaining_header_reader.seek)); |
| 121 | try remaining_header_reader.discardAll(padding_after_name); |
| 128 | 122 | |
| 129 | | std.debug.assert(header_counting_reader.bytes_read % 4 == 0); |
| 130 | | const data_version = try header_reader.takeInt(u32, .little); |
| 131 | | const memory_flags: MemoryFlags = @bitCast(try header_reader.takeInt(u16, .little)); |
| 132 | | const language: Language = @bitCast(try header_reader.takeInt(u16, .little)); |
| 133 | | const version = try header_reader.takeInt(u32, .little); |
| 134 | | const characteristics = try header_reader.takeInt(u32, .little); |
| 123 | std.debug.assert(remaining_header_reader.seek % 4 == 0); |
| 124 | const data_version = try remaining_header_reader.takeInt(u32, .little); |
| 125 | const memory_flags: MemoryFlags = @bitCast(try remaining_header_reader.takeInt(u16, .little)); |
| 126 | const language: Language = @bitCast(try remaining_header_reader.takeInt(u16, .little)); |
| 127 | const version = try remaining_header_reader.takeInt(u32, .little); |
| 128 | const characteristics = try remaining_header_reader.takeInt(u32, .little); |
| 135 | 129 | |
| 136 | | const header_bytes_read = header_counting_reader.bytes_read; |
| 137 | | if (header_size != header_bytes_read) return error.HeaderSizeMismatch; |
| 130 | if (remaining_header_reader.seek != remaining_header_reader.end) return error.HeaderSizeMismatch; |
| 138 | 131 | |
| 139 | 132 | const data = try allocator.alloc(u8, data_size); |
| 140 | 133 | errdefer allocator.free(data); |
| 141 | | try reader.readNoEof(data); |
| 134 | try reader.readSliceAll(data); |
| 142 | 135 | |
| 143 | 136 | const padding_after_data = numPaddingBytesNeeded(@intCast(data_size)); |
| 144 | | try reader.skipBytes(padding_after_data, .{ .buf_size = 3 }); |
| 137 | try reader.discardAll(padding_after_data); |
| 145 | 138 | |
| 146 | 139 | return .{ |
| 147 | 140 | .resource = .{ |