Commit 4d9c0c39 authored by Timo Teräs's avatar Timo Teräs

io: make io vtables const struct, and add accessors for them

This reduces function pointers in heap, and unifies how the
io functions are called.
parent ca9d476b
......@@ -548,7 +548,7 @@ int main(int argc, char **argv)
struct apk_bstream *bs = apk_bstream_from_file(AT_FDCWD, test_installed_db);
if (!IS_ERR_OR_NULL(bs)) {
apk_db_index_read(&db, bs, -1);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
for (i = 0; i < test_repos->num; i++) {
......@@ -576,7 +576,7 @@ int main(int argc, char **argv)
}
apk_db_index_read(&db, bs, repo);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
if (repo != -2) {
if (!(apk_flags & APK_NO_NETWORK))
db.available_repos |= BIT(repo);
......
......@@ -54,27 +54,39 @@ struct apk_file_info {
struct apk_xattr_array *xattrs;
};
struct apk_istream {
struct apk_istream_ops {
void (*get_meta)(void *stream, struct apk_file_meta *meta);
ssize_t (*read)(void *stream, void *ptr, size_t size);
void (*close)(void *stream);
};
struct apk_istream {
const struct apk_istream_ops *ops;
};
#define APK_BSTREAM_SINGLE_READ 0x0001
#define APK_BSTREAM_EOF 0x0002
struct apk_bstream {
unsigned int flags;
struct apk_bstream_ops {
void (*get_meta)(void *stream, struct apk_file_meta *meta);
apk_blob_t (*read)(void *stream, apk_blob_t token);
void (*close)(void *stream, size_t *size);
};
struct apk_ostream {
struct apk_bstream {
unsigned int flags;
const struct apk_bstream_ops *ops;
};
struct apk_ostream_ops {
ssize_t (*write)(void *stream, const void *buf, size_t size);
int (*close)(void *stream);
};
struct apk_ostream {
const struct apk_ostream_ops *ops;
};
#define APK_MPART_DATA 1 /* data processed so far */
#define APK_MPART_BOUNDARY 2 /* final part of data, before boundary */
#define APK_MPART_END 3 /* signals end of stream */
......@@ -118,6 +130,18 @@ static inline struct apk_istream *apk_istream_from_url_if_modified(const char *u
{
return apk_istream_from_fd_url_if_modified(AT_FDCWD, url, since);
}
static inline void apk_istream_get_meta(struct apk_istream *is, struct apk_file_meta *meta)
{
is->ops->get_meta(is, meta);
}
static inline ssize_t apk_istream_read(struct apk_istream *is, void *ptr, size_t size)
{
return is->ops->read(is, ptr, size);
}
static inline void apk_istream_close(struct apk_istream *is)
{
is->ops->close(is);
}
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
struct apk_bstream *apk_bstream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int));
......@@ -143,11 +167,31 @@ static inline struct apk_bstream *apk_bstream_from_url_if_modified(const char *u
{
return apk_bstream_from_fd_url_if_modified(AT_FDCWD, url, since);
}
static inline void apk_bstream_get_meta(struct apk_bstream *bs, struct apk_file_meta *meta)
{
bs->ops->get_meta(bs, meta);
}
static inline apk_blob_t apk_bstream_read(struct apk_bstream *bs, apk_blob_t token)
{
return bs->ops->read(bs, token);
}
static inline void apk_bstream_close(struct apk_bstream *bs, size_t *size)
{
bs->ops->close(bs, size);
}
struct apk_ostream *apk_ostream_to_fd(int fd);
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, const char *tmpfile, mode_t mode);
struct apk_ostream *apk_ostream_to_file_gz(int atfd, const char *file, const char *tmpfile, mode_t mode);
size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string);
static inline ssize_t apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size)
{
return os->ops->write(os, buf, size);
}
static inline int apk_ostream_close(struct apk_ostream *os)
{
return os->ops->close(os);
}
apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size);
apk_blob_t apk_blob_from_file(int atfd, const char *file);
......
......@@ -108,7 +108,7 @@ static ssize_t tar_entry_read(void *stream, void *ptr, size_t size)
if (size == 0)
return 0;
r = teis->tar_is->read(teis->tar_is, ptr, size);
r = apk_istream_read(teis->tar_is, ptr, size);
if (r <= 0) {
/* If inner stream returned zero (end-of-stream), we
* are getting short read, because tar header indicated
......@@ -133,6 +133,12 @@ static void tar_entry_close(void *stream)
{
}
static const struct apk_istream_ops tar_istream_ops = {
.get_meta = tar_entry_get_meta,
.read = tar_entry_read,
.close = tar_entry_close,
};
static int blob_realloc(apk_blob_t *b, size_t newsize)
{
char *tmp;
......@@ -191,9 +197,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
{
struct apk_file_info entry;
struct apk_tar_entry_istream teis = {
.is.get_meta = tar_entry_get_meta,
.is.read = tar_entry_read,
.is.close = tar_entry_close,
.is.ops = &tar_istream_ops,
.tar_is = is,
};
struct tar_header buf;
......@@ -206,7 +210,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
odi = (struct apk_tar_digest_info *) &buf.linkname[3];
EVP_MD_CTX_init(&teis.mdctx);
memset(&entry, 0, sizeof(entry));
while ((r = is->read(is, &buf, 512)) == 512) {
while ((r = apk_istream_read(is, &buf, 512)) == 512) {
offset += 512;
if (buf.name[0] == '\0') {
if (end) break;
......@@ -243,7 +247,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
switch (buf.typeflag) {
case 'L': /* GNU long name extension */
if ((r = blob_realloc(&longname, entry.size+1)) != 0 ||
(r = is->read(is, longname.ptr, entry.size)) != entry.size)
(r = apk_istream_read(is, longname.ptr, entry.size)) != entry.size)
goto err;
entry.name = longname.ptr;
entry.name[entry.size] = 0;
......@@ -293,7 +297,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
paxlen = entry.size;
entry.size = 0;
if ((r = blob_realloc(&pax, (paxlen + 511) & -512)) != 0 ||
(r = is->read(is, pax.ptr, paxlen)) != paxlen)
(r = apk_istream_read(is, pax.ptr, paxlen)) != paxlen)
goto err;
offset += paxlen;
break;
......@@ -321,7 +325,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
toskip += 512 - ((offset + toskip) & 511);
offset += toskip;
if (toskip != 0) {
if ((r = is->read(is, NULL, toskip)) != toskip)
if ((r = apk_istream_read(is, NULL, toskip)) != toskip)
goto err;
}
}
......@@ -329,7 +333,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
/* Read remaining end-of-archive records, to ensure we read all of
* the file. The underlying istream is likely doing checksumming. */
if (r == 512) {
while ((r = is->read(is, &buf, 512)) == 512) {
while ((r = apk_istream_read(is, &buf, 512)) == 512) {
if (buf.name[0] != 0) break;
}
}
......@@ -381,15 +385,15 @@ int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae,
put_octal(buf.chksum, sizeof(buf.chksum)-1, chksum);
}
if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf))
return -1;
if (ae == NULL) {
/* End-of-archive is two empty headers */
if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf))
return -1;
} else if (data != NULL) {
if (os->write(os, data, ae->size) != ae->size)
if (apk_ostream_write(os, data, ae->size) != ae->size)
return -1;
if (apk_tar_write_padding(os, ae) != 0)
return -1;
......@@ -405,7 +409,7 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae
pad = 512 - (ae->size & 511);
if (pad != 512 &&
os->write(os, padding, pad) != pad)
apk_ostream_write(os, padding, pad) != pad)
return -1;
return 0;
......
......@@ -658,12 +658,12 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
if (fd >= 0) {
struct apk_file_meta meta;
r = apk_istream_splice(is, fd, APK_SPLICE_ALL, cb, cb_ctx);
is->get_meta(is, &meta);
apk_istream_get_meta(is, &meta);
apk_file_meta_to_fd(fd, &meta);
close(fd);
}
}
if (!IS_ERR_OR_NULL(is)) is->close(is);
if (!IS_ERR_OR_NULL(is)) apk_istream_close(is);
if (r == -EALREADY) return 0;
if (r < 0) {
unlinkat(db->cache_fd, tmpcacheitem, 0);
......@@ -720,7 +720,7 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs)
diri_node = hlist_tail_ptr(&ipkg->owned_dirs);
while (!APK_BLOB_IS_NULL(line = bs->read(bs, token))) {
while (!APK_BLOB_IS_NULL(line = apk_bstream_read(bs, token))) {
if (!apk_blob_rsplit(line, '/', &bdir, &bfile))
break;
......@@ -757,7 +757,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
gid_t gid;
int field, r, lineno = 0;
while (!APK_BLOB_IS_NULL(l = bs->read(bs, token))) {
while (!APK_BLOB_IS_NULL(l = apk_bstream_read(bs, token))) {
lineno++;
if (l.len < 2 || l.ptr[1] != ':') {
......@@ -968,15 +968,15 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
}
if (os->write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
return -EIO;
bbuf = APK_BLOB_BUF(buf);
}
if (os->write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
return -EIO;
bbuf = APK_BLOB_BUF(buf);
}
os->write(os, "\n", 1);
apk_ostream_write(os, "\n", 1);
}
return 0;
......@@ -1088,13 +1088,13 @@ static void apk_db_triggers_write(struct apk_database *db, struct apk_ostream *o
bfn = APK_BLOB_BUF(buf);
apk_blob_push_csum(&bfn, &ipkg->pkg->csum);
bfn = apk_blob_pushed(APK_BLOB_BUF(buf), bfn);
os->write(os, bfn.ptr, bfn.len);
apk_ostream_write(os, bfn.ptr, bfn.len);
foreach_array_item(trigger, ipkg->triggers) {
os->write(os, " ", 1);
apk_ostream_write(os, " ", 1);
apk_ostream_write_string(os, *trigger);
}
os->write(os, "\n", 1);
apk_ostream_write(os, "\n", 1);
}
}
......@@ -1105,7 +1105,7 @@ static void apk_db_triggers_read(struct apk_database *db, struct apk_bstream *bs
struct apk_installed_package *ipkg;
apk_blob_t l;
while (!APK_BLOB_IS_NULL(l = bs->read(bs, APK_BLOB_STR("\n")))) {
while (!APK_BLOB_IS_NULL(l = apk_bstream_read(bs, APK_BLOB_STR("\n")))) {
apk_blob_pull_csum(&l, &csum);
apk_blob_pull_char(&l, ' ');
......@@ -1148,14 +1148,14 @@ static int apk_db_read_state(struct apk_database *db, int flags)
bs = apk_bstream_from_file(db->root_fd, apk_installed_file);
if (!IS_ERR_OR_NULL(bs)) {
r = apk_db_index_read(db, bs, -1);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
if (r != 0) return -1;
}
bs = apk_bstream_from_file(db->root_fd, apk_triggers_file);
if (!IS_ERR_OR_NULL(bs)) {
apk_db_triggers_read(db, bs);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
......@@ -1164,7 +1164,7 @@ static int apk_db_read_state(struct apk_database *db, int flags)
if (!IS_ERR_OR_NULL(is)) {
apk_tar_parse(is, apk_read_script_archive_entry, db,
FALSE, &db->id_cache);
is->close(is);
apk_istream_close(is);
}
}
......@@ -1190,7 +1190,7 @@ static int write_index_entry(apk_hash_item item, void *ctx)
if (r < 0)
return r;
if (iwctx->os->write(iwctx->os, "\n", 1) != 1)
if (apk_ostream_write(iwctx->os, "\n", 1) != 1)
return -EIO;
iwctx->count++;
......@@ -1224,7 +1224,7 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
if (r != 0)
return r;
}
r = os->close(os);
r = apk_ostream_close(os);
if (r < 0)
return r;
......@@ -1656,7 +1656,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
bs = apk_bstream_from_file(db->cache_fd, "installed");
if (!IS_ERR_OR_NULL(bs)) {
apk_db_index_read(db, bs, -2);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
}
......@@ -1727,8 +1727,8 @@ int apk_db_write_config(struct apk_database *db)
0644);
if (IS_ERR_OR_NULL(os)) return PTR_ERR(os);
apk_deps_write(db, db->world, os, APK_BLOB_PTR_LEN("\n", 1));
os->write(os, "\n", 1);
r = os->close(os);
apk_ostream_write(os, "\n", 1);
r = apk_ostream_close(os);
if (r < 0) return r;
os = apk_ostream_to_file(db->root_fd,
......@@ -1737,7 +1737,7 @@ int apk_db_write_config(struct apk_database *db)
0644);
if (IS_ERR_OR_NULL(os)) return PTR_ERR(os);
apk_db_write_fdb(db, os);
r = os->close(os);
r = apk_ostream_close(os);
if (r < 0) return r;
os = apk_ostream_to_file(db->root_fd,
......@@ -1746,7 +1746,7 @@ int apk_db_write_config(struct apk_database *db)
0644);
if (IS_ERR_OR_NULL(os)) return PTR_ERR(os);
apk_db_scriptdb_write(db, os);
r = os->close(os);
r = apk_ostream_close(os);
if (r < 0) return r;
apk_db_index_write_nr_cache(db);
......@@ -1757,7 +1757,7 @@ int apk_db_write_config(struct apk_database *db)
0644);
if (IS_ERR_OR_NULL(os)) return PTR_ERR(os);
apk_db_triggers_write(db, os);
r = os->close(os);
r = apk_ostream_close(os);
if (r < 0) return r;
return 0;
......@@ -2150,7 +2150,7 @@ static int load_apkindex(void *sctx, const struct apk_file_info *fi,
bs = apk_bstream_from_istream(is);
if (!IS_ERR_OR_NULL(bs)) {
apk_db_index_read(ctx->db, bs, ctx->repo);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
......@@ -2174,7 +2174,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs,
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
r = apk_tar_parse(is, load_apkindex, &ctx, FALSE, &db->id_cache);
is->close(is);
apk_istream_close(is);
apk_sign_ctx_free(&ctx.sctx);
if (r >= 0 && ctx.found == 0)
......@@ -2183,7 +2183,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs,
bs = apk_bstream_from_istream(apk_bstream_gunzip(bs));
if (!IS_ERR_OR_NULL(bs)) {
apk_db_index_read(db, bs, repo);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
return r;
......@@ -2737,7 +2737,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE, &db->id_cache);
apk_sign_ctx_free(&ctx.sctx);
tar->close(tar);
apk_istream_close(tar);
if (need_copy) {
if (r == 0) {
......
......@@ -178,11 +178,11 @@ static int fetch_package(apk_hash_item item, void *pctx)
r = apk_istream_splice(is, fd, pkg->size, progress_cb, ctx);
if (fd != STDOUT_FILENO) {
struct apk_file_meta meta;
is->get_meta(is, &meta);
apk_istream_get_meta(is, &meta);
apk_file_meta_to_fd(fd, &meta);
close(fd);
}
is->close(is);
apk_istream_close(is);
if (r != pkg->size) {
unlinkat(ctx->outdir_fd, filename, 0);
......
......@@ -34,7 +34,7 @@ static void gzi_get_meta(void *stream, struct apk_file_meta *meta)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
gis->bs->get_meta(gis->bs, meta);
apk_bstream_get_meta(gis->bs, meta);
}
static ssize_t gzi_read(void *stream, void *ptr, size_t size)
......@@ -77,7 +77,7 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
APK_BLOB_PTR_LEN(gis->cbprev,
(void *)gis->zs.next_in - gis->cbprev));
}
blob = gis->bs->read(gis->bs, APK_BLOB_NULL);
blob = apk_bstream_read(gis->bs, APK_BLOB_NULL);
gis->cbprev = blob.ptr;
gis->zs.avail_in = blob.len;
gis->zs.next_in = (void *) gis->cbprev;
......@@ -147,10 +147,16 @@ static void gzi_close(void *stream)
container_of(stream, struct apk_gzip_istream, is);
inflateEnd(&gis->zs);
gis->bs->close(gis->bs, NULL);
apk_bstream_close(gis->bs, NULL);
free(gis);
}
static const struct apk_istream_ops gunzip_istream_ops = {
.get_meta = gzi_get_meta,
.read = gzi_read,
.close = gzi_close,
};
struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
apk_multipart_cb cb, void *ctx)
{
......@@ -162,9 +168,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
if (!gis) goto err;
*gis = (struct apk_gzip_istream) {
.is.get_meta = gzi_get_meta,
.is.read = gzi_read,
.is.close = gzi_close,
.is.ops = &gunzip_istream_ops,
.bs = bs,
.cb = cb,
.cbctx = ctx,
......@@ -177,7 +181,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
return &gis->is;
err:
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
return ERR_PTR(-ENOMEM);
}
......@@ -203,7 +207,7 @@ static ssize_t gzo_write(void *stream, const void *ptr, size_t size)
return -EIO;
have = sizeof(buffer) - gos->zs.avail_out;
if (have != 0) {
r = gos->output->write(gos->output, buffer, have);
r = apk_ostream_write(gos->output, buffer, have);
if (r != have)
return -EIO;
}
......@@ -224,10 +228,10 @@ static int gzo_close(void *stream)
gos->zs.next_out = buffer;
r = deflate(&gos->zs, Z_FINISH);
have = sizeof(buffer) - gos->zs.avail_out;
if (gos->output->write(gos->output, buffer, have) != have)
if (apk_ostream_write(gos->output, buffer, have) != have)
rc = -EIO;
} while (r == Z_OK);
r = gos->output->close(gos->output);
r = apk_ostream_close(gos->output);
if (r != 0)
rc = r;
......@@ -237,6 +241,11 @@ static int gzo_close(void *stream)
return rc;
}
static const struct apk_ostream_ops gzip_ostream_ops = {
.write = gzo_write,
.close = gzo_close,
};
struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
{
struct apk_gzip_ostream *gos;
......@@ -247,8 +256,7 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
if (gos == NULL) goto err;
*gos = (struct apk_gzip_ostream) {
.os.write = gzo_write,
.os.close = gzo_close,
.os.ops = &gzip_ostream_ops,
.output = output,
};
......@@ -260,7 +268,7 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
return &gos->os;
err:
output->close(output);
apk_ostream_close(output);
return ERR_PTR(-ENOMEM);
}
......@@ -215,7 +215,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
fi.name = "APKINDEX";
counter = apk_ostream_counter(&fi.size);
r = apk_db_index_write(db, counter);
counter->close(counter);
apk_ostream_close(counter);
if (r >= 0) {
os = apk_ostream_gzip(os);
......@@ -237,7 +237,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
} else {
r = apk_db_index_write(db, os);
}
os->close(os);
apk_ostream_close(os);
if (r < 0) {
apk_error("Index generation failed: %s", apk_error_str(r));
......
......@@ -140,8 +140,8 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
os = apk_ostream_to_fd(STDOUT_FILENO);
if (!IS_ERR_OR_NULL(os)) {
apk_deps_write(db, deps, os, APK_BLOB_PTR_LEN(" ", 1));
os->write(os, "\n", 1);
os->close(os);
apk_ostream_write(os, "\n", 1);
apk_ostream_close(os);
}
}
apk_dependency_array_free(&deps);
......
......@@ -110,6 +110,12 @@ static void fdi_close(void *stream)
free(fis);
}
static const struct apk_istream_ops fd_istream_ops = {
.get_meta = fdi_get_meta,
.read = fdi_read,
.close = fdi_close,
};
struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int))
{
struct apk_fd_istream *fis;
......@@ -123,9 +129,7 @@ struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_s
}
*fis = (struct apk_fd_istream) {
.is.get_meta = fdi_get_meta,
.is.read = fdi_read,
.is.close = fdi_close,
.is.ops = &fd_istream_ops,
.fd = fd,
.pid = pid,
.translate_status = translate_status,
......@@ -153,7 +157,7 @@ size_t apk_istream_skip(struct apk_istream *is, size_t size)
togo = size - done;
if (togo > sizeof(buf))
togo = sizeof(buf);
r = is->read(is, buf, togo);
r = apk_istream_read(is, buf, togo);
if (r < 0)
return r;
done += r;
......@@ -202,7 +206,7 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
togo = size - done;
if (togo > bufsz)
togo = bufsz;
r = is->read(is, buf, togo);
r = apk_istream_read(is, buf, togo);
if (r < 0)
goto err;
if (r == 0)
......@@ -240,7 +244,7 @@ static void is_bs_get_meta(void *stream, struct apk_file_meta *meta)
{
struct apk_istream_bstream *isbs =
container_of(stream, struct apk_istream_bstream, bs);
return isbs->is->get_meta(isbs->is, meta);
return apk_istream_get_meta(isbs->is, meta);
}
static apk_blob_t is_bs_read(void *stream, apk_blob_t token)
......@@ -268,8 +272,8 @@ static apk_blob_t is_bs_read(void *stream, apk_blob_t token)
if (isbs->left.len != 0)
memmove(isbs->buffer, isbs->left.ptr, isbs->left.len);
isbs->left.ptr = isbs->buffer;
size = isbs->is->read(isbs->is, isbs->buffer + isbs->left.len,
sizeof(isbs->buffer) - isbs->left.len);
size = apk_istream_read(isbs->is, isbs->buffer + isbs->left.len,
sizeof(isbs->buffer) - isbs->left.len);
if (size > 0) {
isbs->size += size;
isbs->left.len += size;
......@@ -306,10 +310,16 @@ static void is_bs_close(void *stream, size_t *size)
if (size != NULL)
*size = isbs->size;
isbs->is->close(isbs->is);
apk_istream_close(isbs->is);
free(isbs);
}
static const struct apk_bstream_ops is_bstream_ops = {
.get_meta = is_bs_get_meta,
.read = is_bs_read,
.close = is_bs_close,
};
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream)
{
struct apk_istream_bstream *isbs;
......@@ -320,9 +330,7 @@ struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream)
if (isbs == NULL) return ERR_PTR(-ENOMEM);
isbs->bs = (struct apk_bstream) {
.get_meta = is_bs_get_meta,
.read = is_bs_read,
.close = is_bs_close,
.ops = &is_bstream_ops,
};
isbs->is = istream;
isbs->left = APK_BLOB_PTR_LEN(isbs->buffer, 0),
......@@ -376,6 +384,12 @@ static void mmap_close(void *stream, size_t *size)
free(mbs);
}
static const struct apk_bstream_ops mmap_bstream_ops = {
.get_meta = mmap_get_meta,
.read = mmap_read,
.close = mmap_close,
};
static struct apk_bstream *apk_mmap_bstream_from_fd(int fd)
{
struct apk_mmap_bstream *mbs;
......@@ -395,9 +409,7 @@ static struct apk_bstream *apk_mmap_bstream_from_fd(int fd)
mbs->bs = (struct apk_bstream) {
.flags = APK_BSTREAM_SINGLE_READ,
.get_meta = mmap_get_meta,
.read = mmap_read,
.close = mmap_close,
.ops = &mmap_bstream_ops,
};
mbs->fd = fd;
mbs->size = st.st_size;
......@@ -446,7 +458,7 @@ static void tee_get_meta(void *stream, struct apk_file_meta *meta)
{
struct apk_tee_bstream *tbs =
container_of(stream, struct apk_tee_bstream, bs);
tbs->inner_bs->get_meta(tbs->inner_bs, meta);
apk_bstream_get_meta(tbs->inner_bs, meta);
}
static apk_blob_t tee_read(void *stream, apk_blob_t token)
......@@ -455,11 +467,10 @@ static apk_blob_t tee_read(void *stream, apk_blob_t token)
container_of(stream, struct apk_tee_bstream, bs);
apk_blob_t blob;
blob = tbs->inner_bs->read(tbs->inner_bs, token);
blob = apk_bstream_read(tbs->inner_bs, token);
if (!APK_BLOB_IS_NULL(blob)) {
tbs->size += write(tbs->fd, blob.ptr, blob.len);