Skip to content

Commit bb643d8

Browse files
larsxschneidergitster
authored andcommitted
pkt-line: add functions to read/write flush terminated packet streams
write_packetized_from_fd() and write_packetized_from_buf() write a stream of packets. All content packets use the maximal packet size except for the last one. After the last content packet a `flush` control packet is written. read_packetized_to_strbuf() reads arbitrary sized packets until it detects a `flush` packet. Signed-off-by: Lars Schneider <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent edfb780 commit bb643d8

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

pkt-line.c

+72
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,46 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
197197
va_end(args);
198198
}
199199

200+
int write_packetized_from_fd(int fd_in, int fd_out)
201+
{
202+
static char buf[LARGE_PACKET_DATA_MAX];
203+
int err = 0;
204+
ssize_t bytes_to_write;
205+
206+
while (!err) {
207+
bytes_to_write = xread(fd_in, buf, sizeof(buf));
208+
if (bytes_to_write < 0)
209+
return COPY_READ_ERROR;
210+
if (bytes_to_write == 0)
211+
break;
212+
err = packet_write_gently(fd_out, buf, bytes_to_write);
213+
}
214+
if (!err)
215+
err = packet_flush_gently(fd_out);
216+
return err;
217+
}
218+
219+
int write_packetized_from_buf(const char *src_in, size_t len, int fd_out)
220+
{
221+
int err = 0;
222+
size_t bytes_written = 0;
223+
size_t bytes_to_write;
224+
225+
while (!err) {
226+
if ((len - bytes_written) > LARGE_PACKET_DATA_MAX)
227+
bytes_to_write = LARGE_PACKET_DATA_MAX;
228+
else
229+
bytes_to_write = len - bytes_written;
230+
if (bytes_to_write == 0)
231+
break;
232+
err = packet_write_gently(fd_out, src_in + bytes_written, bytes_to_write);
233+
bytes_written += bytes_to_write;
234+
}
235+
if (!err)
236+
err = packet_flush_gently(fd_out);
237+
return err;
238+
}
239+
200240
static int get_packet_data(int fd, char **src_buf, size_t *src_size,
201241
void *dst, unsigned size, int options)
202242
{
@@ -287,3 +327,35 @@ char *packet_read_line_buf(char **src, size_t *src_len, int *dst_len)
287327
{
288328
return packet_read_line_generic(-1, src, src_len, dst_len);
289329
}
330+
331+
ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out)
332+
{
333+
int packet_len;
334+
335+
size_t orig_len = sb_out->len;
336+
size_t orig_alloc = sb_out->alloc;
337+
338+
for (;;) {
339+
strbuf_grow(sb_out, LARGE_PACKET_DATA_MAX);
340+
packet_len = packet_read(fd_in, NULL, NULL,
341+
/* strbuf_grow() above always allocates one extra byte to
342+
* store a '\0' at the end of the string. packet_read()
343+
* writes a '\0' extra byte at the end, too. Let it know
344+
* that there is already room for the extra byte.
345+
*/
346+
sb_out->buf + sb_out->len, LARGE_PACKET_DATA_MAX+1,
347+
PACKET_READ_GENTLE_ON_EOF);
348+
if (packet_len <= 0)
349+
break;
350+
sb_out->len += packet_len;
351+
}
352+
353+
if (packet_len < 0) {
354+
if (orig_alloc == 0)
355+
strbuf_release(sb_out);
356+
else
357+
strbuf_setlen(sb_out, orig_len);
358+
return packet_len;
359+
}
360+
return sb_out->len - orig_len;
361+
}

pkt-line.h

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ void packet_buf_flush(struct strbuf *buf);
2525
void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
2626
int packet_flush_gently(int fd);
2727
int packet_write_fmt_gently(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
28+
int write_packetized_from_fd(int fd_in, int fd_out);
29+
int write_packetized_from_buf(const char *src_in, size_t len, int fd_out);
2830

2931
/*
3032
* Read a packetized line into the buffer, which must be at least size bytes
@@ -77,8 +79,14 @@ char *packet_read_line(int fd, int *size);
7779
*/
7880
char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size);
7981

82+
/*
83+
* Reads a stream of variable sized packets until a flush packet is detected.
84+
*/
85+
ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out);
86+
8087
#define DEFAULT_PACKET_MAX 1000
8188
#define LARGE_PACKET_MAX 65520
89+
#define LARGE_PACKET_DATA_MAX (LARGE_PACKET_MAX - 4)
8290
extern char packet_buffer[LARGE_PACKET_MAX];
8391

8492
#endif

0 commit comments

Comments
 (0)