Przeglądaj źródła

refactor & feat: 新增reader模块

SongZihuan 3 lat temu
rodzic
commit
6f35026511

+ 45 - 0
include/core/reader.h

@@ -0,0 +1,45 @@
+#ifndef AFUN_READER_H
+#define AFUN_READER_H
+#include "aFuntool.h"
+#include "aFunCoreExport.h"
+
+namespace aFuncore {
+    class Reader {
+    public:
+        typedef enum ReadMode {
+            read_mode_normal = 0,
+            read_mode_finished = 1,
+            read_mode_error = 2,
+        } ReadMode;
+
+        static const size_t DEFAULT_BUF_SIZE = 1024;
+        static const size_t NEW_BUF_SIZE  = 512;
+
+        explicit inline Reader(aFuntool::FilePath path_, aFuntool::FileLine line_ = 1);
+        Reader(const Reader &) = delete;
+        virtual ~Reader();
+        Reader &operator=(const Reader &) = delete;
+
+        virtual size_t readText(char *dest, size_t len, ReadMode &mode) = 0;
+
+        [[nodiscard]] inline aFuntool::FileLine getFileLine() const;
+        [[nodiscard]] inline const aFuntool::FilePath &getFilePath() const;
+        char *readWord(size_t del_index);
+        void readFirstWord();
+        char getChar();
+
+    private:
+        char *buf;
+        size_t buf_size;  // buf的长度-1
+        char *read;
+        bool read_end;
+        bool read_error;
+
+        aFuntool::FileLine line;
+        aFuntool::FilePath path;
+    };
+}
+
+#include "reader.inline.h"
+
+#endif //AFUN_READER_H

+ 22 - 0
include/core/reader.inline.h

@@ -0,0 +1,22 @@
+#ifndef AFUN_READER_INLINE_H
+#define AFUN_READER_INLINE_H
+#include "reader.h"
+
+namespace aFuncore {
+    inline Reader::Reader(aFuntool::FilePath path_, aFuntool::FileLine line_)
+            : path{std::move(path_)}, line{line_}, read_end{false}, read_error{false} {
+        buf = aFuntool::safeCalloc<char>(DEFAULT_BUF_SIZE + 1);
+        buf_size = DEFAULT_BUF_SIZE;  // buf_size 不包括NUL
+        read = buf;
+    }
+
+    aFuntool::FileLine Reader::getFileLine() const {
+        return line;
+    }
+
+    const aFuntool::FilePath &Reader::getFilePath() const {
+        return path;
+    }
+}
+
+#endif //AFUN_READER_INLINE_H

+ 1 - 0
src/core/lexical.cpp

@@ -0,0 +1 @@
+#include "reader.h"

+ 114 - 0
src/core/reader.cpp

@@ -0,0 +1,114 @@
+#include "init.h"
+#include "reader.h"
+
+namespace aFuncore {
+    Reader::~Reader() {
+        aFuntool::safeFree(buf);
+    }
+
+    char *Reader::readWord(size_t del_index) {
+        char *re;
+        ReadMode mode = read_mode_normal;
+        read = buf;  // 重置指针
+
+        if (del_index == 0)
+            return aFuntool::strCopy("");  // 返回空字符串
+
+        re = aFuntool::safeCalloc<char>(del_index + 1);
+        memcpy(re, buf, del_index);  // 复制旧字符串
+        memmove(buf, buf + del_index, buf_size - del_index + 1);  // +1是为了涵盖NUL
+
+        if (!read_end) { // 没到尾部, 则写入数据
+            char *write = buf + strlen(buf);  // 数据写入的位置
+            size_t len_ = buf_size - strlen(buf);
+            size_t len = readText(write, len_, mode);
+            if (len > len_)
+                len = len_;
+            *(write + len) = aFuntool::NUL;
+        }
+
+        if (mode == read_mode_finished)
+            read_end = true;
+        else if (mode == read_mode_error) {
+            read_end = true;
+            read_error = true;
+        }
+
+        /* 计算行号 */
+        for (char *tmp = re; *tmp != aFuntool::NUL; tmp ++) {
+            if (*tmp == '\n')
+                line++;
+        }
+
+        if (!aFuntool::isCharUTF8(re)) {
+            free(re);
+            errorLog(aFunCoreLogger, "Is not utf-8");
+            return nullptr;
+        }
+
+        return re;
+    }
+
+    void Reader::readFirstWord() {
+        ReadMode mode = read_mode_normal;
+        read = buf;  // 重置指针
+
+        char *write = buf + strlen(buf);  // 数据写入的位置
+        size_t len_ = buf_size - strlen(buf);
+        size_t len = readText(write, len_, mode);
+        if (len > len_)
+            len = len_;
+        *(write + len) = aFuntool::NUL;
+
+        if (mode == read_mode_finished)
+            read_end = true;
+        else if (mode == read_mode_error) {
+            read_end = true;
+            read_error = true;
+        }
+    }
+
+    char Reader::getChar() {
+        char ch = *read;
+        if (ch != aFuntool::NUL) {  // 未读取到末尾
+            read++;
+            return ch;
+        } else if (read_end)  // 读取到末尾, 且无新内容
+            return aFuntool::NUL;
+
+        if (read == buf + buf_size) {
+            char *new_buf = aFuntool::safeCalloc<char>(buf_size + NEW_BUF_SIZE + 1);
+            memcpy(new_buf, buf, buf_size);
+
+            ReadMode mode = read_mode_normal;
+            size_t len = readText(new_buf + buf_size, NEW_BUF_SIZE, mode);
+            if (len > NEW_BUF_SIZE)
+                len = NEW_BUF_SIZE;
+            *(new_buf + buf_size + len) = aFuntool::NUL;
+
+            if (mode == read_mode_finished)
+                read_end = true;
+            else if (mode == read_mode_error) {
+                read_end = true;
+                read_error = true;
+            }
+
+            aFuntool::safeFree(buf);
+            buf = new_buf;
+            buf_size = buf_size + NEW_BUF_SIZE;
+            read = buf + buf_size - NEW_BUF_SIZE;  // 当前读取的位置
+        } else {
+            ReadMode mode = read_mode_normal;
+            size_t len_ = buf_size - (read - buf);  // 总长度  - (已读取长度) = 剩余空白
+            size_t len = readText(read, len_, mode);
+            if (len > len_)
+                len = len_;
+            *(read + len) = aFuntool::NUL;
+        }
+
+        ch = *read;
+        if (ch != aFuntool::NUL)
+            read++;
+        return ch;
+    }
+}

+ 1 - 0
test/src/CMakeLists.txt

@@ -31,5 +31,6 @@ add_new_test(core-code COMMAND "$<TARGET_FILE:core-code>")
 add_new_test(core-env-var COMMAND "$<TARGET_FILE:core-env-var>")
 add_new_test(core-down-msg COMMAND "$<TARGET_FILE:core-down-msg>")
 add_new_test(core-up-msg COMMAND "$<TARGET_FILE:core-up-msg>")
+add_new_test(core-reader COMMAND "$<TARGET_FILE:core-reader>")
 
 add_new_test(run-code COMMAND "$<TARGET_FILE:run-code>")

+ 61 - 0
test/src/core-reader.cpp

@@ -0,0 +1,61 @@
+#include "reader.h"
+
+class ReaderText : public aFuncore::Reader {
+    int count;
+public:
+    ReaderText() : Reader{"Test", 0} {
+        count = 0;
+    }
+
+    size_t readText(char *dest, size_t len, ReadMode &mode) override {
+        count++;
+        if (count == 1) {
+            memset(dest, 's', len);
+            return len;
+        } else if (count == 2) {
+            memset(dest, 'w', len - 5);
+            return len - 5;
+        }
+        return 0;
+    }
+};
+
+int main() {
+    printf("HelloWorld\n");
+
+    {
+        ReaderText test = ReaderText();
+        test.readFirstWord();
+
+        char ch;
+        size_t count = 0;
+        do {
+            ch = test.getChar();
+            printf("%zu\t\tch = %c\n", count, ch);
+            count++;
+        } while (ch != aFuntool::NUL);
+
+    }
+
+    {
+        ReaderText test = ReaderText();
+        test.readFirstWord();
+
+        char ch;
+        for (size_t i = 0; i < 1000; i++) {
+            ch = test.getChar();
+            printf("%zu\t\tch = %c\n", i, ch);
+        }
+        char *new_word = test.readWord(100);  // 提取前面100个值
+        free(new_word);
+
+        size_t count = 0;
+        do {
+            ch = test.getChar();
+            printf("%zu\t\tch = %c\n", count, ch);  // 923-s 1019-w
+            count++;
+        } while (ch != aFuntool::NUL);
+    }
+
+    return 0;
+}