streaming: make streaming-write-entry to be more reusable

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>

Junio C Hamano committed Mar 7, 2012 at 17:54 UTC 47a02ff2ca821c52268197dd5fa46cd60a2e94bc
3 files changed +62 -48
entry.c
+5 -48
@@ -120,58 +120,15 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,
120 const struct checkout *state, int to_tempfile,
121 int *fstat_done, struct stat *statbuf)
122 {
123 - struct git_istream *st;
124 - enum object_type type;
125 - unsigned long sz;
123 int result = -1;
127 - ssize_t kept = 0;
128 - int fd = -1;
129 -
130 - st = open_istream(ce->sha1, &type, &sz, filter);
131 - if (!st)
132 - return -1;
133 - if (type != OBJ_BLOB)
134 - goto close_and_exit;
124 + int fd;
125
126 fd = open_output_fd(path, ce, to_tempfile);
137 - if (fd < 0)
138 - goto close_and_exit;
139 -
140 - for (;;) {
141 - char buf[1024 * 16];
142 - ssize_t wrote, holeto;
143 - ssize_t readlen = read_istream(st, buf, sizeof(buf));
144 -
145 - if (!readlen)
146 - break;
147 - if (sizeof(buf) == readlen) {
148 - for (holeto = 0; holeto < readlen; holeto++)
149 - if (buf[holeto])
150 - break;
151 - if (readlen == holeto) {
152 - kept += holeto;
153 - continue;
154 - }
155 - }
156 -
157 - if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
158 - goto close_and_exit;
159 - else
160 - kept = 0;
161 - wrote = write_in_full(fd, buf, readlen);
162 -
163 - if (wrote != readlen)
164 - goto close_and_exit;
165 - }
166 - if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
167 - write(fd, "", 1) != 1))
168 - goto close_and_exit;
169 - *fstat_done = fstat_output(fd, state, statbuf);
170 -
171 -close_and_exit:
172 - close_istream(st);
173 - if (0 <= fd)
127 + if (0 <= fd) {
128 + result = stream_blob_to_fd(fd, ce->sha1, filter, 1);
129 + *fstat_done = fstat_output(fd, state, statbuf);
130 result = close(fd);
131 + }
132 if (result && 0 <= fd)
133 unlink(path);
134 return result;
streaming.c
+55
@@ -489,3 +489,58 @@ static open_method_decl(incore)
489
490 return st->u.incore.buf ? 0 : -1;
491 }
492 +
493 +
494 +/****************************************************************
495 + * Users of streaming interface
496 + ****************************************************************/
497 +
498 +int stream_blob_to_fd(int fd, unsigned const char *sha1, struct stream_filter *filter,
499 + int can_seek)
500 +{
501 + struct git_istream *st;
502 + enum object_type type;
503 + unsigned long sz;
504 + ssize_t kept = 0;
505 + int result = -1;
506 +
507 + st = open_istream(sha1, &type, &sz, filter);
508 + if (!st)
509 + return result;
510 + if (type != OBJ_BLOB)
511 + goto close_and_exit;
512 + for (;;) {
513 + char buf[1024 * 16];
514 + ssize_t wrote, holeto;
515 + ssize_t readlen = read_istream(st, buf, sizeof(buf));
516 +
517 + if (!readlen)
518 + break;
519 + if (can_seek && sizeof(buf) == readlen) {
520 + for (holeto = 0; holeto < readlen; holeto++)
521 + if (buf[holeto])
522 + break;
523 + if (readlen == holeto) {
524 + kept += holeto;
525 + continue;
526 + }
527 + }
528 +
529 + if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
530 + goto close_and_exit;
531 + else
532 + kept = 0;
533 + wrote = write_in_full(fd, buf, readlen);
534 +
535 + if (wrote != readlen)
536 + goto close_and_exit;
537 + }
538 + if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
539 + write(fd, "", 1) != 1))
540 + goto close_and_exit;
541 + result = 0;
542 +
543 + close_and_exit:
544 + close_istream(st);
545 + return result;
546 +}
streaming.h
+2
@@ -12,4 +12,6 @@ extern struct git_istream *open_istream(const unsigned char *, enum object_type
12 extern int close_istream(struct git_istream *);
13 extern ssize_t read_istream(struct git_istream *, char *, size_t);
14
15 +extern int stream_blob_to_fd(int fd, const unsigned char *, struct stream_filter *, int can_seek);
16 +
17 #endif /* STREAMING_H */