1026 lines
22 KiB
Go
1026 lines
22 KiB
Go
// 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 bsonx
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"reflect"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
|
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
|
"go.mongodb.org/mongo-driver/bson/bsontype"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
var (
|
|
tPrimitiveD = reflect.TypeOf(primitive.D{})
|
|
tPrimitiveCWS = reflect.TypeOf(primitive.CodeWithScope{})
|
|
defaultValueEncoders = bsoncodec.DefaultValueEncoders{}
|
|
defaultValueDecoders = bsoncodec.DefaultValueDecoders{}
|
|
)
|
|
|
|
type reflectionFreeDCodec struct{}
|
|
|
|
// ReflectionFreeDCodec is a ValueEncoder for the primitive.D type that does not use reflection.
|
|
var ReflectionFreeDCodec bsoncodec.ValueCodec = &reflectionFreeDCodec{}
|
|
|
|
func (r *reflectionFreeDCodec) EncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
|
if !val.IsValid() || val.Type() != tPrimitiveD {
|
|
return bsoncodec.ValueEncoderError{Name: "DEncodeValue", Types: []reflect.Type{tPrimitiveD}, Received: val}
|
|
}
|
|
|
|
if val.IsNil() {
|
|
return vw.WriteNull()
|
|
}
|
|
|
|
doc := val.Interface().(primitive.D)
|
|
return r.encodeDocument(ec, vw, doc)
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
|
if !val.IsValid() || !val.CanSet() || val.Type() != tPrimitiveD {
|
|
return bsoncodec.ValueDecoderError{Name: "DDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
|
|
}
|
|
|
|
switch vrType := vr.Type(); vrType {
|
|
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
|
case bsontype.Null:
|
|
val.Set(reflect.Zero(val.Type()))
|
|
return vr.ReadNull()
|
|
default:
|
|
return fmt.Errorf("cannot decode %v into a primitive.D", vrType)
|
|
}
|
|
|
|
doc, err := r.decodeDocument(dc, vr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
val.Set(reflect.ValueOf(doc))
|
|
return nil
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) decodeDocument(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (primitive.D, error) {
|
|
dr, err := vr.ReadDocument()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
doc := primitive.D{}
|
|
for {
|
|
key, elemVr, err := dr.ReadElement()
|
|
if err == bsonrw.ErrEOD {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
val, err := r.decodeValue(dc, elemVr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
doc = append(doc, primitive.E{Key: key, Value: val})
|
|
}
|
|
|
|
return doc, nil
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) decodeArray(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (primitive.A, error) {
|
|
ar, err := vr.ReadArray()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
array := primitive.A{}
|
|
for {
|
|
arrayValReader, err := ar.ReadValue()
|
|
if err == bsonrw.ErrEOA {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
val, err := r.decodeValue(dc, arrayValReader)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
array = append(array, val)
|
|
}
|
|
|
|
return array, nil
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) decodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (interface{}, error) {
|
|
switch vrType := vr.Type(); vrType {
|
|
case bsontype.Null:
|
|
return nil, vr.ReadNull()
|
|
case bsontype.Double:
|
|
return vr.ReadDouble()
|
|
case bsontype.String:
|
|
return vr.ReadString()
|
|
case bsontype.Binary:
|
|
data, subtype, err := vr.ReadBinary()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.Binary{
|
|
Data: data,
|
|
Subtype: subtype,
|
|
}, nil
|
|
case bsontype.Undefined:
|
|
return primitive.Undefined{}, vr.ReadUndefined()
|
|
case bsontype.ObjectID:
|
|
return vr.ReadObjectID()
|
|
case bsontype.Boolean:
|
|
return vr.ReadBoolean()
|
|
case bsontype.DateTime:
|
|
dt, err := vr.ReadDateTime()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.DateTime(dt), nil
|
|
case bsontype.Regex:
|
|
pattern, options, err := vr.ReadRegex()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.Regex{
|
|
Pattern: pattern,
|
|
Options: options,
|
|
}, nil
|
|
case bsontype.DBPointer:
|
|
ns, oid, err := vr.ReadDBPointer()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.DBPointer{
|
|
DB: ns,
|
|
Pointer: oid,
|
|
}, nil
|
|
case bsontype.JavaScript:
|
|
js, err := vr.ReadJavascript()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.JavaScript(js), nil
|
|
case bsontype.Symbol:
|
|
sym, err := vr.ReadSymbol()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.Symbol(sym), nil
|
|
case bsontype.CodeWithScope:
|
|
cws := reflect.New(tPrimitiveCWS).Elem()
|
|
err := defaultValueDecoders.CodeWithScopeDecodeValue(dc, vr, cws)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return cws.Interface().(primitive.CodeWithScope), nil
|
|
case bsontype.Int32:
|
|
return vr.ReadInt32()
|
|
case bsontype.Int64:
|
|
return vr.ReadInt64()
|
|
case bsontype.Timestamp:
|
|
t, i, err := vr.ReadTimestamp()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return primitive.Timestamp{
|
|
T: t,
|
|
I: i,
|
|
}, nil
|
|
case bsontype.Decimal128:
|
|
return vr.ReadDecimal128()
|
|
case bsontype.MinKey:
|
|
return primitive.MinKey{}, vr.ReadMinKey()
|
|
case bsontype.MaxKey:
|
|
return primitive.MaxKey{}, vr.ReadMaxKey()
|
|
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
|
return r.decodeDocument(dc, vr)
|
|
case bsontype.Array:
|
|
return r.decodeArray(dc, vr)
|
|
default:
|
|
return nil, fmt.Errorf("cannot decode invalid BSON type %s", vrType)
|
|
}
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeDocumentValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, v interface{}) error {
|
|
switch val := v.(type) {
|
|
case int:
|
|
return r.encodeInt(vw, val)
|
|
case int8:
|
|
return vw.WriteInt32(int32(val))
|
|
case int16:
|
|
return vw.WriteInt32(int32(val))
|
|
case int32:
|
|
return vw.WriteInt32(val)
|
|
case int64:
|
|
return r.encodeInt64(ec, vw, val)
|
|
case uint:
|
|
return r.encodeUint64(ec, vw, uint64(val))
|
|
case uint8:
|
|
return vw.WriteInt32(int32(val))
|
|
case uint16:
|
|
return vw.WriteInt32(int32(val))
|
|
case uint32:
|
|
return r.encodeUint64(ec, vw, uint64(val))
|
|
case uint64:
|
|
return r.encodeUint64(ec, vw, val)
|
|
case float32:
|
|
return vw.WriteDouble(float64(val))
|
|
case float64:
|
|
return vw.WriteDouble(val)
|
|
case []byte:
|
|
return vw.WriteBinary(val)
|
|
case primitive.Binary:
|
|
return vw.WriteBinaryWithSubtype(val.Data, val.Subtype)
|
|
case bool:
|
|
return vw.WriteBoolean(val)
|
|
case primitive.CodeWithScope:
|
|
return defaultValueEncoders.CodeWithScopeEncodeValue(ec, vw, reflect.ValueOf(val))
|
|
case primitive.DBPointer:
|
|
return vw.WriteDBPointer(val.DB, val.Pointer)
|
|
case primitive.DateTime:
|
|
return vw.WriteDateTime(int64(val))
|
|
case time.Time:
|
|
dt := primitive.NewDateTimeFromTime(val)
|
|
return vw.WriteDateTime(int64(dt))
|
|
case primitive.Decimal128:
|
|
return vw.WriteDecimal128(val)
|
|
case primitive.JavaScript:
|
|
return vw.WriteJavascript(string(val))
|
|
case primitive.MinKey:
|
|
return vw.WriteMinKey()
|
|
case primitive.MaxKey:
|
|
return vw.WriteMaxKey()
|
|
case primitive.Null, nil:
|
|
return vw.WriteNull()
|
|
case primitive.ObjectID:
|
|
return vw.WriteObjectID(val)
|
|
case primitive.Regex:
|
|
return vw.WriteRegex(val.Pattern, val.Options)
|
|
case string:
|
|
return vw.WriteString(val)
|
|
case primitive.Symbol:
|
|
return vw.WriteSymbol(string(val))
|
|
case primitive.Timestamp:
|
|
return vw.WriteTimestamp(val.T, val.I)
|
|
case primitive.Undefined:
|
|
return vw.WriteUndefined()
|
|
case primitive.D:
|
|
return r.encodeDocument(ec, vw, val)
|
|
case primitive.A:
|
|
return r.encodePrimitiveA(ec, vw, val)
|
|
case []interface{}:
|
|
return r.encodePrimitiveA(ec, vw, val)
|
|
case []primitive.D:
|
|
return r.encodeSliceD(ec, vw, val)
|
|
case []int:
|
|
return r.encodeSliceInt(vw, val)
|
|
case []int8:
|
|
return r.encodeSliceInt8(vw, val)
|
|
case []int16:
|
|
return r.encodeSliceInt16(vw, val)
|
|
case []int32:
|
|
return r.encodeSliceInt32(vw, val)
|
|
case []int64:
|
|
return r.encodeSliceInt64(ec, vw, val)
|
|
case []uint:
|
|
return r.encodeSliceUint(ec, vw, val)
|
|
case []uint16:
|
|
return r.encodeSliceUint16(vw, val)
|
|
case []uint32:
|
|
return r.encodeSliceUint32(ec, vw, val)
|
|
case []uint64:
|
|
return r.encodeSliceUint64(ec, vw, val)
|
|
case [][]byte:
|
|
return r.encodeSliceByteSlice(vw, val)
|
|
case []primitive.Binary:
|
|
return r.encodeSliceBinary(vw, val)
|
|
case []bool:
|
|
return r.encodeSliceBoolean(vw, val)
|
|
case []primitive.CodeWithScope:
|
|
return r.encodeSliceCWS(ec, vw, val)
|
|
case []primitive.DBPointer:
|
|
return r.encodeSliceDBPointer(vw, val)
|
|
case []primitive.DateTime:
|
|
return r.encodeSliceDateTime(vw, val)
|
|
case []time.Time:
|
|
return r.encodeSliceTimeTime(vw, val)
|
|
case []primitive.Decimal128:
|
|
return r.encodeSliceDecimal128(vw, val)
|
|
case []float32:
|
|
return r.encodeSliceFloat32(vw, val)
|
|
case []float64:
|
|
return r.encodeSliceFloat64(vw, val)
|
|
case []primitive.JavaScript:
|
|
return r.encodeSliceJavaScript(vw, val)
|
|
case []primitive.MinKey:
|
|
return r.encodeSliceMinKey(vw, val)
|
|
case []primitive.MaxKey:
|
|
return r.encodeSliceMaxKey(vw, val)
|
|
case []primitive.Null:
|
|
return r.encodeSliceNull(vw, val)
|
|
case []primitive.ObjectID:
|
|
return r.encodeSliceObjectID(vw, val)
|
|
case []primitive.Regex:
|
|
return r.encodeSliceRegex(vw, val)
|
|
case []string:
|
|
return r.encodeSliceString(vw, val)
|
|
case []primitive.Symbol:
|
|
return r.encodeSliceSymbol(vw, val)
|
|
case []primitive.Timestamp:
|
|
return r.encodeSliceTimestamp(vw, val)
|
|
case []primitive.Undefined:
|
|
return r.encodeSliceUndefined(vw, val)
|
|
default:
|
|
return fmt.Errorf("value of type %T not supported", v)
|
|
}
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeInt(vw bsonrw.ValueWriter, val int) error {
|
|
if fitsIn32Bits(int64(val)) {
|
|
return vw.WriteInt32(int32(val))
|
|
}
|
|
return vw.WriteInt64(int64(val))
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeInt64(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val int64) error {
|
|
if ec.MinSize && fitsIn32Bits(val) {
|
|
return vw.WriteInt32(int32(val))
|
|
}
|
|
return vw.WriteInt64(val)
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeUint64(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val uint64) error {
|
|
if ec.MinSize && val <= math.MaxInt32 {
|
|
return vw.WriteInt32(int32(val))
|
|
}
|
|
if val > math.MaxInt64 {
|
|
return fmt.Errorf("%d overflows int64", val)
|
|
}
|
|
|
|
return vw.WriteInt64(int64(val))
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeDocument(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, doc primitive.D) error {
|
|
dw, err := vw.WriteDocument()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, elem := range doc {
|
|
docValWriter, err := dw.WriteDocumentElement(elem.Key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeDocumentValue(ec, docValWriter, elem.Value); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return dw.WriteDocumentEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceByteSlice(vw bsonrw.ValueWriter, arr [][]byte) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteBinary(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceBinary(vw bsonrw.ValueWriter, arr []primitive.Binary) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteBinaryWithSubtype(val.Data, val.Subtype); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceBoolean(vw bsonrw.ValueWriter, arr []bool) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteBoolean(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceCWS(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.CodeWithScope) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := defaultValueEncoders.CodeWithScopeEncodeValue(ec, arrayValWriter, reflect.ValueOf(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceDBPointer(vw bsonrw.ValueWriter, arr []primitive.DBPointer) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteDBPointer(val.DB, val.Pointer); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceDateTime(vw bsonrw.ValueWriter, arr []primitive.DateTime) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteDateTime(int64(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceTimeTime(vw bsonrw.ValueWriter, arr []time.Time) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dt := primitive.NewDateTimeFromTime(val)
|
|
if err := arrayValWriter.WriteDateTime(int64(dt)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceDecimal128(vw bsonrw.ValueWriter, arr []primitive.Decimal128) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteDecimal128(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceFloat32(vw bsonrw.ValueWriter, arr []float32) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteDouble(float64(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceFloat64(vw bsonrw.ValueWriter, arr []float64) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteDouble(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceJavaScript(vw bsonrw.ValueWriter, arr []primitive.JavaScript) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteJavascript(string(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceMinKey(vw bsonrw.ValueWriter, arr []primitive.MinKey) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteMinKey(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceMaxKey(vw bsonrw.ValueWriter, arr []primitive.MaxKey) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteMaxKey(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceNull(vw bsonrw.ValueWriter, arr []primitive.Null) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteNull(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceObjectID(vw bsonrw.ValueWriter, arr []primitive.ObjectID) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteObjectID(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceRegex(vw bsonrw.ValueWriter, arr []primitive.Regex) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteRegex(val.Pattern, val.Options); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceString(vw bsonrw.ValueWriter, arr []string) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteString(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceSymbol(vw bsonrw.ValueWriter, arr []primitive.Symbol) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteSymbol(string(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceTimestamp(vw bsonrw.ValueWriter, arr []primitive.Timestamp) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteTimestamp(val.T, val.I); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceUndefined(vw bsonrw.ValueWriter, arr []primitive.Undefined) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteUndefined(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodePrimitiveA(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr primitive.A) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeDocumentValue(ec, arrayValWriter, val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceD(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.D) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeDocument(ec, arrayValWriter, val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceInt(vw bsonrw.ValueWriter, arr []int) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeInt(arrayValWriter, val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceInt8(vw bsonrw.ValueWriter, arr []int8) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteInt32(int32(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceInt16(vw bsonrw.ValueWriter, arr []int16) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteInt32(int32(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceInt32(vw bsonrw.ValueWriter, arr []int32) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteInt32(val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceInt64(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []int64) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeInt64(ec, arrayValWriter, val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceUint(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []uint) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeUint64(ec, arrayValWriter, uint64(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceUint16(vw bsonrw.ValueWriter, arr []uint16) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := arrayValWriter.WriteInt32(int32(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceUint32(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []uint32) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeUint64(ec, arrayValWriter, uint64(val)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func (r *reflectionFreeDCodec) encodeSliceUint64(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []uint64) error {
|
|
aw, err := vw.WriteArray()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, val := range arr {
|
|
arrayValWriter, err := aw.WriteArrayElement()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := r.encodeUint64(ec, arrayValWriter, val); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return aw.WriteArrayEnd()
|
|
}
|
|
|
|
func fitsIn32Bits(i int64) bool {
|
|
return math.MinInt32 <= i && i <= math.MaxInt32
|
|
}
|