diff --git a/CMakeLists.txt b/CMakeLists.txt index fe3a06a..dbc977d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ set(SOURCE_FILE_HEADERS cfileop.h cpp2c.h cstr_util.h + dict.h err.h fileop.h list_pointer.h diff --git a/cstr_util.c b/cstr_util.c index e64cd2b..0c2d424 100644 --- a/cstr_util.c +++ b/cstr_util.c @@ -117,7 +117,7 @@ int cstr_read_str(char* buf, char** dest, size_t* pos, size_t buf_len) { tmp[n] = 0; } *pos = p >= buf_len ? p : p + 1; - char* ntmp = realloc(tmp, n); + char* ntmp = realloc(tmp, n + 1); *dest = ntmp ? ntmp : tmp; return 0; } diff --git a/dict.h b/dict.h new file mode 100644 index 0000000..3fd156a --- /dev/null +++ b/dict.h @@ -0,0 +1,74 @@ +#ifndef _UTIL_DICT_H +#define _UTIL_DICT_H +#include "linked_list.h" +template +struct dict_entry { + T key; + V value; +}; +template +struct Dict { + struct dict_entry d; + struct Dict* prev; + struct Dict* next; +}; +template +size_t dict_count(struct Dict* d) { + return linked_list_count((struct LinkedList>*)d); +} +template +void dict_free(struct Dict*& d, void(*free_func)(struct dict_entry) = nullptr) { + return linked_list_clear((struct LinkedList>*&)d, free_func); +} +template +bool dict_set(struct Dict*& d, K key, V value, void(*free_func)(V) = nullptr) { + if (!d) { + struct dict_entry v = { key, value }; + return linked_list_append((struct LinkedList>*&)d, &v); + } + struct Dict* t = d; + if (t->d.key == key) { + if (free_func) free_func(t->d.value); + t->d.value = value; + return true; + } + while (t->next) { + t = t->next; + if (t->d.key == key) { + if (free_func) free_func(t->d.value); + t->d.value = value; + return true; + } + } + struct dict_entry v = { key, value }; + return linked_list_append((struct LinkedList>*&)d, &v); +} +template +bool dict_set(struct Dict*& d, K key, V value, void(*value_copy_func)(V, V), void(*free_func)(V) = nullptr) { + if (!value_copy_func) return false; + if (!d) { + struct dict_entry v; + v.key = key; + value_copy_func(v.value, value); + return linked_list_append((struct LinkedList>*&)d, &v); + } + struct Dict* t = d; + if (t->d.key == key) { + if (free_func) free_func(t->d.value); + value_copy_func(t->d.value, value); + return true; + } + while (t->next) { + t = t->next; + if (t->d.key == key) { + if (free_func) free_func(t->d.value); + value_copy_func(t->d.value, value); + return true; + } + } + struct dict_entry v; + v.key = key; + value_copy_func(v.value, value); + return linked_list_append((struct LinkedList>*&)d, &v); +} +#endif diff --git a/file_reader.c b/file_reader.c index 8580ef6..a6e856b 100644 --- a/file_reader.c +++ b/file_reader.c @@ -60,6 +60,40 @@ void set_file_reader_endian(file_reader_file* f, unsigned char endian) { f->endian = endian; } +int file_reader_read_char(file_reader_file* f, char* re) { + if (!f) return 1; + char buf[1]; + if (!f->read(f->f, 1, buf)) { + return 1; + } + if (re) *re = buf[0]; + return 0; +} + +int file_reader_read_uint8(file_reader_file* f, uint8_t* re) { + return file_reader_read_char(f, (char*)re); +} + +int file_reader_read_int16(file_reader_file* f, int16_t* re) { + if (!f) return 1; + int64_t offset = f->tell(f->f); + int16_t r = 0; + int origin = SEEK_SET; + if (offset == -1) { + origin = SEEK_CUR; + } + size_t c; + uint8_t buf[2]; + if ((c = f->read(f->f, 2, buf)) < 2) { + if (origin == SEEK_CUR) offset = -c; + f->seek(f->f, offset, origin); + return 1; + } + r = cstr_read_int16(buf, f->endian); + if (re) *re = r; + return 0; +} + int file_reader_read_int32(file_reader_file* f, int32_t* re) { if (!f) return 1; int64_t offset = f->tell(f->f); diff --git a/file_reader.h b/file_reader.h index 6046ad4..9c032f3 100644 --- a/file_reader.h +++ b/file_reader.h @@ -38,6 +38,27 @@ 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 Read char from reader + * @param f reader + * @param re result + * @return 0 if successed otherwise 1 +*/ +int file_reader_read_char(file_reader_file* f, char* re); +/** + * @brief Read uint8 from reader + * @param f reader + * @param re result + * @return 0 if successed otherwise 1 +*/ +int file_reader_read_uint8(file_reader_file* f, uint8_t* re); +/** + * @brief Read int16 from reader + * @param f reader + * @param re result + * @return 0 if successed otherwise 1 +*/ +int file_reader_read_int16(file_reader_file* f, int16_t* re); /** * @brief Read int32 from reader * @param f reader diff --git a/linked_list.h b/linked_list.h index d9fd35e..04dd1f5 100644 --- a/linked_list.h +++ b/linked_list.h @@ -17,7 +17,7 @@ bool linked_list_append(struct LinkedList*& list, T* data = nullptr, struct L struct LinkedList* tmp = (struct LinkedList*)malloc(sizeof(LinkedList)); if (!tmp) return false; memset(tmp, 0, sizeof(LinkedList)); - if (data) tmp->d = T(*data); else tmp->d = T(); + if (data) tmp->d = *data; else tmp->d = T(); if (!have_list) { list = tmp; } else { @@ -41,7 +41,7 @@ bool linked_list_append_head(struct LinkedList*& list, T* data = nullptr) { struct LinkedList* tmp = (struct LinkedList*)malloc(sizeof(LinkedList)); if (!tmp) return false; memset(tmp, 0, sizeof(LinkedList)); - if (data) tmp->d = T(*data); else tmp->d = T(); + if (data) tmp->d = *data; else tmp->d = T(); if (have_list) { tmp->next = list; list->prev = tmp;