| ... | ... | @@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress { |
| 89 | 89 | .stream = stream, |
| 90 | 90 | .rebase = rebase, |
| 91 | 91 | .discard = discard, |
| 92 | | .readVec = Reader.indirectReadVec, |
| 92 | .readVec = readVec, |
| 93 | 93 | }, |
| 94 | 94 | .buffer = buffer, |
| 95 | 95 | .seek = 0, |
| ... | ... | @@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void { |
| 109 | 109 | r.seek -= discard_n; |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | | fn discard(r: *Reader, limit: Limit) Reader.Error!usize { |
| 113 | | r.rebase(zstd.block_size_max) catch unreachable; |
| 114 | | var d: Writer.Discarding = .init(r.buffer); |
| 115 | | const n = r.stream(&d.writer, limit) catch |err| switch (err) { |
| 112 | /// This could be improved so that when an amount is discarded that includes an |
| 113 | /// entire frame, skip decoding that frame. |
| 114 | fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize { |
| 115 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); |
| 116 | r.rebase(d.window_len) catch unreachable; |
| 117 | var writer: Writer = .{ |
| 118 | .vtable = &.{ |
| 119 | .drain = std.Io.Writer.Discarding.drain, |
| 120 | .sendFile = std.Io.Writer.Discarding.sendFile, |
| 121 | }, |
| 122 | .buffer = r.buffer, |
| 123 | .end = r.end, |
| 124 | }; |
| 125 | const n = r.stream(&writer, limit) catch |err| switch (err) { |
| 116 | 126 | error.WriteFailed => unreachable, |
| 117 | 127 | error.ReadFailed => return error.ReadFailed, |
| 118 | 128 | error.EndOfStream => return error.EndOfStream, |
| ... | ... | @@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize { |
| 121 | 131 | return n; |
| 122 | 132 | } |
| 123 | 133 | |
| 134 | fn readVec(r: *Reader, data: []const []u8) Reader.Error!usize { |
| 135 | _ = data; |
| 136 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); |
| 137 | assert(r.seek == r.end); |
| 138 | r.rebase(d.window_len) catch unreachable; |
| 139 | var writer: Writer = .{ |
| 140 | .buffer = r.buffer, |
| 141 | .end = r.end, |
| 142 | .vtable = &.{ .drain = Writer.fixedDrain }, |
| 143 | }; |
| 144 | r.end += r.vtable.stream(r, &writer, .limited(writer.buffer.len - writer.end)) catch |err| switch (err) { |
| 145 | error.WriteFailed => unreachable, |
| 146 | else => |e| return e, |
| 147 | }; |
| 148 | return 0; |
| 149 | } |
| 150 | |
| 124 | 151 | fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize { |
| 125 | 152 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); |
| 126 | 153 | const in = d.input; |