github.com/m3db/m3@v1.5.0/src/dbnode/encoding/proto/custom_marshal.go (about)

     1  // Copyright (c) 2019 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package proto
    22  
    23  import (
    24  	"math"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  )
    28  
    29  // encoding methods correspond to the scalar types defined in the protobuf 3
    30  // specificaiton: https://developers.google.com/protocol-buffers/docs/proto3#scalar
    31  type customFieldMarshaller interface {
    32  	encFloat64(tag int32, x float64)
    33  	encFloat32(tag int32, x float32)
    34  	encInt32(tag int32, x int32)
    35  	encSInt32(tag int32, x int32)
    36  	encSFixedInt32(tax int32, x int32)
    37  	encUInt32(tag int32, x uint32)
    38  	encInt64(tag int32, x int64)
    39  	encSInt64(tag int32, x int64)
    40  	encSFixedInt64(tax int32, x int64)
    41  	encUInt64(tag int32, x uint64)
    42  	encBool(tag int32, x bool)
    43  	encBytes(tag int32, x []byte)
    44  
    45  	// Used in cases where marshalled protobuf bytes have already been generated
    46  	// and need to be appended to the stream. Assumes that the <tag, wireType>
    47  	// tuple has already been included.
    48  	encPartialProto(x []byte)
    49  
    50  	bytes() []byte
    51  	reset()
    52  }
    53  
    54  type customMarshaller struct {
    55  	buf *buffer
    56  }
    57  
    58  func newCustomMarshaller() customFieldMarshaller {
    59  	return &customMarshaller{
    60  		buf: newCodedBuffer(nil),
    61  	}
    62  }
    63  
    64  func (m *customMarshaller) encFloat64(tag int32, x float64) {
    65  	if x == 0.0 {
    66  		// Default values are not included in the stream.
    67  		return
    68  	}
    69  
    70  	m.buf.encodeTagAndWireType(tag, proto.WireFixed64)
    71  	m.buf.encodeFixed64(math.Float64bits(x))
    72  }
    73  
    74  func (m *customMarshaller) encFloat32(tag int32, x float32) {
    75  	if x == 0.0 {
    76  		// Default values are not included in the stream.
    77  		return
    78  	}
    79  
    80  	m.buf.encodeTagAndWireType(tag, proto.WireFixed32)
    81  	m.buf.encodeFixed32(math.Float32bits(x))
    82  }
    83  
    84  func (m *customMarshaller) encBool(tag int32, x bool) {
    85  	if !x {
    86  		// Default values are not included in the stream.
    87  		return
    88  	}
    89  
    90  	m.encUInt64(tag, 1)
    91  }
    92  
    93  func (m *customMarshaller) encInt32(tag int32, x int32) {
    94  	m.encUInt64(tag, uint64(x))
    95  }
    96  
    97  func (m *customMarshaller) encSInt32(tag int32, x int32) {
    98  	m.encUInt64(tag, encodeZigZag32(x))
    99  }
   100  
   101  func (m *customMarshaller) encSFixedInt32(tag int32, x int32) {
   102  	m.buf.encodeTagAndWireType(tag, proto.WireFixed32)
   103  	m.buf.encodeFixed32(uint32(x))
   104  }
   105  
   106  func (m *customMarshaller) encUInt32(tag int32, x uint32) {
   107  	m.encUInt64(tag, uint64(x))
   108  }
   109  
   110  func (m *customMarshaller) encInt64(tag int32, x int64) {
   111  	m.encUInt64(tag, uint64(x))
   112  }
   113  
   114  func (m *customMarshaller) encSInt64(tag int32, x int64) {
   115  	m.encUInt64(tag, encodeZigZag64(x))
   116  }
   117  
   118  func (m *customMarshaller) encSFixedInt64(tag int32, x int64) {
   119  	m.buf.encodeTagAndWireType(tag, proto.WireFixed64)
   120  	m.buf.encodeFixed64(uint64(x))
   121  }
   122  
   123  func (m *customMarshaller) encUInt64(tag int32, x uint64) {
   124  	if x == 0 {
   125  		// Default values are not included in the stream.
   126  		return
   127  	}
   128  
   129  	m.buf.encodeTagAndWireType(tag, proto.WireVarint)
   130  	m.buf.encodeVarint(x)
   131  }
   132  
   133  func (m *customMarshaller) encBytes(tag int32, x []byte) {
   134  	if len(x) == 0 {
   135  		// Default values are not included in the stream.
   136  		return
   137  	}
   138  
   139  	m.buf.encodeTagAndWireType(tag, proto.WireBytes)
   140  	m.buf.encodeRawBytes(x)
   141  }
   142  
   143  func (m *customMarshaller) encPartialProto(x []byte) {
   144  	m.buf.append(x)
   145  }
   146  
   147  func (m *customMarshaller) bytes() []byte {
   148  	return m.buf.buf
   149  }
   150  
   151  func (m *customMarshaller) reset() {
   152  	b := m.buf.buf
   153  	if b != nil {
   154  		b = b[:0]
   155  	}
   156  	m.buf.reset(b)
   157  }