]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | // Go support for Protocol Buffers - Google's data interchange format |
2 | // | |
3 | // Copyright 2010 The Go Authors. All rights reserved. | |
4 | // https://github.com/golang/protobuf | |
5 | // | |
6 | // Redistribution and use in source and binary forms, with or without | |
7 | // modification, are permitted provided that the following conditions are | |
8 | // met: | |
9 | // | |
10 | // * Redistributions of source code must retain the above copyright | |
11 | // notice, this list of conditions and the following disclaimer. | |
12 | // * Redistributions in binary form must reproduce the above | |
13 | // copyright notice, this list of conditions and the following disclaimer | |
14 | // in the documentation and/or other materials provided with the | |
15 | // distribution. | |
16 | // * Neither the name of Google Inc. nor the names of its | |
17 | // contributors may be used to endorse or promote products derived from | |
18 | // this software without specific prior written permission. | |
19 | // | |
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
31 | ||
32 | package proto | |
33 | ||
34 | /* | |
35 | * Routines for decoding protocol buffer data to construct in-memory representations. | |
36 | */ | |
37 | ||
38 | import ( | |
39 | "errors" | |
40 | "fmt" | |
41 | "io" | |
42 | ) | |
43 | ||
44 | // errOverflow is returned when an integer is too large to be represented. | |
45 | var errOverflow = errors.New("proto: integer overflow") | |
46 | ||
47 | // ErrInternalBadWireType is returned by generated code when an incorrect | |
48 | // wire type is encountered. It does not get returned to user code. | |
49 | var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") | |
50 | ||
51 | // DecodeVarint reads a varint-encoded integer from the slice. | |
52 | // It returns the integer and the number of bytes consumed, or | |
53 | // zero if there is not enough. | |
54 | // This is the format for the | |
55 | // int32, int64, uint32, uint64, bool, and enum | |
56 | // protocol buffer types. | |
57 | func DecodeVarint(buf []byte) (x uint64, n int) { | |
58 | for shift := uint(0); shift < 64; shift += 7 { | |
59 | if n >= len(buf) { | |
60 | return 0, 0 | |
61 | } | |
62 | b := uint64(buf[n]) | |
63 | n++ | |
64 | x |= (b & 0x7F) << shift | |
65 | if (b & 0x80) == 0 { | |
66 | return x, n | |
67 | } | |
68 | } | |
69 | ||
70 | // The number is too large to represent in a 64-bit value. | |
71 | return 0, 0 | |
72 | } | |
73 | ||
74 | func (p *Buffer) decodeVarintSlow() (x uint64, err error) { | |
75 | i := p.index | |
76 | l := len(p.buf) | |
77 | ||
78 | for shift := uint(0); shift < 64; shift += 7 { | |
79 | if i >= l { | |
80 | err = io.ErrUnexpectedEOF | |
81 | return | |
82 | } | |
83 | b := p.buf[i] | |
84 | i++ | |
85 | x |= (uint64(b) & 0x7F) << shift | |
86 | if b < 0x80 { | |
87 | p.index = i | |
88 | return | |
89 | } | |
90 | } | |
91 | ||
92 | // The number is too large to represent in a 64-bit value. | |
93 | err = errOverflow | |
94 | return | |
95 | } | |
96 | ||
97 | // DecodeVarint reads a varint-encoded integer from the Buffer. | |
98 | // This is the format for the | |
99 | // int32, int64, uint32, uint64, bool, and enum | |
100 | // protocol buffer types. | |
101 | func (p *Buffer) DecodeVarint() (x uint64, err error) { | |
102 | i := p.index | |
103 | buf := p.buf | |
104 | ||
105 | if i >= len(buf) { | |
106 | return 0, io.ErrUnexpectedEOF | |
107 | } else if buf[i] < 0x80 { | |
108 | p.index++ | |
109 | return uint64(buf[i]), nil | |
110 | } else if len(buf)-i < 10 { | |
111 | return p.decodeVarintSlow() | |
112 | } | |
113 | ||
114 | var b uint64 | |
115 | // we already checked the first byte | |
116 | x = uint64(buf[i]) - 0x80 | |
117 | i++ | |
118 | ||
119 | b = uint64(buf[i]) | |
120 | i++ | |
121 | x += b << 7 | |
122 | if b&0x80 == 0 { | |
123 | goto done | |
124 | } | |
125 | x -= 0x80 << 7 | |
126 | ||
127 | b = uint64(buf[i]) | |
128 | i++ | |
129 | x += b << 14 | |
130 | if b&0x80 == 0 { | |
131 | goto done | |
132 | } | |
133 | x -= 0x80 << 14 | |
134 | ||
135 | b = uint64(buf[i]) | |
136 | i++ | |
137 | x += b << 21 | |
138 | if b&0x80 == 0 { | |
139 | goto done | |
140 | } | |
141 | x -= 0x80 << 21 | |
142 | ||
143 | b = uint64(buf[i]) | |
144 | i++ | |
145 | x += b << 28 | |
146 | if b&0x80 == 0 { | |
147 | goto done | |
148 | } | |
149 | x -= 0x80 << 28 | |
150 | ||
151 | b = uint64(buf[i]) | |
152 | i++ | |
153 | x += b << 35 | |
154 | if b&0x80 == 0 { | |
155 | goto done | |
156 | } | |
157 | x -= 0x80 << 35 | |
158 | ||
159 | b = uint64(buf[i]) | |
160 | i++ | |
161 | x += b << 42 | |
162 | if b&0x80 == 0 { | |
163 | goto done | |
164 | } | |
165 | x -= 0x80 << 42 | |
166 | ||
167 | b = uint64(buf[i]) | |
168 | i++ | |
169 | x += b << 49 | |
170 | if b&0x80 == 0 { | |
171 | goto done | |
172 | } | |
173 | x -= 0x80 << 49 | |
174 | ||
175 | b = uint64(buf[i]) | |
176 | i++ | |
177 | x += b << 56 | |
178 | if b&0x80 == 0 { | |
179 | goto done | |
180 | } | |
181 | x -= 0x80 << 56 | |
182 | ||
183 | b = uint64(buf[i]) | |
184 | i++ | |
185 | x += b << 63 | |
186 | if b&0x80 == 0 { | |
187 | goto done | |
188 | } | |
15c0b25d AP |
189 | |
190 | return 0, errOverflow | |
191 | ||
192 | done: | |
193 | p.index = i | |
194 | return x, nil | |
195 | } | |
196 | ||
197 | // DecodeFixed64 reads a 64-bit integer from the Buffer. | |
198 | // This is the format for the | |
199 | // fixed64, sfixed64, and double protocol buffer types. | |
200 | func (p *Buffer) DecodeFixed64() (x uint64, err error) { | |
201 | // x, err already 0 | |
202 | i := p.index + 8 | |
203 | if i < 0 || i > len(p.buf) { | |
204 | err = io.ErrUnexpectedEOF | |
205 | return | |
206 | } | |
207 | p.index = i | |
208 | ||
209 | x = uint64(p.buf[i-8]) | |
210 | x |= uint64(p.buf[i-7]) << 8 | |
211 | x |= uint64(p.buf[i-6]) << 16 | |
212 | x |= uint64(p.buf[i-5]) << 24 | |
213 | x |= uint64(p.buf[i-4]) << 32 | |
214 | x |= uint64(p.buf[i-3]) << 40 | |
215 | x |= uint64(p.buf[i-2]) << 48 | |
216 | x |= uint64(p.buf[i-1]) << 56 | |
217 | return | |
218 | } | |
219 | ||
220 | // DecodeFixed32 reads a 32-bit integer from the Buffer. | |
221 | // This is the format for the | |
222 | // fixed32, sfixed32, and float protocol buffer types. | |
223 | func (p *Buffer) DecodeFixed32() (x uint64, err error) { | |
224 | // x, err already 0 | |
225 | i := p.index + 4 | |
226 | if i < 0 || i > len(p.buf) { | |
227 | err = io.ErrUnexpectedEOF | |
228 | return | |
229 | } | |
230 | p.index = i | |
231 | ||
232 | x = uint64(p.buf[i-4]) | |
233 | x |= uint64(p.buf[i-3]) << 8 | |
234 | x |= uint64(p.buf[i-2]) << 16 | |
235 | x |= uint64(p.buf[i-1]) << 24 | |
236 | return | |
237 | } | |
238 | ||
239 | // DecodeZigzag64 reads a zigzag-encoded 64-bit integer | |
240 | // from the Buffer. | |
241 | // This is the format used for the sint64 protocol buffer type. | |
242 | func (p *Buffer) DecodeZigzag64() (x uint64, err error) { | |
243 | x, err = p.DecodeVarint() | |
244 | if err != nil { | |
245 | return | |
246 | } | |
247 | x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) | |
248 | return | |
249 | } | |
250 | ||
251 | // DecodeZigzag32 reads a zigzag-encoded 32-bit integer | |
252 | // from the Buffer. | |
253 | // This is the format used for the sint32 protocol buffer type. | |
254 | func (p *Buffer) DecodeZigzag32() (x uint64, err error) { | |
255 | x, err = p.DecodeVarint() | |
256 | if err != nil { | |
257 | return | |
258 | } | |
259 | x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) | |
260 | return | |
261 | } | |
262 | ||
263 | // DecodeRawBytes reads a count-delimited byte buffer from the Buffer. | |
264 | // This is the format used for the bytes protocol buffer | |
265 | // type and for embedded messages. | |
266 | func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { | |
267 | n, err := p.DecodeVarint() | |
268 | if err != nil { | |
269 | return nil, err | |
270 | } | |
271 | ||
272 | nb := int(n) | |
273 | if nb < 0 { | |
274 | return nil, fmt.Errorf("proto: bad byte length %d", nb) | |
275 | } | |
276 | end := p.index + nb | |
277 | if end < p.index || end > len(p.buf) { | |
278 | return nil, io.ErrUnexpectedEOF | |
279 | } | |
280 | ||
281 | if !alloc { | |
282 | // todo: check if can get more uses of alloc=false | |
283 | buf = p.buf[p.index:end] | |
284 | p.index += nb | |
285 | return | |
286 | } | |
287 | ||
288 | buf = make([]byte, nb) | |
289 | copy(buf, p.buf[p.index:]) | |
290 | p.index += nb | |
291 | return | |
292 | } | |
293 | ||
294 | // DecodeStringBytes reads an encoded string from the Buffer. | |
295 | // This is the format used for the proto2 string type. | |
296 | func (p *Buffer) DecodeStringBytes() (s string, err error) { | |
297 | buf, err := p.DecodeRawBytes(false) | |
298 | if err != nil { | |
299 | return | |
300 | } | |
301 | return string(buf), nil | |
302 | } | |
303 | ||
304 | // Unmarshaler is the interface representing objects that can | |
305 | // unmarshal themselves. The argument points to data that may be | |
306 | // overwritten, so implementations should not keep references to the | |
307 | // buffer. | |
308 | // Unmarshal implementations should not clear the receiver. | |
309 | // Any unmarshaled data should be merged into the receiver. | |
310 | // Callers of Unmarshal that do not want to retain existing data | |
311 | // should Reset the receiver before calling Unmarshal. | |
312 | type Unmarshaler interface { | |
313 | Unmarshal([]byte) error | |
314 | } | |
315 | ||
316 | // newUnmarshaler is the interface representing objects that can | |
317 | // unmarshal themselves. The semantics are identical to Unmarshaler. | |
318 | // | |
319 | // This exists to support protoc-gen-go generated messages. | |
320 | // The proto package will stop type-asserting to this interface in the future. | |
321 | // | |
322 | // DO NOT DEPEND ON THIS. | |
323 | type newUnmarshaler interface { | |
324 | XXX_Unmarshal([]byte) error | |
325 | } | |
326 | ||
327 | // Unmarshal parses the protocol buffer representation in buf and places the | |
328 | // decoded result in pb. If the struct underlying pb does not match | |
329 | // the data in buf, the results can be unpredictable. | |
330 | // | |
331 | // Unmarshal resets pb before starting to unmarshal, so any | |
332 | // existing data in pb is always removed. Use UnmarshalMerge | |
333 | // to preserve and append to existing data. | |
334 | func Unmarshal(buf []byte, pb Message) error { | |
335 | pb.Reset() | |
336 | if u, ok := pb.(newUnmarshaler); ok { | |
337 | return u.XXX_Unmarshal(buf) | |
338 | } | |
339 | if u, ok := pb.(Unmarshaler); ok { | |
340 | return u.Unmarshal(buf) | |
341 | } | |
342 | return NewBuffer(buf).Unmarshal(pb) | |
343 | } | |
344 | ||
345 | // UnmarshalMerge parses the protocol buffer representation in buf and | |
346 | // writes the decoded result to pb. If the struct underlying pb does not match | |
347 | // the data in buf, the results can be unpredictable. | |
348 | // | |
349 | // UnmarshalMerge merges into existing data in pb. | |
350 | // Most code should use Unmarshal instead. | |
351 | func UnmarshalMerge(buf []byte, pb Message) error { | |
352 | if u, ok := pb.(newUnmarshaler); ok { | |
353 | return u.XXX_Unmarshal(buf) | |
354 | } | |
355 | if u, ok := pb.(Unmarshaler); ok { | |
356 | // NOTE: The history of proto have unfortunately been inconsistent | |
357 | // whether Unmarshaler should or should not implicitly clear itself. | |
358 | // Some implementations do, most do not. | |
359 | // Thus, calling this here may or may not do what people want. | |
360 | // | |
361 | // See https://github.com/golang/protobuf/issues/424 | |
362 | return u.Unmarshal(buf) | |
363 | } | |
364 | return NewBuffer(buf).Unmarshal(pb) | |
365 | } | |
366 | ||
367 | // DecodeMessage reads a count-delimited message from the Buffer. | |
368 | func (p *Buffer) DecodeMessage(pb Message) error { | |
369 | enc, err := p.DecodeRawBytes(false) | |
370 | if err != nil { | |
371 | return err | |
372 | } | |
373 | return NewBuffer(enc).Unmarshal(pb) | |
374 | } | |
375 | ||
376 | // DecodeGroup reads a tag-delimited group from the Buffer. | |
377 | // StartGroup tag is already consumed. This function consumes | |
378 | // EndGroup tag. | |
379 | func (p *Buffer) DecodeGroup(pb Message) error { | |
380 | b := p.buf[p.index:] | |
381 | x, y := findEndGroup(b) | |
382 | if x < 0 { | |
383 | return io.ErrUnexpectedEOF | |
384 | } | |
385 | err := Unmarshal(b[:x], pb) | |
386 | p.index += y | |
387 | return err | |
388 | } | |
389 | ||
390 | // Unmarshal parses the protocol buffer representation in the | |
391 | // Buffer and places the decoded result in pb. If the struct | |
392 | // underlying pb does not match the data in the buffer, the results can be | |
393 | // unpredictable. | |
394 | // | |
395 | // Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. | |
396 | func (p *Buffer) Unmarshal(pb Message) error { | |
397 | // If the object can unmarshal itself, let it. | |
398 | if u, ok := pb.(newUnmarshaler); ok { | |
399 | err := u.XXX_Unmarshal(p.buf[p.index:]) | |
400 | p.index = len(p.buf) | |
401 | return err | |
402 | } | |
403 | if u, ok := pb.(Unmarshaler); ok { | |
404 | // NOTE: The history of proto have unfortunately been inconsistent | |
405 | // whether Unmarshaler should or should not implicitly clear itself. | |
406 | // Some implementations do, most do not. | |
407 | // Thus, calling this here may or may not do what people want. | |
408 | // | |
409 | // See https://github.com/golang/protobuf/issues/424 | |
410 | err := u.Unmarshal(p.buf[p.index:]) | |
411 | p.index = len(p.buf) | |
412 | return err | |
413 | } | |
414 | ||
415 | // Slow workaround for messages that aren't Unmarshalers. | |
416 | // This includes some hand-coded .pb.go files and | |
417 | // bootstrap protos. | |
418 | // TODO: fix all of those and then add Unmarshal to | |
419 | // the Message interface. Then: | |
420 | // The cast above and code below can be deleted. | |
421 | // The old unmarshaler can be deleted. | |
422 | // Clients can call Unmarshal directly (can already do that, actually). | |
423 | var info InternalMessageInfo | |
424 | err := info.Unmarshal(pb, p.buf[p.index:]) | |
425 | p.index = len(p.buf) | |
426 | return err | |
427 | } |