github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/gopkg.in/mgo.v2/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  	"strconv"
    36  	"sync"
    37  	"time"
    38  )
    39  
    40  type decoder struct {
    41  	in      []byte
    42  	i       int
    43  	docType reflect.Type
    44  }
    45  
    46  var typeM = reflect.TypeOf(M{})
    47  
    48  func newDecoder(in []byte) *decoder {
    49  	return &decoder{in, 0, typeM}
    50  }
    51  
    52  // --------------------------------------------------------------------------
    53  // Some helper functions.
    54  
    55  func corrupted() {
    56  	panic("Document is corrupted")
    57  }
    58  
    59  func 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  
    69  const (
    70  	setterUnknown = iota
    71  	setterNone
    72  	setterType
    73  	setterAddr
    74  )
    75  
    76  var setterStyles map[reflect.Type]int
    77  var setterIface reflect.Type
    78  var setterMutex sync.RWMutex
    79  
    80  func init() {
    81  	var iface Setter
    82  	setterIface = reflect.TypeOf(&iface).Elem()
    83  	setterStyles = make(map[reflect.Type]int)
    84  }
    85  
    86  func 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  
   105  func 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  
   121  func clearMap(m reflect.Value) {
   122  	var none reflect.Value
   123  	for _, k := range m.MapKeys() {
   124  		m.SetMapIndex(k, none)
   125  	}
   126  }
   127  
   128  func (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  
   290  func (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  
   325  func (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  
   368  var typeSlice = reflect.TypeOf([]interface{}{})
   369  var typeIface = typeSlice.Elem()
   370  
   371  func (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  
   388  func (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  
   405  func (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  
   431  var blackHole = settableValueOf(struct{}{})
   432  
   433  func (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.
   440  func (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  
   751  func (d *decoder) readRegEx() RegEx {
   752  	re := RegEx{}
   753  	re.Pattern = d.readCStr()
   754  	re.Options = d.readCStr()
   755  	return re
   756  }
   757  
   758  func (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  
   770  func (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  
   779  func (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  
   795  func (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  
   806  func (d *decoder) readFloat64() float64 {
   807  	return math.Float64frombits(uint64(d.readInt64()))
   808  }
   809  
   810  func (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  
   818  func (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  
   830  func (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  
   839  func (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  }