...
1
2
3
4
5
6
7 package bsoncore
8
9 import (
10 "fmt"
11 "io"
12 "strconv"
13 "strings"
14 )
15
16
17
18 func NewArrayLengthError(length, rem int) error {
19 return lengthError("array", length, rem)
20 }
21
22
23 type Array []byte
24
25
26
27 func NewArrayFromReader(r io.Reader) (Array, error) {
28 return newBufferFromReader(r)
29 }
30
31
32
33 func (a Array) Index(index uint) Value {
34 value, err := a.IndexErr(index)
35 if err != nil {
36 panic(err)
37 }
38 return value
39 }
40
41
42 func (a Array) IndexErr(index uint) (Value, error) {
43 elem, err := indexErr(a, index)
44 if err != nil {
45 return Value{}, err
46 }
47 return elem.Value(), err
48 }
49
50
51
52 func (a Array) DebugString() string {
53 if len(a) < 5 {
54 return "<malformed>"
55 }
56 var buf strings.Builder
57 buf.WriteString("Array")
58 length, rem, _ := ReadLength(a)
59 buf.WriteByte('(')
60 buf.WriteString(strconv.Itoa(int(length)))
61 length -= 4
62 buf.WriteString(")[")
63 var elem Element
64 var ok bool
65 for length > 1 {
66 elem, rem, ok = ReadElement(rem)
67 length -= int32(len(elem))
68 if !ok {
69 buf.WriteString(fmt.Sprintf("<malformed (%d)>", length))
70 break
71 }
72 buf.WriteString(elem.Value().DebugString())
73 if length != 1 {
74 buf.WriteByte(',')
75 }
76 }
77 buf.WriteByte(']')
78
79 return buf.String()
80 }
81
82
83
84 func (a Array) String() string {
85 if len(a) < 5 {
86 return ""
87 }
88 var buf strings.Builder
89 buf.WriteByte('[')
90
91 length, rem, _ := ReadLength(a)
92
93 length -= 4
94
95 var elem Element
96 var ok bool
97 for length > 1 {
98 elem, rem, ok = ReadElement(rem)
99 length -= int32(len(elem))
100 if !ok {
101 return ""
102 }
103 buf.WriteString(elem.Value().String())
104 if length > 1 {
105 buf.WriteByte(',')
106 }
107 }
108 if length != 1 {
109 return ""
110 }
111
112 buf.WriteByte(']')
113 return buf.String()
114 }
115
116
117
118
119 func (a Array) Values() ([]Value, error) {
120 return values(a)
121 }
122
123
124 func (a Array) Validate() error {
125 length, rem, ok := ReadLength(a)
126 if !ok {
127 return NewInsufficientBytesError(a, rem)
128 }
129 if int(length) > len(a) {
130 return NewArrayLengthError(int(length), len(a))
131 }
132 if a[length-1] != 0x00 {
133 return ErrMissingNull
134 }
135
136 length -= 4
137 var elem Element
138
139 var keyNum int64
140 for length > 1 {
141 elem, rem, ok = ReadElement(rem)
142 length -= int32(len(elem))
143 if !ok {
144 return NewInsufficientBytesError(a, rem)
145 }
146
147
148 err := elem.Validate()
149 if err != nil {
150 return err
151 }
152
153
154 if fmt.Sprint(keyNum) != elem.Key() {
155 return fmt.Errorf("array key %q is out of order or invalid", elem.Key())
156 }
157 keyNum++
158 }
159
160 if len(rem) < 1 || rem[0] != 0x00 {
161 return ErrMissingNull
162 }
163 return nil
164 }
165
View as plain text