From 78a3e890d2ad85c609c39650ad151740dd47d885 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sun, 9 Jan 2022 18:03:02 +0800 Subject: [PATCH] Update --- dict.h | 18 ++++++++++ file_reader.c | 24 +++++++++++++ file_reader.h | 9 +++++ linked_list.h | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ memfile.c | 59 ++++++++++++++++++++++++++++++ memfile.h | 19 ++++++++++ 6 files changed, 228 insertions(+) diff --git a/dict.h b/dict.h index 3fd156a..caece24 100644 --- a/dict.h +++ b/dict.h @@ -21,6 +21,24 @@ void dict_free(struct Dict*& d, void(*free_func)(struct dict_entry) return linked_list_clear((struct LinkedList>*&)d, free_func); } template +bool dict_get_internal(struct dict_entry o, K key) { + return o.key == key; +} +template +struct dict_entry* dict_get(struct Dict* d, K key) { + struct Dict* re = (struct Dict*)linked_list_get((struct LinkedList>*)d, key, &dict_get_internal); + if (!re) return nullptr; + return &re->d; +} +template +bool dict_heve_key_internal(struct dict_entry origin, K key) { + return key == origin.key; +} +template +bool dict_have_key(struct Dict* d, K key) { + return linked_list_have((struct LinkedList>*)d, key, &dict_heve_key_internal); +} +template bool dict_set(struct Dict*& d, K key, V value, void(*free_func)(V) = nullptr) { if (!d) { struct dict_entry v = { key, value }; diff --git a/file_reader.c b/file_reader.c index a6e856b..95f1bbc 100644 --- a/file_reader.c +++ b/file_reader.c @@ -60,6 +60,30 @@ void set_file_reader_endian(file_reader_file* f, unsigned char endian) { f->endian = endian; } +int file_reader_align(file_reader_file* f) { + if (!f) return 1; + int64_t ofs = f->tell(f->f); + if (ofs == -1) return 1; + int64_t nofs = (ofs + 3) & -4; + if (f->seek(f->f, nofs - ofs, SEEK_CUR)) return 1; + return 0; +} + +size_t file_reader_read(file_reader_file* f, size_t buf_len, char* buf) { + if (!f || !buf) return 0; + return f->read(f->f, buf_len, buf); +} + +int file_reader_seek(file_reader_file* f, int64_t offset, int origin) { + if (!f) return 1; + return f->seek(f->f, offset, origin); +} + +int64_t file_reader_tell(file_reader_file* f) { + if (!f) return -1; + return f->tell(f->f); +} + int file_reader_read_char(file_reader_file* f, char* re) { if (!f) return 1; char buf[1]; diff --git a/file_reader.h b/file_reader.h index 9c032f3..f28dddb 100644 --- a/file_reader.h +++ b/file_reader.h @@ -38,6 +38,15 @@ void free_file_reader(file_reader_file* f); * @param endian 0 if little endian otherwise big endian */ void set_file_reader_endian(file_reader_file* f, unsigned char endian); +/** + * @brief Aligin the current position + * @param f reader + * @return 0 if successed otherwise 1 +*/ +int file_reader_align(file_reader_file* f); +size_t file_reader_read(file_reader_file* f, size_t buf_len, char* buf); +int file_reader_seek(file_reader_file* f, int64_t offset, int origin); +int64_t file_reader_tell(file_reader_file* f); /** * @brief Read char from reader * @param f reader diff --git a/linked_list.h b/linked_list.h index 04dd1f5..1dd3596 100644 --- a/linked_list.h +++ b/linked_list.h @@ -110,6 +110,49 @@ size_t linked_list_count(struct LinkedList* list) { return c; } +template +bool linked_list_delete(struct LinkedList*& list, T data) { + if (!list) return false; + struct LinkedList* t = list; + while (t->prev) { + t = t->prev; + } + if (t->d == data) { + if (t->prev) t->prev->next = t->next; + if (t->next) t->next->prev = t->prev; + if (t == list) { + if (t->prev) { + list = t->prev; + } else if (t->next) { + list = t->next; + } else { + list = nullptr; + } + } + free(t); + return true; + } + while (t->next) { + t = t->next; + if (t->d == data) { + if (t->prev) t->prev->next = t->next; + if (t->next) t->next->prev = t->prev; + if (t == list) { + if (t->prev) { + list = t->prev; + } else if (t->next) { + list = t->next; + } else { + list = nullptr; + } + } + free(t); + return true; + } + } + return false; +} + template void linked_list_free_tail(struct LinkedList*& list, void(*free_func)(T) = nullptr) { if (!list) return; @@ -125,6 +168,50 @@ void linked_list_free_tail(struct LinkedList*& list, void(*free_func)(T) = nu } } +template +struct LinkedList* linked_list_get(struct LinkedList* list, D data, bool(*compare_func)(T, D)) { + if (!list || !compare_func) return nullptr; + struct LinkedList* t = list; + while (t->prev) { + t = t->prev; + } + if (compare_func(t->d, data)) return t; + while (t->next) { + t = t->next; + if (compare_func(t->d, data)) return t; + } + return nullptr; +} + +template +struct LinkedList* linked_list_get(struct LinkedList* list, size_t index) { + if (!list) return nullptr; + struct LinkedList* t = list; + while (t->prev) { + t = t->prev; + } + size_t n = 0; + if (index == n) return t; + while (t->next) { + t = t->next; + n++; + if (index == n) return t; + } + return nullptr; +} + +template +bool linked_list_have(struct LinkedList* list, T data) { + if (!list) return false; + struct LinkedList* t = list; + if (t->d == data) return true; + while (t->next) { + t = t->next; + if (t->d == data) return true; + } + return false; +} + template bool linked_list_have(struct LinkedList* list, T data, bool(*compare_func)(T, T, Args...), Args... args) { if (!list || !compare_func) return false; @@ -137,6 +224,18 @@ bool linked_list_have(struct LinkedList* list, T data, bool(*compare_func)(T, return false; } +template +bool linked_list_have(struct LinkedList* list, D data, bool(*compare_func)(T, D, Args...), Args... args) { + if (!list || !compare_func) return false; + struct LinkedList* t = list; + if (compare_func(t->d, data, args...)) return true; + while (t->next) { + t = t->next; + if (compare_func(t->d, data, args...)) return true; + } + return false; +} + template void linked_list_remove(struct LinkedList*& node, void(*free_func)(T) = nullptr) { if (!node) return; diff --git a/memfile.c b/memfile.c index bd2a336..a8feea2 100644 --- a/memfile.c +++ b/memfile.c @@ -1,5 +1,6 @@ #include "memfile.h" #include +#include #include #include @@ -23,6 +24,16 @@ MemFile* new_memfile(const char* data, size_t len) { return f; } +CMemFile* new_cmemfile(const char* data, size_t len) { + if (!data || !len) return NULL; + CMemFile* f = malloc(sizeof(CMemFile)); + if (!f) return NULL; + f->data = data; + f->len = len; + f->loc = 0; + return f; +} + void free_memfile(MemFile* f) { if (!f) return; if (f->data) { @@ -31,6 +42,11 @@ void free_memfile(MemFile* f) { free(f); } +void free_cmemfile(CMemFile* f) { + if (!f) return; + free(f); +} + size_t memfile_read(MemFile* f, char* buf, size_t buf_len) { if (!f || !buf) return (size_t)-1; if (!buf_len || f->loc >= f->len) return 0; @@ -40,6 +56,37 @@ size_t memfile_read(MemFile* f, char* buf, size_t buf_len) { return le; } +size_t cmemfile_read(CMemFile* f, size_t buf_len, char* buf) { + if (!f || !buf) return 0; + if (!buf_len || f->loc >= f->len) return 0; + size_t le = min(buf_len, f->len - f->loc); + memcpy(buf, f->data + f->loc, le); + f->loc += le; + return le; +} + +int cmemfile_seek(CMemFile* f, int64_t offset, int origin) { + if (!f) return 1; + int64_t npos = 0; + if (origin == SEEK_SET) { + npos = offset; + } else if (origin == SEEK_CUR) { + npos = f->loc + offset; + } else if (origin == SEEK_END) { + npos = f->len + offset; + } else { + return 1; + } + if (npos < 0 || npos > f->len) return 1; + f->loc = npos; + return 0; +} + +int64_t cmemfile_tell(CMemFile* f) { + if (!f) return -1; + return f->loc; +} + #define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) #define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) #define AVERROR_EOF FFERRTAG( 'E','O','F',' ') @@ -51,3 +98,15 @@ int memfile_readpacket(void* f, uint8_t* buf, int buf_size) { else if (ret == (size_t)-1) return -1; else return ret; } + +size_t cmemfile_read2(void* f, size_t buf_len, char* buf) { + return cmemfile_read((CMemFile*)f, buf_len, buf); +} + +int cmemfile_seek2(void* f, int64_t offset, int origin) { + return cmemfile_seek((CMemFile*)f, offset, origin); +} + +int64_t cmemfile_tell2(void* f) { + return cmemfile_tell((CMemFile*)f); +} diff --git a/memfile.h b/memfile.h index 88ccd18..3676998 100644 --- a/memfile.h +++ b/memfile.h @@ -10,6 +10,11 @@ typedef struct MemFile { size_t len; size_t loc; } MemFile; +typedef struct CMemFile { + const char* data; + size_t len; + size_t loc; +} CMemFile; /** * @brief Create a new memory file @@ -18,9 +23,23 @@ typedef struct MemFile { * @return MemFile struct if succeessed otherwise NULL. */ MemFile* new_memfile(const char* data, size_t len); +/** + * @brief Create a new memory file + * @param data Data. Will not allocate new memory for data. Make sure it can be used. + * @param len The size of data. + * @return CMemFile struct if succeessed otherwise NULL. +*/ +CMemFile* new_cmemfile(const char* data, size_t len); void free_memfile(MemFile* f); +void free_cmemfile(CMemFile* f); size_t memfile_read(MemFile* f, char* buf, size_t buf_len); +size_t cmemfile_read(CMemFile* f, size_t buf_len, char* buf); +int cmemfile_seek(CMemFile* f, int64_t offset, int origin); +int64_t cmemfile_tell(CMemFile* f); int memfile_readpacket(void* f, uint8_t* buf, int buf_size); +size_t cmemfile_read2(void* f, size_t buf_len, char* buf); +int cmemfile_seek2(void* f, int64_t offset, int origin); +int64_t cmemfile_tell2(void* f); #ifdef __cplusplus } #endif