pb 数据解析

1. pb文件 

syntax = "proto3";  // syntax 版本2/3是不一样,默认是proto2
package IM.Login;	//  package 生成对应的C++命名空间 IM::Login::
import "IM.BaseDefine.proto";	// import 引用其他proto文件
option optimize_for = LITE_RUNTIME;

// message关键字 代表一个对象
message Phone{
    string number = 1;	// = 1是什么?默认值
    IM.BaseDefine.PhoneType phone_type = 2;
}

message Book{
    string name = 1;
    float price = 2;
}

message Person{
    string  name    = 1;
    int32   age     = 2;
    repeated string languages = 3;
    Phone   phone   = 4;
    repeated Book   books   = 5;	// repeated 重复, 可以嵌套对象
    bool            vip     = 6;
    string          address = 7;
}

//使用T开头测试
message TInt32{
    int32   int1     = 1;
}

message TString{
    string   str1     = 1;
}

2.对数据进行解析

​

/*
如果proto结构体的变量是基础变量,比如int、string等等,那么set的时候直接调用set_xxx即可。

如果变量是自定义类型(也就是message嵌套),那么C++的生成代码中,就没有set_xxx函数名,取而代之的是三个函数名:
set_allocated_xxx()
release_xxx()
mutable_xxx()

使用set_allocated_xxx()来设置变量的时候,变量不能是普通栈内存数据,
必须是手动new出来的指针,至于何时delete,就不需要调用者关心了,
protobuf内部会自动delete掉通过set_allocated_设置的内存;

release_xxx()是用来取消之前由set_allocated_xxx设置的数据,
调用release_xxx以后,protobuf内部就不会自动去delete这个数据;

mutable_xxx()返回分配内存后的对象,如果已经分配过则直接返回,如果没有分配则在内部分配,建议使用mutable_xxx
*/
#if 1
message Person{
    string  name    = 1;
    int32   age     = 2;
    repeated string languages = 3;
    Phone   phone   = 4;
    repeated Book   books   = 5;	// repeated 重复, 可以嵌套对象
    bool            vip     = 6;
    string          address = 7;
}

#endif
bool ProtobufEncode(std::string &strPb)
{
    IM::Login::Person person;
    person.set_name("darren");      // 设置以set_为前缀
    person.set_age(80);
    person.add_languages("C++");    // 数组add
    person.add_languages("Java");
    // 电话号码
    // mutable_ 嵌套对象时使用,并且是单个对象时使用,比如对应的Person里面的Phone  phone = 4;
    // 比如mutable_phone如果phone已经存在则直接返回,如果不存在则new 一个返回
    IM::Login::Phone *phone = person.mutable_phone();
    if(!phone)
    {
        std::cout << "mutable_phone failed." << std::endl;
        return false;
    }
    phone->set_number("18570368134");
    phone->set_phone_type(IM::BaseDefine::PHONE_HOME);
    // 书籍
    // add_则是针对repeated的嵌套对象,每次调用都返回一个新的对象,注意和mutable_的区别。
    // 比如Person里面的repeated Book   books   = 5;
    IM::Login::Book *book = person.add_books();
    book->set_name("Linux kernel development");
    book->set_price(7.7);
    book = person.add_books();
    book->set_name("Linux server development");
    book->set_price(8.0);
    // vip
    person.set_vip(true);
    // 地址
    person.set_address("yageguoji");
    uint32_t pbSize = person.ByteSize();        // 序列化后的大小  
    strPb.clear();
    strPb.resize(pbSize);
    uint8_t *szData = (uint8_t *)strPb.c_str();
    if (!person.SerializeToArray(szData, pbSize))   // 拷贝序列化后的数据
    {
        std::cout << "person pb msg SerializeToArray failed." << std::endl;
        return false;
    }
    return true;
}

​

3.解析数据


static void printPerson(IM::Login::Person &person)
{
    std::cout << "name:\t" << person.name() << std::endl;
    std::cout << "age:\t" << person.age() << std::endl;
    std::string languages;
    for (int i = 0; i < person.languages_size(); i++)
    {
        if (i != 0)
        {
            languages += ", ";
        }
        languages += person.languages(i);
    }
    std::cout << "languages:\t" << languages << std::endl;

    if (person.has_phone()) // 自定义message的嵌套并且不是设置为repeated则有has_
    {
        // 注意引用
        const IM::Login::Phone &phone = person.phone();
        std::cout << "phone number:\t" << phone.number() << ", type:\t" << phone.phone_type() << std::endl;
    }
    else
    {
        std::cout << "no phone" << std::endl;
    }
    

    for (int i = 0; i < person.books_size(); i++)
    {
        const IM::Login::Book &book = person.books(i);
        std::cout << "book name:\t" << book.name() << ", price:\t" << book.price() << std::endl;
    }

    std::cout << "vip:\t" << person.vip() << std::endl;
    std::cout << "address:\t" << person.address() << std::endl;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值