Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / go.opencensus.io / tag / map_codec.go
1 // Copyright 2017, OpenCensus Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15
16 package tag
17
18 import (
19         "encoding/binary"
20         "fmt"
21 )
22
23 // KeyType defines the types of keys allowed. Currently only keyTypeString is
24 // supported.
25 type keyType byte
26
27 const (
28         keyTypeString keyType = iota
29         keyTypeInt64
30         keyTypeTrue
31         keyTypeFalse
32
33         tagsVersionID = byte(0)
34 )
35
36 type encoderGRPC struct {
37         buf               []byte
38         writeIdx, readIdx int
39 }
40
41 // writeKeyString writes the fieldID '0' followed by the key string and value
42 // string.
43 func (eg *encoderGRPC) writeTagString(k, v string) {
44         eg.writeByte(byte(keyTypeString))
45         eg.writeStringWithVarintLen(k)
46         eg.writeStringWithVarintLen(v)
47 }
48
49 func (eg *encoderGRPC) writeTagUint64(k string, i uint64) {
50         eg.writeByte(byte(keyTypeInt64))
51         eg.writeStringWithVarintLen(k)
52         eg.writeUint64(i)
53 }
54
55 func (eg *encoderGRPC) writeTagTrue(k string) {
56         eg.writeByte(byte(keyTypeTrue))
57         eg.writeStringWithVarintLen(k)
58 }
59
60 func (eg *encoderGRPC) writeTagFalse(k string) {
61         eg.writeByte(byte(keyTypeFalse))
62         eg.writeStringWithVarintLen(k)
63 }
64
65 func (eg *encoderGRPC) writeBytesWithVarintLen(bytes []byte) {
66         length := len(bytes)
67
68         eg.growIfRequired(binary.MaxVarintLen64 + length)
69         eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length))
70         copy(eg.buf[eg.writeIdx:], bytes)
71         eg.writeIdx += length
72 }
73
74 func (eg *encoderGRPC) writeStringWithVarintLen(s string) {
75         length := len(s)
76
77         eg.growIfRequired(binary.MaxVarintLen64 + length)
78         eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length))
79         copy(eg.buf[eg.writeIdx:], s)
80         eg.writeIdx += length
81 }
82
83 func (eg *encoderGRPC) writeByte(v byte) {
84         eg.growIfRequired(1)
85         eg.buf[eg.writeIdx] = v
86         eg.writeIdx++
87 }
88
89 func (eg *encoderGRPC) writeUint32(i uint32) {
90         eg.growIfRequired(4)
91         binary.LittleEndian.PutUint32(eg.buf[eg.writeIdx:], i)
92         eg.writeIdx += 4
93 }
94
95 func (eg *encoderGRPC) writeUint64(i uint64) {
96         eg.growIfRequired(8)
97         binary.LittleEndian.PutUint64(eg.buf[eg.writeIdx:], i)
98         eg.writeIdx += 8
99 }
100
101 func (eg *encoderGRPC) readByte() byte {
102         b := eg.buf[eg.readIdx]
103         eg.readIdx++
104         return b
105 }
106
107 func (eg *encoderGRPC) readUint32() uint32 {
108         i := binary.LittleEndian.Uint32(eg.buf[eg.readIdx:])
109         eg.readIdx += 4
110         return i
111 }
112
113 func (eg *encoderGRPC) readUint64() uint64 {
114         i := binary.LittleEndian.Uint64(eg.buf[eg.readIdx:])
115         eg.readIdx += 8
116         return i
117 }
118
119 func (eg *encoderGRPC) readBytesWithVarintLen() ([]byte, error) {
120         if eg.readEnded() {
121                 return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx)
122         }
123         length, valueStart := binary.Uvarint(eg.buf[eg.readIdx:])
124         if valueStart <= 0 {
125                 return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx)
126         }
127
128         valueStart += eg.readIdx
129         valueEnd := valueStart + int(length)
130         if valueEnd > len(eg.buf) {
131                 return nil, fmt.Errorf("malformed encoding: length:%v, upper:%v, maxLength:%v", length, valueEnd, len(eg.buf))
132         }
133
134         eg.readIdx = valueEnd
135         return eg.buf[valueStart:valueEnd], nil
136 }
137
138 func (eg *encoderGRPC) readStringWithVarintLen() (string, error) {
139         bytes, err := eg.readBytesWithVarintLen()
140         if err != nil {
141                 return "", err
142         }
143         return string(bytes), nil
144 }
145
146 func (eg *encoderGRPC) growIfRequired(expected int) {
147         if len(eg.buf)-eg.writeIdx < expected {
148                 tmp := make([]byte, 2*(len(eg.buf)+1)+expected)
149                 copy(tmp, eg.buf)
150                 eg.buf = tmp
151         }
152 }
153
154 func (eg *encoderGRPC) readEnded() bool {
155         return eg.readIdx >= len(eg.buf)
156 }
157
158 func (eg *encoderGRPC) bytes() []byte {
159         return eg.buf[:eg.writeIdx]
160 }
161
162 // Encode encodes the tag map into a []byte. It is useful to propagate
163 // the tag maps on wire in binary format.
164 func Encode(m *Map) []byte {
165         if m == nil {
166                 return nil
167         }
168         eg := &encoderGRPC{
169                 buf: make([]byte, len(m.m)),
170         }
171         eg.writeByte(byte(tagsVersionID))
172         for k, v := range m.m {
173                 eg.writeByte(byte(keyTypeString))
174                 eg.writeStringWithVarintLen(k.name)
175                 eg.writeBytesWithVarintLen([]byte(v))
176         }
177         return eg.bytes()
178 }
179
180 // Decode decodes the given []byte into a tag map.
181 func Decode(bytes []byte) (*Map, error) {
182         ts := newMap()
183         err := DecodeEach(bytes, ts.upsert)
184         if err != nil {
185                 // no partial failures
186                 return nil, err
187         }
188         return ts, nil
189 }
190
191 // DecodeEach decodes the given serialized tag map, calling handler for each
192 // tag key and value decoded.
193 func DecodeEach(bytes []byte, fn func(key Key, val string)) error {
194         eg := &encoderGRPC{
195                 buf: bytes,
196         }
197         if len(eg.buf) == 0 {
198                 return nil
199         }
200
201         version := eg.readByte()
202         if version > tagsVersionID {
203                 return fmt.Errorf("cannot decode: unsupported version: %q; supports only up to: %q", version, tagsVersionID)
204         }
205
206         for !eg.readEnded() {
207                 typ := keyType(eg.readByte())
208
209                 if typ != keyTypeString {
210                         return fmt.Errorf("cannot decode: invalid key type: %q", typ)
211                 }
212
213                 k, err := eg.readBytesWithVarintLen()
214                 if err != nil {
215                         return err
216                 }
217
218                 v, err := eg.readBytesWithVarintLen()
219                 if err != nil {
220                         return err
221                 }
222
223                 key, err := NewKey(string(k))
224                 if err != nil {
225                         return err
226                 }
227                 val := string(v)
228                 if !checkValue(val) {
229                         return errInvalidValue
230                 }
231                 fn(key, val)
232                 if err != nil {
233                         return err
234                 }
235         }
236         return nil
237 }