diff --git a/luprex/cpp/core/luasnap.cpp b/luprex/cpp/core/luasnap.cpp index 1dfc3dd5..6f3f8e4f 100644 --- a/luprex/cpp/core/luasnap.cpp +++ b/luprex/cpp/core/luasnap.cpp @@ -75,7 +75,8 @@ void LuaSnap::serialize(StreamBuffer *sb) { // Write dummy length, use eris to write data, then overwrite length. sb->write_int64(0); int64_t pos1 = sb->total_writes(); - eris_dump(state_, sb->lua_writer, sb->lua_writer_ud()); + + eris_dump(state_, lua_writer_into_streambuffer, sb); int64_t pos2 = sb->total_writes(); sb->overwrite_int64(pos1, pos2 - pos1); lua_settop(state_, 0); @@ -85,14 +86,15 @@ void LuaSnap::deserialize(StreamBuffer *sb) { // Lua stack should be empty. assert(lua_gettop(state_) == 0); - // Get the length of the eris dump. - int64_t len = sb->read_int64(); - void *ud = sb->lua_reader_ud(len); - + // Get the eris data and convert it to a LuaByteReader. + int64_t eris_len = sb->read_int64(); + const char *eris_bytes = sb->read_bytes(eris_len); + LuaByteReader bytereader(eris_bytes, eris_len); + // Call eris with the permanents table and passing the snapshot as a lua_Reader. lua_pushstring(state_, "unpersist"); lua_rawget(state_, LUA_REGISTRYINDEX); - eris_undump(state_, sb->lua_reader, ud); + eris_undump(state_, bytereader.lua_reader, bytereader.lua_reader_userdata()); // Set up a stack frame manually. Eris deserialization // should have left permstable and regcopy on the stack. diff --git a/luprex/cpp/core/luastack.cpp b/luprex/cpp/core/luastack.cpp index 09c81a35..210f7af6 100644 --- a/luprex/cpp/core/luastack.cpp +++ b/luprex/cpp/core/luastack.cpp @@ -559,3 +559,12 @@ void LuaKeywordParser::final_check_throw() { luaL_error(L_, "%s", err.c_str()); } } + +const char *LuaByteReader::lua_reader(lua_State *L, void *ud, size_t *size) { + LuaByteReader *reader = (LuaByteReader*)ud; + *size = reader->size_; + const char *data = reader->data_; + reader->data_ = 0; + reader->size_ = 0; + return data; +} diff --git a/luprex/cpp/core/luastack.hpp b/luprex/cpp/core/luastack.hpp index c64ac676..d2368bfa 100644 --- a/luprex/cpp/core/luastack.hpp +++ b/luprex/cpp/core/luastack.hpp @@ -724,6 +724,24 @@ public: lua_State *state() const { return L_; } }; +//////////////////////////////////////////////////////////////////// +// +// Lua Byte Reader +// +// Converts a block of bytes in RAM into a lua_reader. +// +//////////////////////////////////////////////////////////////////// + +class LuaByteReader { +private: + const char *data_; + int64_t size_; +public: + LuaByteReader(const char *d, int64_t s) : data_(d), size_(s) {} + void *lua_reader_userdata() { return this; } + static const char *lua_reader(lua_State *L, void *ud, size_t *size); +}; + //////////////////////////////////////////////////////////////////// // // The Lua Constant Registry diff --git a/luprex/cpp/core/streambuffer.cpp b/luprex/cpp/core/streambuffer.cpp index 900418a0..decbea93 100644 --- a/luprex/cpp/core/streambuffer.cpp +++ b/luprex/cpp/core/streambuffer.cpp @@ -15,8 +15,6 @@ void StreamBuffer::init(bool fixed, bool owned, char *buf, int64_t size) { pre_read_count_ = 0; owned_ = owned; fixed_size_ = fixed; - lua_reader_data_ = 0; - lua_reader_size_ = 0; } StreamBuffer::StreamBuffer() { @@ -80,8 +78,6 @@ void StreamBuffer::make_space_slow(int64_t bytes) { // Update some simple things. pre_read_count_ += (read_cursor_ - buf_lo_); - lua_reader_data_ = 0; - lua_reader_size_ = 0; // Move the data to the beginning of the buffer, or to // the beginning of a new buffer. @@ -128,8 +124,6 @@ void StreamBuffer::clear() { read_cursor_ = buf_lo_; write_cursor_ = buf_lo_; pre_read_count_ = 0; - lua_reader_data_ = 0; - lua_reader_size_ = 0; } eng::string StreamBuffer::readline() { @@ -341,34 +335,6 @@ util::HashValue StreamBuffer::hash() const { return std::make_pair(hash1, hash2); } -int StreamBuffer::lua_writer(lua_State *L, const void* p, size_t sz, void* ud) { - StreamBuffer *sb = (StreamBuffer *)ud; - memcpy(sb->make_space(sz), p, sz); - sb->write_cursor_ += sz; - return 0; -} - -void *StreamBuffer::lua_writer_ud() { - return this; -} - -const char *StreamBuffer::lua_reader(lua_State *L, void *ud, size_t *size) { - StreamBuffer *sb = (StreamBuffer *)ud; - *size = sb->lua_reader_size_; - const char *data = sb->lua_reader_data_; - // Next time the reader gets called, there's no data left. - sb->lua_reader_data_ = 0; - sb->lua_reader_size_ = 0; - return data; -} - -void *StreamBuffer::lua_reader_ud(int64_t size) { - const char *data = read_bytes(size); - lua_reader_data_ = data; - lua_reader_size_ = size; - return this; -} - class StreamBufferWriter : public std::streambuf, public eng::opnew { private: StreamBuffer *target_; @@ -401,6 +367,13 @@ std::ostream &StreamBuffer::ostream() { return *ostream_; } +int lua_writer_into_streambuffer(lua_State *L, const void* bytes, size_t sz, void* sbv) { + StreamBuffer *sb = (StreamBuffer *)sbv; + memcpy(sb->make_space(sz), bytes, sz); + sb->wrote_space(sz); + return 0; +} + static bool streq(const char *str, const char *data) { int len = strlen(str); return memcmp(str, data, len) == 0; diff --git a/luprex/cpp/core/streambuffer.hpp b/luprex/cpp/core/streambuffer.hpp index a1b42017..124b3958 100644 --- a/luprex/cpp/core/streambuffer.hpp +++ b/luprex/cpp/core/streambuffer.hpp @@ -266,6 +266,17 @@ public: // Get the total number of bytes ever written to this buffer. int64_t total_writes() const; + // Make the specified amount of space in the buffer for writing. + // Return a pointer to the space. + char *make_space(int64_t bytes) { + int64_t available = buf_hi_ - write_cursor_; + if (available < bytes) make_space_slow(bytes); + return write_cursor_; + } + + // Used after calling make_space then filling the space. + void wrote_space(int64_t bytes); + // Amount of data inside the buffer. int64_t fill() const; @@ -374,14 +385,6 @@ public: // Calculate a noncryptographic but good hash of what's in the buffer. util::HashValue hash() const; - // Use the stream buffer as a lua_Writer. - static int lua_writer(lua_State *L, const void* p, size_t sz, void* ud); - void *lua_writer_ud(); - - // Use the stream buffer as a lua_Reader. - static const char *lua_reader(lua_State *L, void *data, size_t *size); - void *lua_reader_ud(int64_t bytes); - // Get an ostream that writes into the StreamBuffer. std::ostream &ostream(); @@ -407,26 +410,13 @@ private: // True if we're not allowed to expand this buffer. bool fixed_size_; - // Lua reader return value. - const char *lua_reader_data_; - int64_t lua_reader_size_; - // The ostream. Only allocated on demand. std::unique_ptr ostream_; // Initialize with a new buffer. void init(bool fixed, bool owned, char *buf, int64_t size); - // Make the specified amount of space in the buffer for writing. - // Return a pointer to the space. - char *make_space(int64_t bytes) { - int64_t available = buf_hi_ - write_cursor_; - if (available < bytes) make_space_slow(bytes); - return write_cursor_; - } void make_space_slow(int64_t bytes); - - void wrote_space(int64_t bytes); // Implementation for the overwrite_int functions. char *get_overwrite(int64_t size, int64_t write_count_after); @@ -437,4 +427,7 @@ private: friend int lfn_unittests_streambuffer(lua_State *L); }; +// Use a streambuffer as a lua_writer. +int lua_writer_into_streambuffer(lua_State *L, const void* bytes, size_t sz, void* sb); + #endif // STREAMBUFFER_HPP