podman

Форк
0
248 строк · 9.6 Кб
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 bson
8

9
import (
10
	"bytes"
11
	"encoding/json"
12

13
	"go.mongodb.org/mongo-driver/bson/bsoncodec"
14
	"go.mongodb.org/mongo-driver/bson/bsonrw"
15
	"go.mongodb.org/mongo-driver/bson/bsontype"
16
)
17

18
const defaultDstCap = 256
19

20
var bvwPool = bsonrw.NewBSONValueWriterPool()
21
var extjPool = bsonrw.NewExtJSONValueWriterPool()
22

23
// Marshaler is an interface implemented by types that can marshal themselves
24
// into a BSON document represented as bytes. The bytes returned must be a valid
25
// BSON document if the error is nil.
26
type Marshaler interface {
27
	MarshalBSON() ([]byte, error)
28
}
29

30
// ValueMarshaler is an interface implemented by types that can marshal
31
// themselves into a BSON value as bytes. The type must be the valid type for
32
// the bytes returned. The bytes and byte type together must be valid if the
33
// error is nil.
34
type ValueMarshaler interface {
35
	MarshalBSONValue() (bsontype.Type, []byte, error)
36
}
37

38
// Marshal returns the BSON encoding of val as a BSON document. If val is not a type that can be transformed into a
39
// document, MarshalValue should be used instead.
40
//
41
// Marshal will use the default registry created by NewRegistry to recursively
42
// marshal val into a []byte. Marshal will inspect struct tags and alter the
43
// marshaling process accordingly.
44
func Marshal(val interface{}) ([]byte, error) {
45
	return MarshalWithRegistry(DefaultRegistry, val)
46
}
47

48
// MarshalAppend will encode val as a BSON document and append the bytes to dst. If dst is not large enough to hold the
49
// bytes, it will be grown. If val is not a type that can be transformed into a document, MarshalValueAppend should be
50
// used instead.
51
func MarshalAppend(dst []byte, val interface{}) ([]byte, error) {
52
	return MarshalAppendWithRegistry(DefaultRegistry, dst, val)
53
}
54

55
// MarshalWithRegistry returns the BSON encoding of val as a BSON document. If val is not a type that can be transformed
56
// into a document, MarshalValueWithRegistry should be used instead.
57
func MarshalWithRegistry(r *bsoncodec.Registry, val interface{}) ([]byte, error) {
58
	dst := make([]byte, 0)
59
	return MarshalAppendWithRegistry(r, dst, val)
60
}
61

62
// MarshalWithContext returns the BSON encoding of val as a BSON document using EncodeContext ec. If val is not a type
63
// that can be transformed into a document, MarshalValueWithContext should be used instead.
64
func MarshalWithContext(ec bsoncodec.EncodeContext, val interface{}) ([]byte, error) {
65
	dst := make([]byte, 0)
66
	return MarshalAppendWithContext(ec, dst, val)
67
}
68

69
// MarshalAppendWithRegistry will encode val as a BSON document using Registry r and append the bytes to dst. If dst is
70
// not large enough to hold the bytes, it will be grown. If val is not a type that can be transformed into a document,
71
// MarshalValueAppendWithRegistry should be used instead.
72
func MarshalAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}) ([]byte, error) {
73
	return MarshalAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val)
74
}
75

76
// MarshalAppendWithContext will encode val as a BSON document using Registry r and EncodeContext ec and append the
77
// 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
78
// transformed into a document, MarshalValueAppendWithContext should be used instead.
79
func MarshalAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}) ([]byte, error) {
80
	sw := new(bsonrw.SliceWriter)
81
	*sw = dst
82
	vw := bvwPool.Get(sw)
83
	defer bvwPool.Put(vw)
84

85
	enc := encPool.Get().(*Encoder)
86
	defer encPool.Put(enc)
87

88
	err := enc.Reset(vw)
89
	if err != nil {
90
		return nil, err
91
	}
92
	err = enc.SetContext(ec)
93
	if err != nil {
94
		return nil, err
95
	}
96

97
	err = enc.Encode(val)
98
	if err != nil {
99
		return nil, err
100
	}
101

102
	return *sw, nil
103
}
104

105
// MarshalValue returns the BSON encoding of val.
106
//
107
// MarshalValue will use bson.DefaultRegistry to transform val into a BSON value. If val is a struct, this function will
108
// inspect struct tags and alter the marshalling process accordingly.
109
func MarshalValue(val interface{}) (bsontype.Type, []byte, error) {
110
	return MarshalValueWithRegistry(DefaultRegistry, val)
111
}
112

113
// MarshalValueAppend will append the BSON encoding of val to dst. If dst is not large enough to hold the BSON encoding
114
// of val, dst will be grown.
115
func MarshalValueAppend(dst []byte, val interface{}) (bsontype.Type, []byte, error) {
116
	return MarshalValueAppendWithRegistry(DefaultRegistry, dst, val)
117
}
118

119
// MarshalValueWithRegistry returns the BSON encoding of val using Registry r.
120
func MarshalValueWithRegistry(r *bsoncodec.Registry, val interface{}) (bsontype.Type, []byte, error) {
121
	dst := make([]byte, 0)
122
	return MarshalValueAppendWithRegistry(r, dst, val)
123
}
124

125
// MarshalValueWithContext returns the BSON encoding of val using EncodeContext ec.
126
func MarshalValueWithContext(ec bsoncodec.EncodeContext, val interface{}) (bsontype.Type, []byte, error) {
127
	dst := make([]byte, 0)
128
	return MarshalValueAppendWithContext(ec, dst, val)
129
}
130

131
// MarshalValueAppendWithRegistry will append the BSON encoding of val to dst using Registry r. If dst is not large
132
// enough to hold the BSON encoding of val, dst will be grown.
133
func MarshalValueAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}) (bsontype.Type, []byte, error) {
134
	return MarshalValueAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val)
135
}
136

137
// MarshalValueAppendWithContext will append the BSON encoding of val to dst using EncodeContext ec. If dst is not large
138
// enough to hold the BSON encoding of val, dst will be grown.
139
func MarshalValueAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}) (bsontype.Type, []byte, error) {
140
	// get a ValueWriter configured to write to dst
141
	sw := new(bsonrw.SliceWriter)
142
	*sw = dst
143
	vwFlusher := bvwPool.GetAtModeElement(sw)
144

145
	// get an Encoder and encode the value
146
	enc := encPool.Get().(*Encoder)
147
	defer encPool.Put(enc)
148
	if err := enc.Reset(vwFlusher); err != nil {
149
		return 0, nil, err
150
	}
151
	if err := enc.SetContext(ec); err != nil {
152
		return 0, nil, err
153
	}
154
	if err := enc.Encode(val); err != nil {
155
		return 0, nil, err
156
	}
157

158
	// flush the bytes written because we cannot guarantee that a full document has been written
159
	// after the flush, *sw will be in the format
160
	// [value type, 0 (null byte to indicate end of empty element name), value bytes..]
161
	if err := vwFlusher.Flush(); err != nil {
162
		return 0, nil, err
163
	}
164
	buffer := *sw
165
	return bsontype.Type(buffer[0]), buffer[2:], nil
166
}
167

168
// MarshalExtJSON returns the extended JSON encoding of val.
169
func MarshalExtJSON(val interface{}, canonical, escapeHTML bool) ([]byte, error) {
170
	return MarshalExtJSONWithRegistry(DefaultRegistry, val, canonical, escapeHTML)
171
}
172

173
// MarshalExtJSONAppend will append the extended JSON encoding of val to dst.
174
// If dst is not large enough to hold the extended JSON encoding of val, dst
175
// will be grown.
176
func MarshalExtJSONAppend(dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
177
	return MarshalExtJSONAppendWithRegistry(DefaultRegistry, dst, val, canonical, escapeHTML)
178
}
179

180
// MarshalExtJSONWithRegistry returns the extended JSON encoding of val using Registry r.
181
func MarshalExtJSONWithRegistry(r *bsoncodec.Registry, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
182
	dst := make([]byte, 0, defaultDstCap)
183
	return MarshalExtJSONAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val, canonical, escapeHTML)
184
}
185

186
// MarshalExtJSONWithContext returns the extended JSON encoding of val using Registry r.
187
func MarshalExtJSONWithContext(ec bsoncodec.EncodeContext, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
188
	dst := make([]byte, 0, defaultDstCap)
189
	return MarshalExtJSONAppendWithContext(ec, dst, val, canonical, escapeHTML)
190
}
191

192
// MarshalExtJSONAppendWithRegistry will append the extended JSON encoding of
193
// val to dst using Registry r. If dst is not large enough to hold the BSON
194
// encoding of val, dst will be grown.
195
func MarshalExtJSONAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
196
	return MarshalExtJSONAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val, canonical, escapeHTML)
197
}
198

199
// MarshalExtJSONAppendWithContext will append the extended JSON encoding of
200
// val to dst using Registry r. If dst is not large enough to hold the BSON
201
// encoding of val, dst will be grown.
202
func MarshalExtJSONAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
203
	sw := new(bsonrw.SliceWriter)
204
	*sw = dst
205
	ejvw := extjPool.Get(sw, canonical, escapeHTML)
206
	defer extjPool.Put(ejvw)
207

208
	enc := encPool.Get().(*Encoder)
209
	defer encPool.Put(enc)
210

211
	err := enc.Reset(ejvw)
212
	if err != nil {
213
		return nil, err
214
	}
215
	err = enc.SetContext(ec)
216
	if err != nil {
217
		return nil, err
218
	}
219

220
	err = enc.Encode(val)
221
	if err != nil {
222
		return nil, err
223
	}
224

225
	return *sw, nil
226
}
227

228
// IndentExtJSON will prefix and indent the provided extended JSON src and append it to dst.
229
func IndentExtJSON(dst *bytes.Buffer, src []byte, prefix, indent string) error {
230
	return json.Indent(dst, src, prefix, indent)
231
}
232

233
// MarshalExtJSONIndent returns the extended JSON encoding of val with each line with prefixed
234
// and indented.
235
func MarshalExtJSONIndent(val interface{}, canonical, escapeHTML bool, prefix, indent string) ([]byte, error) {
236
	marshaled, err := MarshalExtJSON(val, canonical, escapeHTML)
237
	if err != nil {
238
		return nil, err
239
	}
240

241
	var buf bytes.Buffer
242
	err = IndentExtJSON(&buf, marshaled, prefix, indent)
243
	if err != nil {
244
		return nil, err
245
	}
246

247
	return buf.Bytes(), nil
248
}
249

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.