blob: 61295bd6c1d6823d5c40d2e66265c6f7fee7fe29 [file] [log] [blame]
Don Newton379ae252019-04-01 12:17:06 -04001// 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
7package bsoncodec
8
9import (
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
25var defaultValueEncoders DefaultValueEncoders
26
27var bvwPool = bsonrw.NewBSONValueWriterPool()
28
29var sliceWriterPool = sync.Pool{
30 New: func() interface{} {
31 sw := make(bsonrw.SliceWriter, 0, 0)
32 return &sw
33 },
34}
35
36func 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.
59type DefaultValueEncoders struct{}
60
61// RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
62// the provided RegistryBuilder.
63func (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.
113func (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
120func fitsIn32Bits(i int64) bool {
121 return math.MinInt32 <= i && i <= math.MaxInt32
122}
123
124// IntEncodeValue is the ValueEncoderFunc for int types.
125func (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.
151func (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.
174func (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.
184func (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.
197func (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.
205func (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.
213func (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.
233func (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.
242func (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.
251func (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.
262func (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.
290func (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.
324func (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.
372func (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{}.
425func (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.
442func (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.
457func (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.
472func (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.
497func (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.
506func (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.
515func (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.
525func (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.
534func (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.
543func (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.
552func (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.
563func (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.
574func (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.
585func (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.
594func (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.
603func (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.
614func (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}