Skip to content

Commit

Permalink
io: make io vtables const struct, and add accessors for them
Browse files Browse the repository at this point in the history
This reduces function pointers in heap, and unifies how the
io functions are called.

(cherry picked from commit 09ca58863af02d11e8dbf066b714464fb1638e6f)
  • Loading branch information
fabled committed Jun 23, 2017
1 parent 430b950 commit ec0aae1
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 119 deletions.
4 changes: 2 additions & 2 deletions src/apk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
Expand Down
52 changes: 48 additions & 4 deletions src/apk_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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));
Expand All @@ -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);
Expand Down
30 changes: 17 additions & 13 deletions src/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -321,15 +325,15 @@ 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;
}
}

/* 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;
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Loading

0 comments on commit ec0aae1

Please sign in to comment.