554 lines
12 KiB
C
554 lines
12 KiB
C
/*
|
|
* Copyright (c) 2011, Google Inc.
|
|
*/
|
|
#include "cache.h"
|
|
#include "streaming.h"
|
|
|
|
enum input_source {
|
|
stream_error = -1,
|
|
incore = 0,
|
|
loose = 1,
|
|
pack_non_delta = 2
|
|
};
|
|
|
|
typedef int (*open_istream_fn)(struct git_istream *,
|
|
struct object_info *,
|
|
const unsigned char *,
|
|
enum object_type *);
|
|
typedef int (*close_istream_fn)(struct git_istream *);
|
|
typedef ssize_t (*read_istream_fn)(struct git_istream *, char *, size_t);
|
|
|
|
struct stream_vtbl {
|
|
close_istream_fn close;
|
|
read_istream_fn read;
|
|
};
|
|
|
|
#define open_method_decl(name) \
|
|
int open_istream_ ##name \
|
|
(struct git_istream *st, struct object_info *oi, \
|
|
const unsigned char *sha1, \
|
|
enum object_type *type)
|
|
|
|
#define close_method_decl(name) \
|
|
int close_istream_ ##name \
|
|
(struct git_istream *st)
|
|
|
|
#define read_method_decl(name) \
|
|
ssize_t read_istream_ ##name \
|
|
(struct git_istream *st, char *buf, size_t sz)
|
|
|
|
/* forward declaration */
|
|
static open_method_decl(incore);
|
|
static open_method_decl(loose);
|
|
static open_method_decl(pack_non_delta);
|
|
static struct git_istream *attach_stream_filter(struct git_istream *st,
|
|
struct stream_filter *filter);
|
|
|
|
|
|
static open_istream_fn open_istream_tbl[] = {
|
|
open_istream_incore,
|
|
open_istream_loose,
|
|
open_istream_pack_non_delta,
|
|
};
|
|
|
|
#define FILTER_BUFFER (1024*16)
|
|
|
|
struct filtered_istream {
|
|
struct git_istream *upstream;
|
|
struct stream_filter *filter;
|
|
char ibuf[FILTER_BUFFER];
|
|
char obuf[FILTER_BUFFER];
|
|
int i_end, i_ptr;
|
|
int o_end, o_ptr;
|
|
int input_finished;
|
|
};
|
|
|
|
struct git_istream {
|
|
const struct stream_vtbl *vtbl;
|
|
unsigned long size; /* inflated size of full object */
|
|
git_zstream z;
|
|
enum { z_unused, z_used, z_done, z_error } z_state;
|
|
|
|
union {
|
|
struct {
|
|
char *buf; /* from read_object() */
|
|
unsigned long read_ptr;
|
|
} incore;
|
|
|
|
struct {
|
|
void *mapped;
|
|
unsigned long mapsize;
|
|
char hdr[32];
|
|
int hdr_avail;
|
|
int hdr_used;
|
|
} loose;
|
|
|
|
struct {
|
|
struct packed_git *pack;
|
|
off_t pos;
|
|
} in_pack;
|
|
|
|
struct filtered_istream filtered;
|
|
} u;
|
|
};
|
|
|
|
int close_istream(struct git_istream *st)
|
|
{
|
|
int r = st->vtbl->close(st);
|
|
free(st);
|
|
return r;
|
|
}
|
|
|
|
ssize_t read_istream(struct git_istream *st, void *buf, size_t sz)
|
|
{
|
|
return st->vtbl->read(st, buf, sz);
|
|
}
|
|
|
|
static enum input_source istream_source(const unsigned char *sha1,
|
|
enum object_type *type,
|
|
struct object_info *oi)
|
|
{
|
|