podman

Форк
0
141 строка · 4.0 Кб
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
	"errors"
11
	"fmt"
12
	"reflect"
13
	"sync"
14

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

19
// ErrDecodeToNil is the error returned when trying to decode to a nil value
20
var ErrDecodeToNil = errors.New("cannot Decode to nil value")
21

22
// This pool is used to keep the allocations of Decoders down. This is only used for the Marshal*
23
// methods and is not consumable from outside of this package. The Decoders retrieved from this pool
24
// must have both Reset and SetRegistry called on them.
25
var decPool = sync.Pool{
26
	New: func() interface{} {
27
		return new(Decoder)
28
	},
29
}
30

31
// A Decoder reads and decodes BSON documents from a stream. It reads from a bsonrw.ValueReader as
32
// the source of BSON data.
33
type Decoder struct {
34
	dc bsoncodec.DecodeContext
35
	vr bsonrw.ValueReader
36

37
	// We persist defaultDocumentM and defaultDocumentD on the Decoder to prevent overwriting from
38
	// (*Decoder).SetContext.
39
	defaultDocumentM bool
40
	defaultDocumentD bool
41
}
42

43
// NewDecoder returns a new decoder that uses the DefaultRegistry to read from vr.
44
func NewDecoder(vr bsonrw.ValueReader) (*Decoder, error) {
45
	if vr == nil {
46
		return nil, errors.New("cannot create a new Decoder with a nil ValueReader")
47
	}
48

49
	return &Decoder{
50
		dc: bsoncodec.DecodeContext{Registry: DefaultRegistry},
51
		vr: vr,
52
	}, nil
53
}
54

55
// NewDecoderWithContext returns a new decoder that uses DecodeContext dc to read from vr.
56
func NewDecoderWithContext(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (*Decoder, error) {
57
	if dc.Registry == nil {
58
		dc.Registry = DefaultRegistry
59
	}
60
	if vr == nil {
61
		return nil, errors.New("cannot create a new Decoder with a nil ValueReader")
62
	}
63

64
	return &Decoder{
65
		dc: dc,
66
		vr: vr,
67
	}, nil
68
}
69

70
// Decode reads the next BSON document from the stream and decodes it into the
71
// value pointed to by val.
72
//
73
// The documentation for Unmarshal contains details about of BSON into a Go
74
// value.
75
func (d *Decoder) Decode(val interface{}) error {
76
	if unmarshaler, ok := val.(Unmarshaler); ok {
77
		// TODO(skriptble): Reuse a []byte here and use the AppendDocumentBytes method.
78
		buf, err := bsonrw.Copier{}.CopyDocumentToBytes(d.vr)
79
		if err != nil {
80
			return err
81
		}
82
		return unmarshaler.UnmarshalBSON(buf)
83
	}
84

85
	rval := reflect.ValueOf(val)
86
	switch rval.Kind() {
87
	case reflect.Ptr:
88
		if rval.IsNil() {
89
			return ErrDecodeToNil
90
		}
91
		rval = rval.Elem()
92
	case reflect.Map:
93
		if rval.IsNil() {
94
			return ErrDecodeToNil
95
		}
96
	default:
97
		return fmt.Errorf("argument to Decode must be a pointer or a map, but got %v", rval)
98
	}
99
	decoder, err := d.dc.LookupDecoder(rval.Type())
100
	if err != nil {
101
		return err
102
	}
103
	if d.defaultDocumentM {
104
		d.dc.DefaultDocumentM()
105
	}
106
	if d.defaultDocumentD {
107
		d.dc.DefaultDocumentD()
108
	}
109
	return decoder.DecodeValue(d.dc, d.vr, rval)
110
}
111

112
// Reset will reset the state of the decoder, using the same *DecodeContext used in
113
// the original construction but using vr for reading.
114
func (d *Decoder) Reset(vr bsonrw.ValueReader) error {
115
	d.vr = vr
116
	return nil
117
}
118

119
// SetRegistry replaces the current registry of the decoder with r.
120
func (d *Decoder) SetRegistry(r *bsoncodec.Registry) error {
121
	d.dc.Registry = r
122
	return nil
123
}
124

125
// SetContext replaces the current registry of the decoder with dc.
126
func (d *Decoder) SetContext(dc bsoncodec.DecodeContext) error {
127
	d.dc = dc
128
	return nil
129
}
130

131
// DefaultDocumentM will decode empty documents using the primitive.M type. This behavior is restricted to data typed as
132
// "interface{}" or "map[string]interface{}".
133
func (d *Decoder) DefaultDocumentM() {
134
	d.defaultDocumentM = true
135
}
136

137
// DefaultDocumentD will decode empty documents using the primitive.D type. This behavior is restricted to data typed as
138
// "interface{}" or "map[string]interface{}".
139
func (d *Decoder) DefaultDocumentD() {
140
	d.defaultDocumentD = true
141
}
142

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

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

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

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