summaryrefslogtreecommitdiff
path: root/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mongodb.org/mongo-driver/bson/marshal.go')
-rw-r--r--vendor/go.mongodb.org/mongo-driver/bson/marshal.go225
1 files changed, 215 insertions, 10 deletions
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/marshal.go b/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
index db8d8ee92..17ce6697e 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
@@ -9,6 +9,7 @@ package bson
import (
"bytes"
"encoding/json"
+ "sync"
"go.mongodb.org/mongo-driver/bson/bsoncodec"
"go.mongodb.org/mongo-driver/bson/bsonrw"
@@ -20,17 +21,23 @@ const defaultDstCap = 256
var bvwPool = bsonrw.NewBSONValueWriterPool()
var extjPool = bsonrw.NewExtJSONValueWriterPool()
-// Marshaler is an interface implemented by types that can marshal themselves
-// into a BSON document represented as bytes. The bytes returned must be a valid
-// BSON document if the error is nil.
+// Marshaler is the interface implemented by types that can marshal themselves
+// into a valid BSON document.
+//
+// Implementations of Marshaler must return a full BSON document. To create
+// custom BSON marshaling behavior for individual values in a BSON document,
+// implement the ValueMarshaler interface instead.
type Marshaler interface {
MarshalBSON() ([]byte, error)
}
-// ValueMarshaler is an interface implemented by types that can marshal
-// themselves into a BSON value as bytes. The type must be the valid type for
-// the bytes returned. The bytes and byte type together must be valid if the
-// error is nil.
+// ValueMarshaler is the interface implemented by types that can marshal
+// themselves into a valid BSON value. The format of the returned bytes must
+// match the returned type.
+//
+// Implementations of ValueMarshaler must return an individual BSON value. To
+// create custom BSON marshaling behavior for an entire BSON document, implement
+// the Marshaler interface instead.
type ValueMarshaler interface {
MarshalBSONValue() (bsontype.Type, []byte, error)
}
@@ -48,12 +55,42 @@ func Marshal(val interface{}) ([]byte, error) {
// MarshalAppend will encode val as a BSON document and append the bytes to dst. If dst is not large enough to hold the
// bytes, it will be grown. If val is not a type that can be transformed into a document, MarshalValueAppend should be
// used instead.
+//
+// Deprecated: Use [NewEncoder] and pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewBSONValueWriter]:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+//
+// See [Encoder] for more examples.
func MarshalAppend(dst []byte, val interface{}) ([]byte, error) {
return MarshalAppendWithRegistry(DefaultRegistry, dst, val)
}
// MarshalWithRegistry returns the BSON encoding of val as a BSON document. If val is not a type that can be transformed
// into a document, MarshalValueWithRegistry should be used instead.
+//
+// Deprecated: Use [NewEncoder] and specify the Registry by calling [Encoder.SetRegistry] instead:
+//
+// buf := new(bytes.Buffer)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.SetRegistry(reg)
+//
+// See [Encoder] for more examples.
func MarshalWithRegistry(r *bsoncodec.Registry, val interface{}) ([]byte, error) {
dst := make([]byte, 0)
return MarshalAppendWithRegistry(r, dst, val)
@@ -61,6 +98,22 @@ func MarshalWithRegistry(r *bsoncodec.Registry, val interface{}) ([]byte, error)
// MarshalWithContext returns the BSON encoding of val as a BSON document using EncodeContext ec. If val is not a type
// that can be transformed into a document, MarshalValueWithContext should be used instead.
+//
+// Deprecated: Use [NewEncoder] and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.IntMinSize()
+//
+// See [Encoder] for more examples.
func MarshalWithContext(ec bsoncodec.EncodeContext, val interface{}) ([]byte, error) {
dst := make([]byte, 0)
return MarshalAppendWithContext(ec, dst, val)
@@ -69,16 +122,74 @@ func MarshalWithContext(ec bsoncodec.EncodeContext, val interface{}) ([]byte, er
// MarshalAppendWithRegistry will encode val as a BSON document using Registry r and append the bytes to dst. If dst is
// not large enough to hold the bytes, it will be grown. If val is not a type that can be transformed into a document,
// MarshalValueAppendWithRegistry should be used instead.
+//
+// Deprecated: Use [NewEncoder], and pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewBSONValueWriter], and specify the Registry by calling [Encoder.SetRegistry] instead:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.SetRegistry(reg)
+//
+// See [Encoder] for more examples.
func MarshalAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}) ([]byte, error) {
return MarshalAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val)
}
+// Pool of buffers for marshalling BSON.
+var bufPool = sync.Pool{
+ New: func() interface{} {
+ return new(bytes.Buffer)
+ },
+}
+
// MarshalAppendWithContext will encode val as a BSON document using Registry r and EncodeContext ec and append the
// bytes to dst. If dst is not large enough to hold the bytes, it will be grown. If val is not a type that can be
// transformed into a document, MarshalValueAppendWithContext should be used instead.
+//
+// Deprecated: Use [NewEncoder], pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewBSONValueWriter], and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.IntMinSize()
+//
+// See [Encoder] for more examples.
func MarshalAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}) ([]byte, error) {
- sw := new(bsonrw.SliceWriter)
- *sw = dst
+ sw := bufPool.Get().(*bytes.Buffer)
+ defer func() {
+ // Proper usage of a sync.Pool requires each entry to have approximately
+ // the same memory cost. To obtain this property when the stored type
+ // contains a variably-sized buffer, we add a hard limit on the maximum
+ // buffer to place back in the pool. We limit the size to 16MiB because
+ // that's the maximum wire message size supported by any current MongoDB
+ // server.
+ //
+ // Comment based on
+ // https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/fmt/print.go;l=147
+ //
+ // Recycle byte slices that are smaller than 16MiB and at least half
+ // occupied.
+ if sw.Cap() < 16*1024*1024 && sw.Cap()/2 < sw.Len() {
+ bufPool.Put(sw)
+ }
+ }()
+
+ sw.Reset()
vw := bvwPool.Get(sw)
defer bvwPool.Put(vw)
@@ -99,7 +210,7 @@ func MarshalAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interf
return nil, err
}
- return *sw, nil
+ return append(dst, sw.Bytes()...), nil
}
// MarshalValue returns the BSON encoding of val.
@@ -112,17 +223,26 @@ func MarshalValue(val interface{}) (bsontype.Type, []byte, error) {
// MarshalValueAppend will append the BSON encoding of val to dst. If dst is not large enough to hold the BSON encoding
// of val, dst will be grown.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
func MarshalValueAppend(dst []byte, val interface{}) (bsontype.Type, []byte, error) {
return MarshalValueAppendWithRegistry(DefaultRegistry, dst, val)
}
// MarshalValueWithRegistry returns the BSON encoding of val using Registry r.
+//
+// Deprecated: Using a custom registry to marshal individual BSON values will not be supported in Go
+// Driver 2.0.
func MarshalValueWithRegistry(r *bsoncodec.Registry, val interface{}) (bsontype.Type, []byte, error) {
dst := make([]byte, 0)
return MarshalValueAppendWithRegistry(r, dst, val)
}
// MarshalValueWithContext returns the BSON encoding of val using EncodeContext ec.
+//
+// Deprecated: Using a custom EncodeContext to marshal individual BSON elements will not be
+// supported in Go Driver 2.0.
func MarshalValueWithContext(ec bsoncodec.EncodeContext, val interface{}) (bsontype.Type, []byte, error) {
dst := make([]byte, 0)
return MarshalValueAppendWithContext(ec, dst, val)
@@ -130,12 +250,18 @@ func MarshalValueWithContext(ec bsoncodec.EncodeContext, val interface{}) (bsont
// MarshalValueAppendWithRegistry will append the BSON encoding of val to dst using Registry r. If dst is not large
// enough to hold the BSON encoding of val, dst will be grown.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
func MarshalValueAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}) (bsontype.Type, []byte, error) {
return MarshalValueAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val)
}
// MarshalValueAppendWithContext will append the BSON encoding of val to dst using EncodeContext ec. If dst is not large
// enough to hold the BSON encoding of val, dst will be grown.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
func MarshalValueAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}) (bsontype.Type, []byte, error) {
// get a ValueWriter configured to write to dst
sw := new(bsonrw.SliceWriter)
@@ -173,17 +299,63 @@ func MarshalExtJSON(val interface{}, canonical, escapeHTML bool) ([]byte, error)
// MarshalExtJSONAppend will append the extended JSON encoding of val to dst.
// If dst is not large enough to hold the extended JSON encoding of val, dst
// will be grown.
+//
+// Deprecated: Use [NewEncoder] and pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewExtJSONValueWriter] instead:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+//
+// See [Encoder] for more examples.
func MarshalExtJSONAppend(dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
return MarshalExtJSONAppendWithRegistry(DefaultRegistry, dst, val, canonical, escapeHTML)
}
// MarshalExtJSONWithRegistry returns the extended JSON encoding of val using Registry r.
+//
+// Deprecated: Use [NewEncoder] and specify the Registry by calling [Encoder.SetRegistry] instead:
+//
+// buf := new(bytes.Buffer)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.SetRegistry(reg)
+//
+// See [Encoder] for more examples.
func MarshalExtJSONWithRegistry(r *bsoncodec.Registry, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
dst := make([]byte, 0, defaultDstCap)
return MarshalExtJSONAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val, canonical, escapeHTML)
}
// MarshalExtJSONWithContext returns the extended JSON encoding of val using Registry r.
+//
+// Deprecated: Use [NewEncoder] and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+// buf := new(bytes.Buffer)
+// vw, err := bsonrw.NewBSONValueWriter(buf)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.IntMinSize()
+//
+// See [Encoder] for more examples.
func MarshalExtJSONWithContext(ec bsoncodec.EncodeContext, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
dst := make([]byte, 0, defaultDstCap)
return MarshalExtJSONAppendWithContext(ec, dst, val, canonical, escapeHTML)
@@ -192,6 +364,22 @@ func MarshalExtJSONWithContext(ec bsoncodec.EncodeContext, val interface{}, cano
// MarshalExtJSONAppendWithRegistry will append the extended JSON encoding of
// val to dst using Registry r. If dst is not large enough to hold the BSON
// encoding of val, dst will be grown.
+//
+// Deprecated: Use [NewEncoder], pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewExtJSONValueWriter], and specify the Registry by calling [Encoder.SetRegistry]
+// instead:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+//
+// See [Encoder] for more examples.
func MarshalExtJSONAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
return MarshalExtJSONAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val, canonical, escapeHTML)
}
@@ -199,6 +387,23 @@ func MarshalExtJSONAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val int
// MarshalExtJSONAppendWithContext will append the extended JSON encoding of
// val to dst using Registry r. If dst is not large enough to hold the BSON
// encoding of val, dst will be grown.
+//
+// Deprecated: Use [NewEncoder], pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewExtJSONValueWriter], and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+// buf := bytes.NewBuffer(dst)
+// vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
+// if err != nil {
+// panic(err)
+// }
+// enc, err := bson.NewEncoder(vw)
+// if err != nil {
+// panic(err)
+// }
+// enc.IntMinSize()
+//
+// See [Encoder] for more examples.
func MarshalExtJSONAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
sw := new(bsonrw.SliceWriter)
*sw = dst