Commit ec0aae11 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.

(cherry picked from commit 09ca58863af02d11e8dbf066b714464fb1638e6f)
parent 430b950d
......@@ -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;
......@@ -1655,7 +1655,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);
}
}
}
......@@ -1726,8 +1726,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,
......@@ -1736,7 +1736,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,
......@@ -1745,7 +1745,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);
......@@ -1756,7 +1756,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;
......@@ -2149,7 +2149,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);
}
}
......@@ -2173,7 +2173,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)
......@@ -2182,7 +2182,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;
......@@ -2736,7 +2736,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);
if (tbs->cb)
tbs->cb(tbs->cb_ctx, tbs->size);
if (tbs->cb) tbs->cb(tbs->cb_ctx, tbs->size);
}
return blob;
......@@ -472,16 +483,21 @@ static void tee_close(void *stream, size_t *size)
container_of(stream, struct apk_tee_bstream, bs);
/* copy info */
tbs->inner_bs->get_meta(tbs->inner_bs, &meta);
apk_bstream_get_meta(tbs->inner_bs, &meta);
apk_file_meta_to_fd(tbs->fd, &meta);
tbs->inner_bs->close(tbs->inner_bs, NULL);
if (size != NULL)
*size = tbs->size;
apk_bstream_close(tbs->inner_bs, NULL);
if (size != NULL) *size = tbs->size;
close(tbs->fd);
free(tbs);
}
static const struct apk_bstream_ops tee_bstream_ops = {
.get_meta = tee_get_meta,
.read = tee_read,
.close = tee_close,
};
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to, apk_progress_cb cb, void *cb_ctx)
{
struct apk_tee_bstream *tbs;
......@@ -493,7 +509,7 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0) {
r = errno;
from->close(from, NULL);
apk_bstream_close(from, NULL);
return ERR_PTR(-r);
}
......@@ -501,14 +517,12 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch
if (!tbs) {
r = errno;
close(fd);
from->close(from, NULL);
apk_bstream_close(from, NULL);
return ERR_PTR(-r);
}
tbs->bs