6
golang protobuf序列化分析
source link: https://studygolang.com/articles/32403
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
golang protobuf序列化分析
Lynn_Yuan · 大约5小时之前 · 23 次点击 · 预计阅读时间 4 分钟 · 不到1分钟之前 开始浏览- data.proto
message ColumnarValue { uint32 id= 1; int32 typ = 2; repeated bytes values = 3; }
data.go.proto
type ColumnarValue struct { Id uint32 `protobuf:"varint,1,opt,name=id,json=id,proto3" json:"id,omitempty"` Typ int32 `protobuf:"varint,2,opt,name=typ,json=typ,proto3" json:"typ,omitempty"` Values [][]byte `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty"` }
- 序列化
func (m *ColumnarValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalTo(b) if err != nil { return nil, err } return b[:n], nil }
func (m *ColumnarValue) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Id != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintData(dAtA, i, uint64(m.Id))
}
if m.Typ != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintData(dAtA, i, uint64(m.Typ))
}
if len(m.Values) > 0 { // [][]byte序列化
for _, b := range m.Values {
dAtA[i] = 0x1a
i++
i = encodeVarintData(dAtA, i, uint64(len(b))) // 对byte Slice的长度(int值)编码
i += copy(dAtA[i:], b) // 直接复制b(bytes)切片
}
}
return i, nil
}
编码(slice长度)
func encodeVarintData(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
-
func (m *VecValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) }
func (m *VecValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowData } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { return fmt.Errorf("proto: VecValue: wiretype end group for non-group") } if fieldNum <= 0 { return fmt.Errorf("proto: VecValue: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } m.Id = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowData } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ m.Id |= (uint32(b) & 0x7F) << shift if b < 0x80 { break } } case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Typ", wireType) } m.Typ = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowData } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ m.Typ |= (int32(b) & 0x7F) << shift if b < 0x80 { break } } case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowData } if iNdEx >= l { return io.ErrUnexpectedEOF } b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } if byteLen < 0 { return ErrInvalidLengthData } postIndex := iNdEx + byteLen if postIndex > l { return io.ErrUnexpectedEOF } m.Values = append(m.Values, make([]byte, postIndex-iNdEx)) copy(m.Values[len(m.Values)-1], dAtA[iNdEx:postIndex]) // 直接复制dAtA切片中指定内容, go层内部 内存复制 iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipData(dAtA[iNdEx:]) if err != nil { return err } if skippy < 0 { return ErrInvalidLengthData } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } iNdEx += skippy } } if iNdEx > l { return io.ErrUnexpectedEOF } return nil }
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK