diff options
| author | ruki <[email protected]> | 2026-01-28 22:56:40 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-01-28 22:56:40 +0800 |
| commit | 190df86ff49ed5cf80069ad8ccd34be11d2d948c (patch) | |
| tree | f9141ae8146eec12f4ecd1d0ed798bb55906c35a /core/src | |
| parent | 58be018b11ea325940c8e63aa130d04bd972ef45 (diff) | |
optimize to read all
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/io/file_read.c | 146 |
1 files changed, 124 insertions, 22 deletions
diff --git a/core/src/xmake/io/file_read.c b/core/src/xmake/io/file_read.c index b9be64e10..e38f7bd0d 100644 --- a/core/src/xmake/io/file_read.c +++ b/core/src/xmake/io/file_read.c @@ -229,6 +229,57 @@ static tb_int_t xm_io_file_read_all_directly(lua_State *lua, xm_io_file_t *file) tb_buffer_exit(&buf); return 1; } + +static tb_bool_t xm_io_file_read_all_to_buffer(xm_io_file_t *file, tb_buffer_ref_t buf) { + tb_assert(file && xm_io_file_is_file(file) && file->u.file_ref && buf); + + tb_byte_t *data = tb_buffer_resize(&file->rcache, XM_IO_BLOCK_MAXN); + tb_assert_and_check_return_val(data, tb_false); + + tb_stream_ref_t stream = file->u.file_ref; + tb_hize_t offset = 0; + tb_hong_t size = tb_stream_size(stream); + tb_bool_t sequential_consume = (size == 0); + while (sequential_consume || (offset = tb_stream_offset(stream)) < size) { + tb_long_t real = tb_stream_read(stream, data, XM_IO_BLOCK_MAXN); + if (real > 0) { + tb_buffer_memncat(buf, data, real); + } else if (!real) { + real = tb_stream_wait(stream, TB_STREAM_WAIT_READ, -1); + tb_check_break(real > 0); + } else { + break; + } + } + return tb_true; +} + +static tb_int_t xm_io_file_read_all_with_continuation(lua_State *lua, xm_io_file_t *file, tb_char_t const *continuation) { + tb_assert(lua && file && continuation && xm_io_file_is_file(file) && file->u.file_ref); + + tb_buffer_t buf; + if (!tb_buffer_init(&buf)) { + xm_io_return_error(lua, "init buffer failed!"); + } + while (1) { + tb_int_t state = xm_io_file_buffer_pushline(&buf, file, continuation, tb_true); + if (state == PL_EOF) { + break; + } + if (state == PL_FAIL) { + tb_buffer_exit(&buf); + xm_io_return_error(lua, "failed to readall"); + } + } + if (tb_buffer_size(&buf)) { + lua_pushlstring(lua, (tb_char_t const *)tb_buffer_data(&buf), tb_buffer_size(&buf)); + } else { + lua_pushliteral(lua, ""); + } + tb_buffer_exit(&buf); + return 1; +} + static tb_int_t xm_io_file_read_all(lua_State *lua, xm_io_file_t *file, tb_char_t const *continuation) { tb_assert(lua && file && continuation && xm_io_file_is_file(file) && file->u.file_ref); @@ -238,35 +289,86 @@ static tb_int_t xm_io_file_read_all(lua_State *lua, xm_io_file_t *file, tb_char_ return xm_io_file_read_all_directly(lua, file); } - // init buffer - tb_buffer_t buf; - if (!tb_buffer_init(&buf)) { - xm_io_return_error(lua, "init buffer failed!"); + if (*continuation != '\0') { + return xm_io_file_read_all_with_continuation(lua, file, continuation); } - // read all - tb_bool_t has_content = tb_false; - while (1) { - switch (xm_io_file_buffer_pushline(&buf, file, continuation, tb_true)) { - case PL_EOF: - if (!has_content) { - lua_pushliteral(lua, ""); + tb_buffer_t raw; + tb_buffer_t out; + tb_bool_t raw_ok = tb_false; + tb_bool_t out_ok = tb_false; + tb_int_t result = 0; + tb_char_t const *errors = tb_null; + do { + if (!tb_buffer_init(&raw)) { + errors = "init buffer failed!"; + result = 2; + break; + } + raw_ok = tb_true; + + if (!xm_io_file_read_all_to_buffer(file, &raw)) { + errors = "failed to read all"; + result = 2; + break; + } + + tb_size_t rawsize = tb_buffer_size(&raw); + + if (!tb_buffer_init(&out)) { + errors = "init buffer failed!"; + result = 2; + break; + } + out_ok = tb_true; + + if (!rawsize) { + lua_pushliteral(lua, ""); + result = 1; + break; + } + + tb_byte_t const *rawdata = (tb_byte_t const *)tb_buffer_data(&raw); + tb_byte_t const *p = rawdata; + tb_byte_t const *b = rawdata; + tb_byte_t const *e = rawdata + rawsize; + while (p < e) { + if (*p == '\r' && p + 1 < e && p[1] == '\n') { + if (p > b) { + tb_buffer_memncat(&out, b, p - b); + } + tb_buffer_memncat(&out, (tb_byte_t const *)"\n", 1); + p += 2; + b = p; } else { - lua_pushlstring(lua, (tb_char_t const *)tb_buffer_data(&buf), tb_buffer_size(&buf)); + p++; } - tb_buffer_exit(&buf); - return 1; - case PL_FIN: - case PL_CONL: - has_content = tb_true; - continue; - case PL_FAIL: - default: - tb_buffer_exit(&buf); - xm_io_return_error(lua, "failed to read all"); + } + if (tb_buffer_size(&out)) { + if (e > b) { + tb_buffer_memncat(&out, b, e - b); + } + lua_pushlstring(lua, (tb_char_t const *)tb_buffer_data(&out), tb_buffer_size(&out)); + result = 1; break; } + + lua_pushlstring(lua, (tb_char_t const *)rawdata, rawsize); + result = 1; + + } while (0); + + if (out_ok) { + tb_buffer_exit(&out); + } + if (raw_ok) { + tb_buffer_exit(&raw); } + if (result == 2) { + lua_pushnil(lua); + lua_pushstring(lua, errors); + } + return result; } static tb_int_t xm_io_file_read_line(lua_State *lua, |
