123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 |
- // Copyright (C) MongoDB, Inc. 2017-present.
- //
- // Licensed under the Apache License, Version 2.0 (the "License"); you may
- // not use this file except in compliance with the License. You may obtain
- // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- package bsoncodec
- import (
- "encoding/json"
- "errors"
- "fmt"
- "math"
- "net/url"
- "reflect"
- "sync"
- "time"
- "go.mongodb.org/mongo-driver/bson/bsonrw"
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- )
- var defaultValueEncoders DefaultValueEncoders
- var bvwPool = bsonrw.NewBSONValueWriterPool()
- var sliceWriterPool = sync.Pool{
- New: func() interface{} {
- sw := make(bsonrw.SliceWriter, 0, 0)
- return &sw
- },
- }
- func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.E) error {
- vw, err := dw.WriteDocumentElement(e.Key)
- if err != nil {
- return err
- }
- if e.Value == nil {
- return vw.WriteNull()
- }
- encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value))
- if err != nil {
- return err
- }
- err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value))
- if err != nil {
- return err
- }
- return nil
- }
- // DefaultValueEncoders is a namespace type for the default ValueEncoders used
- // when creating a registry.
- type DefaultValueEncoders struct{}
- // RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
- // the provided RegistryBuilder.
- func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
- if rb == nil {
- panic(errors.New("argument to RegisterDefaultEncoders must not be nil"))
- }
- rb.
- RegisterEncoder(tByteSlice, ValueEncoderFunc(dve.ByteSliceEncodeValue)).
- RegisterEncoder(tTime, ValueEncoderFunc(dve.TimeEncodeValue)).
- RegisterEncoder(tEmpty, ValueEncoderFunc(dve.EmptyInterfaceEncodeValue)).
- RegisterEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
- RegisterEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
- RegisterEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
- RegisterEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
- RegisterEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
- RegisterEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
- RegisterEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)).
- RegisterEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
- RegisterEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
- RegisterEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
- RegisterEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
- RegisterEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
- RegisterEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
- RegisterEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
- RegisterEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
- RegisterEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
- RegisterEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
- RegisterEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
- RegisterEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
- RegisterEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)).
- RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)).
- RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)).
- RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)).
- RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)).
- RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)).
- RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)).
- RegisterDefaultEncoder(reflect.Uint, ValueEncoderFunc(dve.UintEncodeValue)).
- RegisterDefaultEncoder(reflect.Uint8, ValueEncoderFunc(dve.UintEncodeValue)).
- RegisterDefaultEncoder(reflect.Uint16, ValueEncoderFunc(dve.UintEncodeValue)).
- RegisterDefaultEncoder(reflect.Uint32, ValueEncoderFunc(dve.UintEncodeValue)).
- RegisterDefaultEncoder(reflect.Uint64, ValueEncoderFunc(dve.UintEncodeValue)).
- RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)).
- RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)).
- RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)).
- RegisterDefaultEncoder(reflect.Map, ValueEncoderFunc(dve.MapEncodeValue)).
- RegisterDefaultEncoder(reflect.Slice, ValueEncoderFunc(dve.SliceEncodeValue)).
- RegisterDefaultEncoder(reflect.String, ValueEncoderFunc(dve.StringEncodeValue)).
- RegisterDefaultEncoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}).
- RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec())
- }
- // BooleanEncodeValue is the ValueEncoderFunc for bool types.
- func (dve DefaultValueEncoders) BooleanEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Kind() != reflect.Bool {
- return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
- }
- return vw.WriteBoolean(val.Bool())
- }
- func fitsIn32Bits(i int64) bool {
- return math.MinInt32 <= i && i <= math.MaxInt32
- }
- // IntEncodeValue is the ValueEncoderFunc for int types.
- func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- switch val.Kind() {
- case reflect.Int8, reflect.Int16, reflect.Int32:
- return vw.WriteInt32(int32(val.Int()))
- case reflect.Int:
- i64 := val.Int()
- if fitsIn32Bits(i64) {
- return vw.WriteInt32(int32(i64))
- }
- return vw.WriteInt64(i64)
- case reflect.Int64:
- i64 := val.Int()
- if ec.MinSize && fitsIn32Bits(i64) {
- return vw.WriteInt32(int32(i64))
- }
- return vw.WriteInt64(i64)
- }
- return ValueEncoderError{
- Name: "IntEncodeValue",
- Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
- Received: val,
- }
- }
- // UintEncodeValue is the ValueEncoderFunc for uint types.
- func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- switch val.Kind() {
- case reflect.Uint8, reflect.Uint16:
- return vw.WriteInt32(int32(val.Uint()))
- case reflect.Uint, reflect.Uint32, reflect.Uint64:
- u64 := val.Uint()
- if ec.MinSize && u64 <= math.MaxInt32 {
- return vw.WriteInt32(int32(u64))
- }
- if u64 > math.MaxInt64 {
- return fmt.Errorf("%d overflows int64", u64)
- }
- return vw.WriteInt64(int64(u64))
- }
- return ValueEncoderError{
- Name: "UintEncodeValue",
- Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
- Received: val,
- }
- }
- // FloatEncodeValue is the ValueEncoderFunc for float types.
- func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- switch val.Kind() {
- case reflect.Float32, reflect.Float64:
- return vw.WriteDouble(val.Float())
- }
- return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
- }
- // StringEncodeValue is the ValueEncoderFunc for string types.
- func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if val.Kind() != reflect.String {
- return ValueEncoderError{
- Name: "StringEncodeValue",
- Kinds: []reflect.Kind{reflect.String},
- Received: val,
- }
- }
- return vw.WriteString(val.String())
- }
- // ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID.
- func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tOID {
- return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
- }
- return vw.WriteObjectID(val.Interface().(primitive.ObjectID))
- }
- // Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128.
- func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tDecimal {
- return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val}
- }
- return vw.WriteDecimal128(val.Interface().(primitive.Decimal128))
- }
- // JSONNumberEncodeValue is the ValueEncoderFunc for json.Number.
- func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tJSONNumber {
- return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
- }
- jsnum := val.Interface().(json.Number)
- // Attempt int first, then float64
- if i64, err := jsnum.Int64(); err == nil {
- return dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64))
- }
- f64, err := jsnum.Float64()
- if err != nil {
- return err
- }
- return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64))
- }
- // URLEncodeValue is the ValueEncoderFunc for url.URL.
- func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tURL {
- return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val}
- }
- u := val.Interface().(url.URL)
- return vw.WriteString(u.String())
- }
- // TimeEncodeValue is the ValueEncoderFunc for time.TIme.
- func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tTime {
- return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
- }
- tt := val.Interface().(time.Time)
- return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
- }
- // ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
- func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tByteSlice {
- return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
- }
- if val.IsNil() {
- return vw.WriteNull()
- }
- return vw.WriteBinary(val.Interface().([]byte))
- }
- // MapEncodeValue is the ValueEncoderFunc for map[string]* types.
- func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String {
- return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
- }
- if val.IsNil() {
- // If we have a nill map but we can't WriteNull, that means we're probably trying to encode
- // to a TopLevel document. We can't currently tell if this is what actually happened, but if
- // there's a deeper underlying problem, the error will also be returned from WriteDocument,
- // so just continue. The operations on a map reflection value are valid, so we can call
- // MapKeys within mapEncodeValue without a problem.
- err := vw.WriteNull()
- if err == nil {
- return nil
- }
- }
- dw, err := vw.WriteDocument()
- if err != nil {
- return err
- }
- return dve.mapEncodeValue(ec, dw, val, nil)
- }
- // mapEncodeValue handles encoding of the values of a map. The collisionFn returns
- // true if the provided key exists, this is mainly used for inline maps in the
- // struct codec.
- func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
- encoder, err := ec.LookupEncoder(val.Type().Elem())
- if err != nil {
- return err
- }
- keys := val.MapKeys()
- for _, key := range keys {
- if collisionFn != nil && collisionFn(key.String()) {
- return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
- }
- vw, err := dw.WriteDocumentElement(key.String())
- if err != nil {
- return err
- }
- if enc, ok := encoder.(ValueEncoder); ok {
- err = enc.EncodeValue(ec, vw, val.MapIndex(key))
- if err != nil {
- return err
- }
- continue
- }
- err = encoder.EncodeValue(ec, vw, val.MapIndex(key))
- if err != nil {
- return err
- }
- }
- return dw.WriteDocumentEnd()
- }
- // ArrayEncodeValue is the ValueEncoderFunc for array types.
- func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Kind() != reflect.Array {
- return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
- }
- // If we have a []primitive.E we want to treat it as a document instead of as an array.
- if val.Type().Elem() == tE {
- dw, err := vw.WriteDocument()
- if err != nil {
- return err
- }
- for idx := 0; idx < val.Len(); idx++ {
- e := val.Index(idx).Interface().(primitive.E)
- err = encodeElement(ec, dw, e)
- if err != nil {
- return err
- }
- }
- return dw.WriteDocumentEnd()
- }
- aw, err := vw.WriteArray()
- if err != nil {
- return err
- }
- encoder, err := ec.LookupEncoder(val.Type().Elem())
- if err != nil {
- return err
- }
- for idx := 0; idx < val.Len(); idx++ {
- vw, err := aw.WriteArrayElement()
- if err != nil {
- return err
- }
- err = encoder.EncodeValue(ec, vw, val.Index(idx))
- if err != nil {
- return err
- }
- }
- return aw.WriteArrayEnd()
- }
- // SliceEncodeValue is the ValueEncoderFunc for slice types.
- func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Kind() != reflect.Slice {
- return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
- }
- if val.IsNil() {
- return vw.WriteNull()
- }
- // If we have a []primitive.E we want to treat it as a document instead of as an array.
- if val.Type().ConvertibleTo(tD) {
- d := val.Convert(tD).Interface().(primitive.D)
- dw, err := vw.WriteDocument()
- if err != nil {
- return err
- }
- for _, e := range d {
- err = encodeElement(ec, dw, e)
- if err != nil {
- return err
- }
- }
- return dw.WriteDocumentEnd()
- }
- aw, err := vw.WriteArray()
- if err != nil {
- return err
- }
- encoder, err := ec.LookupEncoder(val.Type().Elem())
- if err != nil {
- return err
- }
- for idx := 0; idx < val.Len(); idx++ {
- vw, err := aw.WriteArrayElement()
- if err != nil {
- return err
- }
- err = encoder.EncodeValue(ec, vw, val.Index(idx))
- if err != nil {
- return err
- }
- }
- return aw.WriteArrayEnd()
- }
- // EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}.
- func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tEmpty {
- return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
- }
- if val.IsNil() {
- return vw.WriteNull()
- }
- encoder, err := ec.LookupEncoder(val.Elem().Type())
- if err != nil {
- return err
- }
- return encoder.EncodeValue(ec, vw, val.Elem())
- }
- // ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
- func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || !val.Type().Implements(tValueMarshaler) {
- return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
- }
- fn := val.Convert(tValueMarshaler).MethodByName("MarshalBSONValue")
- returns := fn.Call(nil)
- if !returns[2].IsNil() {
- return returns[2].Interface().(error)
- }
- t, data := returns[0].Interface().(bsontype.Type), returns[1].Interface().([]byte)
- return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data)
- }
- // MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
- func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || !val.Type().Implements(tMarshaler) {
- return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
- }
- fn := val.Convert(tMarshaler).MethodByName("MarshalBSON")
- returns := fn.Call(nil)
- if !returns[1].IsNil() {
- return returns[1].Interface().(error)
- }
- data := returns[0].Interface().([]byte)
- return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data)
- }
- // ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations.
- func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || !val.Type().Implements(tProxy) {
- return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
- }
- fn := val.Convert(tProxy).MethodByName("ProxyBSON")
- returns := fn.Call(nil)
- if !returns[1].IsNil() {
- return returns[1].Interface().(error)
- }
- data := returns[0]
- var encoder ValueEncoder
- var err error
- if data.Elem().IsValid() {
- encoder, err = ec.LookupEncoder(data.Elem().Type())
- } else {
- encoder, err = ec.LookupEncoder(nil)
- }
- if err != nil {
- return err
- }
- return encoder.EncodeValue(ec, vw, data.Elem())
- }
- // JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type.
- func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tJavaScript {
- return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
- }
- return vw.WriteJavascript(val.String())
- }
- // SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type.
- func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tSymbol {
- return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val}
- }
- return vw.WriteSymbol(val.String())
- }
- // BinaryEncodeValue is the ValueEncoderFunc for Binary.
- func (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tBinary {
- return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
- }
- b := val.Interface().(primitive.Binary)
- return vw.WriteBinaryWithSubtype(b.Data, b.Subtype)
- }
- // UndefinedEncodeValue is the ValueEncoderFunc for Undefined.
- func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tUndefined {
- return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val}
- }
- return vw.WriteUndefined()
- }
- // DateTimeEncodeValue is the ValueEncoderFunc for DateTime.
- func (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tDateTime {
- return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
- }
- return vw.WriteDateTime(val.Int())
- }
- // NullEncodeValue is the ValueEncoderFunc for Null.
- func (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tNull {
- return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val}
- }
- return vw.WriteNull()
- }
- // RegexEncodeValue is the ValueEncoderFunc for Regex.
- func (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tRegex {
- return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
- }
- regex := val.Interface().(primitive.Regex)
- return vw.WriteRegex(regex.Pattern, regex.Options)
- }
- // DBPointerEncodeValue is the ValueEncoderFunc for DBPointer.
- func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tDBPointer {
- return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
- }
- dbp := val.Interface().(primitive.DBPointer)
- return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
- }
- // TimestampEncodeValue is the ValueEncoderFunc for Timestamp.
- func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tTimestamp {
- return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
- }
- ts := val.Interface().(primitive.Timestamp)
- return vw.WriteTimestamp(ts.T, ts.I)
- }
- // MinKeyEncodeValue is the ValueEncoderFunc for MinKey.
- func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tMinKey {
- return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
- }
- return vw.WriteMinKey()
- }
- // MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
- func (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tMaxKey {
- return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
- }
- return vw.WriteMaxKey()
- }
- // CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
- func (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tCoreDocument {
- return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
- }
- cdoc := val.Interface().(bsoncore.Document)
- return bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc)
- }
- // CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
- func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
- if !val.IsValid() || val.Type() != tCodeWithScope {
- return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
- }
- cws := val.Interface().(primitive.CodeWithScope)
- dw, err := vw.WriteCodeWithScope(string(cws.Code))
- if err != nil {
- return err
- }
- sw := sliceWriterPool.Get().(*bsonrw.SliceWriter)
- defer sliceWriterPool.Put(sw)
- *sw = (*sw)[:0]
- scopeVW := bvwPool.Get(sw)
- defer bvwPool.Put(scopeVW)
- encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
- if err != nil {
- return err
- }
- err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope))
- if err != nil {
- return err
- }
- err = bsonrw.Copier{}.CopyBytesToDocumentWriter(dw, *sw)
- if err != nil {
- return err
- }
- return dw.WriteDocumentEnd()
- }
|