Protobuf3 序列化

在message_lite.h中定义了SerializeToString ,SerializeToArray ,SerializeToCodedStream ,SerializeToZeroCopyStream 其它序列化到IO流、序列化到文件等接口在它的子类message.h文件中提供。

另外,在util/json_util.h文件中定义了protobuf与json相互转换的接口(需要注意的是:当json字符串字段的值等于protobuf中字段的默认值,message->json则此字段不会出现在json中)。

#include <iostream>
#include <fstream>
#include <istream>
#include <string>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/util/json_util.h>

#include <fcntl.h>
#include <unistd.h>

#include "game.pb.h"

void serializeToString(pt::rsp_login& rsp)
{
    //序列化到字符串和从字符串解析数据
    std::string str{};
    rsp.SerializeToString(&str);
    std::cout << "serialize to string:" << str << std::endl;

    pt::rsp_login rsp2{};
    rsp2.ParseFromString(str);
    std::cout << "parse from string size:" << rsp2.ByteSize() << std::endl;

    auto temp_str = rsp.SerializeAsString();
    std::cout << "serialize as string:" << temp_str << std::endl;
}

void serializeToArray(pt::rsp_login& rsp)
{
    //序列化到数组和从数组解析数据
    std::vector<uint8_t> buff;
    buff.resize(rsp.ByteSize());
    rsp.SerializeToArray(buff.data(), buff.size());

    pt::rsp_login rsp2{};
    if (!rsp2.ParseFromArray(buff.data(), (int)buff.size())) {
        std::cout << "parse error\n";
    }
    std::cout << "parse from array size:" << rsp2.ByteSize() << std::endl;
}

void serializeToCodeStream(pt::rsp_login& rsp)
{
    using namespace google::protobuf::io;
    int fd1 = open("myfile", O_CREAT | O_RDWR);
    if (fd1 == -1) {
        return;
    }
    ZeroCopyOutputStream *raw_output = new FileOutputStream(fd1);
    google::protobuf::io::CodedOutputStream coded_output(raw_output);
    rsp.SerializeToCodedStream(&coded_output);
    delete raw_output;
    close(fd1);

    pt::rsp_login rsp2{};
    int fd2 = open("myfile", O_RDONLY);
    if (fd2 == -1) {
        return;
    }
    ZeroCopyInputStream *raw_input = new FileInputStream(fd2);
    google::protobuf::io::CodedInputStream coded_input(raw_input);
    rsp2.ParseFromCodedStream(&coded_input);
    delete raw_input;
    close(fd2);
}

void serializeToStream(pt::rsp_login& rsp)
{
    std::fstream fs1("stream.info", std::ios::out | std::ios::binary);
    rsp.SerializeToOstream(&fs1);
    fs1.close();

    pt::rsp_login rsp2{};
    std::fstream fs2("stream.info", std::ios::in | std::ios::binary);
    rsp2.ParseFromIstream(&fs2);
    fs2.close();

    std::cout << "parse in stream:" << rsp2.ByteSize() << std::endl;
}

void serializeToFile(pt::rsp_login& rsp)
{
    //序列化到文件
    std::ofstream ofile;
    auto fd = open("game.info", O_CREAT | O_TRUNC | O_RDWR, 0644);
    if (fd <= 0) {
        std::cout << "open file error" << std::endl;
        return;
    }
    rsp.SerializeToFileDescriptor(fd);
    close(fd);

    pt::rsp_login rsp2{};
    fd = open("game.info", O_RDONLY);
    if (fd <= 0) {
        std::cout << "serialize to file error" << std::endl;
        return;
    }
    rsp2.ParseFromFileDescriptor(fd);
    close(fd);

    std::cout << "parse from file rsp2.size:" << rsp2.ByteSize() << std::endl;
}

void jsonMessageConvent(pt::rsp_login& rsp)
{
    //如果字段值=protobuf中的类型默认值,则此字段不会转换到Json字符串中
    std::string json{};
    google::protobuf::util::MessageToJsonString(rsp, &json);
    std::cout << "message to json:" << json << std::endl;

    //json字符串中字段的值=protobuf中字段类型默认值,则此json字段不会转换到protobuf消息中
    pt::rsp_login rsp2{};
    google::protobuf::util::JsonStringToMessage(json, &rsp2);
    std::cout << "json to message size:" << rsp2.ByteSize() << std::endl;
}

int main()
{
    pt::rsp_login rsp{};
    rsp.set_ret(pt::rsp_login_RET_SUCCESS);
    auto user_info = rsp.mutable_user_info();
    user_info->set_nickname("dsw");
    user_info->set_icon("345DS55GF34D774S");
    user_info->set_coin(2000);
    user_info->set_location("zh");

    for (int i = 0; i < 5; i++) {
        auto record = rsp.add_record();
        record->set_time("2017/4/13 12:22:11");
        record->set_kill(i * 4);
        record->set_dead(i * 2);
        record->set_assist(i * 5);
    }
    
    serializeToString(rsp);
    serializeToArray(rsp);
    serializeToCodeStream(rsp);

    serializeToStream(rsp);
    serializeToFile(rsp);

    jsonMessageConvent(rsp);
        
    return 0;
}

 

posted @ 2017-04-13 14:06  滴水瓦  阅读(7620)  评论(0编辑  收藏  举报