73 lines
2.0 KiB
C++
73 lines
2.0 KiB
C++
|
|
#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
|