• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 298  文章 - 377  trackbacks - 0
            <2007年7月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(34)

            隨筆分類

            隨筆檔案

            文章檔案

            相冊

            收藏夾

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            讀完protobuf一些文檔,寫點東西,權作記憶。

            https://github.com/google/protobuf/blob/master/CHANGES.txt

            google發布了protobuf v3,為了pb更好用,更跨語言,他對protobuf v2做了以下change:

                  1. Removal of field presence logic for primitive value fields(匪夷所思,留存以待以后翻譯出來), 刪除required(大大地贊同,即保留repeated,required和optional都不要了,默認就是optional),刪除默認值(不明白)。谷歌生成這些改變視為了更好的兼容Android Java、Objective C和Go語言;

                  2. 刪除對unknown field的支持;

                  3. 不再支持繼承,以Any type代之;

                  4 修正了enum中的unknown類型;

                  5 支持map;

                     protobuf v2和v3都支持map了,其聲明形式如下: 

                     message Foo {

                            map<string, string> values = 1;

                     }

                     注意,此處的map是unordered_map。

                  6 添加了一些類型集,以支持表述時間、動態數據等;

                  7 默認以json形式代替二進制進行編碼。

            目前v3 alpha版僅僅實現了1-5這五個feature,6和7還未支持。新添加了syntax關鍵字,以指明proto文件的protobuf協議版本,不指明則是v2。如:

             // foo.proto

                  syntax = "proto3";

                  message Bar {...}

            如果你目前使用了v2,那么暫時不支持你切換到v3,我們還會對v2提供支持。如果你是新手,那就大膽使用v3吧。



            https://github.com/golang/protobuf

            1 go的protobuf實現不支持RPC。

            2 go的protobuf實現了一個go的插件protoc-gen-go,他放置的地方必須在$GOBIN里面,默認放在$GOPATH/bin。它也必須在$PATH里面,以讓protoc編譯器找到。protoc把proto文件編譯成go的源碼文件,其名稱后綴是.pb.go,protoc命令格式如下:

            protoc --go_out=. *.proto

            3 .pb.go源碼的一些事項如下:

              - 變量名稱采用駱駝命名法,如camel_case被編譯為CamelCase.

              - 不會為field生成set方法,直接為成員賦值即可。 

              - 沒有setter,但是有getter方法,如果field被設置了值,則返回設置的值。如果沒有設置,則返回默認值。如果連message都沒有收到,就返回nil。

              - struct的所有成員初始值都是零值,如果要給其成員賦值,就必須在序列化之前。序列化后再修改struct的成員值,沒有任何意義。

              - struc的 Reset()會將struct的所有field的值清零。

              - 非repeated的field成員的類型都是指針類型,當它為空時,意味著其值為空。如"required field int32 f "或者"optional field int32 f "被編譯后的類型都是F *int32。

              - Repeated類型的fields被編譯后則是slices.

              - 與其他語言一樣,go會生成Helper函數,以便于設置field的值。針對獲取值得Helper函數不再建議使用。                        msg.Foo = proto.String("hello") // set field

              - 一個field如果有default值,則這個值會被編譯為一個常量,其名稱的規則為Default_StructName_FieldName,而且相關的Get方法會默認返回這個值。不見直接用這些const值。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            message Test {
                optional int32 type = 2 [default=77];
                extensions 100 to 199;
            }
             
            type Test struct {
                Type             *int32                    `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
            }
             
             
            const Default_Test_Type int32 = 77
                 
            func (m *Test) GetType() int32 {
                if m != nil && m.Type != nil {
                    return *m.Type
                }
                return Default_Test_Type
            }


              -  Enum類型會對類型名稱和其值分別處理,其值的Enum名稱以類型做前綴,每個field的名稱和值會形成map,可以互相查找。

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            enum FOO {
                X = 17; 
                Y = 18; 
            };
            ==>
            type FOO int32
             
            const (
                FOO_X FOO = 17
                FOO_Y FOO = 18
            )
             
            var FOO_name = map[int32]string{
                17: "X",
                18: "Y",
            }
            var FOO_value = map[string]int32{
                "X": 17, 
                "Y": 18, 
            }
             
            func (x FOO) Enum() *FOO {
                p := new(FOO)
                *p = x 
                return p
            }
            func (x FOO) String() string {
                return proto.EnumName(FOO_name, int32(x))
            }
            func (x *FOO) UnmarshalJSON(data []byte) error {
                value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO")
                if err != nil {
                    return err
                }
                *x = FOO(value)
                return nil
            }

              - 如果group和enum是內置在message中的,則其名稱的前綴會有message的名稱。 

              - Extensions會被編譯為一個變量,其名稱開頭為E_。extension相關的方法有 HasExtension, ClearExtension, GetExtension, SetExtension .

              - 序列化方法有Marshal和Unmarshal.





            https://developers.google.com/protocol-buffers/docs/proto:

            1 default value。bool的默認值是false,數值的默認值是0,enum的默認值是其第一個元素,string的默認值是空字符串。

             2 tag id. id 1-15占用1個字節,16到2047占用兩個字節。所以1-15要留個頻繁使用的字段,不要剛開始定義字段的是時候都分配出去。

               tag值最小是1, 最大是(2^29 - 1)即536,870,911,但是要避開19000到19999,這是protobuf內置的類型要用到的tag id。 

             3 enum可以有alias。enum的值不能為負數。

             enum EnumAllowingAlias {

              option allow_alias = true;

              UNKNOWN = 0;

              STARTED = 1;

              RUNNING = 1;

            }

            enum EnumNotAllowingAlias {

              UNKNOWN = 0;

              STARTED = 1;

              // RUNNING = 1;  // Uncommenting this line will cause a compile error inside Google and a warning message outside.

            }

             4 當協議更新的時候,如果某個字段過時了,就可以更改field的name,如"OBSOLETE_xxx",以告訴使用者不要在使用這個field。

               也可以更改field type,前提是tag id不變,這些類型就是兼容的(之所以能兼容,按照我的理解,一個field就是一個kay-value對,tag id為key,value即為值,而type只是在序列化和反序列化的時候起到解釋值的作用,并無其他作用;key = (tag << 3) | wire_type,即類型占用最多3個字節,所以有上面的tag范圍是2^29 - 1)。如下幾個類型是兼容的:

               A int32 uint32 int64 uint64 bool    

               B sint32 siint64

               C string bytes (字符類型是UTF8)

               D fixed32 sfixed32 fixed64 sfixed64

               E optional repeated

               F default([default = value])value也可以被修改

             5 protoc --proto-path= --cpp_out= --java_out= file.proto

               --proto-path可以被-I代替。

             6 protobuf對repeated壓縮不夠好,所以盡量在后面加上[packed = true]。

             7 序列化的時候不能把多個message序列化后的內容放在一起發出去,盡量以len1 + msg1 + len2 + msg2這種形式發送。

             8 不要讓protobuf對象成為全局變量或者類成員,因為其clear方法只會把占用的內存空間清零,而不會釋放,使得進程空間越來越大,可參考《Protobuf使用不當導致的程序內存上漲問題》。 



            https://developers.google.com/protocol-buffers/docs/encoding:

            1 正常field的kv對的編碼順序是:1 小端序;2 varints,即每7個bit為一個byte,在byte的第一個bit賦值1,最后一個byte的第一個bit賦值0;3 對field的tag加type構成key,值為value,即((tag_id << 3) | wire_type) + value。但是針對repeated這種,其結果為((tag_id << 3) | wire_type) + len + value,長度len為array size,prootbuf解析度時候,會根據wire_type為2知道這是個array。


            2 如果序列化的時候,多個kv對用了一個tag id,則這個kv對應的field的值為最后一次出現的kv對的值。

            3 repeated的[packed = true]只有type為數值的時候才能用。


            https://github.com/google/protobuf/tree/v3.0.0-alpha-1

            1 安裝步驟:

              

            $ ./configure --prefix=/home/user/bin/ $ make $ make check $ make install


            2 如果不想生成動態protobuf庫,則用命令./configure --disable-shared。

            posted on 2018-01-06 18:09 聶文龍 閱讀(9219) 評論(0)  編輯 收藏 引用
            久久国产热精品波多野结衣AV| 99久久精品国内| 久久精品中文字幕一区| 久久亚洲精品国产精品| 欧美激情精品久久久久| 午夜精品久久影院蜜桃| 日韩精品久久久肉伦网站| 99久久精品国产一区二区蜜芽| 伊人久久五月天| 久久婷婷午色综合夜啪| 久久久免费精品re6| 久久青青草原精品国产软件| 97久久婷婷五月综合色d啪蜜芽 | 精品国产福利久久久| 一极黄色视频久久网站| 91久久精品电影| 影音先锋女人AV鲁色资源网久久| 精品国产91久久久久久久a| 亚洲va久久久噜噜噜久久天堂| 国内精品久久久久久久久| 久久久久亚洲av无码专区| 伊人久久无码精品中文字幕| 久久精品国产亚洲欧美| 久久亚洲中文字幕精品有坂深雪 | 国产亚洲色婷婷久久99精品91 | 国产精久久一区二区三区| 久久国产精品99精品国产| 欧美亚洲国产精品久久| 久久艹国产| 久久噜噜电影你懂的| 国产精品久久久久AV福利动漫| 一本久久a久久精品vr综合| 亚洲精品无码久久毛片| 久久精品国产福利国产琪琪| 久久国产精品99精品国产987| 久久精品国产亚洲AV无码娇色 | av无码久久久久久不卡网站| 无码人妻久久一区二区三区免费 | 久久精品一区二区| 99国产精品久久久久久久成人热| 亚洲国产精品无码久久一线 |