项目作者: linux4life798

项目描述 :
Protobuf dynamic marshalling and unmarshalling
高级语言: Go
项目地址: git://github.com/linux4life798/dproto.git
创建时间: 2017-02-16T06:20:25Z
项目社区:https://github.com/linux4life798/dproto

开源协议:MIT License

下载


dproto

GoDoc
Go Report Card
codecov
Build Status

Description

This library allows you to use Protobufs (Google Protocol Buffers) without needing to
generate protobuf code and compile it into your project.
This means you don’t need to compile .proto files.

This library is designed for marshaling and unmarshalling protobufs in a dynamic way.
It is designed to interface with any standard protobuf library and is tested against
the official protobuf C++ and Golang bindings, in addition to the C
Nanopdb library.

The intent of this library was to allow creating long running services that can
interpret and interface with clients using new/unknown protobuf messages.

The basic idea is that you construct a ProtoFieldMap that contains any protobuf
field number to protobuf type associations you are interested in and then you
call DecodeBUffer on the protobuf payload.
DecodeBuffer returns an array of FieldValues that it decoded from the payload.
Each FieldValue specifies the protobuf field number and value decoded as a Golang
primitive(must be inside a interface{}).

Status

Dproto supports all ProtoBuf primitive types. The following is a complete list:

  • int32, int64
  • uint32, uint64
  • sint32, sint64
  • fixed32, fixed64
  • sfixed32, sfixed64
  • float, double
  • bool, string, bytes

Name Explanation

Since we are marshalling and unmarshalling Protobuf messages in a dynamic way,
the project is called dproto.

Examples

To give you a little taste of what dproto can do, check out the following
example of marshalling and unmarshalling a protobuf.

Say you want to interface with some other program using the following
protobuf description:

  1. message LightStatus {
  2. bool status = 1;
  3. int64 intensity = 2;
  4. }

The following example encodes a new message, prints out the byte stream,
and then immediately decodes it.

  1. // Encodes and Decodes a protobuf buffer that would interface with
  2. // a .proto file message containing "bool status =1;" and
  3. // "int64 intensity = 2;".
  4. func ExampleNewProtoFieldMap() {
  5. // Setup the ProtoFieldMap to interface with the
  6. // following .proto file:
  7. // message LightStatus {
  8. // bool status = 1;
  9. // int64 intensity = 2;
  10. // }
  11. // Setup a FieldMap that holds the type-fieldnumber association
  12. // This is effectively the information held in a .proto file
  13. fm := dproto.NewProtoFieldMap()
  14. // Add Protobuf bool as field 1 ("bool status = 1;")
  15. if !fm.Add(1, descriptor.FieldDescriptorProto_TYPE_BOOL) {
  16. panic("Failed to add bool field 1")
  17. }
  18. // Add Protobuf int64 as field 2 ("int64 intensity = 2;")
  19. if !fm.Add(2, descriptor.FieldDescriptorProto_TYPE_INT64) {
  20. panic("Failed to add bool field 1")
  21. }
  22. // Provide some values for our "status" and "intensity"
  23. values := []dproto.FieldValue{
  24. dproto.FieldValue{
  25. Field: 1, // status field number
  26. Value: bool(true),
  27. },
  28. dproto.FieldValue{
  29. Field: 2, // intensity field number
  30. Value: int64(10),
  31. },
  32. }
  33. // Encode out values into the protobuf message described in fm
  34. bytes, err := fm.EncodeBuffer(values)
  35. if err != nil {
  36. panic("Error Encoding: " + err.Error())
  37. }
  38. fmt.Printf("ProtobufBinary: [ %# x ]\n", bytes)
  39. // Decode all protobuf fields
  40. decodedValues, err := fm.DecodeBuffer(bytes)
  41. if err != nil {
  42. panic("Error Decoding: " + err.Error())
  43. }
  44. for _, val := range decodedValues {
  45. fmt.Printf("%v: %v\n", val.Field, val.Value)
  46. }
  47. // Unordered output:
  48. // ProtobufBinary: [ 0x08 0x01 0x10 0x0a ]
  49. // 1: true
  50. // 2: 10
  51. }

This and other examples can be found in example_test.go.