簡體   English   中英

Protobuf如何編碼消息構造之一

[英]How Protobuf encodes oneof message construct

對於此python程序,在編碼時運行protobuf編碼可得到以下輸出:

0a 10 08 7f 8a 01 04 08 02 10 03 92 01 04 08 02 10 03 18 01

我不明白的是,為什么在8a之后有一個01,又為什么在92之后有01。對於oneof類型的信息元素來說,似乎增加了額外的01,但是為什么呢? 如果有人了解protobuf編碼,請幫助我

import sys
import test2_pb2

def write_to_file(file,value):
    with open(file, "wb") as f:
        f.write(value)

def cell_test_dct():

  msg=test2_pb2.TestPrimM();
  msg.textx=1
  msg.testmsg.testint=127
  msg.testmsg.prbbundlingtype.x =2
  msg.testmsg.prbbundlingtype.static=
   test2_pb2.BUNDLE_SIZE_N_4_WIDEBAND
  msg.testmsg.bundlingtype.x =2
  msg.testmsg.bundlingtype.static=
  test2_pb2.BUNDLE_SIZE_N_4_WIDEBAND
  print (msg)
  str = msg.SerializeToString()
  #write_to_file("/tmp/protobuf_test_file.bin",str)

def main_test():
    cell_test_dct()

main_test()

對於以下protobuf文件:

package NR_TEST;

enum BundleSizeE {
    BUNDLE_SIZE_N_4 = 0;
    BUNDLE_SIZE_WIDEBAND = 1;
    BUNDLE_SIZE_N_2_WIDEBAND = 2;
    BUNDLE_SIZE_N_4_WIDEBAND = 3;
}

message DynamicBundleSizesM {
    // bundleSizeSet1
    optional BundleSizeE bundleSizeSet1 = 1;
    // bundleSizeSet2
    optional BundleSizeE bundleSizeSet2 = 2;
}

message PrbBundlingTypeM {
    optional uint32 x=1;
    oneof BundlingTypeC {
    BundleSizeE static = 2;
    DynamicBundleSizesM dynamic = 3;
    }
}

message Test {
    required int32 testint   =1;
    required PrbBundlingTypeM prbbundlingtype = 17;
    required PrbBundlingTypeM bundlingtype = 18;
}
message TestPrimM
{
  oneof TestMsgC {
    Test testmsg=1;
    int32  nomsg=2;
    }
    required  int32 textx=3;
}

給定protobuf編碼,您的消息如下:

0a .. varint key '1|010' -> field 1, type LENGTH_DELIMITED
    10 .. varint length -> 16
    Contents:
        08 .. varint key '1|000' -> field 1, type VARINT
            7f .. varint value -> 127
        8a 01 .. varint key '00000010001|010' -> field 17, type LENGTH_DELIMITED
            04 .. varint length -> 4
            Contents:
                08 .. varint key '1|000' -> field 1, type VARINT
                    02 .. varint value -> 2
                10 .. varint key '10|000' -> field 2, type VARINT
                    03 .. varint value -> 3
        92 01 .. varint key '00000010010|010' -> field 18, type LENGTH_DELIMITED
            04 .. varint length -> 4
            Contents:
                08 .. varint key '1|000' -> field 1, type VARINT
                    02 .. varint value -> 2
                10 .. varint key '10|000' -> field 2, type VARINT
                    03 .. varint value -> 3
18 .. varint key '11|000' field 3, type VARINT
    01 .. varint value -> 1

長度定界字段17的標簽的整數值是二進制的: 10001|01010001是17且010是長度定界的線型 )->給出10001010 (二進制)。

要將這個數字編碼為varint,您需要將總位長調整為7的倍數(用零填充):

-> 000000 10001010

然后將其分成7位組:

-> 0000001 0001010

然后顛倒這些組的順序:

-> 0001010 0000001

並為每個組( MSB )添加一個額外的位-最后一個組為零,所有其他組為一個(MSB等於1告訴解析器后面還有另一個組):

-> 1 0001010 0 0000001

以十六進制(您的值)給出0x8A 0x01

這里描述了 Varint編碼。


據我所知,oneof構造不會更改線路格式(它僅擴展了解析器邏輯,它忽略所有內容,但忽略單個oneof組中的最后一個字段)。

祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM