zoukankan      html  css  js  c++  java
  • Flatbuffers学习

    flatbuffers简介

    FlatBuffers 是一个(二进制 buffer)序列化开源库,由 Google 开源现在它支持C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift等。
     

    特点

    1. 无需解析/解包即可访问序列化数据;
    2. 强类型;
    3. 使用方便;
    4. 无依赖的跨平台代码;

    与Protocol Buffers的比较(优点):

      使用过程中,我觉得flat对比proto最大的优点就是“零拷贝”反序列化,如果你需要大量的反序列化,flat要比proto更合适一些。
     
     

    FlatBuffers schema

     
     1 #include "FbBasicType.fbs";       // 消息头的类型,时间戳等等
     2 
     3 namespace Jflat;
     4 
     5 table FbFunction{
     6     func_id         : uint32;
     7     param_list      : [string];   // vector类型
     8     return_value    : string;
     9 }
    10 
    11 root_type FbFunction;            // root_type声明序列化数据的object

    FlatBuffers schema compilation

      使用“flatc”编译.fbs文件,它将为对应编程语言创建生成代码。

    1 flatc --gen-mutable --gen-object-api --reflect-names --cpp-ptr-type flatbuffers::unique_ptr --gen-compare  --json --cpp --java --js --python *.fbs #--gen-all
    2 
    3       --gen-mutable          Generate accessors that can mutate buffers in-place.
    4       --gen-object-api       Generate an additional object-based API.
    5       --reflect-names        Add minimal type/name reflection.
    6       --gen-compare          Generate operator== for object-based API types.

    FlatBuffers serialization methods

    .h文件

     1 #ifndef JFUNCTION_H
     2 #define JFUNCTION_H
     3 
     4 #include "JflatHeader.h"
     5 
     6 class JFunction : public JflatHeader
     7 {
     8 public:
     9 
    10     uint32_t                    func_id;
    11     std::vector<std::string>    param_list;
    12     std::string                 return_value;
    13 
    14 public:
    15     JFunction();
    16 
    17     explicit JFunction(const uint8_t *tmp_data);
    18 
    19     explicit JFunction(uint32_t tmp_func_id, std::vector<std::string> &tmp_param_list, const std::string &tmp_return_value);
    20 
    21     JFunction(const JFunction &tmp);
    22 
    23     JFunction &operator=(const JFunction &tmp);
    24 
    25     ~JFunction() = default;
    26 
    27     std::string str();
    28             
    29     const Jflat::FbMessage *getFbMessage(const uint8_t *data);
    30 
    31     flatbuffers::Offset<Jflat::FbFunction> createFbFunction(flatbuffers::FlatBufferBuilder &builder) const;
    32 
    33     flatbuffers::Offset<Jflat::FbMessage> createFbMessage(flatbuffers::FlatBufferBuilder &builder) const override;
    34 
    35     std::shared_ptr<flatbuffers::DetachedBuffer> serializeAsFlat() const;
    36 
    37     bool deserialize(const uint8_t *data) override;
    38 
    39     bool getFbFunction(const Jflat::FbFunction *flat_function);
    40     
    41     std::string serializeAsString() const;
    42 
    43 private:
    44     void assignmentVariable(const JFunction &tmp);
    45 };
    46 
    47 #endif //JFUNCTION_H

     .cpp文件

      1 #include "JFunction.h"
      2 
      3 JFunction::JFunction() : func_id(0),
      4                          param_list(std::vector<std::string>()),
      5                          return_value("")
      6 {
      7     mObjType = Jflat::FbDataHeadType_FBT_RFC;
      8 }
      9 
     10 JFunction::JFunction(uint32_t tmp_func_id, std::vector<std::string> &tmp_param_list, const std::string &tmp_return_value)
     11         : func_id(tmp_func_id),
     12           param_list(tmp_param_list),
     13           return_value(tmp_return_value)
     14 {
     15     mObjType = Jflat::FbDataHeadType_FBT_RFC;
     16 }
     17 
     18 JFunction::JFunction(const uint8_t *tmp_data)
     19 {
     20     mObjType = Jflat::FbDataHeadType_FBT_RFC;
     21     deserialize(tmp_data);
     22 }
     23 
     24 JFunction::JFunction(const JFunction &tmp)
     25 {
     26     mObjType = Jflat::FbDataHeadType_FBT_RFC;
     27     assignmentVariable(tmp);
     28 }
     29 
     30 JFunction &JFunction::operator=(const JFunction &tmp)
     31 {
     32     if (this != &tmp) assignmentVariable(tmp);
     33     return *this;
     34 }
     35 
     36 void JFunction::assignmentVariable(const JFunction &tmp)
     37 {
     38     QObject::assignmentVariable(tmp.mStamp, tmp.mId, tmp.mObjType);
     39 
     40     param_list.assign(tmp.param_list.begin(), tmp.param_list.end());
     41     func_id          = tmp.func_id;
     42     return_value     = tmp.return_value;
     43 }
     44 
     45 std::string JFunction::str()
     46 {
     47     return flatbuffers::FlatBufferToString(serializeAsFlat()->data(), Qflat::FbMessageTypeTable(), true);
     48 }
     49 
     50 std::string JFunction::serializeAsString() const
     51 {
     52     auto detached_buffer = serializeAsFlat();
     53     if (detached_buffer)
     54         return std::string((char *) detached_buffer->data(), detached_buffer->size());
     55     else
     56         return "";
     57 }
     58 
     59 std::shared_ptr<flatbuffers::DetachedBuffer> JFunction::serializeAsFlat() const
     60 {
     61     flatbuffers::FlatBufferBuilder builder;
     62     auto flat = createFbMessage(builder);
     63     builder.Finish(flat);
     64   
     65     return std::make_shared<flatbuffers::DetachedBuffer>(builder.Release());
     66 }
     67 
     68 const Jflat::FbMessage *JFunction::getFbMessage(const uint8_t *data)
     69 {
     70     auto data_flat  = Jflat::GetFbMessage(data);
     71     obj_type        = data_flat->header()->type();
     72     stamp           = data_flat->header()->stamp();
     73     id              = data_flat->header()->id();
     74 
     75     return data_flat;
     76 }
     77 
     78 flatbuffers::Offset<Jflat::FbFunction> JFunction::createFbFunction(flatbuffers::FlatBufferBuilder &builder) const
     79 {
     80     auto flat_param_list     = builder.CreateVectorOfStrings(param_list);
     81     auto flat_return_value   = builder.CreateString(return_value);
     82     auto flat_function       = Jflat::CreateFbFunction(builder, func_id, flat_param_list, flat_return_value);
     83 
     84     return flat_function;
     85 }
     86 
     87 flatbuffers::Offset<Jflat::FbMessage> JFunction::createFbMessage(flatbuffers::FlatBufferBuilder &builder) const
     88 {
     89     auto header_function     = Jflat::CreateFbMsgHeader(builder, Jflat::FbDataHeadType_FBT_RFC, mStamp, mId);
     90     auto flat_function       = createFbFunction(builder);
     91     auto flat                = Jflat::CreateFbMessage(builder, header_function, Jflat::FbMsgBody_FbFunction, flat_function.Union());
     92 
     93     return flat;
     94 }
     95 
     96 bool JFunction::deserialize(const uint8_t *data)
     97 {
     98     auto data_flat       = getFbMessage(data);
     99     auto flat_function   = data_flat->data_as_FbFunction();
    100     getFbFunction(flat_function);
    101 
    102     return true;
    103 }
    104 
    105 bool JFunction::getFbFunction(const Jflat::FbFunction *flat_function)
    106 {
    107     func_id = flat_function->func_id();
    108 
    109     param_list.clear();
    110     for (const auto &flat_data : *flat_function->param_list())
    111         param_list.emplace_back(std::string(flat_data->data(), flat_data->size()));
    112 
    113     return_value = std::string(flat_function->return_value()->data(), flat_function->return_value()->size());
    114 
    115     return true;
    116

    FlatBuffers example

     1 #include "JFunction.h"
     2 
     3 #include <iostream>
     4 
     5 #define FLAT_DATA_DIFF(before_data, after_data) 
     6 {   
     7     if(!(before_data == after_data))   
     8     {   
     9         std::cout << #before_data << " : line" << __LINE__ << "========================== before =================================" << std::endl;    
    10         std::cout << before_data << std::endl;    
    11         std::cout << #after_data << " : line" << __LINE__ << "========================== after =================================" << std::endl;  
    12         std::cout << after_data << std::endl; 
    13     }   
    14 }
    15 
    16 void assignment_JFunction_instance(JFunction &jFunction_1)
    17 {
    18     jFunction_1.func_id = 222;
    19 
    20     for (uint16_t i = 0; i < GENERIC_16_ARRAY_SIZE; ++i)
    21         jFunction_1.param_list.push_back(std::to_string(i));
    22 
    23     jFunction_1.return_value = "return_value pi pi sha";   /// 嘿嘿嘿,我女朋友
    24 }
    25 
    26 int main(void)
    27 {
    28     JFunction jFunction_1;
    29     assignment_JFunction_instance(jFunction_1);
    30     auto buf = jFunction_1.serializeAsFlat();
    31     
    32     JFunction jFunction_2(buf->data());
    33     
    34     FLAT_DATA_DIFF(jFunction_1.str(), jFunction_2.str());
    35     
    36     return 0;
    37 }

    所有代码仅供参考,记录我当时的应用方法。

  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/jiangyibo/p/14286248.html
Copyright © 2011-2022 走看看