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 */