How It Works
Toggle navigation
How It Works
Home
About Me
Archives
Tags
protobuf源码-编码的过程
2017-03-23 11:40:38
668
0
0
ochapman
结构化非常清晰 创建一个generator,然后对里面的数据进行操作 proto包对generator的Request进行操作 ``` func Marshal(pb Message) ([]byte, error) { ``` 注意pb是一个Message,一个接口 ``` // Message is implemented by generated protocol buffer messages. type Message interface { Reset() String() string ProtoMessage() } ``` 对于每个message,用protoc-gen-go将生成Message接口的三个方法,例如 ``` package lm; message helloworld { required int32 id = 1; // ID required string str = 2; // str optional int32 opt = 3; //optional field } ``` 将生成 ``` func (m *Helloworld) Reset() { *m = Helloworld{} } func (m *Helloworld) String() string { return proto.CompactTextString(m) } func (*Helloworld) ProtoMessage() {} ``` #如何定义和使用Buffer来管理系列化过程的数据 ``` // A Buffer is a buffer manager for marshaling and unmarshaling // protocol buffers. It may be reused between invocations to // reduce memory usage. It is not necessary to use a Buffer; // the global functions Marshal and Unmarshal create a // temporary Buffer and are fine for most applications. type Buffer struct { buf []byte // encode/decode byte stream index int // read point // pools of basic types to amortize allocation. bools []bool uint32s []uint32 uint64s []uint64 // extra pools, only used with pointer_reflect.go int32s []int32 int64s []int64 float32s []float32 float64s []float64 } ``` 对于Marshal方法 ``` // Marshal takes the protocol buffer // and encodes it into the wire format, returning the data. func Marshal(pb Message) ([]byte, error) { // Can the object marshal itself? if m, ok := pb.(Marshaler); ok { return m.Marshal() } p := NewBuffer(nil) err := p.Marshal(pb) var state errorState if err != nil && !state.shouldContinue(err, nil) { return nil, err } if p.buf == nil && err == nil { // Return a non-nil slice on success. return []byte{}, nil } return p.buf, err } ``` p.Marshal是Buffer的方法 ``` func (p *Buffer) Marshal(pb Message) error { // Can the object marshal itself? if m, ok := pb.(Marshaler); ok { data, err := m.Marshal() if err != nil { return err } p.buf = append(p.buf, data...) return nil } t, base, err := getbase(pb) if structPointer_IsNil(base) { return ErrNil } if err == nil { err = p.enc_struct(GetProperties(t.Elem()), base) } if collectStats { stats.Encode++ } if len(p.buf) > maxMarshalSize { return ErrTooLarge } return err } ``` 重点是 ``` err = p.enc_struct(GetProperties(t.Elem()), base) ``` 在enc_struct里面 ``` err := p.enc(o, p, base) ``` enc是在properties.go中 ``` case reflect.Bool: p.enc = (*Buffer).enc_proto3_bool p.dec = (*Buffer).dec_proto3_bool ``` enc_proto3_bool的定义 ``` func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error { v := *structPointer_BoolVal(base, p.field) if !v { return ErrNil } o.buf = append(o.buf, p.tagcode...) p.valEnc(o, 1) return nil } ``` 可以看到编码的结果放在Buffer里面的buf上
Pre:
janus是怎么做频率限制
Next:
一种梳理二进制局部变量的方法
0
likes
668
Weibo
Wechat
Tencent Weibo
QQ Zone
RenRen
Table of content