Bladeren bron

feat: 调整reader机制

reader函数不再自行判断是否读取结束
SongZihuan 3 jaren geleden
bovenliggende
commit
52518b78b8
6 gewijzigde bestanden met toevoegingen van 48 en 32 verwijderingen
  1. 1 1
      include/core/reader.h
  2. 2 1
      include/tool/mem.h
  3. 1 1
      src/core/__reader.h
  4. 41 22
      src/core/parser.c
  5. 2 6
      src/core/reader.c
  6. 1 1
      test/src/reader.c

+ 1 - 1
include/core/reader.h

@@ -2,7 +2,7 @@
 #define AFUN_READER_H
 #include "tool.h"
 
-typedef size_t readerFunc(void *data, char *dest, size_t len);
+typedef size_t readerFunc(void *data, char *dest, size_t len, bool *is_end);
 DEFINE_DLC_SYMBOL(readerFunc);
 
 typedef void destructReaderFunc(void *data);

+ 2 - 1
include/tool/mem.h

@@ -22,7 +22,8 @@ static void *safeCalloc(size_t n, size_t size) {
     return re;
 }
 
-#define calloc(n, size) (safeCalloc(n, size))
+#define calloc_bak(n, size) (safeCalloc(n, size))  /* 备份 */
+#define calloc calloc_bak
 
 #endif
 #endif  // AFUN_MEM_H

+ 1 - 1
src/core/__reader.h

@@ -10,7 +10,7 @@
 
 typedef struct af_Reader af_Reader;
 
-typedef size_t readerFunc(void *data, char *dest, size_t len);
+typedef size_t readerFunc(void *data, char *dest, size_t len, bool *is_end);
 NEW_DLC_SYMBOL(readerFunc, readerFunc);
 
 typedef void destructReaderFunc(void *data);

+ 41 - 22
src/core/parser.c

@@ -59,12 +59,14 @@ struct readerDataString {
     size_t len;
 };
 
-static size_t readFuncString(struct readerDataString *data, char *dest, size_t len) {
+static size_t readFuncString(struct readerDataString *data, char *dest, size_t len, bool *read_end) {
     if (data->index == data->len)  // 读取到末尾
         return 0;
 
-    if (data->index + len > data->len)  // 超出长度范围
+    if (data->index + len > data->len) {  // 超出长度范围
         len = data->len - data->index;
+        *read_end = true;
+    }
     memcpy(dest, data->str + data->index, len);
     data->index += len;
     return len;
@@ -92,8 +94,11 @@ struct readerDataFile {
     FILE *file;
 };
 
-static size_t readFuncFile(struct readerDataFile *data, char *dest, size_t len) {
-    return fread(dest, sizeof(char), len, data->file);
+static size_t readFuncFile(struct readerDataFile *data, char *dest, size_t len, bool *read_end) {
+    size_t len_r =  fread(dest, sizeof(char), len, data->file);
+    if (feof(data->file))
+        *read_end = true;
+    return len_r;
 }
 
 static void destructFile(struct readerDataFile *data) {
@@ -118,29 +123,43 @@ af_Parser *makeParserByFile(FilePath path){
     return parser;
 }
 
-static size_t readFuncStdin(struct readerDataFile *data, char *dest, size_t len) {
-    size_t read_size = 0;
-    printf(">>> ");
-    while (1) {
-        /* 检查是否只输入了回车符 */
-        /* 若是则结束循环 */
+struct readerDataStdin {
+    bool no_first;
+    bool read_continue;  /* 上一次的内容没有读取完毕 */
+};
+
+static size_t readFuncStdin(struct readerDataStdin *data, char *dest, size_t len, bool *read_end) {
+    if (!data->read_continue) {
+        if (data->no_first)
+            printf("... ");
+        else
+            printf(">>> ");
+
         int ch = getc(stdin);
-        if (ch == '\n' || ch == EOF)
-            break;
+        if (ch == '\n' || ch == EOF) {
+            /* 读取结束 */
+            *read_end = true;
+            return false;
+        }
+
         ungetc(ch, stdin);
+    }
 
-        if (fgets(dest, (int)((len - read_size) + 1), stdin) == NULL)  // + 1 是因为len不包含NUL的位置
-            break;
-        read_size += strlen(dest);
-        if (read_size == len)
-            break;
-        dest += strlen(dest);  // 移动的NUL的位置
-        printf("... ");
+    data->no_first = false;
+    data->read_continue = false;
+
+    if (fgets(dest, (int)(len + 1), stdin) == NULL) {  // + 1 是因为len不包含NUL的位置
+        *read_end = true;
+        return 0;
     }
-    return read_size;
+
+    if (strchr(dest, '\n') == NULL)  // 未找到 \n 代表还没读取完
+        data->read_continue = true;
+
+    return strlen(dest);
 }
 
-static void destructStdin(struct readerDataFile *data) {
+static void destructStdin(struct readerDataStdin *data) {
     // 什么都不用做
 }
 
@@ -150,7 +169,7 @@ af_Parser *makeParserByStdin(){
 
     DLC_SYMBOL(readerFunc) read_func = MAKE_SYMBOL(readFuncStdin, readerFunc);
     DLC_SYMBOL(destructReaderFunc) destruct = MAKE_SYMBOL(destructStdin, destructReaderFunc);
-    af_Parser *parser = makeParser(read_func, destruct, sizeof(struct readerDataString));
+    af_Parser *parser = makeParser(read_func, destruct, sizeof(struct readerDataStdin));
     initParser(parser);
     FREE_SYMBOL(read_func);
     FREE_SYMBOL(destruct);

+ 2 - 6
src/core/reader.c

@@ -51,11 +51,9 @@ char *readWord(size_t del_index, af_Reader *reader) {
     memcpy(re, reader->buf, del_index);  // 复制旧字符串
     memmove(reader->buf, reader->buf + del_index, reader->buf_size - del_index + 1);  // +1是为了涵盖NUL
     if (!reader->read_end) { // 没到尾部, 则写入数据
-        size_t len = GET_SYMBOL(reader->read_func)(reader->data, write, del_index);
+        size_t len = GET_SYMBOL(reader->read_func)(reader->data, write, del_index, &reader->read_end);
         if (len > del_index)
             len = del_index;
-        else if (len < del_index)
-            reader->read_end = true;
         *(write + len) = NUL;
     }
 
@@ -79,11 +77,9 @@ char getChar(af_Reader *reader) {
     char *new_buf = NEW_STR(reader->buf_size + NEW_BUF_SIZE);
     memcpy(new_buf, reader->buf, reader->buf_size);
 
-    size_t len = GET_SYMBOL(reader->read_func)(reader->data, new_buf + reader->buf_size, NEW_BUF_SIZE);
+    size_t len = GET_SYMBOL(reader->read_func)(reader->data, new_buf + reader->buf_size, NEW_BUF_SIZE, &reader->read_end);
     if (len > NEW_BUF_SIZE)
         len = NEW_BUF_SIZE;
-    else if (len < NEW_BUF_SIZE)
-        reader->read_end = true;
     *(new_buf + reader->buf_size + len + 1) = NUL;
 
     free(reader->buf);

+ 1 - 1
test/src/reader.c

@@ -4,7 +4,7 @@
 /* 测试程序, 直接调用内部函数 */
 typedef struct af_Reader af_Reader;
 
-typedef size_t readerFunc(void *data, char *dest, size_t len);
+typedef size_t readerFunc(void *data, char *dest, size_t len, bool *is_end);
 DEFINE_DLC_SYMBOL(readerFunc);
 
 typedef void destructReaderFunc(void *data);