@@ -53,15 +53,24 @@ pub const Error = Container.Error || error{
53
53
EndOfStream ,
54
54
};
55
55
56
+ const direct_vtable : Reader.VTable = .{
57
+ .stream = streamDirect ,
58
+ .rebase = rebaseFallible ,
59
+ .discard = discard ,
60
+ .readVec = readVec ,
61
+ };
62
+
63
+ const indirect_vtable : Reader.VTable = .{
64
+ .stream = streamIndirect ,
65
+ .rebase = rebaseFallible ,
66
+ .discard = discard ,
67
+ .readVec = readVec ,
68
+ };
69
+
56
70
pub fn init (input : * Reader , container : Container , buffer : []u8 ) Decompress {
57
71
return .{
58
72
.reader = .{
59
- .vtable = &.{
60
- .stream = stream ,
61
- .rebase = rebaseFallible ,
62
- .discard = discard ,
63
- .readVec = readVec ,
64
- },
73
+ .vtable = if (buffer .len == 0 ) & direct_vtable else & indirect_vtable ,
65
74
.buffer = buffer ,
66
75
.seek = 0 ,
67
76
.end = 0 ,
@@ -79,12 +88,10 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
79
88
}
80
89
81
90
fn rebaseFallible (r : * Reader , capacity : usize ) Reader.RebaseError ! void {
82
- const d : * Decompress = @alignCast (@fieldParentPtr ("reader" , r ));
83
- rebase (d , capacity );
91
+ rebase (r , capacity );
84
92
}
85
93
86
- fn rebase (d : * Decompress , capacity : usize ) void {
87
- const r = & d .reader ;
94
+ fn rebase (r : * Reader , capacity : usize ) void {
88
95
assert (capacity <= r .buffer .len - flate .history_len );
89
96
assert (r .end + capacity > r .buffer .len );
90
97
const discard_n = r .end - flate .history_len ;
@@ -98,7 +105,7 @@ fn rebase(d: *Decompress, capacity: usize) void {
98
105
/// This could be improved so that when an amount is discarded that includes an
99
106
/// entire frame, skip decoding that frame.
100
107
fn discard (r : * Reader , limit : std.Io.Limit ) Reader.Error ! usize {
101
- r . rebase ( flate .history_len ) catch unreachable ;
108
+ if ( r . end + flate .history_len > r . buffer . len ) rebase ( r , flate . history_len ) ;
102
109
var writer : Writer = .{
103
110
.vtable = &.{
104
111
.drain = std .Io .Writer .Discarding .drain ,
@@ -124,12 +131,12 @@ fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
124
131
fn readVec (r : * Reader , data : [][]u8 ) Reader.Error ! usize {
125
132
_ = data ;
126
133
const d : * Decompress = @alignCast (@fieldParentPtr ("reader" , r ));
127
- return streamIndirect (d );
134
+ return streamIndirectInner (d );
128
135
}
129
136
130
- fn streamIndirect (d : * Decompress ) Reader.Error ! usize {
137
+ fn streamIndirectInner (d : * Decompress ) Reader.Error ! usize {
131
138
const r = & d .reader ;
132
- if (r .end + flate .history_len > r .buffer .len ) rebase (d , flate .history_len );
139
+ if (r .end + flate .history_len > r .buffer .len ) rebase (r , flate .history_len );
133
140
var writer : Writer = .{
134
141
.buffer = r .buffer ,
135
142
.end = r .end ,
@@ -200,10 +207,16 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol {
200
207
return sym ;
201
208
}
202
209
203
- pub fn stream (r : * Reader , w : * Writer , limit : std.Io.Limit ) Reader.StreamError ! usize {
210
+ fn streamDirect (r : * Reader , w : * Writer , limit : std.Io.Limit ) Reader.StreamError ! usize {
211
+ const d : * Decompress = @alignCast (@fieldParentPtr ("reader" , r ));
212
+ return streamFallible (d , w , limit );
213
+ }
214
+
215
+ fn streamIndirect (r : * Reader , w : * Writer , limit : std.Io.Limit ) Reader.StreamError ! usize {
204
216
const d : * Decompress = @alignCast (@fieldParentPtr ("reader" , r ));
205
- if (w .end >= r .end ) return streamFallible (d , w , limit );
206
- return streamIndirect (d );
217
+ _ = limit ;
218
+ _ = w ;
219
+ return streamIndirectInner (d );
207
220
}
208
221
209
222
fn streamFallible (d : * Decompress , w : * Writer , limit : std.Io.Limit ) Reader.StreamError ! usize {
0 commit comments