piece-chain

Research & implementation of a Piece Chain
git clone git://src.gearsix.net/piece-chain.git
Log | Files | Refs | Atom | README

commit 0cec6d691981dbb10d2d0967dd0e3302eda34586
parent 699facb796acd5fbf1a8d94ca52d669a333af237
Author: gearsix <gearsix@tuta.io>
Date:   Wed,  6 Jul 2022 18:59:40 +0100

added bufout & test for it

Diffstat:
Mbuf.c | 31++++++++++++++++++++++++++-----
Mbuf.h | 4+++-
Mtest.c | 32++++++++++++++++++++++++++++----
3 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/buf.c b/buf.c @@ -65,17 +65,15 @@ static Piece *psplit(Piece *p, long int offset) return p; } -struct Buf *bufinit(const char *fpath) +struct Buf *bufinit(FILE *f) { Buf *b = calloc(1, sizeof(Buf)); b->append = tmpfile(); b->tail = b->pos = b->head = palloc(); - if (fpath) { - b->read = fopen(fpath, "rb"); - if (ferror(b->read)) perror(fpath); - + if (f) { + b->read =f; b->pos->f = b->read; fseek(b->read, 0, SEEK_END); b->size = b->pos->len = ftell(b->read); @@ -159,3 +157,26 @@ size_t bufdel(Buf *b, size_t pos, size_t num) b->idx = pos; return (b->size -= num); } + +int bufout(Buf *b, FILE *f) +{ + size_t n, fsiz = 0; + char buf[BUFSIZ]; + Piece *p = b->tail; + + do { + if ((size_t)ftell(p->f) != p->off) + fseek(p->f, p->off, SEEK_SET); + + n = 0; + do { + buf[0] = '\0'; + fread(buf, 1, p->len, p->f); + fsiz += fwrite(buf, 1, p->len, f); + } while (p->len - (BUFSIZ*n++) > BUFSIZ); + + p = p->next; + } while(p); + + return fsiz; +} diff --git a/buf.h b/buf.h @@ -15,10 +15,12 @@ typedef struct Buf { struct Piece *tail, *pos, *head; } Buf; -Buf *bufinit(const char *fpath); +Buf *bufinit(FILE *f); Piece *bufidx(Buf *b, size_t pos); size_t bufins(Buf *b, size_t pos, const char *s); size_t bufdel(Buf *b, size_t pos, size_t num); + +int bufout(Buf *b, FILE *f); diff --git a/test.c b/test.c @@ -9,18 +9,27 @@ #define OUTBUF "hey buddy!" /* tests will aim to change INBUF to this */ Buf *b; +FILE *in, *out; void setup() { - FILE *in = fopen(INFILE, "w+b"); + in = fopen(INFILE, "w+b"); if (ferror(in)) perror("fopen in.txt"); fputs(INBUF, in); - fclose(in); + + out = fopen(OUTFILE, "w+b"); + if (ferror(in)) perror("fopen out.txt"); return; } -void print(Buf *b) +void setdown() +{ + fclose(out); + fclose(in); +} + +void print() { Piece *p = b->tail; @@ -32,6 +41,8 @@ void print(Buf *b) if (p == b->pos) printf("<-pos"); if (p == b->head) printf("<-head"); puts(""); + printf("\tf: %s, off: %lu, len %lu\n", + (p->f == b->read) ? "read" : "append", p->off, p->len); } while ((p = p->next)); printf("\n"); fflush(stdout); @@ -41,7 +52,7 @@ void test_bufinit() { Piece *p; - b = bufinit(INFILE); + b = bufinit(in); assert(b->read); assert(b->append); @@ -131,6 +142,17 @@ void test_bufins1() assert(b->pos->next == NULL); } +void test_bufout() +{ + char buf[BUFSIZ] = {0}; + + bufout(b, out); + + rewind(out); + assert(fread(buf, 1, BUFSIZ, out) > 0); + assert(strcmp(buf, OUTBUF) == 0); +} + int main() { setup(); @@ -139,6 +161,8 @@ int main() test_bufins(); test_bufdel(); test_bufins1(); + test_bufout(); + setdown(); puts("success - no assertions failed"); return 0; }