15
typedef int (*close_istream_fn)(struct git_istream *);
16
typedef ssize_t (*read_istream_fn)(struct git_istream *, char *, size_t);
17
18
-struct stream_vtbl {
19
- close_istream_fn close;
20
- read_istream_fn read;
21
-};
22
-
18
#define FILTER_BUFFER (1024*16)
19
20
struct filtered_istream {
28
};
29
30
struct git_istream {
36
- const struct stream_vtbl *vtbl;
31
+ open_istream_fn open;
32
+ close_istream_fn close;
33
+ read_istream_fn read;
34
+
35
unsigned long size; /* inflated size of full object */
36
git_zstream z;
37
enum { z_unused, z_used, z_done, z_error } z_state;
144
return filled;
145
}
146
149
-static struct stream_vtbl filtered_vtbl = {
150
- close_istream_filtered,
151
- read_istream_filtered,
152
-};
153
-
147
static struct git_istream *attach_stream_filter(struct git_istream *st,
148
struct stream_filter *filter)
149
{
150
struct git_istream *ifs = xmalloc(sizeof(*ifs));
151
struct filtered_istream *fs = &(ifs->u.filtered);
152
160
- ifs->vtbl = &filtered_vtbl;
153
+ ifs->close = close_istream_filtered;
154
+ ifs->read = read_istream_filtered;
155
fs->upstream = st;
156
fs->filter = filter;
157
fs->i_end = fs->i_ptr = 0;
219
return 0;
220
}
221
228
-static struct stream_vtbl loose_vtbl = {
229
- close_istream_loose,
230
- read_istream_loose,
231
-};
232
-
222
static int open_istream_loose(struct git_istream *st, struct repository *r,
223
const struct object_id *oid,
224
enum object_type *type)
240
st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
241
st->u.loose.hdr_avail = st->z.total_out;
242
st->z_state = z_used;
243
+ st->close = close_istream_loose;
244
+ st->read = read_istream_loose;
245
255
- st->vtbl = &loose_vtbl;
246
return 0;
247
}
248
318
return 0;
319
}
320
331
-static struct stream_vtbl pack_non_delta_vtbl = {
332
- close_istream_pack_non_delta,
333
- read_istream_pack_non_delta,
334
-};
335
-
321
static int open_istream_pack_non_delta(struct git_istream *st,
322
struct repository *r,
323
const struct object_id *oid,
343
break;
344
}
345
st->z_state = z_unused;
361
- st->vtbl = &pack_non_delta_vtbl;
346
+ st->close = close_istream_pack_non_delta;
347
+ st->read = read_istream_pack_non_delta;
348
+
349
return 0;
350
}
351
376
return read_size;
377
}
378
392
-static struct stream_vtbl incore_vtbl = {
393
- close_istream_incore,
394
- read_istream_incore,
395
-};
396
-
379
static int open_istream_incore(struct git_istream *st, struct repository *r,
380
const struct object_id *oid, enum object_type *type)
381
{
382
st->u.incore.buf = read_object_file_extended(r, oid, type, &st->size, 0);
383
st->u.incore.read_ptr = 0;
402
- st->vtbl = &incore_vtbl;
384
+ st->close = close_istream_incore;
385
+ st->read = read_istream_incore;
386
387
return st->u.incore.buf ? 0 : -1;
388
}
391
* static helpers variables and functions for users of streaming interface
392
*****************************************************************************/
393
411
-static open_istream_fn istream_source(struct git_istream *st,
412
- struct repository *r,
413
- const struct object_id *oid,
414
- enum object_type *type)
394
+static int istream_source(struct git_istream *st,
395
+ struct repository *r,
396
+ const struct object_id *oid,
397
+ enum object_type *type)
398
{
399
unsigned long size;
400
int status;
404
oi.sizep = &size;
405
status = oid_object_info_extended(r, oid, &oi, 0);
406
if (status < 0)
424
- return NULL;
407
+ return status;
408
409
switch (oi.whence) {
410
case OI_LOOSE:
428
- return open_istream_loose;
411
+ st->open = open_istream_loose;
412
+ return 0;
413
case OI_PACKED:
414
if (!oi.u.packed.is_delta && big_file_threshold < size) {
415
st->u.in_pack.pack = oi.u.packed.pack;
416
st->u.in_pack.pos = oi.u.packed.offset;
433
- return open_istream_pack_non_delta;
417
+ st->open = open_istream_pack_non_delta;
418
+ return 0;
419
}
420
/* fallthru */
421
default:
437
- return open_istream_incore;
422
+ st->open = open_istream_incore;
423
+ return 0;
424
}
425
}
426
430
431
int close_istream(struct git_istream *st)
432
{
447
- int r = st->vtbl->close(st);
433
+ int r = st->close(st);
434
free(st);
435
return r;
436
}
437
438
ssize_t read_istream(struct git_istream *st, void *buf, size_t sz)
439
{
454
- return st->vtbl->read(st, buf, sz);
440
+ return st->read(st, buf, sz);
441
}
442
443
struct git_istream *open_istream(struct repository *r,
448
{
449
struct git_istream *st = xmalloc(sizeof(*st));
450
const struct object_id *real = lookup_replace_object(r, oid);
465
- open_istream_fn open_fn = istream_source(st, r, real, type);
451
+ int ret = istream_source(st, r, real, type);
452
467
- if (!open_fn) {
453
+ if (ret) {
454
free(st);
455
return NULL;
456
}
457
472
- if (open_fn(st, r, real, type)) {
458
+ if (st->open(st, r, real, type)) {
459
if (open_istream_incore(st, r, real, type)) {
460
free(st);
461
return NULL;