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