#ifndef PACKER_HPP #define PACKER_HPP #include "luastack.hpp" #include #include #include #include class Packer { private: std::ostringstream *oss_; // Packer is not copyable. Packer(const Packer &other) { assert(false); } public: using fixhandle = size_t; Packer(std::ostringstream *s) : oss_(s) {} // Get the current file position. size_t tellp() { return oss_->tellp(); } void write_int8(int8_t v); void write_int16(int16_t v); void write_int32(int32_t v); void write_int64(int64_t v); // Sometimes, you want to write a length followed by a block of data. // Sometimes, you don't know the length until after you've written the block // of data. To help with this situation, we provide the overwrite_int // functions. Here's what you do: // // 1. write a dummy length into the stream. // 2. use 'tellp' to fetch the stream position *after* the dummy length. // 3. write the block of data. // 4. use an overwrite function below to overwrite the dummy length. // void overwrite_int8(size_t tell_after, int8_t value); void overwrite_int16(size_t tell_after, int16_t value); void overwrite_int32(size_t tell_after, int32_t value); void overwrite_int64(size_t tell_after, int64_t value); // The packer can be used as a lua_Writer. static int lua_writer(lua_State *L, const void *p, size_t sz, void *ud); void *lua_writer_ud() { return this; } }; class Unpacker { private: const char *data_; size_t size_; public: Unpacker(const char *d, size_t s); const char *data() { return data_; } size_t size() { return size_; } int8_t read_int8(); int16_t read_int16(); int32_t read_int32(); int64_t read_int64(); void skip(size_t n); Unpacker read_section(size_t n); // The unpacker can be used as a lua_Reader static const char *lua_reader(lua_State *L, void *ud, size_t *size); void *lua_reader_ud() { return this; } }; #endif // PACKER_HPP