From 966aeb8d647779b5961389332c0e92345ca63709 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 7 May 2022 16:25:39 +0800 Subject: [PATCH] Update --- file_reader.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ file_reader.h | 8 +++++ fileop.cpp | 8 +++++ fileop.h | 5 ++++ 4 files changed, 104 insertions(+) diff --git a/file_reader.c b/file_reader.c index ed39d63..99bb00b 100644 --- a/file_reader.c +++ b/file_reader.c @@ -266,3 +266,86 @@ int file_reader_read_str(file_reader_file* f, char** buf) { f->seek(f->f, offset, origin); return 0; } + +int file_reader_read_line(file_reader_file* f, char** buf, size_t* buf_size) { + if (!f) return 1; + char* b = NULL; + char bu[128]; + size_t blen = 128, n = 0, c = 0, tc = 0, pos = 0; + if (buf) { + b = malloc(blen); + if (!b) return 1; + } + int64_t offset = f->tell(f->f); + int origin = SEEK_SET; + if (offset == -1) { + origin = SEEK_CUR; + } + while (1) { + if (n >= c) { + if (!(tc = f->read(f->f, 128, bu))) { + if (c > 0) { + n--; + break; + } + if (b) free(b); + if (origin == SEEK_CUR) { + offset = -c; + } + f->seek(f->f, offset, origin); + return 1; + } + c += tc; + } + if (buf && n >= blen) { + size_t nlen = blen + 128; + char* nb = realloc(b, nlen); + if (!nb) { + if (b) free(b); + if (origin == SEEK_CUR) { + offset = -c; + } + f->seek(f->f, offset, origin); + return 1; + } + b = nb; + blen = nlen; + } + pos = n - (c - tc); + if (buf && b) { + b[n] = bu[pos]; + } + if (bu[pos] == '\n') { + break; + } + n++; + } + if (origin == SEEK_SET) { + offset += n + 1; + } else { + offset = -(c - n - 1); + } + f->seek(f->f, offset, origin); + if (n >= 1 && b && b[n - 1] == '\r' && b[n] == '\n') { + n -= 2; + } else if (b && b[n] == '\n') { + n -= 1; + } + if (buf) { + char* nb = realloc(b, n + 2); + if (!nb) { + free(b); + if (origin == SEEK_CUR) { + offset = -c; + } + f->seek(f->f, offset, origin); + return 1; + } + nb[n + 1] = 0; + *buf = nb; + } + if (buf_size) { + *buf_size = n + 1; + } + return 0; +} diff --git a/file_reader.h b/file_reader.h index 895471f..1daa7e1 100644 --- a/file_reader.h +++ b/file_reader.h @@ -117,6 +117,14 @@ int file_reader_read_int64(file_reader_file* f, int64_t* re); * @return 0 if successed otherwise 1 */ int file_reader_read_str(file_reader_file* f, char** buf); +/** + * @brief Read a line (ends with \\r\\n or \\n) from reader + * @param f reader + * @param buf Result. (\\r\\n or \\n is removed) Need free memory by using free. + * @param buf_size The size of the result. + * @return 0 if successed otherwise 1 +*/ +int file_reader_read_line(file_reader_file* f, char** buf, size_t* buf_size); #if __cplusplus } #endif diff --git a/fileop.cpp b/fileop.cpp index d23c509..6e228d7 100644 --- a/fileop.cpp +++ b/fileop.cpp @@ -535,3 +535,11 @@ std::string fileop::filename(std::string path) { auto loc = path.find_last_of('.'); return loc == -1 ? path : path.substr(0, loc); } + +int fileop::fcloseall() { +#if _WIN32 + return ::_fcloseall(); +#else + return ::closeall(); +#endif +} diff --git a/fileop.h b/fileop.h index 17c41b9..5f4f9a1 100644 --- a/fileop.h +++ b/fileop.h @@ -169,5 +169,10 @@ namespace fileop { * @return Result */ std::string filename(std::string path); + /** + * @brief Close all open streams + * @return 0(>=0) succeed. EOF error happened. + */ + int fcloseall(); } #endif