/
bson.go
111 lines (98 loc) · 2.8 KB
/
bson.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Package bson implements encoding and decoding of BSON objects as defined
// at http://bsonspec.org/spec.html. The mapping between BSON objects and Go
// values is described in the documentation for the Marshal and Unmarshal functions.
package bson
import (
"bytes"
"encoding/binary"
"errors"
"io"
)
var ErrTooShort = errors.New("bson document too short")
// Marshal returns the BSON encoding of v.
//
// Struct values encode as JSON objects. Each exported struct field becomes
// a member of the object unless
// - the field's tag is "-", or
// - the field is empty and its tag specifies the "omitempty" option.
//
// Map values encode as JSON objects. The map's key type must be string;
// the object keys are used directly as map keys.
func Marshal(v interface{}) ([]byte, error) {
return encode(v)
}
// Unmarshal parses the BSON-encoded data and stores the result in the
// value pointed to by v.
//
// Unmarshal uses the inverse of the encodings that Marshal uses,
// allocating maps, slices, and pointers as necessary.
//
// Portions of data may be retained by the decoded result in v. Data should
// not be reused.
func Unmarshal(data []byte, v interface{}) error {
if len(data) < 5 {
return ErrTooShort
}
return decode(data, v)
}
// A Decoder reads and decodes BSON objects from an input stream.
type Decoder struct {
r io.Reader
}
// NewDecoder returns a new decoder that reads from r.
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
// Decode reads the next BSON-encoded value from its input and stores it in
// the value pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of
// BSON into a Go value.
func (d *Decoder) Decode(v interface{}) error {
var header [4]byte
n, err := io.ReadFull(d.r, header[:])
if err != nil {
return err
}
if n < 4 {
return ErrTooShort
}
doclen := int64(binary.LittleEndian.Uint32(header[:])) - 4
r := io.LimitReader(d.r, doclen)
buf := bytes.NewBuffer(header[:])
nn, err := io.Copy(buf, r)
if err != nil {
return err
}
if nn != int64(doclen) {
return io.ErrUnexpectedEOF
}
return Unmarshal(buf.Bytes(), v)
}
// An Encoder writes BSON objects to an output stream.
type Encoder struct {
w io.Writer
}
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{w: w}
}
// Encode writes the BSON encoding of v to the stream, followed by a
// newline character.
//
// See the documentation for Marshal for details about the conversion of Go
// values to BSON.
func (e *Encoder) Encode(v interface{}) error {
buf, err := Marshal(v)
if err != nil {
return err
}
_, err = e.w.Write(buf)
return err
}
// ObjectId represnts a BSON ObjectId data type
type ObjectId [12]byte
// Datetime because dates
type Datetime uint64
// Timestamp because timestamp
type Timestamp uint64