Documentation
¶
Overview ¶
Package easyproto provides building blocks for marshaling and unmarshaling protobuf v3 messages according to https://protobuf.dev/programming-guides/encoding/ .
Example ¶
package main import ( "fmt" "github.com/VictoriaMetrics/easyproto" ) // Timeseries is a named time series. // // It has the following protobuf v3 definition: // // message timeseries { // string name = 1; // repeated sample samples = 2; // } type Timeseries struct { Name string Samples []Sample } // Sample represents a sample for the named time series. // // It has the following protobuf v3 definition: // // message sample { // double value = 1; // int64 timestamp = 2; // } type Sample struct { Value float64 Timestamp int64 } // MarshalProtobuf marshals ts into protobuf message, appends this message to dst and returns the result. // // This function doesn't allocate memory on repeated calls. func (ts *Timeseries) MarshalProtobuf(dst []byte) []byte { m := mp.Get() ts.marshalProtobuf(m.MessageMarshaler()) dst = m.Marshal(dst) mp.Put(m) return dst } func (ts *Timeseries) marshalProtobuf(mm *easyproto.MessageMarshaler) { mm.AppendString(1, ts.Name) for _, s := range ts.Samples { s.marshalProtobuf(mm.AppendMessage(2)) } } func (s *Sample) marshalProtobuf(mm *easyproto.MessageMarshaler) { mm.AppendDouble(1, s.Value) mm.AppendInt64(2, s.Timestamp) } var mp easyproto.MarshalerPool // UnmarshalProtobuf unmarshals ts from protobuf message at src. func (ts *Timeseries) UnmarshalProtobuf(src []byte) (err error) { // Set default Timeseries values ts.Name = "" ts.Samples = ts.Samples[:0] // Parse Timeseries message at src var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in Timeseries message") } switch fc.FieldNum { case 1: name, ok := fc.String() if !ok { return fmt.Errorf("cannot read Timeseries name") } // name refers to src. This means that the name changes when src changes. // Make a copy with strings.Clone(name) if needed. ts.Name = name case 2: data, ok := fc.MessageData() if !ok { return fmt.Errorf("cannot read Timeseries sample data") } ts.Samples = append(ts.Samples, Sample{}) s := &ts.Samples[len(ts.Samples)-1] if err := s.UnmarshalProtobuf(data); err != nil { return fmt.Errorf("cannot unmarshal sample: %w", err) } } } return nil } // UnmarshalProtobuf unmarshals s from protobuf message at src. func (s *Sample) UnmarshalProtobuf(src []byte) (err error) { // Set default Sample values s.Value = 0 s.Timestamp = 0 // Parse Sample message at src var fc easyproto.FieldContext for len(src) > 0 { src, err = fc.NextField(src) if err != nil { return fmt.Errorf("cannot read next field in sample") } switch fc.FieldNum { case 1: value, ok := fc.Double() if !ok { return fmt.Errorf("cannot read sample value") } s.Value = value case 2: timestamp, ok := fc.Int64() if !ok { return fmt.Errorf("cannot read sample timestamp") } s.Timestamp = timestamp } } return nil } func main() { ts := &Timeseries{ Name: "foo", Samples: []Sample{ { Value: 123, Timestamp: -453426, }, { Value: -234.344, Timestamp: 23328434, }, }, } data := ts.MarshalProtobuf(nil) var tsNew Timeseries if err := tsNew.UnmarshalProtobuf(data); err != nil { fmt.Printf("unexpected error: %s\n", err) return } fmt.Printf("name: %s\n", tsNew.Name) fmt.Printf("samples:\n") for _, s := range tsNew.Samples { fmt.Printf(" {value:%v, timestamp:%d}\n", s.Value, s.Timestamp) } }
Output: name: foo samples: {value:123, timestamp:-453426} {value:-234.344, timestamp:23328434}
Index ¶
- func UnmarshalMessageLen(src []byte) (int, []byte, bool)
- type FieldContext
- func (fc *FieldContext) Bool() (bool, bool)
- func (fc *FieldContext) Bytes() ([]byte, bool)
- func (fc *FieldContext) Double() (float64, bool)
- func (fc *FieldContext) Fixed32() (uint32, bool)
- func (fc *FieldContext) Fixed64() (uint64, bool)
- func (fc *FieldContext) Float() (float32, bool)
- func (fc *FieldContext) Int32() (int32, bool)
- func (fc *FieldContext) Int64() (int64, bool)
- func (fc *FieldContext) MessageData() ([]byte, bool)
- func (fc *FieldContext) NextField(src []byte) ([]byte, error)
- func (fc *FieldContext) Sfixed32() (int32, bool)
- func (fc *FieldContext) Sfixed64() (int64, bool)
- func (fc *FieldContext) Sint32() (int32, bool)
- func (fc *FieldContext) Sint64() (int64, bool)
- func (fc *FieldContext) String() (string, bool)
- func (fc *FieldContext) Uint32() (uint32, bool)
- func (fc *FieldContext) Uint64() (uint64, bool)
- func (fc *FieldContext) UnpackBools(dst []bool) ([]bool, bool)
- func (fc *FieldContext) UnpackDoubles(dst []float64) ([]float64, bool)
- func (fc *FieldContext) UnpackFixed32s(dst []uint32) ([]uint32, bool)
- func (fc *FieldContext) UnpackFixed64s(dst []uint64) ([]uint64, bool)
- func (fc *FieldContext) UnpackFloats(dst []float32) ([]float32, bool)
- func (fc *FieldContext) UnpackInt32s(dst []int32) ([]int32, bool)
- func (fc *FieldContext) UnpackInt64s(dst []int64) ([]int64, bool)
- func (fc *FieldContext) UnpackSfixed32s(dst []int32) ([]int32, bool)
- func (fc *FieldContext) UnpackSfixed64s(dst []int64) ([]int64, bool)
- func (fc *FieldContext) UnpackSint32s(dst []int32) ([]int32, bool)
- func (fc *FieldContext) UnpackSint64s(dst []int64) ([]int64, bool)
- func (fc *FieldContext) UnpackUint32s(dst []uint32) ([]uint32, bool)
- func (fc *FieldContext) UnpackUint64s(dst []uint64) ([]uint64, bool)
- type Marshaler
- type MarshalerPool
- type MessageMarshaler
- func (mm *MessageMarshaler) AppendBool(fieldNum uint32, v bool)
- func (mm *MessageMarshaler) AppendBools(fieldNum uint32, bs []bool)
- func (mm *MessageMarshaler) AppendBytes(fieldNum uint32, b []byte)
- func (mm *MessageMarshaler) AppendDouble(fieldNum uint32, f float64)
- func (mm *MessageMarshaler) AppendDoubles(fieldNum uint32, fs []float64)
- func (mm *MessageMarshaler) AppendFixed32(fieldNum, u32 uint32)
- func (mm *MessageMarshaler) AppendFixed32s(fieldNum uint32, u32s []uint32)
- func (mm *MessageMarshaler) AppendFixed64(fieldNum uint32, u64 uint64)
- func (mm *MessageMarshaler) AppendFixed64s(fieldNum uint32, u64s []uint64)
- func (mm *MessageMarshaler) AppendFloat(fieldNum uint32, f float32)
- func (mm *MessageMarshaler) AppendFloats(fieldNum uint32, fs []float32)
- func (mm *MessageMarshaler) AppendInt32(fieldNum uint32, i32 int32)
- func (mm *MessageMarshaler) AppendInt32s(fieldNum uint32, i32s []int32)
- func (mm *MessageMarshaler) AppendInt64(fieldNum uint32, i64 int64)
- func (mm *MessageMarshaler) AppendInt64s(fieldNum uint32, i64s []int64)
- func (mm *MessageMarshaler) AppendMessage(fieldNum uint32) *MessageMarshaler
- func (mm *MessageMarshaler) AppendSfixed32(fieldNum uint32, i32 int32)
- func (mm *MessageMarshaler) AppendSfixed32s(fieldNum uint32, i32s []int32)
- func (mm *MessageMarshaler) AppendSfixed64(fieldNum uint32, i64 int64)
- func (mm *MessageMarshaler) AppendSfixed64s(fieldNum uint32, i64s []int64)
- func (mm *MessageMarshaler) AppendSint32(fieldNum uint32, i32 int32)
- func (mm *MessageMarshaler) AppendSint32s(fieldNum uint32, i32s []int32)
- func (mm *MessageMarshaler) AppendSint64(fieldNum uint32, i64 int64)
- func (mm *MessageMarshaler) AppendSint64s(fieldNum uint32, i64s []int64)
- func (mm *MessageMarshaler) AppendString(fieldNum uint32, s string)
- func (mm *MessageMarshaler) AppendUint32(fieldNum, u32 uint32)
- func (mm *MessageMarshaler) AppendUint32s(fieldNum uint32, u32s []uint32)
- func (mm *MessageMarshaler) AppendUint64(fieldNum uint32, u64 uint64)
- func (mm *MessageMarshaler) AppendUint64s(fieldNum uint32, u64s []uint64)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func UnmarshalMessageLen ¶
UnmarshalMessageLen unmarshals protobuf message length from src.
It returns the tail left after unmarshaling message length from src.
It is expected that src is marshaled with Marshaler.MarshalWithLen().
False is returned if message length cannot be unmarshaled from src.
Types ¶
type FieldContext ¶
type FieldContext struct { // FieldNum is the number of protobuf field read after NextField() call. FieldNum uint32 // contains filtered or unexported fields }
FieldContext represents a single protobuf-encoded field after NextField() call.
func (*FieldContext) Bool ¶
func (fc *FieldContext) Bool() (bool, bool)
Bool returns bool value for fc.
False is returned in the second result if fc doesn't contain bool value.
func (*FieldContext) Bytes ¶
func (fc *FieldContext) Bytes() ([]byte, bool)
Bytes returns bytes value for fc.
The returned byte slice is valid while the underlying buffer isn't changed.
False is returned if fc doesn't contain bytes value.
func (*FieldContext) Double ¶
func (fc *FieldContext) Double() (float64, bool)
Double returns dobule value for fc.
False is returned if fc doesn't contain double value.
func (*FieldContext) Fixed32 ¶
func (fc *FieldContext) Fixed32() (uint32, bool)
Fixed32 returns fixed32 value for fc.
False is returned if fc doesn't contain fixed32 value.
func (*FieldContext) Fixed64 ¶
func (fc *FieldContext) Fixed64() (uint64, bool)
Fixed64 returns fixed64 value for fc.
False is returned if fc doesn't contain fixed64 value.
func (*FieldContext) Float ¶
func (fc *FieldContext) Float() (float32, bool)
Float returns float value for fc.
False is returned if fc doesn't contain float value.
func (*FieldContext) Int32 ¶
func (fc *FieldContext) Int32() (int32, bool)
Int32 returns int32 value for fc.
False is returned if fc doesn't contain int32 value.
func (*FieldContext) Int64 ¶
func (fc *FieldContext) Int64() (int64, bool)
Int64 returns int64 value for fc.
False is returned if fc doesn't contain int64 value.
func (*FieldContext) MessageData ¶
func (fc *FieldContext) MessageData() ([]byte, bool)
MessageData returns protobuf message data for fc.
False is returned if fc doesn't contain message data.
func (*FieldContext) NextField ¶
func (fc *FieldContext) NextField(src []byte) ([]byte, error)
NextField reads the next field from protobuf-encoded src.
It returns the tail left after reading the next field from src.
It is unsafe modifying src while FieldContext is in use.
func (*FieldContext) Sfixed32 ¶
func (fc *FieldContext) Sfixed32() (int32, bool)
Sfixed32 returns sfixed32 value for fc.
False is returned if fc doesn't contain sfixed value.
func (*FieldContext) Sfixed64 ¶
func (fc *FieldContext) Sfixed64() (int64, bool)
Sfixed64 returns sfixed64 value for fc.
False is returned if fc doesn't contain sfixed64 value.
func (*FieldContext) Sint32 ¶
func (fc *FieldContext) Sint32() (int32, bool)
Sint32 returns sint32 value for fc.
False is returned if fc doesn't contain sint32 value.
func (*FieldContext) Sint64 ¶
func (fc *FieldContext) Sint64() (int64, bool)
Sint64 returns sint64 value for fc.
False is returned if fc doesn't contain sint64 value.
func (*FieldContext) String ¶
func (fc *FieldContext) String() (string, bool)
String returns string value for fc.
The returned string is valid while the underlying buffer isn't changed.
False is returned if fc doesn't contain string value.
func (*FieldContext) Uint32 ¶
func (fc *FieldContext) Uint32() (uint32, bool)
Uint32 returns uint32 value for fc.
False is returned if fc doesn't contain uint32 value.
func (*FieldContext) Uint64 ¶
func (fc *FieldContext) Uint64() (uint64, bool)
Uint64 returns uint64 value for fc.
False is returned if fc doesn't contain uint64 value.
func (*FieldContext) UnpackBools ¶
func (fc *FieldContext) UnpackBools(dst []bool) ([]bool, bool)
UnpackBools unpacks bool values from fc, appends them to dst and returns the result.
False is returned in the second result if fc doesn't contain bool values.
func (*FieldContext) UnpackDoubles ¶
func (fc *FieldContext) UnpackDoubles(dst []float64) ([]float64, bool)
UnpackDoubles unpacks double values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain double values.
func (*FieldContext) UnpackFixed32s ¶
func (fc *FieldContext) UnpackFixed32s(dst []uint32) ([]uint32, bool)
UnpackFixed32s unpacks fixed32 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain fixed32 values.
func (*FieldContext) UnpackFixed64s ¶
func (fc *FieldContext) UnpackFixed64s(dst []uint64) ([]uint64, bool)
UnpackFixed64s unpacks fixed64 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain fixed64 values.
func (*FieldContext) UnpackFloats ¶
func (fc *FieldContext) UnpackFloats(dst []float32) ([]float32, bool)
UnpackFloats unpacks float values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain float values.
func (*FieldContext) UnpackInt32s ¶
func (fc *FieldContext) UnpackInt32s(dst []int32) ([]int32, bool)
UnpackInt32s unpacks int32 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain int32 values.
func (*FieldContext) UnpackInt64s ¶
func (fc *FieldContext) UnpackInt64s(dst []int64) ([]int64, bool)
UnpackInt64s unpacks int64 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain int64 values.
func (*FieldContext) UnpackSfixed32s ¶
func (fc *FieldContext) UnpackSfixed32s(dst []int32) ([]int32, bool)
UnpackSfixed32s unpacks sfixed32 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain sfixed32 values.
func (*FieldContext) UnpackSfixed64s ¶
func (fc *FieldContext) UnpackSfixed64s(dst []int64) ([]int64, bool)
UnpackSfixed64s unpacks sfixed64 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain sfixed64 values.
func (*FieldContext) UnpackSint32s ¶
func (fc *FieldContext) UnpackSint32s(dst []int32) ([]int32, bool)
UnpackSint32s unpacks sint32 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain sint32 values.
func (*FieldContext) UnpackSint64s ¶
func (fc *FieldContext) UnpackSint64s(dst []int64) ([]int64, bool)
UnpackSint64s unpacks sint64 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain sint64 values.
func (*FieldContext) UnpackUint32s ¶
func (fc *FieldContext) UnpackUint32s(dst []uint32) ([]uint32, bool)
UnpackUint32s unpacks uint32 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain uint32 values.
func (*FieldContext) UnpackUint64s ¶
func (fc *FieldContext) UnpackUint64s(dst []uint64) ([]uint64, bool)
UnpackUint64s unpacks uint64 values from fc, appends them to dst and returns the result.
False is returned if fc doesn't contain uint64 values.
type Marshaler ¶
type Marshaler struct {
// contains filtered or unexported fields
}
Marshaler helps marshaling arbitrary protobuf messages.
Construct message with Append* functions at MessageMarshaler() and then call Marshal* for marshaling the constructed message.
It is unsafe to use a single Marshaler instance from multiple concurrently running goroutines.
It is recommended re-cycling Marshaler via MarshalerPool in order to reduce memory allocations.
func (*Marshaler) Marshal ¶
Marshal appends marshaled protobuf m to dst and returns the result.
The marshaled message can be read via FieldContext.NextField().
See also MarshalWithLen.
func (*Marshaler) MarshalWithLen ¶
MarshalWithLen marshals m, appends its length together with the marshaled m to dst and returns the result.
E.g. appends length-delimited protobuf message to dst. The length of the resulting message can be read via UnmarshalMessageLen() function.
See also Marshal.
func (*Marshaler) MessageMarshaler ¶
func (m *Marshaler) MessageMarshaler() *MessageMarshaler
MessageMarshaler returns message marshaler for the given m.
type MarshalerPool ¶
type MarshalerPool struct {
// contains filtered or unexported fields
}
MarshalerPool is a pool of Marshaler structs.
func (*MarshalerPool) Get ¶
func (mp *MarshalerPool) Get() *Marshaler
Get obtains a Marshaler from the pool.
The returned Marshaler can be returned to the pool via Put after it is no longer needed.
func (*MarshalerPool) Put ¶
func (mp *MarshalerPool) Put(m *Marshaler)
Put returns the given m to the pool.
m cannot be used after returning to the pool.
type MessageMarshaler ¶
type MessageMarshaler struct {
// contains filtered or unexported fields
}
MessageMarshaler helps constructing protobuf message for marshaling.
MessageMarshaler must be obtained via Marshaler.MessageMarshaler().
func (*MessageMarshaler) AppendBool ¶
func (mm *MessageMarshaler) AppendBool(fieldNum uint32, v bool)
AppendBool appends the given bool value under the given fieldNum to mm.
func (*MessageMarshaler) AppendBools ¶
func (mm *MessageMarshaler) AppendBools(fieldNum uint32, bs []bool)
AppendBools appends the given bool values under the given fieldNum to mm.
func (*MessageMarshaler) AppendBytes ¶
func (mm *MessageMarshaler) AppendBytes(fieldNum uint32, b []byte)
AppendBytes appends bytes value under the given fieldNum to mm.
func (*MessageMarshaler) AppendDouble ¶
func (mm *MessageMarshaler) AppendDouble(fieldNum uint32, f float64)
AppendDouble appends double value under the given fieldNum to mm.
func (*MessageMarshaler) AppendDoubles ¶
func (mm *MessageMarshaler) AppendDoubles(fieldNum uint32, fs []float64)
AppendDoubles appends the given double values under the given fieldNum to mm.
func (*MessageMarshaler) AppendFixed32 ¶
func (mm *MessageMarshaler) AppendFixed32(fieldNum, u32 uint32)
AppendFixed32 appends fixed32 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendFixed32s ¶
func (mm *MessageMarshaler) AppendFixed32s(fieldNum uint32, u32s []uint32)
AppendFixed32s appends the given fixed32 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendFixed64 ¶
func (mm *MessageMarshaler) AppendFixed64(fieldNum uint32, u64 uint64)
AppendFixed64 appends fixed64 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendFixed64s ¶
func (mm *MessageMarshaler) AppendFixed64s(fieldNum uint32, u64s []uint64)
AppendFixed64s appends the given fixed64 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendFloat ¶
func (mm *MessageMarshaler) AppendFloat(fieldNum uint32, f float32)
AppendFloat appends float value under the given fieldNum to mm.
func (*MessageMarshaler) AppendFloats ¶
func (mm *MessageMarshaler) AppendFloats(fieldNum uint32, fs []float32)
AppendFloats appends the given float values under the given fieldNum to mm.
func (*MessageMarshaler) AppendInt32 ¶
func (mm *MessageMarshaler) AppendInt32(fieldNum uint32, i32 int32)
AppendInt32 appends the given int32 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendInt32s ¶
func (mm *MessageMarshaler) AppendInt32s(fieldNum uint32, i32s []int32)
AppendInt32s appends the given int32 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendInt64 ¶
func (mm *MessageMarshaler) AppendInt64(fieldNum uint32, i64 int64)
AppendInt64 appends the given int64 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendInt64s ¶
func (mm *MessageMarshaler) AppendInt64s(fieldNum uint32, i64s []int64)
AppendInt64s appends the given int64 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendMessage ¶
func (mm *MessageMarshaler) AppendMessage(fieldNum uint32) *MessageMarshaler
AppendMessage appends protobuf message with the given fieldNum to m.
The function returns the MessageMarshaler for constructing the appended message.
func (*MessageMarshaler) AppendSfixed32 ¶
func (mm *MessageMarshaler) AppendSfixed32(fieldNum uint32, i32 int32)
AppendSfixed32 appends sfixed32 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendSfixed32s ¶
func (mm *MessageMarshaler) AppendSfixed32s(fieldNum uint32, i32s []int32)
AppendSfixed32s appends the given sfixed32 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendSfixed64 ¶
func (mm *MessageMarshaler) AppendSfixed64(fieldNum uint32, i64 int64)
AppendSfixed64 appends sfixed64 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendSfixed64s ¶
func (mm *MessageMarshaler) AppendSfixed64s(fieldNum uint32, i64s []int64)
AppendSfixed64s appends the given sfixed64 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendSint32 ¶
func (mm *MessageMarshaler) AppendSint32(fieldNum uint32, i32 int32)
AppendSint32 appends the given sint32 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendSint32s ¶
func (mm *MessageMarshaler) AppendSint32s(fieldNum uint32, i32s []int32)
AppendSint32s appends the given sint32 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendSint64 ¶
func (mm *MessageMarshaler) AppendSint64(fieldNum uint32, i64 int64)
AppendSint64 appends the given sint64 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendSint64s ¶
func (mm *MessageMarshaler) AppendSint64s(fieldNum uint32, i64s []int64)
AppendSint64s appends the given sint64 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendString ¶
func (mm *MessageMarshaler) AppendString(fieldNum uint32, s string)
AppendString appends string value under the given fieldNum to mm.
func (*MessageMarshaler) AppendUint32 ¶
func (mm *MessageMarshaler) AppendUint32(fieldNum, u32 uint32)
AppendUint32 appends the given uint32 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendUint32s ¶
func (mm *MessageMarshaler) AppendUint32s(fieldNum uint32, u32s []uint32)
AppendUint32s appends the given uint32 values under the given fieldNum to mm.
func (*MessageMarshaler) AppendUint64 ¶
func (mm *MessageMarshaler) AppendUint64(fieldNum uint32, u64 uint64)
AppendUint64 appends the given uint64 value under the given fieldNum to mm.
func (*MessageMarshaler) AppendUint64s ¶
func (mm *MessageMarshaler) AppendUint64s(fieldNum uint32, u64s []uint64)
AppendUint64s appends the given uint64 values under the given fieldNum to mm.