Add Packer/Unpacker, add serialization to LuaSnap

This commit is contained in:
2021-03-02 18:58:50 -05:00
parent 49df7b4895
commit 9d86347d54
5 changed files with 254 additions and 44 deletions

View File

@@ -0,0 +1,72 @@
#ifndef PACKER_HPP
#define PACKER_HPP
#include "luastack.hpp"
#include <cstdint>
#include <string>
#include <sstream>
#include <cassert>
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