| ... | @@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress { | ... | @@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress { |
| 89 | .stream = stream, | 89 | .stream = stream, |
| 90 | .rebase = rebase, | 90 | .rebase = rebase, |
| 91 | .discard = discard, | 91 | .discard = discard, |
| 92 | .readVec = Reader.indirectReadVec, | 92 | .readVec = readVec, |
| 93 | }, | 93 | }, |
| 94 | .buffer = buffer, | 94 | .buffer = buffer, |
| 95 | .seek = 0, | 95 | .seek = 0, |
| ... | @@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void { | ... | @@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void { |
| 109 | r.seek -= discard_n; | 109 | r.seek -= discard_n; |
| 110 | } | 110 | } |
| 111 | | 111 | |
| 112 | fn discard(r: *Reader, limit: Limit) Reader.Error!usize { | 112 | /// This could be improved so that when an amount is discarded that includes an |
| 113 | r.rebase(zstd.block_size_max) catch unreachable; | 113 | /// entire frame, skip decoding that frame. |
| 114 | var d: Writer.Discarding = .init(r.buffer); | 114 | fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize { |
| 115 | const n = r.stream(&d.writer, limit) catch |err| switch (err) { | 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 | error.WriteFailed => unreachable, | 126 | error.WriteFailed => unreachable, |
| 117 | error.ReadFailed => return error.ReadFailed, | 127 | error.ReadFailed => return error.ReadFailed, |
| 118 | error.EndOfStream => return error.EndOfStream, | 128 | error.EndOfStream => return error.EndOfStream, |
| ... | @@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize { | ... | @@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize { |
| 121 | return n; | 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 | fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize { | 151 | fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize { |
| 125 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); | 152 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); |
| 126 | const in = d.input; | 153 | const in = d.input; |