Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/amachronic/microtar.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-11-04 20:00:54 +0300
committerAidan MacDonald <amachronic@protonmail.com>2021-11-04 23:08:29 +0300
commit2b65975df91d389b6c8e5584a5258669ec3680a2 (patch)
treef367eda2b42bded5c31e5c5fab76de990a7d841c
parent2a6bf50265c94138b7144243b5ba0e57a9afcbf4 (diff)
Move stream ops into mtar_ops_t; separate open and init
Moving stream ops into a separate struct lets them be defined in a const object and shared between multiple mtar_t objects. Also provide a new mtar_init() call which accepts the ops struct and initializes the mtar_t object properly.
-rw-r--r--src/microtar-stdio.c57
-rw-r--r--src/microtar.c24
-rw-r--r--src/microtar.h17
3 files changed, 55 insertions, 43 deletions
diff --git a/src/microtar-stdio.c b/src/microtar-stdio.c
index 87ae4f7..4aed2a6 100644
--- a/src/microtar-stdio.c
+++ b/src/microtar-stdio.c
@@ -25,61 +25,48 @@
#include <stdio.h>
#include <string.h>
-static int file_write(mtar_t* tar, const void* data, unsigned size)
+static int file_read(void* stream, void* data, unsigned size)
{
- unsigned res = fwrite(data, 1, size, tar->stream);
- return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
+ unsigned res = fread(data, 1, size, (FILE*)stream);
+ return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
}
-static int file_read(mtar_t* tar, void* data, unsigned size)
+static int file_write(void* stream, const void* data, unsigned size)
{
- unsigned res = fread(data, 1, size, tar->stream);
- return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
+ unsigned res = fwrite(data, 1, size, (FILE*)stream);
+ return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
}
-static int file_seek(mtar_t* tar, unsigned offset)
+static int file_seek(void* stream, unsigned offset)
{
- int res = fseek(tar->stream, offset, SEEK_SET);
+ int res = fseek((FILE*)stream, offset, SEEK_SET);
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
}
-static int file_close(mtar_t* tar)
+static int file_close(void* stream)
{
- fclose(tar->stream);
- return MTAR_ESUCCESS;
+ int err = fclose((FILE*)stream);
+ return (err == 0 ? MTAR_ESUCCESS : MTAR_EFAILURE);
}
+static const mtar_ops_t file_ops = {
+ .read = file_read,
+ .write = file_write,
+ .seek = file_seek,
+ .close = file_close,
+};
+
int mtar_open(mtar_t* tar, const char* filename, const char* mode)
{
- int err;
- mtar_header_t h;
-
- /* Init tar struct and functions */
- memset(tar, 0, sizeof(*tar));
- tar->write = file_write;
- tar->read = file_read;
- tar->seek = file_seek;
- tar->close = file_close;
-
- /* Assure mode is always binary */
+ /* Ensure mode is always binary */
if(strchr(mode, 'r')) mode = "rb";
if(strchr(mode, 'w')) mode = "wb";
if(strchr(mode, 'a')) mode = "ab";
/* Open file */
- tar->stream = fopen(filename, mode);
- if(!tar->stream)
+ FILE* file = fopen(filename, mode);
+ if(!file)
return MTAR_EOPENFAIL;
- /* Read first header to check it is valid if mode is `r` */
- if(*mode == 'r') {
- err = mtar_read_header(tar, &h);
- if(err != MTAR_ESUCCESS) {
- mtar_close(tar);
- return err;
- }
- }
-
- /* Return ok */
- return MTAR_ESUCCESS;
+ return mtar_init(tar, &file_ops, file);
}
diff --git a/src/microtar.c b/src/microtar.c
index 81e1031..2f5f781 100644
--- a/src/microtar.c
+++ b/src/microtar.c
@@ -99,7 +99,7 @@ static unsigned checksum(const mtar_raw_header_t* rh)
static int tread(mtar_t* tar, void* data, unsigned size)
{
- int err = tar->read(tar, data, size);
+ int err = tar->ops->read(tar->stream, data, size);
tar->pos += size;
return err;
}
@@ -107,7 +107,7 @@ static int tread(mtar_t* tar, void* data, unsigned size)
static int twrite(mtar_t* tar, const void* data, unsigned size)
{
- int err = tar->write(tar, data, size);
+ int err = tar->ops->write(tar->stream, data, size);
tar->pos += size;
return err;
}
@@ -216,18 +216,34 @@ const char* mtar_strerror(int err)
}
}
+int mtar_init(mtar_t* tar, const mtar_ops_t* ops, void* stream)
+{
+ memset(tar, 0, sizeof(mtar_t));
+ tar->ops = ops;
+ tar->stream = stream;
+ return 0;
+}
+
int mtar_close(mtar_t* tar)
{
- return tar->close(tar);
+ int err = tar->ops->close(tar->stream);
+ tar->ops = NULL;
+ tar->stream = NULL;
+ return err;
}
int mtar_seek(mtar_t* tar, unsigned pos)
{
- int err = tar->seek(tar, pos);
+ int err = tar->ops->seek(tar->stream, pos);
tar->pos = pos;
return err;
}
+int mtar_is_open(mtar_t* tar)
+{
+ return (tar->ops != NULL) ? 1 : 0;
+}
+
int mtar_rewind(mtar_t* tar)
{
tar->remaining_data = 0;
diff --git a/src/microtar.h b/src/microtar.h
index d17129c..b24c8dc 100644
--- a/src/microtar.h
+++ b/src/microtar.h
@@ -57,6 +57,7 @@ enum {
typedef struct mtar_header mtar_header_t;
typedef struct mtar_raw_header mtar_raw_header_t;
typedef struct mtar mtar_t;
+typedef struct mtar_ops mtar_ops_t;
struct mtar_header {
unsigned mode;
@@ -82,12 +83,17 @@ struct mtar_raw_header {
char _padding[255];
};
+struct mtar_ops {
+ int(*read)(void* stream, void* data, unsigned size);
+ int(*write)(void* stream, const void* data, unsigned size);
+ int(*seek)(void* stream, unsigned pos);
+ int(*close)(void* stream);
+};
+
struct mtar {
- int (*read)(mtar_t* tar, void* data, unsigned size);
- int (*write)(mtar_t* tar, const void* data, unsigned size);
- int (*seek)(mtar_t* tar, unsigned pos);
- int (*close)(mtar_t* tar);
+ const mtar_ops_t* ops;
void* stream;
+
unsigned pos;
unsigned remaining_data;
unsigned last_header;
@@ -98,7 +104,10 @@ struct mtar {
const char* mtar_strerror(int err);
int mtar_open(mtar_t* tar, const char* filename, const char* mode);
+
+int mtar_init(mtar_t* tar, const mtar_ops_t* ops, void* stream);
int mtar_close(mtar_t* tar);
+int mtar_is_open(mtar_t* tar);
int mtar_seek(mtar_t* tar, unsigned pos);
int mtar_rewind(mtar_t* tar);