我如何知道谷歌二进制输出的大小?

时间:2017-01-03 16:50:27

标签: c++ serialization cereal

我试图通过TCP链接传输Cereal的序列化结果(二进制存档)。对于接收方,首先要确定恢复消息对象需要多少字节(至少),但似乎无法获取此信息。

具有基本类型的所有成员的结构的序列化结果似乎与结构的size的结果一样大。这有什么保证吗?我很担心,因为如果通过便携式二进制存档序列化,结果会大1个字节。我知道这是为了记录字节序,但接收方怎么知道呢?我想出的唯一安全方法是序列化消息并从输出流中获取大小。对于接收方而言,这看起来并不那么优雅。

1 个答案:

答案 0 :(得分:1)

我自己找到了解决方案。在这里分享,以防其他人也有用。

获得大小的最可靠方法是实际序列化数据,因此我所做的是避免在序列化期间(使用std :: stringstream时)通常的内存分配/访问开销。 / p>

解决方案始于从std :: basic_streambuf<>派生而来。 (对于谷歌,它必须是std :: streambuf)

class COUNTER_BUFFER : public std::streambuf
{
    private :
        size_t mSize = 0;

    private :
        int_type overflow(int_type C)
        {
            return mSize++;
        }

    public :
        size_t Size(void) const
        {
            return mSize;
        }
};

通常,从std :: basic_streambuf派生的类应该将字符写入某个缓冲区(文件,字符串等),但是这里它会计算写入多少个字符(字节)。

下一步为std :: basic_ostream分配一个实例,该实例从Cereal传递给一个存档:

COUNTER_BUFFER Buffer;
std::basic_ostream<char> Stream(&Buffer);
cereal::BinaryOutputArchive Archive(Stream);

正常序列化任何数据结构,完成后,调用Buffer.Size()来获取大小。

对于只包含基本类型的数据结构,应该有一种方法可以在编译时获取序列化大小,但是使用这种非最佳方法我只能在运行时获取它。

这对我来说已经足够好了。