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  }