Skip to content

Commit 47a02ff

Browse files
committed
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2980b0d commit 47a02ff

File tree

3 files changed

+62
-48
lines changed

3 files changed

+62
-48
lines changed

entry.c

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -120,58 +120,15 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,
120120
const struct checkout *state, int to_tempfile,
121121
int *fstat_done, struct stat *statbuf)
122122
{
123-
struct git_istream *st;
124-
enum object_type type;
125-
unsigned long sz;
126123
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;
135125

136126
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);
174130
result = close(fd);
131+
}
175132
if (result && 0 <= fd)
176133
unlink(path);
177134
return result;

streaming.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,58 @@ static open_method_decl(incore)
489489

490490
return st->u.incore.buf ? 0 : -1;
491491
}
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ extern struct git_istream *open_istream(const unsigned char *, enum object_type
1212
extern int close_istream(struct git_istream *);
1313
extern ssize_t read_istream(struct git_istream *, char *, size_t);
1414

15+
extern int stream_blob_to_fd(int fd, const unsigned char *, struct stream_filter *, int can_seek);
16+
1517
#endif /* STREAMING_H */

0 commit comments

Comments
 (0)