byte_slice_codec.go raw

   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  	"fmt"
  11  	"reflect"
  12  
  13  	"go.mongodb.org/mongo-driver/bson/bsonoptions"
  14  	"go.mongodb.org/mongo-driver/bson/bsonrw"
  15  	"go.mongodb.org/mongo-driver/bson/bsontype"
  16  )
  17  
  18  // ByteSliceCodec is the Codec used for []byte values.
  19  //
  20  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with the
  21  // ByteSliceCodec registered.
  22  type ByteSliceCodec struct {
  23  	// EncodeNilAsEmpty causes EncodeValue to marshal nil Go byte slices as empty BSON binary values
  24  	// instead of BSON null.
  25  	//
  26  	// Deprecated: Use bson.Encoder.NilByteSliceAsEmpty instead.
  27  	EncodeNilAsEmpty bool
  28  }
  29  
  30  var (
  31  	defaultByteSliceCodec = NewByteSliceCodec()
  32  
  33  	// Assert that defaultByteSliceCodec satisfies the typeDecoder interface, which allows it to be
  34  	// used by collection type decoders (e.g. map, slice, etc) to set individual values in a
  35  	// collection.
  36  	_ typeDecoder = defaultByteSliceCodec
  37  )
  38  
  39  // NewByteSliceCodec returns a ByteSliceCodec with options opts.
  40  //
  41  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with the
  42  // ByteSliceCodec registered.
  43  func NewByteSliceCodec(opts ...*bsonoptions.ByteSliceCodecOptions) *ByteSliceCodec {
  44  	byteSliceOpt := bsonoptions.MergeByteSliceCodecOptions(opts...)
  45  	codec := ByteSliceCodec{}
  46  	if byteSliceOpt.EncodeNilAsEmpty != nil {
  47  		codec.EncodeNilAsEmpty = *byteSliceOpt.EncodeNilAsEmpty
  48  	}
  49  	return &codec
  50  }
  51  
  52  // EncodeValue is the ValueEncoder for []byte.
  53  func (bsc *ByteSliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
  54  	if !val.IsValid() || val.Type() != tByteSlice {
  55  		return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
  56  	}
  57  	if val.IsNil() && !bsc.EncodeNilAsEmpty && !ec.nilByteSliceAsEmpty {
  58  		return vw.WriteNull()
  59  	}
  60  	return vw.WriteBinary(val.Interface().([]byte))
  61  }
  62  
  63  func (bsc *ByteSliceCodec) decodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
  64  	if t != tByteSlice {
  65  		return emptyValue, ValueDecoderError{
  66  			Name:     "ByteSliceDecodeValue",
  67  			Types:    []reflect.Type{tByteSlice},
  68  			Received: reflect.Zero(t),
  69  		}
  70  	}
  71  
  72  	var data []byte
  73  	var err error
  74  	switch vrType := vr.Type(); vrType {
  75  	case bsontype.String:
  76  		str, err := vr.ReadString()
  77  		if err != nil {
  78  			return emptyValue, err
  79  		}
  80  		data = []byte(str)
  81  	case bsontype.Symbol:
  82  		sym, err := vr.ReadSymbol()
  83  		if err != nil {
  84  			return emptyValue, err
  85  		}
  86  		data = []byte(sym)
  87  	case bsontype.Binary:
  88  		var subtype byte
  89  		data, subtype, err = vr.ReadBinary()
  90  		if err != nil {
  91  			return emptyValue, err
  92  		}
  93  		if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
  94  			return emptyValue, decodeBinaryError{subtype: subtype, typeName: "[]byte"}
  95  		}
  96  	case bsontype.Null:
  97  		err = vr.ReadNull()
  98  	case bsontype.Undefined:
  99  		err = vr.ReadUndefined()
 100  	default:
 101  		return emptyValue, fmt.Errorf("cannot decode %v into a []byte", vrType)
 102  	}
 103  	if err != nil {
 104  		return emptyValue, err
 105  	}
 106  
 107  	return reflect.ValueOf(data), nil
 108  }
 109  
 110  // DecodeValue is the ValueDecoder for []byte.
 111  func (bsc *ByteSliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 112  	if !val.CanSet() || val.Type() != tByteSlice {
 113  		return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
 114  	}
 115  
 116  	elem, err := bsc.decodeType(dc, vr, tByteSlice)
 117  	if err != nil {
 118  		return err
 119  	}
 120  
 121  	val.Set(elem)
 122  	return nil
 123  }
 124