@@ -61,8 +61,11 @@ struct git_istream {
61
61
} incore ;
62
62
63
63
struct {
64
- int fd ; /* open for reading */
65
- /* NEEDSWORK: what else? */
64
+ void * mapped ;
65
+ unsigned long mapsize ;
66
+ char hdr [32 ];
67
+ int hdr_avail ;
68
+ int hdr_used ;
66
69
} loose ;
67
70
68
71
struct {
@@ -150,9 +153,85 @@ static void close_deflated_stream(struct git_istream *st)
150
153
*
151
154
*****************************************************************/
152
155
156
+ static read_method_decl (loose )
157
+ {
158
+ size_t total_read = 0 ;
159
+
160
+ switch (st -> z_state ) {
161
+ case z_done :
162
+ return 0 ;
163
+ case z_error :
164
+ return -1 ;
165
+ default :
166
+ break ;
167
+ }
168
+
169
+ if (st -> u .loose .hdr_used < st -> u .loose .hdr_avail ) {
170
+ size_t to_copy = st -> u .loose .hdr_avail - st -> u .loose .hdr_used ;
171
+ if (sz < to_copy )
172
+ to_copy = sz ;
173
+ memcpy (buf , st -> u .loose .hdr + st -> u .loose .hdr_used , to_copy );
174
+ st -> u .loose .hdr_used += to_copy ;
175
+ total_read += to_copy ;
176
+ }
177
+
178
+ while (total_read < sz ) {
179
+ int status ;
180
+
181
+ st -> z .next_out = (unsigned char * )buf + total_read ;
182
+ st -> z .avail_out = sz - total_read ;
183
+ status = git_inflate (& st -> z , Z_FINISH );
184
+
185
+ total_read = st -> z .next_out - (unsigned char * )buf ;
186
+
187
+ if (status == Z_STREAM_END ) {
188
+ git_inflate_end (& st -> z );
189
+ st -> z_state = z_done ;
190
+ break ;
191
+ }
192
+ if (status != Z_OK && status != Z_BUF_ERROR ) {
193
+ git_inflate_end (& st -> z );
194
+ st -> z_state = z_error ;
195
+ return -1 ;
196
+ }
197
+ }
198
+ return total_read ;
199
+ }
200
+
201
+ static close_method_decl (loose )
202
+ {
203
+ close_deflated_stream (st );
204
+ munmap (st -> u .loose .mapped , st -> u .loose .mapsize );
205
+ return 0 ;
206
+ }
207
+
208
+ static struct stream_vtbl loose_vtbl = {
209
+ close_istream_loose ,
210
+ read_istream_loose ,
211
+ };
212
+
153
213
static open_method_decl (loose )
154
214
{
155
- return -1 ; /* for now */
215
+ st -> u .loose .mapped = map_sha1_file (sha1 , & st -> u .loose .mapsize );
216
+ if (!st -> u .loose .mapped )
217
+ return -1 ;
218
+ if (unpack_sha1_header (& st -> z ,
219
+ st -> u .loose .mapped ,
220
+ st -> u .loose .mapsize ,
221
+ st -> u .loose .hdr ,
222
+ sizeof (st -> u .loose .hdr )) < 0 ) {
223
+ git_inflate_end (& st -> z );
224
+ munmap (st -> u .loose .mapped , st -> u .loose .mapsize );
225
+ return -1 ;
226
+ }
227
+
228
+ parse_sha1_header (st -> u .loose .hdr , & st -> size );
229
+ st -> u .loose .hdr_used = strlen (st -> u .loose .hdr ) + 1 ;
230
+ st -> u .loose .hdr_avail = st -> z .total_out ;
231
+ st -> z_state = z_used ;
232
+
233
+ st -> vtbl = & loose_vtbl ;
234
+ return 0 ;
156
235
}
157
236
158
237
0 commit comments