1// 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 "errors" 32 "fmt" 33 "io" 34 "math" 35 "net/url" 36 "reflect" 37 "strconv" 38 "sync" 39 "time" 40) 41 42type decoder struct { 43 in []byte 44 i int 45 docType reflect.Type 46} 47 48var typeM = reflect.TypeOf(M{}) 49 50func newDecoder(in []byte) *decoder { 51 return &decoder{in, 0, typeM} 52} 53 54// -------------------------------------------------------------------------- 55// Some helper functions. 56 57func corrupted() { 58 panic("Document is corrupted") 59} 60 61// -------------------------------------------------------------------------- 62// Unmarshaling of documents. 63 64const ( 65 setterUnknown = iota 66 setterNone 67 setterType 68 setterAddr 69) 70 71var setterStyles map[reflect.Type]int 72var setterIface reflect.Type 73var setterMutex sync.RWMutex 74 75func init() { 76 var iface Setter 77 setterIface = reflect.TypeOf(&iface).Elem() 78 setterStyles = make(map[reflect.Type]int) 79} 80 81func setterStyle(outt reflect.Type) int { 82 setterMutex.RLock() 83 style := setterStyles[outt] 84 setterMutex.RUnlock() 85 if style != setterUnknown { 86 return style 87 } 88 89 setterMutex.Lock() 90 defer setterMutex.Unlock() 91 if outt.Implements(setterIface) { 92 style = setterType 93 } else if reflect.PtrTo(outt).Implements(setterIface) { 94 style = setterAddr 95 } else { 96 style = setterNone 97 } 98 setterStyles[outt] = style 99 return style 100} 101 102func getSetter(outt reflect.Type, out reflect.Value) Setter { 103 style := setterStyle(outt) 104 if style == setterNone { 105 return nil 106 } 107 if style == setterAddr { 108 if !out.CanAddr() { 109 return nil 110 } 111 out = out.Addr() 112 } else if outt.Kind() == reflect.Ptr && out.IsNil() { 113 out.Set(reflect.New(outt.Elem())) 114 } 115 return out.Interface().(Setter) 116} 117 118func clearMap(m reflect.Value) { 119 var none reflect.Value 120 for _, k := range m.MapKeys() { 121 m.SetMapIndex(k, none) 122 } 123} 124 125func (d *decoder) readDocTo(out reflect.Value) { 126 var elemType reflect.Type 127 outt := out.Type() 128 outk := outt.Kind() 129 130 for { 131 if outk == reflect.Ptr && out.IsNil() { 132 out.Set(reflect.New(outt.Elem())) 133 } 134 if setter := getSetter(outt, out); setter != nil { 135 raw := d.readRaw(ElementDocument) 136 err := setter.SetBSON(raw) 137 if _, ok := err.(*TypeError); err != nil && !ok { 138 panic(err) 139 } 140 return 141 } 142 if outk == reflect.Ptr { 143 out = out.Elem() 144 outt = out.Type() 145 outk = out.Kind() 146 continue 147 } 148 break 149 } 150 151 var fieldsMap map[string]fieldInfo 152 var inlineMap reflect.Value 153 if outt == typeRaw { 154 out.Set(reflect.ValueOf(d.readRaw(ElementDocument))) 155 return 156 } 157 158 origout := out 159 if outk == reflect.Interface { 160 if d.docType.Kind() == reflect.Map { 161 mv := reflect.MakeMap(d.docType) 162 out.Set(mv) 163 out = mv 164 } else { 165 dv := reflect.New(d.docType).Elem() 166 out.Set(dv) 167 out = dv 168 } 169 outt = out.Type() 170 outk = outt.Kind() 171 } 172 173 docType := d.docType 174 keyType := typeString 175 convertKey := false 176 switch outk { 177 case reflect.Map: 178 keyType = outt.Key() 179 if keyType != typeString { 180 convertKey = true 181 } 182 elemType = outt.Elem() 183 if elemType == typeIface { 184 d.docType = outt 185 } 186 if out.IsNil() { 187 out.Set(reflect.MakeMap(out.Type())) 188 } else if out.Len() > 0 { 189 clearMap(out) 190 } 191 case reflect.Struct: 192 sinfo, err := getStructInfo(out.Type()) 193 if err != nil { 194 panic(err) 195 } 196 fieldsMap = sinfo.FieldsMap 197 out.Set(sinfo.Zero) 198 if sinfo.InlineMap != -1 { 199 inlineMap = out.Field(sinfo.InlineMap) 200 if !inlineMap.IsNil() && inlineMap.Len() > 0 { 201 clearMap(inlineMap) 202 } 203 elemType = inlineMap.Type().Elem() 204 if elemType == typeIface { 205 d.docType = inlineMap.Type() 206 } 207 } 208 case reflect.Slice: 209 switch outt.Elem() { 210 case typeDocElem: 211 origout.Set(d.readDocElems(outt)) 212 return 213 case typeRawDocElem: 214 origout.Set(d.readRawDocElems(outt)) 215 return 216 } 217 fallthrough 218 default: 219 panic("Unsupported document type for unmarshalling: " + out.Type().String()) 220 } 221 222 end := int(d.readInt32()) 223 end += d.i - 4 224 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { 225 corrupted() 226 } 227 for d.in[d.i] != '\x00' { 228 kind := d.readByte() 229 name := d.readCStr() 230 if d.i >= end { 231 corrupted() 232 } 233 234 switch outk { 235 case reflect.Map: 236 e := reflect.New(elemType).Elem() 237 if d.readElemTo(e, kind) { 238 k := reflect.ValueOf(name) 239 if convertKey { 240 mapKeyType := out.Type().Key() 241 mapKeyKind := mapKeyType.Kind() 242 243 switch mapKeyKind { 244 case reflect.Int: 245 fallthrough 246 case reflect.Int8: 247 fallthrough 248 case reflect.Int16: 249 fallthrough 250 case reflect.Int32: 251 fallthrough 252 case reflect.Int64: 253 fallthrough 254 case reflect.Uint: 255 fallthrough 256 case reflect.Uint8: 257 fallthrough 258 case reflect.Uint16: 259 fallthrough 260 case reflect.Uint32: 261 fallthrough 262 case reflect.Uint64: 263 fallthrough 264 case reflect.Float32: 265 fallthrough 266 case reflect.Float64: 267 parsed := d.parseMapKeyAsFloat(k, mapKeyKind) 268 k = reflect.ValueOf(parsed) 269 case reflect.String: 270 mapKeyType = keyType 271 default: 272 panic("BSON map must have string or decimal keys. Got: " + outt.String()) 273 } 274 275 k = k.Convert(mapKeyType) 276 } 277 out.SetMapIndex(k, e) 278 } 279 case reflect.Struct: 280 if info, ok := fieldsMap[name]; ok { 281 if info.Inline == nil { 282 d.readElemTo(out.Field(info.Num), kind) 283 } else { 284 d.readElemTo(out.FieldByIndex(info.Inline), kind) 285 } 286 } else if inlineMap.IsValid() { 287 if inlineMap.IsNil() { 288 inlineMap.Set(reflect.MakeMap(inlineMap.Type())) 289 } 290 e := reflect.New(elemType).Elem() 291 if d.readElemTo(e, kind) { 292 inlineMap.SetMapIndex(reflect.ValueOf(name), e) 293 } 294 } else { 295 d.dropElem(kind) 296 } 297 case reflect.Slice: 298 } 299 300 if d.i >= end { 301 corrupted() 302 } 303 } 304 d.i++ // '\x00' 305 if d.i != end { 306 corrupted() 307 } 308 d.docType = docType 309} 310 311func (decoder) parseMapKeyAsFloat(k reflect.Value, mapKeyKind reflect.Kind) float64 { 312 parsed, err := strconv.ParseFloat(k.String(), 64) 313 if err != nil { 314 panic("Map key is defined to be a decimal type (" + mapKeyKind.String() + ") but got error " + 315 err.Error()) 316 } 317 318 return parsed 319} 320 321func (d *decoder) readArrayDocTo(out reflect.Value) { 322 end := int(d.readInt32()) 323 end += d.i - 4 324 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { 325 corrupted() 326 } 327 i := 0 328 l := out.Len() 329 for d.in[d.i] != '\x00' { 330 if i >= l { 331 panic("Length mismatch on array field") 332 } 333 kind := d.readByte() 334 for d.i < end && d.in[d.i] != '\x00' { 335 d.i++ 336 } 337 if d.i >= end { 338 corrupted() 339 } 340 d.i++ 341 d.readElemTo(out.Index(i), kind) 342 if d.i >= end { 343 corrupted() 344 } 345 i++ 346 } 347 if i != l { 348 panic("Length mismatch on array field") 349 } 350 d.i++ // '\x00' 351 if d.i != end { 352 corrupted() 353 } 354} 355 356func (d *decoder) readSliceDoc(t reflect.Type) interface{} { 357 tmp := make([]reflect.Value, 0, 8) 358 elemType := t.Elem() 359 if elemType == typeRawDocElem { 360 d.dropElem(ElementArray) 361 return reflect.Zero(t).Interface() 362 } 363 if elemType == typeRaw { 364 return d.readSliceOfRaw() 365 } 366 367 end := int(d.readInt32()) 368 end += d.i - 4 369 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { 370 corrupted() 371 } 372 for d.in[d.i] != '\x00' { 373 kind := d.readByte() 374 for d.i < end && d.in[d.i] != '\x00' { 375 d.i++ 376 } 377 if d.i >= end { 378 corrupted() 379 } 380 d.i++ 381 e := reflect.New(elemType).Elem() 382 if d.readElemTo(e, kind) { 383 tmp = append(tmp, e) 384 } 385 if d.i >= end { 386 corrupted() 387 } 388 } 389 d.i++ // '\x00' 390 if d.i != end { 391 corrupted() 392 } 393 394 n := len(tmp) 395 slice := reflect.MakeSlice(t, n, n) 396 for i := 0; i != n; i++ { 397 slice.Index(i).Set(tmp[i]) 398 } 399 return slice.Interface() 400} 401 402func BSONElementSize(kind byte, offset int, buffer []byte) (int, error) { 403 switch kind { 404 case ElementFloat64: // Float64 405 return 8, nil 406 case ElementJavaScriptWithoutScope: // JavaScript without scope 407 fallthrough 408 case ElementSymbol: // Symbol 409 fallthrough 410 case ElementString: // UTF-8 string 411 size, err := getSize(offset, buffer) 412 if err != nil { 413 return 0, err 414 } 415 if size < 1 { 416 return 0, errors.New("String size can't be less then one byte") 417 } 418 size += 4 419 if offset+size > len(buffer) { 420 return 0, io.ErrUnexpectedEOF 421 } 422 if buffer[offset+size-1] != 0 { 423 return 0, errors.New("Invalid string: non zero-terminated") 424 } 425 return size, nil 426 case ElementArray: // Array 427 fallthrough 428 case ElementDocument: // Document 429 size, err := getSize(offset, buffer) 430 if err != nil { 431 return 0, err 432 } 433 if size < 5 { 434 return 0, errors.New("Declared document size is too small") 435 } 436 return size, nil 437 case ElementBinary: // Binary 438 size, err := getSize(offset, buffer) 439 if err != nil { 440 return 0, err 441 } 442 if size < 0 { 443 return 0, errors.New("Binary data size can't be negative") 444 } 445 return size + 5, nil 446 case Element06: // Undefined (obsolete, but still seen in the wild) 447 return 0, nil 448 case ElementObjectId: // ObjectId 449 return 12, nil 450 case ElementBool: // Bool 451 return 1, nil 452 case ElementDatetime: // Timestamp 453 return 8, nil 454 case ElementNil: // Nil 455 return 0, nil 456 case ElementRegEx: // RegEx 457 end := offset 458 for i := 0; i < 2; i++ { 459 for end < len(buffer) && buffer[end] != '\x00' { 460 end++ 461 } 462 end++ 463 } 464 if end > len(buffer) { 465 return 0, io.ErrUnexpectedEOF 466 } 467 return end - offset, nil 468 case ElementDBPointer: // DBPointer 469 size, err := getSize(offset, buffer) 470 if err != nil { 471 return 0, err 472 } 473 if size < 1 { 474 return 0, errors.New("String size can't be less then one byte") 475 } 476 return size + 12 + 4, nil 477 case ElementJavaScriptWithScope: // JavaScript with scope 478 size, err := getSize(offset, buffer) 479 if err != nil { 480 return 0, err 481 } 482 if size < 4+5+5 { 483 return 0, errors.New("Declared document element is too small") 484 } 485 return size, nil 486 case ElementInt32: // Int32 487 return 4, nil 488 case ElementTimestamp: // Mongo-specific timestamp 489 return 8, nil 490 case ElementInt64: // Int64 491 return 8, nil 492 case ElementDecimal128: // Decimal128 493 return 16, nil 494 case ElementMaxKey: // Max key 495 return 0, nil 496 case ElementMinKey: // Min key 497 return 0, nil 498 default: 499 return 0, errors.New(fmt.Sprintf("Unknown element kind (0x%02X)", kind)) 500 } 501} 502 503func (d *decoder) readRaw(kind byte) Raw { 504 size, err := BSONElementSize(kind, d.i, d.in) 505 if err != nil { 506 corrupted() 507 } 508 if d.i+size > len(d.in) { 509 corrupted() 510 } 511 d.i += size 512 return Raw{ 513 Kind: kind, 514 Data: d.in[d.i-size : d.i], 515 } 516} 517 518func (d *decoder) readSliceOfRaw() interface{} { 519 tmp := make([]Raw, 0, 8) 520 end := int(d.readInt32()) 521 end += d.i - 4 522 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { 523 corrupted() 524 } 525 for d.in[d.i] != '\x00' { 526 kind := d.readByte() 527 for d.i < end && d.in[d.i] != '\x00' { 528 d.i++ 529 } 530 if d.i >= end { 531 corrupted() 532 } 533 d.i++ 534 e := d.readRaw(kind) 535 tmp = append(tmp, e) 536 if d.i >= end { 537 corrupted() 538 } 539 } 540 d.i++ // '\x00' 541 if d.i != end { 542 corrupted() 543 } 544 return tmp 545} 546 547var typeSlice = reflect.TypeOf([]interface{}{}) 548var typeIface = typeSlice.Elem() 549 550func (d *decoder) readDocElems(typ reflect.Type) reflect.Value { 551 docType := d.docType 552 d.docType = typ 553 slice := make([]DocElem, 0, 8) 554 d.readDocWith(func(kind byte, name string) { 555 e := DocElem{Name: name} 556 v := reflect.ValueOf(&e.Value) 557 if d.readElemTo(v.Elem(), kind) { 558 slice = append(slice, e) 559 } 560 }) 561 slicev := reflect.New(typ).Elem() 562 slicev.Set(reflect.ValueOf(slice)) 563 d.docType = docType 564 return slicev 565} 566 567func (d *decoder) readRawDocElems(typ reflect.Type) reflect.Value { 568 docType := d.docType 569 d.docType = typ 570 slice := make([]RawDocElem, 0, 8) 571 d.readDocWith(func(kind byte, name string) { 572 e := RawDocElem{Name: name, Value: d.readRaw(kind)} 573 slice = append(slice, e) 574 }) 575 slicev := reflect.New(typ).Elem() 576 slicev.Set(reflect.ValueOf(slice)) 577 d.docType = docType 578 return slicev 579} 580 581func (d *decoder) readDocWith(f func(kind byte, name string)) { 582 end := int(d.readInt32()) 583 end += d.i - 4 584 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { 585 corrupted() 586 } 587 for d.in[d.i] != '\x00' { 588 kind := d.readByte() 589 name := d.readCStr() 590 if d.i >= end { 591 corrupted() 592 } 593 f(kind, name) 594 if d.i >= end { 595 corrupted() 596 } 597 } 598 d.i++ // '\x00' 599 if d.i != end { 600 corrupted() 601 } 602} 603 604// -------------------------------------------------------------------------- 605// Unmarshaling of individual elements within a document. 606func (d *decoder) dropElem(kind byte) { 607 size, err := BSONElementSize(kind, d.i, d.in) 608 if err != nil { 609 corrupted() 610 } 611 if d.i+size > len(d.in) { 612 corrupted() 613 } 614 d.i += size 615} 616 617// Attempt to decode an element from the document and put it into out. 618// If the types are not compatible, the returned ok value will be 619// false and out will be unchanged. 620func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) { 621 outt := out.Type() 622 623 if outt == typeRaw { 624 out.Set(reflect.ValueOf(d.readRaw(kind))) 625 return true 626 } 627 628 if outt == typeRawPtr { 629 raw := d.readRaw(kind) 630 out.Set(reflect.ValueOf(&raw)) 631 return true 632 } 633 634 if kind == ElementDocument { 635 // Delegate unmarshaling of documents. 636 outt := out.Type() 637 outk := out.Kind() 638 switch outk { 639 case reflect.Interface, reflect.Ptr, reflect.Struct, reflect.Map: 640 d.readDocTo(out) 641 return true 642 } 643 if setterStyle(outt) != setterNone { 644 d.readDocTo(out) 645 return true 646 } 647 if outk == reflect.Slice { 648 switch outt.Elem() { 649 case typeDocElem: 650 out.Set(d.readDocElems(outt)) 651 case typeRawDocElem: 652 out.Set(d.readRawDocElems(outt)) 653 default: 654 d.dropElem(kind) 655 } 656 return true 657 } 658 d.dropElem(kind) 659 return true 660 } 661 662 if setter := getSetter(outt, out); setter != nil { 663 err := setter.SetBSON(d.readRaw(kind)) 664 if err == ErrSetZero { 665 out.Set(reflect.Zero(outt)) 666 return true 667 } 668 if err == nil { 669 return true 670 } 671 if _, ok := err.(*TypeError); !ok { 672 panic(err) 673 } 674 return false 675 } 676 677 var in interface{} 678 679 switch kind { 680 case ElementFloat64: 681 in = d.readFloat64() 682 case ElementString: 683 in = d.readStr() 684 case ElementDocument: 685 panic("Can't happen. Handled above.") 686 case ElementArray: 687 outt := out.Type() 688 if setterStyle(outt) != setterNone { 689 // Skip the value so its data is handed to the setter below. 690 d.dropElem(kind) 691 break 692 } 693 for outt.Kind() == reflect.Ptr { 694 outt = outt.Elem() 695 } 696 switch outt.Kind() { 697 case reflect.Array: 698 d.readArrayDocTo(out) 699 return true 700 case reflect.Slice: 701 in = d.readSliceDoc(outt) 702 default: 703 in = d.readSliceDoc(typeSlice) 704 } 705 case ElementBinary: 706 b := d.readBinary() 707 if b.Kind == BinaryGeneric || b.Kind == BinaryBinaryOld { 708 in = b.Data 709 } else { 710 in = b 711 } 712 case Element06: // Undefined (obsolete, but still seen in the wild) 713 in = Undefined 714 case ElementObjectId: 715 in = ObjectId(d.readBytes(12)) 716 case ElementBool: 717 in = d.readBool() 718 case ElementDatetime: // Timestamp 719 // MongoDB handles timestamps as milliseconds. 720 i := d.readInt64() 721 if i == -62135596800000 { 722 in = time.Time{} // In UTC for convenience. 723 } else { 724 in = time.Unix(i/1e3, i%1e3*1e6).UTC() 725 } 726 case ElementNil: 727 in = nil 728 case ElementRegEx: 729 in = d.readRegEx() 730 case ElementDBPointer: 731 in = DBPointer{Namespace: d.readStr(), Id: ObjectId(d.readBytes(12))} 732 case ElementJavaScriptWithoutScope: 733 in = JavaScript{Code: d.readStr()} 734 case ElementSymbol: 735 in = Symbol(d.readStr()) 736 case ElementJavaScriptWithScope: 737 start := d.i 738 l := int(d.readInt32()) 739 js := JavaScript{d.readStr(), make(M)} 740 d.readDocTo(reflect.ValueOf(js.Scope)) 741 if d.i != start+l { 742 corrupted() 743 } 744 in = js 745 case ElementInt32: 746 in = int(d.readInt32()) 747 case ElementTimestamp: // Mongo-specific timestamp 748 in = MongoTimestamp(d.readInt64()) 749 case ElementInt64: 750 switch out.Type() { 751 case typeTimeDuration: 752 in = time.Duration(time.Duration(d.readInt64()) * time.Millisecond) 753 default: 754 in = d.readInt64() 755 } 756 case ElementDecimal128: 757 in = Decimal128{ 758 l: uint64(d.readInt64()), 759 h: uint64(d.readInt64()), 760 } 761 case ElementMaxKey: 762 in = MaxKey 763 case ElementMinKey: 764 in = MinKey 765 default: 766 panic(fmt.Sprintf("Unknown element kind (0x%02X)", kind)) 767 } 768 769 if in == nil { 770 out.Set(reflect.Zero(outt)) 771 return true 772 } 773 774 outk := outt.Kind() 775 776 // Dereference and initialize pointer if necessary. 777 first := true 778 for outk == reflect.Ptr { 779 if !out.IsNil() { 780 out = out.Elem() 781 } else { 782 elem := reflect.New(outt.Elem()) 783 if first { 784 // Only set if value is compatible. 785 first = false 786 defer func(out, elem reflect.Value) { 787 if good { 788 out.Set(elem) 789 } 790 }(out, elem) 791 } else { 792 out.Set(elem) 793 } 794 out = elem 795 } 796 outt = out.Type() 797 outk = outt.Kind() 798 } 799 800 inv := reflect.ValueOf(in) 801 if outt == inv.Type() { 802 out.Set(inv) 803 return true 804 } 805 806 switch outk { 807 case reflect.Interface: 808 out.Set(inv) 809 return true 810 case reflect.String: 811 switch inv.Kind() { 812 case reflect.String: 813 out.SetString(inv.String()) 814 return true 815 case reflect.Slice: 816 if b, ok := in.([]byte); ok { 817 out.SetString(string(b)) 818 return true 819 } 820 case reflect.Int, reflect.Int64: 821 if outt == typeJSONNumber { 822 out.SetString(strconv.FormatInt(inv.Int(), 10)) 823 return true 824 } 825 case reflect.Float64: 826 if outt == typeJSONNumber { 827 out.SetString(strconv.FormatFloat(inv.Float(), 'f', -1, 64)) 828 return true 829 } 830 } 831 case reflect.Slice, reflect.Array: 832 // Remember, array (0x04) slices are built with the correct 833 // element type. If we are here, must be a cross BSON kind 834 // conversion (e.g. 0x05 unmarshalling on string). 835 if outt.Elem().Kind() != reflect.Uint8 { 836 break 837 } 838 switch inv.Kind() { 839 case reflect.String: 840 slice := []byte(inv.String()) 841 out.Set(reflect.ValueOf(slice)) 842 return true 843 case reflect.Slice: 844 switch outt.Kind() { 845 case reflect.Array: 846 reflect.Copy(out, inv) 847 case reflect.Slice: 848 out.SetBytes(inv.Bytes()) 849 } 850 return true 851 } 852 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 853 switch inv.Kind() { 854 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 855 out.SetInt(inv.Int()) 856 return true 857 case reflect.Float32, reflect.Float64: 858 out.SetInt(int64(inv.Float())) 859 return true 860 case reflect.Bool: 861 if inv.Bool() { 862 out.SetInt(1) 863 } else { 864 out.SetInt(0) 865 } 866 return true 867 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 868 panic("can't happen: no uint types in BSON (!?)") 869 } 870 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 871 switch inv.Kind() { 872 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 873 out.SetUint(uint64(inv.Int())) 874 return true 875 case reflect.Float32, reflect.Float64: 876 out.SetUint(uint64(inv.Float())) 877 return true 878 case reflect.Bool: 879 if inv.Bool() { 880 out.SetUint(1) 881 } else { 882 out.SetUint(0) 883 } 884 return true 885 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 886 panic("Can't happen. No uint types in BSON.") 887 } 888 case reflect.Float32, reflect.Float64: 889 switch inv.Kind() { 890 case reflect.Float32, reflect.Float64: 891 out.SetFloat(inv.Float()) 892 return true 893 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 894 out.SetFloat(float64(inv.Int())) 895 return true 896 case reflect.Bool: 897 if inv.Bool() { 898 out.SetFloat(1) 899 } else { 900 out.SetFloat(0) 901 } 902 return true 903 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 904 panic("Can't happen. No uint types in BSON?") 905 } 906 case reflect.Bool: 907 switch inv.Kind() { 908 case reflect.Bool: 909 out.SetBool(inv.Bool()) 910 return true 911 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 912 out.SetBool(inv.Int() != 0) 913 return true 914 case reflect.Float32, reflect.Float64: 915 out.SetBool(inv.Float() != 0) 916 return true 917 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 918 panic("Can't happen. No uint types in BSON?") 919 } 920 case reflect.Struct: 921 if outt == typeURL && inv.Kind() == reflect.String { 922 u, err := url.Parse(inv.String()) 923 if err != nil { 924 panic(err) 925 } 926 out.Set(reflect.ValueOf(u).Elem()) 927 return true 928 } 929 if outt == typeBinary { 930 if b, ok := in.([]byte); ok { 931 out.Set(reflect.ValueOf(Binary{Data: b})) 932 return true 933 } 934 } 935 } 936 937 return false 938} 939 940// -------------------------------------------------------------------------- 941// Parsers of basic types. 942 943func (d *decoder) readRegEx() RegEx { 944 re := RegEx{} 945 re.Pattern = d.readCStr() 946 re.Options = d.readCStr() 947 return re 948} 949 950func (d *decoder) readBinary() Binary { 951 l := d.readInt32() 952 b := Binary{} 953 b.Kind = d.readByte() 954 if b.Kind == BinaryBinaryOld && l > 4 { 955 // Weird obsolete format with redundant length. 956 rl := d.readInt32() 957 if rl != l-4 { 958 corrupted() 959 } 960 l = rl 961 } 962 b.Data = d.readBytes(l) 963 return b 964} 965 966func (d *decoder) readStr() string { 967 l := d.readInt32() 968 b := d.readBytes(l - 1) 969 if d.readByte() != '\x00' { 970 corrupted() 971 } 972 return string(b) 973} 974 975func (d *decoder) readCStr() string { 976 start := d.i 977 end := start 978 l := len(d.in) 979 for ; end != l; end++ { 980 if d.in[end] == '\x00' { 981 break 982 } 983 } 984 d.i = end + 1 985 if d.i > l { 986 corrupted() 987 } 988 return string(d.in[start:end]) 989} 990 991func (d *decoder) readBool() bool { 992 b := d.readByte() 993 if b == 0 { 994 return false 995 } 996 if b == 1 { 997 return true 998 } 999 panic(fmt.Sprintf("encoded boolean must be 1 or 0, found %d", b)) 1000} 1001 1002func (d *decoder) readFloat64() float64 { 1003 return math.Float64frombits(uint64(d.readInt64())) 1004} 1005 1006func (d *decoder) readInt32() int32 { 1007 b := d.readBytes(4) 1008 return int32((uint32(b[0]) << 0) | 1009 (uint32(b[1]) << 8) | 1010 (uint32(b[2]) << 16) | 1011 (uint32(b[3]) << 24)) 1012} 1013 1014func getSize(offset int, b []byte) (int, error) { 1015 if offset+4 > len(b) { 1016 return 0, io.ErrUnexpectedEOF 1017 } 1018 return int((uint32(b[offset]) << 0) | 1019 (uint32(b[offset+1]) << 8) | 1020 (uint32(b[offset+2]) << 16) | 1021 (uint32(b[offset+3]) << 24)), nil 1022} 1023 1024func (d *decoder) readInt64() int64 { 1025 b := d.readBytes(8) 1026 return int64((uint64(b[0]) << 0) | 1027 (uint64(b[1]) << 8) | 1028 (uint64(b[2]) << 16) | 1029 (uint64(b[3]) << 24) | 1030 (uint64(b[4]) << 32) | 1031 (uint64(b[5]) << 40) | 1032 (uint64(b[6]) << 48) | 1033 (uint64(b[7]) << 56)) 1034} 1035 1036func (d *decoder) readByte() byte { 1037 i := d.i 1038 d.i++ 1039 if d.i > len(d.in) { 1040 corrupted() 1041 } 1042 return d.in[i] 1043} 1044 1045func (d *decoder) readBytes(length int32) []byte { 1046 if length < 0 { 1047 corrupted() 1048 } 1049 start := d.i 1050 d.i += int(length) 1051 if d.i < start || d.i > len(d.in) { 1052 corrupted() 1053 } 1054 return d.in[start : start+int(length)] 1055} 1056