forked from mongodb/mongo-go-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
array.go
97 lines (83 loc) · 2.27 KB
/
array.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
// Copyright (C) MongoDB, Inc. 2017-present.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package bsonx // import "go.mongodb.org/mongo-driver/x/bsonx"
import (
"bytes"
"errors"
"fmt"
"strconv"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
// ErrNilArray indicates that an operation was attempted on a nil *Array.
var ErrNilArray = errors.New("array is nil")
// Arr represents an array in BSON.
type Arr []Val
// String implements the fmt.Stringer interface.
func (a Arr) String() string {
var buf bytes.Buffer
buf.Write([]byte("bson.Array["))
for idx, val := range a {
if idx > 0 {
buf.Write([]byte(", "))
}
fmt.Fprintf(&buf, "%s", val)
}
buf.WriteByte(']')
return buf.String()
}
// MarshalBSONValue implements the bsoncodec.ValueMarshaler interface.
func (a Arr) MarshalBSONValue() (bsontype.Type, []byte, error) {
if a == nil {
// TODO: Should we do this?
return bsontype.Null, nil, nil
}
idx, dst := bsoncore.ReserveLength(nil)
for idx, value := range a {
t, data, _ := value.MarshalBSONValue() // marshalBSONValue never returns an error.
dst = append(dst, byte(t))
dst = append(dst, strconv.Itoa(idx)...)
dst = append(dst, 0x00)
dst = append(dst, data...)
}
dst = append(dst, 0x00)
dst = bsoncore.UpdateLength(dst, idx, int32(len(dst[idx:])))
return bsontype.Array, dst, nil
}
// UnmarshalBSONValue implements the bsoncodec.ValueUnmarshaler interface.
func (a *Arr) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
if a == nil {
return ErrNilArray
}
*a = (*a)[:0]
elements, err := bsoncore.Document(data).Elements()
if err != nil {
return err
}
for _, elem := range elements {
var val Val
rawval := elem.Value()
err = val.UnmarshalBSONValue(rawval.Type, rawval.Data)
if err != nil {
return err
}
*a = append(*a, val)
}
return nil
}
// Equal compares this document to another, returning true if they are equal.
func (a Arr) Equal(a2 Arr) bool {
if len(a) != len(a2) {
return false
}
for idx := range a {
if !a[idx].Equal(a2[idx]) {
return false
}
}
return true
}
func (Arr) idoc() {}