streaming: create structure for filtered object streams

As explained in a preceding commit, we want to get rid of the union of stream-type specific data in `struct odb_read_stream`. Create a new structure for filtered object streams to move towards this design. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Nov 23, 2025 at 19:59 UTC 1154b2d2e511113e9b7d567788b72acb05713915
1 file changed +25 -29
streaming.c
+25 -29
@@ -19,16 +19,6 @@ typedef ssize_t (*read_istream_fn)(struct odb_read_stream *, char *, size_t);
19
20 #define FILTER_BUFFER (1024*16)
21
22 -struct filtered_istream {
23 - struct odb_read_stream *upstream;
24 - struct stream_filter *filter;
25 - char ibuf[FILTER_BUFFER];
26 - char obuf[FILTER_BUFFER];
27 - int i_end, i_ptr;
28 - int o_end, o_ptr;
29 - int input_finished;
30 -};
31 -
22 struct odb_read_stream {
23 close_istream_fn close;
24 read_istream_fn read;
@@ -37,10 +27,6 @@ struct odb_read_stream {
27 unsigned long size; /* inflated size of full object */
28 git_zstream z;
29 enum { z_unused, z_used, z_done, z_error } z_state;
40 -
41 - union {
42 - struct filtered_istream filtered;
43 - } u;
30 };
31
32 /*****************************************************************
@@ -62,16 +48,28 @@ static void close_deflated_stream(struct odb_read_stream *st)
48 *
49 *****************************************************************/
50
65 -static int close_istream_filtered(struct odb_read_stream *st)
51 +struct odb_filtered_read_stream {
52 + struct odb_read_stream base;
53 + struct odb_read_stream *upstream;
54 + struct stream_filter *filter;
55 + char ibuf[FILTER_BUFFER];
56 + char obuf[FILTER_BUFFER];
57 + int i_end, i_ptr;
58 + int o_end, o_ptr;
59 + int input_finished;
60 +};
61 +
62 +static int close_istream_filtered(struct odb_read_stream *_fs)
63 {
67 - free_stream_filter(st->u.filtered.filter);
68 - return close_istream(st->u.filtered.upstream);
64 + struct odb_filtered_read_stream *fs = (struct odb_filtered_read_stream *)_fs;
65 + free_stream_filter(fs->filter);
66 + return close_istream(fs->upstream);
67 }
68
71 -static ssize_t read_istream_filtered(struct odb_read_stream *st, char *buf,
69 +static ssize_t read_istream_filtered(struct odb_read_stream *_fs, char *buf,
70 size_t sz)
71 {
74 - struct filtered_istream *fs = &(st->u.filtered);
72 + struct odb_filtered_read_stream *fs = (struct odb_filtered_read_stream *)_fs;
73 size_t filled = 0;
74
75 while (sz) {
@@ -131,19 +129,17 @@ static ssize_t read_istream_filtered(struct odb_read_stream *st, char *buf,
129 static struct odb_read_stream *attach_stream_filter(struct odb_read_stream *st,
130 struct stream_filter *filter)
131 {
134 - struct odb_read_stream *ifs = xmalloc(sizeof(*ifs));
135 - struct filtered_istream *fs = &(ifs->u.filtered);
132 + struct odb_filtered_read_stream *fs;
133
137 - ifs->close = close_istream_filtered;
138 - ifs->read = read_istream_filtered;
134 + CALLOC_ARRAY(fs, 1);
135 + fs->base.close = close_istream_filtered;
136 + fs->base.read = read_istream_filtered;
137 fs->upstream = st;
138 fs->filter = filter;
141 - fs->i_end = fs->i_ptr = 0;
142 - fs->o_end = fs->o_ptr = 0;
143 - fs->input_finished = 0;
144 - ifs->size = -1; /* unknown */
145 - ifs->type = st->type;
146 - return ifs;
139 + fs->base.size = -1; /* unknown */
140 + fs->base.type = st->type;
141 +
142 + return &fs->base;
143 }
144
145 /*****************************************************************