From 44c7d3b5896b070089ba4b3782b4a1f352727b87 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Fri, 7 Jan 2022 21:59:30 +0800 Subject: [PATCH] file reader support custom IO --- file_reader.c | 54 +++++++++++++++++++++++++++++++++++++++------------ file_reader.h | 14 +++++++++++++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/file_reader.c b/file_reader.c index 4691f80..8580ef6 100644 --- a/file_reader.c +++ b/file_reader.c @@ -6,16 +6,46 @@ #include "cstr_util.h" typedef struct file_reader_file { - FILE* f; + void* f; + file_reader_file_read read; + file_reader_file_seek seek; + file_reader_file_tell tell; /// 0 if little endian otherwise big endian unsigned char endian; } file_reader_file; +size_t file_reader_default_read(void* f, size_t buf_len, char* buf) { + return fread(buf, 1, buf_len, (FILE*)f); +} + +int file_reader_default_seek(void* f, int64_t offset, int origin) { + return fileop_fseek((FILE*)f, offset, origin); +} + +int64_t file_reader_default_tell(void* f) { + return fileop_ftell((FILE*)f); +} + file_reader_file* create_file_reader(FILE* f, unsigned char endian) { if (!f) return NULL; file_reader_file* r = malloc(sizeof(file_reader_file)); if (!r) return NULL; + r->f = (void*)f; + r->read = &file_reader_default_read; + r->seek = &file_reader_default_seek; + r->tell = &file_reader_default_tell; + r->endian = endian; + return r; +} + +file_reader_file* create_file_reader2(void* f, file_reader_file_read read, file_reader_file_seek seek, file_reader_file_tell tell, unsigned char endian) { + if (!f || !read || !seek | !tell) return NULL; + file_reader_file* r = malloc(sizeof(file_reader_file)); + if (!r) return NULL; r->f = f; + r->read = read; + r->seek = seek; + r->tell = tell; r->endian = endian; return r; } @@ -32,7 +62,7 @@ void set_file_reader_endian(file_reader_file* f, unsigned char endian) { int file_reader_read_int32(file_reader_file* f, int32_t* re) { if (!f) return 1; - int64_t offset = fileop_ftell(f->f); + int64_t offset = f->tell(f->f); int32_t r = 0; int origin = SEEK_SET; if (offset == -1) { @@ -40,9 +70,9 @@ int file_reader_read_int32(file_reader_file* f, int32_t* re) { } size_t c; uint8_t buf[4]; - if ((c = fread(buf, 1, 4, f->f)) < 4) { + if ((c = f->read(f->f, 4, buf)) < 4) { if (origin == SEEK_CUR) offset = -c; - fileop_fseek(f->f, offset, origin); + f->seek(f->f, offset, origin); return 1; } r = cstr_read_int32(buf, f->endian); @@ -56,16 +86,16 @@ int file_reader_read_uint32(file_reader_file* f, uint32_t* re) { int file_reader_read_int64(file_reader_file* f, int64_t* re) { if (!f) return 1; - int64_t offset = fileop_ftell(f->f), r = 0; + int64_t offset = f->tell(f->f), r = 0; int origin = SEEK_SET; if (offset == -1) { origin = SEEK_CUR; } size_t c; uint8_t buf[8]; - if ((c = fread(buf, 1, 8, f->f)) < 8) { + if ((c = f->read(f->f, 8, buf)) < 8) { if (origin == SEEK_CUR) offset = -c; - fileop_fseek(f->f, offset, origin); + f->seek(f->f, offset, origin); return 1; } r = cstr_read_int64(buf, f->endian); @@ -82,19 +112,19 @@ int file_reader_read_str(file_reader_file* f, char** buf) { b = malloc(blen); if (!b) return 1; } - int64_t offset = fileop_ftell(f->f); + int64_t offset = f->tell(f->f); int origin = SEEK_SET; if (offset == -1) { origin = SEEK_CUR; } while (1) { if (n >= c) { - if (!(tc = fread(bu, 1, 128, f->f))) { + if (!(tc = f->read(f->f, 128, bu))) { if (b) free(b); if (origin == SEEK_CUR) { offset = -c; } - fileop_fseek(f->f, offset, origin); + f->seek(f->f, offset, origin); return 1; } c += tc; @@ -107,7 +137,7 @@ int file_reader_read_str(file_reader_file* f, char** buf) { if (origin == SEEK_CUR) { offset = -c; } - fileop_fseek(f->f, offset, origin); + f->seek(f->f, offset, origin); return 1; } b = nb; @@ -131,6 +161,6 @@ int file_reader_read_str(file_reader_file* f, char** buf) { } else { offset = -(c - n - 1); } - fileop_fseek(f->f, offset, origin); + f->seek(f->f, offset, origin); return 0; } diff --git a/file_reader.h b/file_reader.h index 9c06019..6046ad4 100644 --- a/file_reader.h +++ b/file_reader.h @@ -1,11 +1,15 @@ #ifndef _UTILS_FILE_READER_H #define _UTILS_FILE_READER_H +#include #include #include #if __cplusplus extern "C" { #endif typedef struct file_reader_file file_reader_file; +typedef size_t(*file_reader_file_read)(void* f, size_t buf_len, char* buf); +typedef int(*file_reader_file_seek)(void* f, int64_t offset, int origin); +typedef int64_t(*file_reader_file_tell)(void* f); /** * @brief Create a reader from a stream * @param f File stream @@ -13,6 +17,16 @@ typedef struct file_reader_file file_reader_file; * @return the reader, NULL if OOM or stream is NULL. */ file_reader_file* create_file_reader(FILE* f, unsigned char endian); +/** + * @brief Create a reader from a custom IO stream + * @param f The data to pass to function + * @param read The read function. Must not be NULL. + * @param seek The seek function. Must not be NULL. + * @param tell The tell function. Must not be NULL. + * @param endian 0 if little endian otherwise big endian + * @return the reader, NULL if OOM or any parameters is NULL. +*/ +file_reader_file* create_file_reader2(void* f, file_reader_file_read read, file_reader_file_seek seek, file_reader_file_tell tell, unsigned char endian); /** * @brief Free a reader. This will not close stream. * @param f the pointer to reader struct