Don Newton | 379ae25 | 2019-04-01 12:17:06 -0400 | [diff] [blame^] | 1 | // Copyright (C) MongoDB, Inc. 2017-present. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | // not use this file except in compliance with the License. You may obtain |
| 5 | // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | |
| 7 | package bsoncodec |
| 8 | |
| 9 | import ( |
| 10 | "encoding/json" |
| 11 | "errors" |
| 12 | "fmt" |
| 13 | "math" |
| 14 | "net/url" |
| 15 | "reflect" |
| 16 | "sync" |
| 17 | "time" |
| 18 | |
| 19 | "github.com/mongodb/mongo-go-driver/bson/bsonrw" |
| 20 | "github.com/mongodb/mongo-go-driver/bson/bsontype" |
| 21 | "github.com/mongodb/mongo-go-driver/bson/primitive" |
| 22 | "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore" |
| 23 | ) |
| 24 | |
| 25 | var defaultValueEncoders DefaultValueEncoders |
| 26 | |
| 27 | var bvwPool = bsonrw.NewBSONValueWriterPool() |
| 28 | |
| 29 | var sliceWriterPool = sync.Pool{ |
| 30 | New: func() interface{} { |
| 31 | sw := make(bsonrw.SliceWriter, 0, 0) |
| 32 | return &sw |
| 33 | }, |
| 34 | } |
| 35 | |
| 36 | func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.E) error { |
| 37 | vw, err := dw.WriteDocumentElement(e.Key) |
| 38 | if err != nil { |
| 39 | return err |
| 40 | } |
| 41 | |
| 42 | if e.Value == nil { |
| 43 | return vw.WriteNull() |
| 44 | } |
| 45 | encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value)) |
| 46 | if err != nil { |
| 47 | return err |
| 48 | } |
| 49 | |
| 50 | err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value)) |
| 51 | if err != nil { |
| 52 | return err |
| 53 | } |
| 54 | return nil |
| 55 | } |
| 56 | |
| 57 | // DefaultValueEncoders is a namespace type for the default ValueEncoders used |
| 58 | // when creating a registry. |
| 59 | type DefaultValueEncoders struct{} |
| 60 | |
| 61 | // RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with |
| 62 | // the provided RegistryBuilder. |
| 63 | func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) { |
| 64 | if rb == nil { |
| 65 | panic(errors.New("argument to RegisterDefaultEncoders must not be nil")) |
| 66 | } |
| 67 | rb. |
| 68 | RegisterEncoder(tByteSlice, ValueEncoderFunc(dve.ByteSliceEncodeValue)). |
| 69 | RegisterEncoder(tTime, ValueEncoderFunc(dve.TimeEncodeValue)). |
| 70 | RegisterEncoder(tEmpty, ValueEncoderFunc(dve.EmptyInterfaceEncodeValue)). |
| 71 | RegisterEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)). |
| 72 | RegisterEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)). |
| 73 | RegisterEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)). |
| 74 | RegisterEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)). |
| 75 | RegisterEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)). |
| 76 | RegisterEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)). |
| 77 | RegisterEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)). |
| 78 | RegisterEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)). |
| 79 | RegisterEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)). |
| 80 | RegisterEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)). |
| 81 | RegisterEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)). |
| 82 | RegisterEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)). |
| 83 | RegisterEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)). |
| 84 | RegisterEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)). |
| 85 | RegisterEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)). |
| 86 | RegisterEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)). |
| 87 | RegisterEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)). |
| 88 | RegisterEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)). |
| 89 | RegisterEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)). |
| 90 | RegisterEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)). |
| 91 | RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)). |
| 92 | RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)). |
| 93 | RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)). |
| 94 | RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)). |
| 95 | RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)). |
| 96 | RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)). |
| 97 | RegisterDefaultEncoder(reflect.Uint, ValueEncoderFunc(dve.UintEncodeValue)). |
| 98 | RegisterDefaultEncoder(reflect.Uint8, ValueEncoderFunc(dve.UintEncodeValue)). |
| 99 | RegisterDefaultEncoder(reflect.Uint16, ValueEncoderFunc(dve.UintEncodeValue)). |
| 100 | RegisterDefaultEncoder(reflect.Uint32, ValueEncoderFunc(dve.UintEncodeValue)). |
| 101 | RegisterDefaultEncoder(reflect.Uint64, ValueEncoderFunc(dve.UintEncodeValue)). |
| 102 | RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)). |
| 103 | RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)). |
| 104 | RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)). |
| 105 | RegisterDefaultEncoder(reflect.Map, ValueEncoderFunc(dve.MapEncodeValue)). |
| 106 | RegisterDefaultEncoder(reflect.Slice, ValueEncoderFunc(dve.SliceEncodeValue)). |
| 107 | RegisterDefaultEncoder(reflect.String, ValueEncoderFunc(dve.StringEncodeValue)). |
| 108 | RegisterDefaultEncoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}). |
| 109 | RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec()) |
| 110 | } |
| 111 | |
| 112 | // BooleanEncodeValue is the ValueEncoderFunc for bool types. |
| 113 | func (dve DefaultValueEncoders) BooleanEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 114 | if !val.IsValid() || val.Kind() != reflect.Bool { |
| 115 | return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val} |
| 116 | } |
| 117 | return vw.WriteBoolean(val.Bool()) |
| 118 | } |
| 119 | |
| 120 | func fitsIn32Bits(i int64) bool { |
| 121 | return math.MinInt32 <= i && i <= math.MaxInt32 |
| 122 | } |
| 123 | |
| 124 | // IntEncodeValue is the ValueEncoderFunc for int types. |
| 125 | func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 126 | switch val.Kind() { |
| 127 | case reflect.Int8, reflect.Int16, reflect.Int32: |
| 128 | return vw.WriteInt32(int32(val.Int())) |
| 129 | case reflect.Int: |
| 130 | i64 := val.Int() |
| 131 | if fitsIn32Bits(i64) { |
| 132 | return vw.WriteInt32(int32(i64)) |
| 133 | } |
| 134 | return vw.WriteInt64(i64) |
| 135 | case reflect.Int64: |
| 136 | i64 := val.Int() |
| 137 | if ec.MinSize && fitsIn32Bits(i64) { |
| 138 | return vw.WriteInt32(int32(i64)) |
| 139 | } |
| 140 | return vw.WriteInt64(i64) |
| 141 | } |
| 142 | |
| 143 | return ValueEncoderError{ |
| 144 | Name: "IntEncodeValue", |
| 145 | Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, |
| 146 | Received: val, |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | // UintEncodeValue is the ValueEncoderFunc for uint types. |
| 151 | func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 152 | switch val.Kind() { |
| 153 | case reflect.Uint8, reflect.Uint16: |
| 154 | return vw.WriteInt32(int32(val.Uint())) |
| 155 | case reflect.Uint, reflect.Uint32, reflect.Uint64: |
| 156 | u64 := val.Uint() |
| 157 | if ec.MinSize && u64 <= math.MaxInt32 { |
| 158 | return vw.WriteInt32(int32(u64)) |
| 159 | } |
| 160 | if u64 > math.MaxInt64 { |
| 161 | return fmt.Errorf("%d overflows int64", u64) |
| 162 | } |
| 163 | return vw.WriteInt64(int64(u64)) |
| 164 | } |
| 165 | |
| 166 | return ValueEncoderError{ |
| 167 | Name: "UintEncodeValue", |
| 168 | Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, |
| 169 | Received: val, |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | // FloatEncodeValue is the ValueEncoderFunc for float types. |
| 174 | func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 175 | switch val.Kind() { |
| 176 | case reflect.Float32, reflect.Float64: |
| 177 | return vw.WriteDouble(val.Float()) |
| 178 | } |
| 179 | |
| 180 | return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val} |
| 181 | } |
| 182 | |
| 183 | // StringEncodeValue is the ValueEncoderFunc for string types. |
| 184 | func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 185 | if val.Kind() != reflect.String { |
| 186 | return ValueEncoderError{ |
| 187 | Name: "StringEncodeValue", |
| 188 | Kinds: []reflect.Kind{reflect.String}, |
| 189 | Received: val, |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | return vw.WriteString(val.String()) |
| 194 | } |
| 195 | |
| 196 | // ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID. |
| 197 | func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 198 | if !val.IsValid() || val.Type() != tOID { |
| 199 | return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val} |
| 200 | } |
| 201 | return vw.WriteObjectID(val.Interface().(primitive.ObjectID)) |
| 202 | } |
| 203 | |
| 204 | // Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128. |
| 205 | func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 206 | if !val.IsValid() || val.Type() != tDecimal { |
| 207 | return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val} |
| 208 | } |
| 209 | return vw.WriteDecimal128(val.Interface().(primitive.Decimal128)) |
| 210 | } |
| 211 | |
| 212 | // JSONNumberEncodeValue is the ValueEncoderFunc for json.Number. |
| 213 | func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 214 | if !val.IsValid() || val.Type() != tJSONNumber { |
| 215 | return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val} |
| 216 | } |
| 217 | jsnum := val.Interface().(json.Number) |
| 218 | |
| 219 | // Attempt int first, then float64 |
| 220 | if i64, err := jsnum.Int64(); err == nil { |
| 221 | return dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64)) |
| 222 | } |
| 223 | |
| 224 | f64, err := jsnum.Float64() |
| 225 | if err != nil { |
| 226 | return err |
| 227 | } |
| 228 | |
| 229 | return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64)) |
| 230 | } |
| 231 | |
| 232 | // URLEncodeValue is the ValueEncoderFunc for url.URL. |
| 233 | func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 234 | if !val.IsValid() || val.Type() != tURL { |
| 235 | return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val} |
| 236 | } |
| 237 | u := val.Interface().(url.URL) |
| 238 | return vw.WriteString(u.String()) |
| 239 | } |
| 240 | |
| 241 | // TimeEncodeValue is the ValueEncoderFunc for time.TIme. |
| 242 | func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 243 | if !val.IsValid() || val.Type() != tTime { |
| 244 | return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} |
| 245 | } |
| 246 | tt := val.Interface().(time.Time) |
| 247 | return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6)) |
| 248 | } |
| 249 | |
| 250 | // ByteSliceEncodeValue is the ValueEncoderFunc for []byte. |
| 251 | func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 252 | if !val.IsValid() || val.Type() != tByteSlice { |
| 253 | return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val} |
| 254 | } |
| 255 | if val.IsNil() { |
| 256 | return vw.WriteNull() |
| 257 | } |
| 258 | return vw.WriteBinary(val.Interface().([]byte)) |
| 259 | } |
| 260 | |
| 261 | // MapEncodeValue is the ValueEncoderFunc for map[string]* types. |
| 262 | func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 263 | if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { |
| 264 | return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} |
| 265 | } |
| 266 | |
| 267 | if val.IsNil() { |
| 268 | // If we have a nill map but we can't WriteNull, that means we're probably trying to encode |
| 269 | // to a TopLevel document. We can't currently tell if this is what actually happened, but if |
| 270 | // there's a deeper underlying problem, the error will also be returned from WriteDocument, |
| 271 | // so just continue. The operations on a map reflection value are valid, so we can call |
| 272 | // MapKeys within mapEncodeValue without a problem. |
| 273 | err := vw.WriteNull() |
| 274 | if err == nil { |
| 275 | return nil |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | dw, err := vw.WriteDocument() |
| 280 | if err != nil { |
| 281 | return err |
| 282 | } |
| 283 | |
| 284 | return dve.mapEncodeValue(ec, dw, val, nil) |
| 285 | } |
| 286 | |
| 287 | // mapEncodeValue handles encoding of the values of a map. The collisionFn returns |
| 288 | // true if the provided key exists, this is mainly used for inline maps in the |
| 289 | // struct codec. |
| 290 | func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error { |
| 291 | |
| 292 | encoder, err := ec.LookupEncoder(val.Type().Elem()) |
| 293 | if err != nil { |
| 294 | return err |
| 295 | } |
| 296 | |
| 297 | keys := val.MapKeys() |
| 298 | for _, key := range keys { |
| 299 | if collisionFn != nil && collisionFn(key.String()) { |
| 300 | return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key) |
| 301 | } |
| 302 | vw, err := dw.WriteDocumentElement(key.String()) |
| 303 | if err != nil { |
| 304 | return err |
| 305 | } |
| 306 | |
| 307 | if enc, ok := encoder.(ValueEncoder); ok { |
| 308 | err = enc.EncodeValue(ec, vw, val.MapIndex(key)) |
| 309 | if err != nil { |
| 310 | return err |
| 311 | } |
| 312 | continue |
| 313 | } |
| 314 | err = encoder.EncodeValue(ec, vw, val.MapIndex(key)) |
| 315 | if err != nil { |
| 316 | return err |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | return dw.WriteDocumentEnd() |
| 321 | } |
| 322 | |
| 323 | // ArrayEncodeValue is the ValueEncoderFunc for array types. |
| 324 | func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 325 | if !val.IsValid() || val.Kind() != reflect.Array { |
| 326 | return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val} |
| 327 | } |
| 328 | |
| 329 | // If we have a []primitive.E we want to treat it as a document instead of as an array. |
| 330 | if val.Type().Elem() == tE { |
| 331 | dw, err := vw.WriteDocument() |
| 332 | if err != nil { |
| 333 | return err |
| 334 | } |
| 335 | |
| 336 | for idx := 0; idx < val.Len(); idx++ { |
| 337 | e := val.Index(idx).Interface().(primitive.E) |
| 338 | err = encodeElement(ec, dw, e) |
| 339 | if err != nil { |
| 340 | return err |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | return dw.WriteDocumentEnd() |
| 345 | } |
| 346 | |
| 347 | aw, err := vw.WriteArray() |
| 348 | if err != nil { |
| 349 | return err |
| 350 | } |
| 351 | |
| 352 | encoder, err := ec.LookupEncoder(val.Type().Elem()) |
| 353 | if err != nil { |
| 354 | return err |
| 355 | } |
| 356 | |
| 357 | for idx := 0; idx < val.Len(); idx++ { |
| 358 | vw, err := aw.WriteArrayElement() |
| 359 | if err != nil { |
| 360 | return err |
| 361 | } |
| 362 | |
| 363 | err = encoder.EncodeValue(ec, vw, val.Index(idx)) |
| 364 | if err != nil { |
| 365 | return err |
| 366 | } |
| 367 | } |
| 368 | return aw.WriteArrayEnd() |
| 369 | } |
| 370 | |
| 371 | // SliceEncodeValue is the ValueEncoderFunc for slice types. |
| 372 | func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 373 | if !val.IsValid() || val.Kind() != reflect.Slice { |
| 374 | return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} |
| 375 | } |
| 376 | |
| 377 | if val.IsNil() { |
| 378 | return vw.WriteNull() |
| 379 | } |
| 380 | |
| 381 | // If we have a []primitive.E we want to treat it as a document instead of as an array. |
| 382 | if val.Type().ConvertibleTo(tD) { |
| 383 | d := val.Convert(tD).Interface().(primitive.D) |
| 384 | |
| 385 | dw, err := vw.WriteDocument() |
| 386 | if err != nil { |
| 387 | return err |
| 388 | } |
| 389 | |
| 390 | for _, e := range d { |
| 391 | err = encodeElement(ec, dw, e) |
| 392 | if err != nil { |
| 393 | return err |
| 394 | } |
| 395 | } |
| 396 | |
| 397 | return dw.WriteDocumentEnd() |
| 398 | } |
| 399 | |
| 400 | aw, err := vw.WriteArray() |
| 401 | if err != nil { |
| 402 | return err |
| 403 | } |
| 404 | |
| 405 | encoder, err := ec.LookupEncoder(val.Type().Elem()) |
| 406 | if err != nil { |
| 407 | return err |
| 408 | } |
| 409 | |
| 410 | for idx := 0; idx < val.Len(); idx++ { |
| 411 | vw, err := aw.WriteArrayElement() |
| 412 | if err != nil { |
| 413 | return err |
| 414 | } |
| 415 | |
| 416 | err = encoder.EncodeValue(ec, vw, val.Index(idx)) |
| 417 | if err != nil { |
| 418 | return err |
| 419 | } |
| 420 | } |
| 421 | return aw.WriteArrayEnd() |
| 422 | } |
| 423 | |
| 424 | // EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}. |
| 425 | func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 426 | if !val.IsValid() || val.Type() != tEmpty { |
| 427 | return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val} |
| 428 | } |
| 429 | |
| 430 | if val.IsNil() { |
| 431 | return vw.WriteNull() |
| 432 | } |
| 433 | encoder, err := ec.LookupEncoder(val.Elem().Type()) |
| 434 | if err != nil { |
| 435 | return err |
| 436 | } |
| 437 | |
| 438 | return encoder.EncodeValue(ec, vw, val.Elem()) |
| 439 | } |
| 440 | |
| 441 | // ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations. |
| 442 | func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 443 | if !val.IsValid() || !val.Type().Implements(tValueMarshaler) { |
| 444 | return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val} |
| 445 | } |
| 446 | |
| 447 | fn := val.Convert(tValueMarshaler).MethodByName("MarshalBSONValue") |
| 448 | returns := fn.Call(nil) |
| 449 | if !returns[2].IsNil() { |
| 450 | return returns[2].Interface().(error) |
| 451 | } |
| 452 | t, data := returns[0].Interface().(bsontype.Type), returns[1].Interface().([]byte) |
| 453 | return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data) |
| 454 | } |
| 455 | |
| 456 | // MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations. |
| 457 | func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 458 | if !val.IsValid() || !val.Type().Implements(tMarshaler) { |
| 459 | return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val} |
| 460 | } |
| 461 | |
| 462 | fn := val.Convert(tMarshaler).MethodByName("MarshalBSON") |
| 463 | returns := fn.Call(nil) |
| 464 | if !returns[1].IsNil() { |
| 465 | return returns[1].Interface().(error) |
| 466 | } |
| 467 | data := returns[0].Interface().([]byte) |
| 468 | return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data) |
| 469 | } |
| 470 | |
| 471 | // ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations. |
| 472 | func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 473 | if !val.IsValid() || !val.Type().Implements(tProxy) { |
| 474 | return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val} |
| 475 | } |
| 476 | |
| 477 | fn := val.Convert(tProxy).MethodByName("ProxyBSON") |
| 478 | returns := fn.Call(nil) |
| 479 | if !returns[1].IsNil() { |
| 480 | return returns[1].Interface().(error) |
| 481 | } |
| 482 | data := returns[0] |
| 483 | var encoder ValueEncoder |
| 484 | var err error |
| 485 | if data.Elem().IsValid() { |
| 486 | encoder, err = ec.LookupEncoder(data.Elem().Type()) |
| 487 | } else { |
| 488 | encoder, err = ec.LookupEncoder(nil) |
| 489 | } |
| 490 | if err != nil { |
| 491 | return err |
| 492 | } |
| 493 | return encoder.EncodeValue(ec, vw, data.Elem()) |
| 494 | } |
| 495 | |
| 496 | // JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type. |
| 497 | func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 498 | if !val.IsValid() || val.Type() != tJavaScript { |
| 499 | return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val} |
| 500 | } |
| 501 | |
| 502 | return vw.WriteJavascript(val.String()) |
| 503 | } |
| 504 | |
| 505 | // SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type. |
| 506 | func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 507 | if !val.IsValid() || val.Type() != tSymbol { |
| 508 | return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val} |
| 509 | } |
| 510 | |
| 511 | return vw.WriteSymbol(val.String()) |
| 512 | } |
| 513 | |
| 514 | // BinaryEncodeValue is the ValueEncoderFunc for Binary. |
| 515 | func (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 516 | if !val.IsValid() || val.Type() != tBinary { |
| 517 | return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val} |
| 518 | } |
| 519 | b := val.Interface().(primitive.Binary) |
| 520 | |
| 521 | return vw.WriteBinaryWithSubtype(b.Data, b.Subtype) |
| 522 | } |
| 523 | |
| 524 | // UndefinedEncodeValue is the ValueEncoderFunc for Undefined. |
| 525 | func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 526 | if !val.IsValid() || val.Type() != tUndefined { |
| 527 | return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val} |
| 528 | } |
| 529 | |
| 530 | return vw.WriteUndefined() |
| 531 | } |
| 532 | |
| 533 | // DateTimeEncodeValue is the ValueEncoderFunc for DateTime. |
| 534 | func (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 535 | if !val.IsValid() || val.Type() != tDateTime { |
| 536 | return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val} |
| 537 | } |
| 538 | |
| 539 | return vw.WriteDateTime(val.Int()) |
| 540 | } |
| 541 | |
| 542 | // NullEncodeValue is the ValueEncoderFunc for Null. |
| 543 | func (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 544 | if !val.IsValid() || val.Type() != tNull { |
| 545 | return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val} |
| 546 | } |
| 547 | |
| 548 | return vw.WriteNull() |
| 549 | } |
| 550 | |
| 551 | // RegexEncodeValue is the ValueEncoderFunc for Regex. |
| 552 | func (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 553 | if !val.IsValid() || val.Type() != tRegex { |
| 554 | return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val} |
| 555 | } |
| 556 | |
| 557 | regex := val.Interface().(primitive.Regex) |
| 558 | |
| 559 | return vw.WriteRegex(regex.Pattern, regex.Options) |
| 560 | } |
| 561 | |
| 562 | // DBPointerEncodeValue is the ValueEncoderFunc for DBPointer. |
| 563 | func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 564 | if !val.IsValid() || val.Type() != tDBPointer { |
| 565 | return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val} |
| 566 | } |
| 567 | |
| 568 | dbp := val.Interface().(primitive.DBPointer) |
| 569 | |
| 570 | return vw.WriteDBPointer(dbp.DB, dbp.Pointer) |
| 571 | } |
| 572 | |
| 573 | // TimestampEncodeValue is the ValueEncoderFunc for Timestamp. |
| 574 | func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 575 | if !val.IsValid() || val.Type() != tTimestamp { |
| 576 | return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val} |
| 577 | } |
| 578 | |
| 579 | ts := val.Interface().(primitive.Timestamp) |
| 580 | |
| 581 | return vw.WriteTimestamp(ts.T, ts.I) |
| 582 | } |
| 583 | |
| 584 | // MinKeyEncodeValue is the ValueEncoderFunc for MinKey. |
| 585 | func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 586 | if !val.IsValid() || val.Type() != tMinKey { |
| 587 | return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val} |
| 588 | } |
| 589 | |
| 590 | return vw.WriteMinKey() |
| 591 | } |
| 592 | |
| 593 | // MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey. |
| 594 | func (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 595 | if !val.IsValid() || val.Type() != tMaxKey { |
| 596 | return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val} |
| 597 | } |
| 598 | |
| 599 | return vw.WriteMaxKey() |
| 600 | } |
| 601 | |
| 602 | // CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document. |
| 603 | func (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 604 | if !val.IsValid() || val.Type() != tCoreDocument { |
| 605 | return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val} |
| 606 | } |
| 607 | |
| 608 | cdoc := val.Interface().(bsoncore.Document) |
| 609 | |
| 610 | return bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc) |
| 611 | } |
| 612 | |
| 613 | // CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope. |
| 614 | func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { |
| 615 | if !val.IsValid() || val.Type() != tCodeWithScope { |
| 616 | return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} |
| 617 | } |
| 618 | |
| 619 | cws := val.Interface().(primitive.CodeWithScope) |
| 620 | |
| 621 | dw, err := vw.WriteCodeWithScope(string(cws.Code)) |
| 622 | if err != nil { |
| 623 | return err |
| 624 | } |
| 625 | |
| 626 | sw := sliceWriterPool.Get().(*bsonrw.SliceWriter) |
| 627 | defer sliceWriterPool.Put(sw) |
| 628 | *sw = (*sw)[:0] |
| 629 | |
| 630 | scopeVW := bvwPool.Get(sw) |
| 631 | defer bvwPool.Put(scopeVW) |
| 632 | |
| 633 | encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope)) |
| 634 | if err != nil { |
| 635 | return err |
| 636 | } |
| 637 | |
| 638 | err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope)) |
| 639 | if err != nil { |
| 640 | return err |
| 641 | } |
| 642 | |
| 643 | err = bsonrw.Copier{}.CopyBytesToDocumentWriter(dw, *sw) |
| 644 | if err != nil { |
| 645 | return err |
| 646 | } |
| 647 | return dw.WriteDocumentEnd() |
| 648 | } |