[英]How do I assign a oneof field on a protobuf message if the child message has no fields?
[英]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|010
( 10001
是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.