blob: 7c2d8416afe8079199f551cae1275ff87563a00f [file] [log] [blame]
David K. Bainbridge528b3182017-01-23 08:51:59 -08001// BSON library for Go
2//
3// Copyright (c) 2010-2012 - Gustavo Niemeyer <gustavo@niemeyer.net>
4//
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are met:
9//
10// 1. Redistributions of source code must retain the above copyright notice, this
11// list of conditions and the following disclaimer.
12// 2. Redistributions in binary form must reproduce the above copyright notice,
13// this list of conditions and the following disclaimer in the documentation
14// and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26// gobson - BSON library for Go.
27
28package bson
29
30import (
31 "fmt"
32 "math"
33 "net/url"
34 "reflect"
35 "strconv"
36 "sync"
37 "time"
38)
39
40type decoder struct {
41 in []byte
42 i int
43 docType reflect.Type
44}
45
46var typeM = reflect.TypeOf(M{})
47
48func newDecoder(in []byte) *decoder {
49 return &decoder{in, 0, typeM}
50}
51
52// --------------------------------------------------------------------------
53// Some helper functions.
54
55func corrupted() {
56 panic("Document is corrupted")
57}
58
59func settableValueOf(i interface{}) reflect.Value {
60 v := reflect.ValueOf(i)
61 sv := reflect.New(v.Type()).Elem()
62 sv.Set(v)
63 return sv
64}
65
66// --------------------------------------------------------------------------
67// Unmarshaling of documents.
68
69const (
70 setterUnknown = iota
71 setterNone
72 setterType
73 setterAddr
74)
75
76var setterStyles map[reflect.Type]int
77var setterIface reflect.Type
78var setterMutex sync.RWMutex
79
80func init() {
81 var iface Setter
82 setterIface = reflect.TypeOf(&iface).Elem()
83 setterStyles = make(map[reflect.Type]int)
84}
85
86func setterStyle(outt reflect.Type) int {
87 setterMutex.RLock()
88 style := setterStyles[outt]
89 setterMutex.RUnlock()
90 if style == setterUnknown {
91 setterMutex.Lock()
92 defer setterMutex.Unlock()
93 if outt.Implements(setterIface) {
94 setterStyles[outt] = setterType
95 } else if reflect.PtrTo(outt).Implements(setterIface) {
96 setterStyles[outt] = setterAddr
97 } else {
98 setterStyles[outt] = setterNone
99 }
100 style = setterStyles[outt]
101 }
102 return style
103}
104
105func getSetter(outt reflect.Type, out reflect.Value) Setter {
106 style := setterStyle(outt)
107 if style == setterNone {
108 return nil
109 }
110 if style == setterAddr {
111 if !out.CanAddr() {
112 return nil
113 }
114 out = out.Addr()
115 } else if outt.Kind() == reflect.Ptr && out.IsNil() {
116 out.Set(reflect.New(outt.Elem()))
117 }
118 return out.Interface().(Setter)
119}
120
121func clearMap(m reflect.Value) {
122 var none reflect.Value
123 for _, k := range m.MapKeys() {
124 m.SetMapIndex(k, none)
125 }
126}
127
128func (d *decoder) readDocTo(out reflect.Value) {
129 var elemType reflect.Type
130 outt := out.Type()
131 outk := outt.Kind()
132
133 for {
134 if outk == reflect.Ptr && out.IsNil() {
135 out.Set(reflect.New(outt.Elem()))
136 }
137 if setter := getSetter(outt, out); setter != nil {
138 var raw Raw
139 d.readDocTo(reflect.ValueOf(&raw))
140 err := setter.SetBSON(raw)
141 if _, ok := err.(*TypeError); err != nil && !ok {
142 panic(err)
143 }
144 return
145 }
146 if outk == reflect.Ptr {
147 out = out.Elem()
148 outt = out.Type()
149 outk = out.Kind()
150 continue
151 }
152 break
153 }
154
155 var fieldsMap map[string]fieldInfo
156 var inlineMap reflect.Value
157 start := d.i
158
159 origout := out
160 if outk == reflect.Interface {
161 if d.docType.Kind() == reflect.Map {
162 mv := reflect.MakeMap(d.docType)
163 out.Set(mv)
164 out = mv
165 } else {
166 dv := reflect.New(d.docType).Elem()
167 out.Set(dv)
168 out = dv
169 }
170 outt = out.Type()
171 outk = outt.Kind()
172 }
173
174 docType := d.docType
175 keyType := typeString
176 convertKey := false
177 switch outk {
178 case reflect.Map:
179 keyType = outt.Key()
180 if keyType.Kind() != reflect.String {
181 panic("BSON map must have string keys. Got: " + outt.String())
182 }
183 if keyType != typeString {
184 convertKey = true
185 }
186 elemType = outt.Elem()
187 if elemType == typeIface {
188 d.docType = outt
189 }
190 if out.IsNil() {
191 out.Set(reflect.MakeMap(out.Type()))
192 } else if out.Len() > 0 {
193 clearMap(out)
194 }
195 case reflect.Struct:
196 if outt != typeRaw {
197 sinfo, err := getStructInfo(out.Type())
198 if err != nil {
199 panic(err)
200 }
201 fieldsMap = sinfo.FieldsMap
202 out.Set(sinfo.Zero)
203 if sinfo.InlineMap != -1 {
204 inlineMap = out.Field(sinfo.InlineMap)
205 if !inlineMap.IsNil() && inlineMap.Len() > 0 {
206 clearMap(inlineMap)
207 }
208 elemType = inlineMap.Type().Elem()
209 if elemType == typeIface {
210 d.docType = inlineMap.Type()
211 }
212 }
213 }
214 case reflect.Slice:
215 switch outt.Elem() {
216 case typeDocElem:
217 origout.Set(d.readDocElems(outt))
218 return
219 case typeRawDocElem:
220 origout.Set(d.readRawDocElems(outt))
221 return
222 }
223 fallthrough
224 default:
225 panic("Unsupported document type for unmarshalling: " + out.Type().String())
226 }
227
228 end := int(d.readInt32())
229 end += d.i - 4
230 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' {
231 corrupted()
232 }
233 for d.in[d.i] != '\x00' {
234 kind := d.readByte()
235 name := d.readCStr()
236 if d.i >= end {
237 corrupted()
238 }
239
240 switch outk {
241 case reflect.Map:
242 e := reflect.New(elemType).Elem()
243 if d.readElemTo(e, kind) {
244 k := reflect.ValueOf(name)
245 if convertKey {
246 k = k.Convert(keyType)
247 }
248 out.SetMapIndex(k, e)
249 }
250 case reflect.Struct:
251 if outt == typeRaw {
252 d.dropElem(kind)
253 } else {
254 if info, ok := fieldsMap[name]; ok {
255 if info.Inline == nil {
256 d.readElemTo(out.Field(info.Num), kind)
257 } else {
258 d.readElemTo(out.FieldByIndex(info.Inline), kind)
259 }
260 } else if inlineMap.IsValid() {
261 if inlineMap.IsNil() {
262 inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
263 }
264 e := reflect.New(elemType).Elem()
265 if d.readElemTo(e, kind) {
266 inlineMap.SetMapIndex(reflect.ValueOf(name), e)
267 }
268 } else {
269 d.dropElem(kind)
270 }
271 }
272 case reflect.Slice:
273 }
274
275 if d.i >= end {
276 corrupted()
277 }
278 }
279 d.i++ // '\x00'
280 if d.i != end {
281 corrupted()
282 }
283 d.docType = docType
284
285 if outt == typeRaw {
286 out.Set(reflect.ValueOf(Raw{0x03, d.in[start:d.i]}))
287 }
288}
289
290func (d *decoder) readArrayDocTo(out reflect.Value) {
291 end := int(d.readInt32())
292 end += d.i - 4
293 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' {
294 corrupted()
295 }
296 i := 0
297 l := out.Len()
298 for d.in[d.i] != '\x00' {
299 if i >= l {
300 panic("Length mismatch on array field")
301 }
302 kind := d.readByte()
303 for d.i < end && d.in[d.i] != '\x00' {
304 d.i++
305 }
306 if d.i >= end {
307 corrupted()
308 }
309 d.i++
310 d.readElemTo(out.Index(i), kind)
311 if d.i >= end {
312 corrupted()
313 }
314 i++
315 }
316 if i != l {
317 panic("Length mismatch on array field")
318 }
319 d.i++ // '\x00'
320 if d.i != end {
321 corrupted()
322 }
323}
324
325func (d *decoder) readSliceDoc(t reflect.Type) interface{} {
326 tmp := make([]reflect.Value, 0, 8)
327 elemType := t.Elem()
328 if elemType == typeRawDocElem {
329 d.dropElem(0x04)
330 return reflect.Zero(t).Interface()
331 }
332
333 end := int(d.readInt32())
334 end += d.i - 4
335 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' {
336 corrupted()
337 }
338 for d.in[d.i] != '\x00' {
339 kind := d.readByte()
340 for d.i < end && d.in[d.i] != '\x00' {
341 d.i++
342 }
343 if d.i >= end {
344 corrupted()
345 }
346 d.i++
347 e := reflect.New(elemType).Elem()
348 if d.readElemTo(e, kind) {
349 tmp = append(tmp, e)
350 }
351 if d.i >= end {
352 corrupted()
353 }
354 }
355 d.i++ // '\x00'
356 if d.i != end {
357 corrupted()
358 }
359
360 n := len(tmp)
361 slice := reflect.MakeSlice(t, n, n)
362 for i := 0; i != n; i++ {
363 slice.Index(i).Set(tmp[i])
364 }
365 return slice.Interface()
366}
367
368var typeSlice = reflect.TypeOf([]interface{}{})
369var typeIface = typeSlice.Elem()
370
371func (d *decoder) readDocElems(typ reflect.Type) reflect.Value {
372 docType := d.docType
373 d.docType = typ
374 slice := make([]DocElem, 0, 8)
375 d.readDocWith(func(kind byte, name string) {
376 e := DocElem{Name: name}
377 v := reflect.ValueOf(&e.Value)
378 if d.readElemTo(v.Elem(), kind) {
379 slice = append(slice, e)
380 }
381 })
382 slicev := reflect.New(typ).Elem()
383 slicev.Set(reflect.ValueOf(slice))
384 d.docType = docType
385 return slicev
386}
387
388func (d *decoder) readRawDocElems(typ reflect.Type) reflect.Value {
389 docType := d.docType
390 d.docType = typ
391 slice := make([]RawDocElem, 0, 8)
392 d.readDocWith(func(kind byte, name string) {
393 e := RawDocElem{Name: name}
394 v := reflect.ValueOf(&e.Value)
395 if d.readElemTo(v.Elem(), kind) {
396 slice = append(slice, e)
397 }
398 })
399 slicev := reflect.New(typ).Elem()
400 slicev.Set(reflect.ValueOf(slice))
401 d.docType = docType
402 return slicev
403}
404
405func (d *decoder) readDocWith(f func(kind byte, name string)) {
406 end := int(d.readInt32())
407 end += d.i - 4
408 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' {
409 corrupted()
410 }
411 for d.in[d.i] != '\x00' {
412 kind := d.readByte()
413 name := d.readCStr()
414 if d.i >= end {
415 corrupted()
416 }
417 f(kind, name)
418 if d.i >= end {
419 corrupted()
420 }
421 }
422 d.i++ // '\x00'
423 if d.i != end {
424 corrupted()
425 }
426}
427
428// --------------------------------------------------------------------------
429// Unmarshaling of individual elements within a document.
430
431var blackHole = settableValueOf(struct{}{})
432
433func (d *decoder) dropElem(kind byte) {
434 d.readElemTo(blackHole, kind)
435}
436
437// Attempt to decode an element from the document and put it into out.
438// If the types are not compatible, the returned ok value will be
439// false and out will be unchanged.
440func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) {
441
442 start := d.i
443
444 if kind == 0x03 {
445 // Delegate unmarshaling of documents.
446 outt := out.Type()
447 outk := out.Kind()
448 switch outk {
449 case reflect.Interface, reflect.Ptr, reflect.Struct, reflect.Map:
450 d.readDocTo(out)
451 return true
452 }
453 if setterStyle(outt) != setterNone {
454 d.readDocTo(out)
455 return true
456 }
457 if outk == reflect.Slice {
458 switch outt.Elem() {
459 case typeDocElem:
460 out.Set(d.readDocElems(outt))
461 case typeRawDocElem:
462 out.Set(d.readRawDocElems(outt))
463 default:
464 d.readDocTo(blackHole)
465 }
466 return true
467 }
468 d.readDocTo(blackHole)
469 return true
470 }
471
472 var in interface{}
473
474 switch kind {
475 case 0x01: // Float64
476 in = d.readFloat64()
477 case 0x02: // UTF-8 string
478 in = d.readStr()
479 case 0x03: // Document
480 panic("Can't happen. Handled above.")
481 case 0x04: // Array
482 outt := out.Type()
483 if setterStyle(outt) != setterNone {
484 // Skip the value so its data is handed to the setter below.
485 d.dropElem(kind)
486 break
487 }
488 for outt.Kind() == reflect.Ptr {
489 outt = outt.Elem()
490 }
491 switch outt.Kind() {
492 case reflect.Array:
493 d.readArrayDocTo(out)
494 return true
495 case reflect.Slice:
496 in = d.readSliceDoc(outt)
497 default:
498 in = d.readSliceDoc(typeSlice)
499 }
500 case 0x05: // Binary
501 b := d.readBinary()
502 if b.Kind == 0x00 || b.Kind == 0x02 {
503 in = b.Data
504 } else {
505 in = b
506 }
507 case 0x06: // Undefined (obsolete, but still seen in the wild)
508 in = Undefined
509 case 0x07: // ObjectId
510 in = ObjectId(d.readBytes(12))
511 case 0x08: // Bool
512 in = d.readBool()
513 case 0x09: // Timestamp
514 // MongoDB handles timestamps as milliseconds.
515 i := d.readInt64()
516 if i == -62135596800000 {
517 in = time.Time{} // In UTC for convenience.
518 } else {
519 in = time.Unix(i/1e3, i%1e3*1e6)
520 }
521 case 0x0A: // Nil
522 in = nil
523 case 0x0B: // RegEx
524 in = d.readRegEx()
525 case 0x0C:
526 in = DBPointer{Namespace: d.readStr(), Id: ObjectId(d.readBytes(12))}
527 case 0x0D: // JavaScript without scope
528 in = JavaScript{Code: d.readStr()}
529 case 0x0E: // Symbol
530 in = Symbol(d.readStr())
531 case 0x0F: // JavaScript with scope
532 d.i += 4 // Skip length
533 js := JavaScript{d.readStr(), make(M)}
534 d.readDocTo(reflect.ValueOf(js.Scope))
535 in = js
536 case 0x10: // Int32
537 in = int(d.readInt32())
538 case 0x11: // Mongo-specific timestamp
539 in = MongoTimestamp(d.readInt64())
540 case 0x12: // Int64
541 in = d.readInt64()
542 case 0x13: // Decimal128
543 in = Decimal128{
544 l: uint64(d.readInt64()),
545 h: uint64(d.readInt64()),
546 }
547 case 0x7F: // Max key
548 in = MaxKey
549 case 0xFF: // Min key
550 in = MinKey
551 default:
552 panic(fmt.Sprintf("Unknown element kind (0x%02X)", kind))
553 }
554
555 outt := out.Type()
556
557 if outt == typeRaw {
558 out.Set(reflect.ValueOf(Raw{kind, d.in[start:d.i]}))
559 return true
560 }
561
562 if setter := getSetter(outt, out); setter != nil {
563 err := setter.SetBSON(Raw{kind, d.in[start:d.i]})
564 if err == SetZero {
565 out.Set(reflect.Zero(outt))
566 return true
567 }
568 if err == nil {
569 return true
570 }
571 if _, ok := err.(*TypeError); !ok {
572 panic(err)
573 }
574 return false
575 }
576
577 if in == nil {
578 out.Set(reflect.Zero(outt))
579 return true
580 }
581
582 outk := outt.Kind()
583
584 // Dereference and initialize pointer if necessary.
585 first := true
586 for outk == reflect.Ptr {
587 if !out.IsNil() {
588 out = out.Elem()
589 } else {
590 elem := reflect.New(outt.Elem())
591 if first {
592 // Only set if value is compatible.
593 first = false
594 defer func(out, elem reflect.Value) {
595 if good {
596 out.Set(elem)
597 }
598 }(out, elem)
599 } else {
600 out.Set(elem)
601 }
602 out = elem
603 }
604 outt = out.Type()
605 outk = outt.Kind()
606 }
607
608 inv := reflect.ValueOf(in)
609 if outt == inv.Type() {
610 out.Set(inv)
611 return true
612 }
613
614 switch outk {
615 case reflect.Interface:
616 out.Set(inv)
617 return true
618 case reflect.String:
619 switch inv.Kind() {
620 case reflect.String:
621 out.SetString(inv.String())
622 return true
623 case reflect.Slice:
624 if b, ok := in.([]byte); ok {
625 out.SetString(string(b))
626 return true
627 }
628 case reflect.Int, reflect.Int64:
629 if outt == typeJSONNumber {
630 out.SetString(strconv.FormatInt(inv.Int(), 10))
631 return true
632 }
633 case reflect.Float64:
634 if outt == typeJSONNumber {
635 out.SetString(strconv.FormatFloat(inv.Float(), 'f', -1, 64))
636 return true
637 }
638 }
639 case reflect.Slice, reflect.Array:
640 // Remember, array (0x04) slices are built with the correct
641 // element type. If we are here, must be a cross BSON kind
642 // conversion (e.g. 0x05 unmarshalling on string).
643 if outt.Elem().Kind() != reflect.Uint8 {
644 break
645 }
646 switch inv.Kind() {
647 case reflect.String:
648 slice := []byte(inv.String())
649 out.Set(reflect.ValueOf(slice))
650 return true
651 case reflect.Slice:
652 switch outt.Kind() {
653 case reflect.Array:
654 reflect.Copy(out, inv)
655 case reflect.Slice:
656 out.SetBytes(inv.Bytes())
657 }
658 return true
659 }
660 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
661 switch inv.Kind() {
662 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
663 out.SetInt(inv.Int())
664 return true
665 case reflect.Float32, reflect.Float64:
666 out.SetInt(int64(inv.Float()))
667 return true
668 case reflect.Bool:
669 if inv.Bool() {
670 out.SetInt(1)
671 } else {
672 out.SetInt(0)
673 }
674 return true
675 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
676 panic("can't happen: no uint types in BSON (!?)")
677 }
678 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
679 switch inv.Kind() {
680 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
681 out.SetUint(uint64(inv.Int()))
682 return true
683 case reflect.Float32, reflect.Float64:
684 out.SetUint(uint64(inv.Float()))
685 return true
686 case reflect.Bool:
687 if inv.Bool() {
688 out.SetUint(1)
689 } else {
690 out.SetUint(0)
691 }
692 return true
693 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
694 panic("Can't happen. No uint types in BSON.")
695 }
696 case reflect.Float32, reflect.Float64:
697 switch inv.Kind() {
698 case reflect.Float32, reflect.Float64:
699 out.SetFloat(inv.Float())
700 return true
701 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
702 out.SetFloat(float64(inv.Int()))
703 return true
704 case reflect.Bool:
705 if inv.Bool() {
706 out.SetFloat(1)
707 } else {
708 out.SetFloat(0)
709 }
710 return true
711 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
712 panic("Can't happen. No uint types in BSON?")
713 }
714 case reflect.Bool:
715 switch inv.Kind() {
716 case reflect.Bool:
717 out.SetBool(inv.Bool())
718 return true
719 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
720 out.SetBool(inv.Int() != 0)
721 return true
722 case reflect.Float32, reflect.Float64:
723 out.SetBool(inv.Float() != 0)
724 return true
725 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
726 panic("Can't happen. No uint types in BSON?")
727 }
728 case reflect.Struct:
729 if outt == typeURL && inv.Kind() == reflect.String {
730 u, err := url.Parse(inv.String())
731 if err != nil {
732 panic(err)
733 }
734 out.Set(reflect.ValueOf(u).Elem())
735 return true
736 }
737 if outt == typeBinary {
738 if b, ok := in.([]byte); ok {
739 out.Set(reflect.ValueOf(Binary{Data: b}))
740 return true
741 }
742 }
743 }
744
745 return false
746}
747
748// --------------------------------------------------------------------------
749// Parsers of basic types.
750
751func (d *decoder) readRegEx() RegEx {
752 re := RegEx{}
753 re.Pattern = d.readCStr()
754 re.Options = d.readCStr()
755 return re
756}
757
758func (d *decoder) readBinary() Binary {
759 l := d.readInt32()
760 b := Binary{}
761 b.Kind = d.readByte()
762 b.Data = d.readBytes(l)
763 if b.Kind == 0x02 && len(b.Data) >= 4 {
764 // Weird obsolete format with redundant length.
765 b.Data = b.Data[4:]
766 }
767 return b
768}
769
770func (d *decoder) readStr() string {
771 l := d.readInt32()
772 b := d.readBytes(l - 1)
773 if d.readByte() != '\x00' {
774 corrupted()
775 }
776 return string(b)
777}
778
779func (d *decoder) readCStr() string {
780 start := d.i
781 end := start
782 l := len(d.in)
783 for ; end != l; end++ {
784 if d.in[end] == '\x00' {
785 break
786 }
787 }
788 d.i = end + 1
789 if d.i > l {
790 corrupted()
791 }
792 return string(d.in[start:end])
793}
794
795func (d *decoder) readBool() bool {
796 b := d.readByte()
797 if b == 0 {
798 return false
799 }
800 if b == 1 {
801 return true
802 }
803 panic(fmt.Sprintf("encoded boolean must be 1 or 0, found %d", b))
804}
805
806func (d *decoder) readFloat64() float64 {
807 return math.Float64frombits(uint64(d.readInt64()))
808}
809
810func (d *decoder) readInt32() int32 {
811 b := d.readBytes(4)
812 return int32((uint32(b[0]) << 0) |
813 (uint32(b[1]) << 8) |
814 (uint32(b[2]) << 16) |
815 (uint32(b[3]) << 24))
816}
817
818func (d *decoder) readInt64() int64 {
819 b := d.readBytes(8)
820 return int64((uint64(b[0]) << 0) |
821 (uint64(b[1]) << 8) |
822 (uint64(b[2]) << 16) |
823 (uint64(b[3]) << 24) |
824 (uint64(b[4]) << 32) |
825 (uint64(b[5]) << 40) |
826 (uint64(b[6]) << 48) |
827 (uint64(b[7]) << 56))
828}
829
830func (d *decoder) readByte() byte {
831 i := d.i
832 d.i++
833 if d.i > len(d.in) {
834 corrupted()
835 }
836 return d.in[i]
837}
838
839func (d *decoder) readBytes(length int32) []byte {
840 if length < 0 {
841 corrupted()
842 }
843 start := d.i
844 d.i += int(length)
845 if d.i < start || d.i > len(d.in) {
846 corrupted()
847 }
848 return d.in[start : start+int(length)]
849}