Skip to content

Commit

Permalink
streaming: make streaming-write-entry to be more reusable
Browse files Browse the repository at this point in the history
The static function in entry.c takes a cache entry and streams its blob
contents to a file in the working tree.  Refactor the logic to a new API
function stream_blob_to_fd() that takes an object name and an open file
descriptor, so that it can be reused by other callers.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
gitster committed Mar 7, 2012
1 parent 2980b0d commit 47a02ff
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 48 deletions.
53 changes: 5 additions & 48 deletions entry.c
Expand Up @@ -120,58 +120,15 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,
const struct checkout *state, int to_tempfile, const struct checkout *state, int to_tempfile,
int *fstat_done, struct stat *statbuf) int *fstat_done, struct stat *statbuf)
{ {
struct git_istream *st;
enum object_type type;
unsigned long sz;
int result = -1; int result = -1;
ssize_t kept = 0; int fd;
int fd = -1;

st = open_istream(ce->sha1, &type, &sz, filter);
if (!st)
return -1;
if (type != OBJ_BLOB)
goto close_and_exit;


fd = open_output_fd(path, ce, to_tempfile); fd = open_output_fd(path, ce, to_tempfile);
if (fd < 0) if (0 <= fd) {
goto close_and_exit; result = stream_blob_to_fd(fd, ce->sha1, filter, 1);

*fstat_done = fstat_output(fd, state, statbuf);
for (;;) {
char buf[1024 * 16];
ssize_t wrote, holeto;
ssize_t readlen = read_istream(st, buf, sizeof(buf));

if (!readlen)
break;
if (sizeof(buf) == readlen) {
for (holeto = 0; holeto < readlen; holeto++)
if (buf[holeto])
break;
if (readlen == holeto) {
kept += holeto;
continue;
}
}

if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
goto close_and_exit;
else
kept = 0;
wrote = write_in_full(fd, buf, readlen);

if (wrote != readlen)
goto close_and_exit;
}
if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
write(fd, "", 1) != 1))
goto close_and_exit;
*fstat_done = fstat_output(fd, state, statbuf);

close_and_exit:
close_istream(st);
if (0 <= fd)
result = close(fd); result = close(fd);
}
if (result && 0 <= fd) if (result && 0 <= fd)
unlink(path); unlink(path);
return result; return result;
Expand Down
55 changes: 55 additions & 0 deletions streaming.c
Expand Up @@ -489,3 +489,58 @@ static open_method_decl(incore)


return st->u.incore.buf ? 0 : -1; return st->u.incore.buf ? 0 : -1;
} }


/****************************************************************
* Users of streaming interface
****************************************************************/

int stream_blob_to_fd(int fd, unsigned const char *sha1, struct stream_filter *filter,
int can_seek)
{
struct git_istream *st;
enum object_type type;
unsigned long sz;
ssize_t kept = 0;
int result = -1;

st = open_istream(sha1, &type, &sz, filter);
if (!st)
return result;
if (type != OBJ_BLOB)
goto close_and_exit;
for (;;) {
char buf[1024 * 16];
ssize_t wrote, holeto;
ssize_t readlen = read_istream(st, buf, sizeof(buf));

if (!readlen)
break;
if (can_seek && sizeof(buf) == readlen) {
for (holeto = 0; holeto < readlen; holeto++)
if (buf[holeto])
break;
if (readlen == holeto) {
kept += holeto;
continue;
}
}

if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
goto close_and_exit;
else
kept = 0;
wrote = write_in_full(fd, buf, readlen);

if (wrote != readlen)
goto close_and_exit;
}
if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
write(fd, "", 1) != 1))
goto close_and_exit;
result = 0;

close_and_exit:
close_istream(st);
return result;
}
2 changes: 2 additions & 0 deletions streaming.h
Expand Up @@ -12,4 +12,6 @@ extern struct git_istream *open_istream(const unsigned char *, enum object_type
extern int close_istream(struct git_istream *); extern int close_istream(struct git_istream *);
extern ssize_t read_istream(struct git_istream *, char *, size_t); extern ssize_t read_istream(struct git_istream *, char *, size_t);


extern int stream_blob_to_fd(int fd, const unsigned char *, struct stream_filter *, int can_seek);

#endif /* STREAMING_H */ #endif /* STREAMING_H */

0 comments on commit 47a02ff

Please sign in to comment.