From 8240a35ce5d083ebfbebefeb533c58a2a66e3772 Mon Sep 17 00:00:00 2001 From: Inndy Date: Fri, 8 Nov 2019 16:50:41 +0800 Subject: [PATCH 1/5] Add support for in-memory tar --- src/microtar.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/microtar.h | 9 ++++++++ 2 files changed, 72 insertions(+) diff --git a/src/microtar.c b/src/microtar.c index 4b89776..80d6fd1 100644 --- a/src/microtar.c +++ b/src/microtar.c @@ -173,6 +173,69 @@ static int file_close(mtar_t *tar) { return MTAR_ESUCCESS; } +static int mem_write(mtar_t *tar, const void *data, unsigned size) { + mtar_mem_stream_t *mem = tar->stream; + + if(!mem || mem->pos + size >= mem->size) { + return MTAR_EWRITEFAIL; + } + + memcpy(mem->data + mem->pos, data, size); + mem->pos += size; + + return MTAR_ESUCCESS; +} + +static int mem_read(mtar_t *tar, void *data, unsigned size) { + mtar_mem_stream_t *mem = tar->stream; + + if(!mem || mem->pos + size >= mem->size) { + return MTAR_EREADFAIL; + } + + memcpy(data, mem->data + mem->pos, size); + mem->pos += size; + + return MTAR_ESUCCESS; +} + +static int mem_seek(mtar_t *tar, unsigned offset) { + mtar_mem_stream_t *mem = tar->stream; + + if(!mem || offset >= mem->size) + return MTAR_ESEEKFAIL; + + mem->pos = offset; + + return MTAR_ESUCCESS; +} + +static int mem_close(mtar_t *tar) { + tar->stream = NULL; + + return MTAR_ESUCCESS; +} + + +int mtar_open_mem(mtar_t *tar, mtar_mem_stream_t *mem) { + int err; + mtar_header_t h; + + if ( !mem || !mem->data || !mem->size ) { + return MTAR_EOPENFAIL; + } + + memset(tar, 0, sizeof(*tar)); + tar->write = mem_write; + tar->read = mem_read; + tar->seek = mem_seek; + tar->close = mem_close; + + tar->stream = mem; + + return MTAR_ESUCCESS; +} + int mtar_open(mtar_t *tar, const char *filename, const char *mode) { int err; diff --git a/src/microtar.h b/src/microtar.h index f4a62d1..c8daf3a 100644 --- a/src/microtar.h +++ b/src/microtar.h @@ -64,9 +64,18 @@ struct mtar_t { unsigned last_header; }; +struct mtar_mem_stream_t { + char *data; + size_t size; + size_t pos; +}; + +typedef struct mtar_mem_stream_t mtar_mem_stream_t; + const char* mtar_strerror(int err); +int mtar_open_mem(mtar_t *tar, mtar_mem_stream_t *mem); int mtar_open(mtar_t *tar, const char *filename, const char *mode); int mtar_close(mtar_t *tar); From d6e17bdecf7577c5b1b1146d50a05467fab1ddc1 Mon Sep 17 00:00:00 2001 From: Inndy Date: Fri, 8 Nov 2019 17:01:47 +0800 Subject: [PATCH 2/5] Optimize write_null_bytes --- src/microtar.c | 8 +++++--- src/microtar.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/microtar.c b/src/microtar.c index 80d6fd1..d4efa4e 100644 --- a/src/microtar.c +++ b/src/microtar.c @@ -76,12 +76,14 @@ static int twrite(mtar_t *tar, const void *data, unsigned size) { static int write_null_bytes(mtar_t *tar, int n) { int i, err; - char nul = '\0'; - for (i = 0; i < n; i++) { - err = twrite(tar, &nul, 1); + char nul[MTAR_NULL_BLOCKSIZE]; + memset(nul, 0, sizeof(nul)); + while (n > 0) { + err = twrite(tar, &nul, n > MTAR_NULL_BLOCKSIZE ? MTAR_NULL_BLOCKSIZE : n); if (err) { return err; } + n -= MTAR_NULL_BLOCKSIZE; } return MTAR_ESUCCESS; } diff --git a/src/microtar.h b/src/microtar.h index c8daf3a..289bda0 100644 --- a/src/microtar.h +++ b/src/microtar.h @@ -17,6 +17,7 @@ extern "C" #include #define MTAR_VERSION "0.1.0" +#define MTAR_NULL_BLOCKSIZE 16 enum { MTAR_ESUCCESS = 0, From ea7cd648eab30a1326adae7c4ade79d29babc922 Mon Sep 17 00:00:00 2001 From: Inndy Date: Fri, 8 Nov 2019 17:13:44 +0800 Subject: [PATCH 3/5] Add helper function to init mtar_mem_stream_t --- src/microtar.c | 8 ++++++++ src/microtar.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/microtar.c b/src/microtar.c index d4efa4e..4713591 100644 --- a/src/microtar.c +++ b/src/microtar.c @@ -219,6 +219,14 @@ static int mem_close(mtar_t *tar) { } +int mtar_init_mem_stream(mtar_mem_stream_t *mem, void *buff, size_t size) +{ + mem->data = buff; + mem->size = size; + mem->pos = 0; +} + + int mtar_open_mem(mtar_t *tar, mtar_mem_stream_t *mem) { int err; mtar_header_t h; diff --git a/src/microtar.h b/src/microtar.h index 289bda0..2f3f6fd 100644 --- a/src/microtar.h +++ b/src/microtar.h @@ -76,6 +76,8 @@ typedef struct mtar_mem_stream_t mtar_mem_stream_t; const char* mtar_strerror(int err); +int mtar_init_mem_stream(mtar_mem_stream_t *mem, void *buff, size_t size); + int mtar_open_mem(mtar_t *tar, mtar_mem_stream_t *mem); int mtar_open(mtar_t *tar, const char *filename, const char *mode); int mtar_close(mtar_t *tar); From c5a3b29ea66e3e12eb827645552754b2e3c454dc Mon Sep 17 00:00:00 2001 From: Inndy Date: Fri, 8 Nov 2019 17:14:11 +0800 Subject: [PATCH 4/5] Add description for memory stream usage --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 42acf49..475aa2c 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,39 @@ mtar_close(&tar); ``` +#### Writing to memory +```c +mtar_t tar; +mtar_mem_stream_t mem; +char buffer[4096]; +const char *str1 = "Hello world"; +const char *str2 = "Goodbye world"; + +/* Initialize memory stream object */ +mtar_init_mem_stream(&mem, buffer, sizeof(buffer)); +/* Open archive for writing */ +mtar_open_mem(&tar, &mem); + +/* Write strings to files `test1.txt` and `test2.txt` */ +mtar_write_file_header(&tar, "test1.txt", strlen(str1)); +mtar_write_data(&tar, str1, strlen(str1)); +mtar_write_file_header(&tar, "test2.txt", strlen(str2)); +mtar_write_data(&tar, str2, strlen(str2)); + +/* Finalize -- this needs to be the last thing done before closing */ +mtar_finalize(&tar); + +/* Close archive */ +mtar_close(&tar); + +/* Now you can process the buffer */ +size_t data_len = mem.pos; +FILE *fp = fopen("output.tar", "wb"); +fwrite(buffer, data_len, 1, fp); +fclose(fp); +``` + + ## Error handling All functions which return an `int` will return `MTAR_ESUCCESS` if the operation is successful. If an error occurs an error value less-than-zero will be From cbee53b1bede9fad095a13d1ea258fa0fe8bc462 Mon Sep 17 00:00:00 2001 From: Inndy Date: Wed, 9 Aug 2023 23:56:54 +0800 Subject: [PATCH 5/5] Fix missing return --- src/microtar.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/microtar.c b/src/microtar.c index 4713591..5b34d39 100644 --- a/src/microtar.c +++ b/src/microtar.c @@ -224,6 +224,7 @@ int mtar_init_mem_stream(mtar_mem_stream_t *mem, void *buff, size_t size) mem->data = buff; mem->size = size; mem->pos = 0; + return MTAR_ESUCCESS; }