373 lines · 6.7 KB · C
RawDownload
/*  _______         ____    __         ___    ___ * \    _  \       \    /  \  /       \   \  /   /       '   '  ' *  |  | \  \       |  |    ||         |   \/   |         .      . *  |  |  |  |      |  |    ||         ||\  /|  | *  |  |  |  |      |  |    ||         || \/ |  |         '  '  ' *  |  |  |  |      |  |    ||         ||    |  |         .      . *  |  |_/  /        \  \__//          ||    |  | * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque *                                                      /  \ *                                                     / .  \ * dumbfile.c - Hookable, strictly sequential         / / \  \ *              file input functions.                | <  /   \_ *                                                   |  \/ /\   / * By entheh.                                         \_  /  > / *                                                      | \ / / *                                                      |  ' / *                                                       \__/ */ #include <stdlib.h> #include "dumb.h"#include "internal/dumb.h" static const DUMBFILE_SYSTEM *the_dfs = NULL; void register_dumbfile_system(const DUMBFILE_SYSTEM *dfs) {    ASSERT(dfs);    ASSERT(dfs->open);    ASSERT(dfs->getc);    ASSERT(dfs->close);    ASSERT(dfs->seek);    ASSERT(dfs->get_size);    the_dfs = dfs;} #include "internal/dumbfile.h" DUMBFILE *dumbfile_open(const char *filename) {    DUMBFILE *f;     ASSERT(the_dfs);     f = (DUMBFILE *)malloc(sizeof(*f));     if (!f)        return NULL;     f->dfs = the_dfs;     f->file = (*the_dfs->open)(filename);     if (!f->file) {        free(f);        return NULL;    }     f->pos = 0;     return f;} DUMBFILE *dumbfile_open_ex(void *file, const DUMBFILE_SYSTEM *dfs) {    DUMBFILE *f;     ASSERT(dfs);    ASSERT(dfs->getc);    ASSERT(file);     f = (DUMBFILE *)malloc(sizeof(*f));     if (!f) {        if (dfs->close)            (*dfs->close)(file);        return NULL;    }     f->dfs = dfs;    f->file = file;     f->pos = 0;     return f;} dumb_off_t dumbfile_pos(DUMBFILE *f) {    ASSERT(f);     return f->pos;} /* Move forward in the file from the current position by n bytes. */int dumbfile_skip(DUMBFILE *f, dumb_off_t n) {    int rv;     ASSERT(f);    ASSERT(n >= 0);     if (f->pos < 0)        return -1;     f->pos += n;     if (f->dfs->skip) {        rv = (*f->dfs->skip)(f->file, n);        if (rv) {            f->pos = -1;            return rv;        }    } else {        while (n) {            rv = (*f->dfs->getc)(f->file);            if (rv < 0) {                f->pos = -1;                return rv;            }            n--;        }    }     return 0;} int dumbfile_getc(DUMBFILE *f) {    int rv;     ASSERT(f);     if (f->pos < 0)        return -1;     rv = (*f->dfs->getc)(f->file);     if (rv < 0) {        f->pos = -1;        return rv;    }     f->pos++;     return rv;} int dumbfile_igetw(DUMBFILE *f) {    int l, h;     ASSERT(f);     if (f->pos < 0)        return -1;     l = (*f->dfs->getc)(f->file);    if (l < 0) {        f->pos = -1;        return l;    }     h = (*f->dfs->getc)(f->file);    if (h < 0) {        f->pos = -1;        return h;    }     f->pos += 2;     return l | (h << 8);} int dumbfile_mgetw(DUMBFILE *f) {    int l, h;     ASSERT(f);     if (f->pos < 0)        return -1;     h = (*f->dfs->getc)(f->file);    if (h < 0) {        f->pos = -1;        return h;    }     l = (*f->dfs->getc)(f->file);    if (l < 0) {        f->pos = -1;        return l;    }     f->pos += 2;     return l | (h << 8);} long dumbfile_igetl(DUMBFILE *f) {    unsigned long rv, b;     ASSERT(f);     if (f->pos < 0)        return -1;     rv = (*f->dfs->getc)(f->file);    if ((signed long)rv < 0) {        f->pos = -1;        return rv;    }     b = (*f->dfs->getc)(f->file);    if ((signed long)b < 0) {        f->pos = -1;        return b;    }    rv |= b << 8;     b = (*f->dfs->getc)(f->file);    if ((signed long)b < 0) {        f->pos = -1;        return b;    }    rv |= b << 16;     b = (*f->dfs->getc)(f->file);    if ((signed long)b < 0) {        f->pos = -1;        return b;    }    rv |= b << 24;     f->pos += 4;     return rv;} long dumbfile_mgetl(DUMBFILE *f) {    unsigned long rv, b;     ASSERT(f);     if (f->pos < 0)        return -1;     rv = (*f->dfs->getc)(f->file);    if ((signed long)rv < 0) {        f->pos = -1;        return rv;    }    rv <<= 24;     b = (*f->dfs->getc)(f->file);    if ((signed long)b < 0) {        f->pos = -1;        return b;    }    rv |= b << 16;     b = (*f->dfs->getc)(f->file);    if ((signed long)b < 0) {        f->pos = -1;        return b;    }    rv |= b << 8;     b = (*f->dfs->getc)(f->file);    if ((signed long)b < 0) {        f->pos = -1;        return b;    }    rv |= b;     f->pos += 4;     return rv;} unsigned long dumbfile_cgetul(DUMBFILE *f) {    unsigned long rv = 0;    int v;     do {        v = dumbfile_getc(f);         if (v < 0)            return v;         rv <<= 7;        rv |= v & 0x7F;    } while (v & 0x80);     return rv;} signed long dumbfile_cgetsl(DUMBFILE *f) {    unsigned long rv = dumbfile_cgetul(f);     if (f->pos < 0)        return rv;     return (rv >> 1) | (rv << 31);} dumb_ssize_t dumbfile_getnc(char *ptr, size_t n, DUMBFILE *f) {    dumb_ssize_t rv;     ASSERT(f);    ASSERT(n >= 0);     if (f->pos < 0)        return -1;     if (f->dfs->getnc) {        rv = (*f->dfs->getnc)(ptr, n, f->file);        if (rv < (dumb_ssize_t)n) {            f->pos = -1;            return MAX(rv, 0);        }    } else {        for (rv = 0; rv < (dumb_ssize_t)n; rv++) {            int c = (*f->dfs->getc)(f->file);            if (c < 0) {                f->pos = -1;                return rv;            }            *ptr++ = c;        }    }     f->pos += rv;     return rv;} /* Move to an arbitrary position n in the file, specified relative to origin, * where origin shall be one of the DFS_SEEK_* constants. */int dumbfile_seek(DUMBFILE *f, dumb_off_t n, int origin) {    switch (origin) {    case DFS_SEEK_CUR:        n += f->pos;        break;    case DFS_SEEK_END:        n += (*f->dfs->get_size)(f->file);        break;    default:        break; /* keep n, seek position from beginning of file */    }    f->pos = n;    return (*f->dfs->seek)(f->file, n);} dumb_off_t dumbfile_get_size(DUMBFILE *f) {    return (*f->dfs->get_size)(f->file);} int dumbfile_error(DUMBFILE *f) {    ASSERT(f);     return f->pos < 0;} int dumbfile_close(DUMBFILE *f) {    int rv;     ASSERT(f);     rv = f->pos < 0;     if (f->dfs->close)        (*f->dfs->close)(f->file);     free(f);     return rv;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t