add io_stream:tell & fix io_stream:seek

This commit is contained in:
MihailRis 2026-06-11 00:27:15 +03:00
parent ce0f90d21e
commit 0d2a0b012d
5 changed files with 77 additions and 42 deletions

View file

@ -302,46 +302,26 @@ static int l_has_descriptor(lua::State* L) {
static int l_read_descriptor(lua::State* L) {
int descriptor = lua::tointeger(L, 1);
if (!io_descriptors::has_descriptor(descriptor)) {
throw std::runtime_error("unknown descriptor");
}
if (!io_descriptors::is_readable(descriptor)) {
throw std::runtime_error("descriptor is not readable");
}
int maxlen = lua::tointeger(L, 2);
auto* stream = io_descriptors::get_input(descriptor);
auto& stream = io_descriptors::require_input(descriptor);
if (stream.eof()) {
stream.clear();
}
util::Buffer<char> buffer(maxlen);
stream->read(buffer.data(), maxlen);
std::streamsize read_len = stream->gcount();
stream.read(buffer.data(), maxlen);
std::streamsize read_len = stream.gcount();
return lua::create_bytearray(L, buffer.data(), read_len);
}
static int l_write_descriptor(lua::State* L) {
int descriptor = lua::tointeger(L, 1);
if (!io_descriptors::has_descriptor(descriptor)) {
throw std::runtime_error("unknown descriptor");
}
if (!io_descriptors::is_writeable(descriptor)) {
throw std::runtime_error("descriptor is not writeable");
}
auto data = lua::bytearray_as_string(L, 2);
auto* stream = io_descriptors::get_output(descriptor);
stream->write(data.data(), static_cast<std::streamsize>(data.size()));
if (!stream->good()) {
auto& stream = io_descriptors::require_output(descriptor);
stream.write(data.data(), static_cast<std::streamsize>(data.size()));
if (!stream.good()) {
throw std::runtime_error("failed to write to stream");
}
return 0;
@ -354,8 +334,9 @@ static int l_seek_descriptor(lua::State* L) {
throw std::runtime_error("unknown descriptor");
}
std::string mode = lua::require_string(L, 2);
auto mode = lua::require_string(L, 2);
std::ios_base::seekdir dir;
auto position = lua::tointeger(L, 3);
switch (mode[0]) {
case 'b':
@ -371,15 +352,37 @@ static int l_seek_descriptor(lua::State* L) {
throw std::runtime_error("invalid seek mode");
}
auto* stream = io_descriptors::get_output(descriptor);
if (io_descriptors::is_writeable(descriptor)) {
auto& stream = io_descriptors::require_output(descriptor);
stream.seekp(position, dir);
if (!stream.good()) {
throw std::runtime_error("failed to seek stream");
}
}
if (io_descriptors::is_readable(descriptor)) {
auto& stream = io_descriptors::require_input(descriptor);
stream.seekg(position, dir);
if (!stream.good()) {
throw std::runtime_error("failed to seek stream");
}
}
return 0;
}
stream->seekp(lua::tointeger(L, 3), dir);
static int l_tell_descriptor(lua::State* L) {
int descriptor = lua::tointeger(L, 1);
if (!stream->good()) {
throw std::runtime_error("failed to seek stream");
if (!io_descriptors::has_descriptor(descriptor)) {
throw std::runtime_error("unknown descriptor");
}
return 0;
if (io_descriptors::is_writeable(descriptor)) {
auto& stream = io_descriptors::require_output(descriptor);
return lua::pushinteger(L, stream.tellp());
} else {
auto& stream = io_descriptors::require_input(descriptor);
return lua::pushinteger(L, stream.tellg());
}
}
static int l_flush_descriptor(lua::State* L) {
@ -442,6 +445,7 @@ const luaL_Reg filelib[] = {
{"__read_descriptor", lua::wrap<l_read_descriptor>},
{"__write_descriptor", lua::wrap<l_write_descriptor>},
{"__seek_descriptor", lua::wrap<l_seek_descriptor>},
{"__tell_descriptor", lua::wrap<l_tell_descriptor>},
{"__flush_descriptor", lua::wrap<l_flush_descriptor>},
{"__close_descriptor", lua::wrap<l_close_descriptor>},
{"__close_all_descriptors", lua::wrap<l_close_all_descriptors>},