pbc應用分析

pbc源碼:https://github.com/cloudwu/pbc

https://blog.codingnow.com/2011/12/protocol_buffers_for_c.html

pbc應用例子

安裝protobuf,源碼:https://github.com/google/protobuf

建立protobuf文件address.proto:

syntax = "proto2";
// See README.txt for information and build instructions.

package tutorial;

option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";

message Profile {
  optional string nick_name = 1;
  optional string icon = 2;
}

message Person {
  required string name = 1;
  required int32 id = 2;        // Unique ID number for this person.
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
  repeated int32 test = 5 [packed=true];

  optional Profile profile = 6;

  extensions 10 to max; 
}

message Ext {
  extend Person {
    optional int32 test = 10;
  }
}
// Our address book file is just one of these.
message AddressBook {
  repeated Person person = 1;
}

建立C文件addressbook.c :

#include "pbc.h"

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

#include "readfile.h"

static void
dump(uint8_t *buffer, int sz) {
    int i , j;
    for (i=0;i<sz;i++) {
        printf("%02X ",buffer[i]);
        if (i % 16 == 15) {
            for (j = 0 ;j <16 ;j++) {
                char c = buffer[i/16 * 16+j];
                if (c>=32 && c<127) {
                    printf("%c",c);
                } else {
                    printf(".");
                }
            }
            printf("\n");
        }
    }

    printf("\n");
}

static void
test_rmessage(struct pbc_env *env, struct pbc_slice *slice) {
    struct pbc_rmessage * m = pbc_rmessage_new(env, "tutorial.Person", slice);
    if (m==NULL) {
        printf("Error : %s",pbc_error(env));
        return;
    }
    printf("name = %s\n", pbc_rmessage_string(m , "name" , 0 , NULL));
    printf("id = %d\n", pbc_rmessage_integer(m , "id" , 0 , NULL));
    printf("email = %s\n", pbc_rmessage_string(m , "email" , 0 , NULL));

    int phone_n = pbc_rmessage_size(m, "phone");
    int i;
    const char * field_name;
    pbc_type(env, "tutorial.Person", "phone", &field_name);
    printf("phone type [%s]\n",field_name);

    for (i=0;i<phone_n;i++) {
        struct pbc_rmessage * p = pbc_rmessage_message(m , "phone", i);
        printf("\tnumber[%d] = %s\n",i,pbc_rmessage_string(p , "number", i ,NULL));
        printf("\ttype[%d] = %s\n",i,pbc_rmessage_string(p, "type", i, NULL));
    }

    int n = pbc_rmessage_size(m , "test");

    for (i=0;i<n;i++) {
        printf("test[%d] = %d\n",i, pbc_rmessage_integer(m , "test" , i , NULL));
    }

    printf("tutorial.Ext.test = %d\n", pbc_rmessage_integer(m,"tutorial.Ext.test",0,NULL));
    pbc_rmessage_delete(m);
}

static struct pbc_wmessage *
test_wmessage(struct pbc_env * env)
{
    struct pbc_wmessage * msg = pbc_wmessage_new(env, "tutorial.Person");

    pbc_wmessage_string(msg, "name", "Alice", -1);
    pbc_wmessage_integer(msg, "id" , 12345, 0);
    pbc_wmessage_string(msg, "email", "alice@unkown", -1);

    struct pbc_wmessage * phone = pbc_wmessage_message(msg , "phone");
    pbc_wmessage_string(phone , "number", "87654321" , -1);

    phone = pbc_wmessage_message(msg , "phone");
    pbc_wmessage_string(phone , "number", "13901234567" , -1);
    pbc_wmessage_string(phone , "type" , "MOBILE" , -1);

    pbc_wmessage_integer(msg, "test", -123,0);
    pbc_wmessage_integer(msg, "test", 12345,0);
    pbc_wmessage_integer(msg, "test", 1234567,0);

    pbc_wmessage_integer(msg, "tutorial.Ext.test", 54321 , 0);

    return msg;
}

int
main()
{
    struct pbc_slice slice; //數據存放buffer, len 
    read_file("addressbook.pb", &slice); //讀取protoc生成的pb文件
    if (slice.buffer == NULL)    
        return 1;
    struct pbc_env * env = pbc_new();  //新建pbc的數據環境
    int r = pbc_register(env, &slice); //講slice數據消息regist到pbc的環境
    if (r) {
        printf("Error : %s", pbc_error(env));
        return 1;
    }

    free(slice.buffer);//釋放slice數據空間

    struct pbc_wmessage *msg = test_wmessage(env); //解析protobuf消息數據

    pbc_wmessage_buffer(msg, &slice);//將protobuf數據放入slice

    dump(slice.buffer, slice.len); //打印出protobuf數據

    test_rmessage(env, &slice); //將protobuf數據解析成可讀數據

    pbc_wmessage_delete(msg);  //清除數據
    pbc_delete(env);        //清環境

    return 0;
}

編譯,生成addressbook.pb文件以及可執行文件addressbook

執行命令,結果如下:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章