odb/source-inmemory: implement `read_object_stream()` callback

Implement the `read_object_stream()` callback function for the in-memory source. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 10, 2026 at 14:12 UTC 8d9c1e421ce36be06ff304ce166593cf2e4ef66f
1 file changed +52
odb/source-inmemory.c
+52
@@ -1,6 +1,7 @@
1 #include "git-compat-util.h"
2 #include "odb.h"
3 #include "odb/source-inmemory.h"
4 +#include "odb/streaming.h"
5 #include "repository.h"
6
7 static const struct cached_object *find_cached_object(struct odb_source_inmemory *source,
@@ -53,6 +54,56 @@ static int odb_source_inmemory_read_object_info(struct odb_source *source,
54 return 0;
55 }
56
57 +struct odb_read_stream_inmemory {
58 + struct odb_read_stream base;
59 + const unsigned char *buf;
60 + size_t offset;
61 +};
62 +
63 +static ssize_t odb_read_stream_inmemory_read(struct odb_read_stream *stream,
64 + char *buf, size_t buf_len)
65 +{
66 + struct odb_read_stream_inmemory *inmemory =
67 + container_of(stream, struct odb_read_stream_inmemory, base);
68 + size_t bytes = buf_len;
69 +
70 + if (buf_len > inmemory->base.size - inmemory->offset)
71 + bytes = inmemory->base.size - inmemory->offset;
72 +
73 + memcpy(buf, inmemory->buf + inmemory->offset, bytes);
74 + inmemory->offset += bytes;
75 +
76 + return bytes;
77 +}
78 +
79 +static int odb_read_stream_inmemory_close(struct odb_read_stream *stream UNUSED)
80 +{
81 + return 0;
82 +}
83 +
84 +static int odb_source_inmemory_read_object_stream(struct odb_read_stream **out,
85 + struct odb_source *source,
86 + const struct object_id *oid)
87 +{
88 + struct odb_source_inmemory *inmemory = odb_source_inmemory_downcast(source);
89 + struct odb_read_stream_inmemory *stream;
90 + const struct cached_object *object;
91 +
92 + object = find_cached_object(inmemory, oid);
93 + if (!object)
94 + return -1;
95 +
96 + CALLOC_ARRAY(stream, 1);
97 + stream->base.read = odb_read_stream_inmemory_read;
98 + stream->base.close = odb_read_stream_inmemory_close;
99 + stream->base.size = object->size;
100 + stream->base.type = object->type;
101 + stream->buf = object->buf;
102 +
103 + *out = &stream->base;
104 + return 0;
105 +}
106 +
107 static void odb_source_inmemory_free(struct odb_source *source)
108 {
109 struct odb_source_inmemory *inmemory = odb_source_inmemory_downcast(source);
@@ -72,6 +123,7 @@ struct odb_source_inmemory *odb_source_inmemory_new(struct object_database *odb)
123
124 source->base.free = odb_source_inmemory_free;
125 source->base.read_object_info = odb_source_inmemory_read_object_info;
126 + source->base.read_object_stream = odb_source_inmemory_read_object_stream;
127
128 return source;
129 }