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