1
2
3
4
5
6
7 package bsonrw
8
9 import (
10 "errors"
11 "fmt"
12 "io"
13 "sync"
14
15 "go.mongodb.org/mongo-driver/bson/bsontype"
16 "go.mongodb.org/mongo-driver/bson/primitive"
17 )
18
19
20
21
22 type ExtJSONValueReaderPool struct {
23 pool sync.Pool
24 }
25
26
27
28
29 func NewExtJSONValueReaderPool() *ExtJSONValueReaderPool {
30 return &ExtJSONValueReaderPool{
31 pool: sync.Pool{
32 New: func() interface{} {
33 return new(extJSONValueReader)
34 },
35 },
36 }
37 }
38
39
40
41
42 func (bvrp *ExtJSONValueReaderPool) Get(r io.Reader, canonical bool) (ValueReader, error) {
43 vr := bvrp.pool.Get().(*extJSONValueReader)
44 return vr.reset(r, canonical)
45 }
46
47
48
49
50
51 func (bvrp *ExtJSONValueReaderPool) Put(vr ValueReader) (ok bool) {
52 bvr, ok := vr.(*extJSONValueReader)
53 if !ok {
54 return false
55 }
56
57 bvr, _ = bvr.reset(nil, false)
58 bvrp.pool.Put(bvr)
59 return true
60 }
61
62 type ejvrState struct {
63 mode mode
64 vType bsontype.Type
65 depth int
66 }
67
68
69 type extJSONValueReader struct {
70 p *extJSONParser
71
72 stack []ejvrState
73 frame int
74 }
75
76
77
78
79 func NewExtJSONValueReader(r io.Reader, canonical bool) (ValueReader, error) {
80 return newExtJSONValueReader(r, canonical)
81 }
82
83 func newExtJSONValueReader(r io.Reader, canonical bool) (*extJSONValueReader, error) {
84 ejvr := new(extJSONValueReader)
85 return ejvr.reset(r, canonical)
86 }
87
88 func (ejvr *extJSONValueReader) reset(r io.Reader, canonical bool) (*extJSONValueReader, error) {
89 p := newExtJSONParser(r, canonical)
90 typ, err := p.peekType()
91
92 if err != nil {
93 return nil, ErrInvalidJSON
94 }
95
96 var m mode
97 switch typ {
98 case bsontype.EmbeddedDocument:
99 m = mTopLevel
100 case bsontype.Array:
101 m = mArray
102 default:
103 m = mValue
104 }
105
106 stack := make([]ejvrState, 1, 5)
107 stack[0] = ejvrState{
108 mode: m,
109 vType: typ,
110 }
111 return &extJSONValueReader{
112 p: p,
113 stack: stack,
114 }, nil
115 }
116
117 func (ejvr *extJSONValueReader) advanceFrame() {
118 if ejvr.frame+1 >= len(ejvr.stack) {
119 length := len(ejvr.stack)
120 if length+1 >= cap(ejvr.stack) {
121
122 buf := make([]ejvrState, 2*cap(ejvr.stack)+1)
123 copy(buf, ejvr.stack)
124 ejvr.stack = buf
125 }
126 ejvr.stack = ejvr.stack[:length+1]
127 }
128 ejvr.frame++
129
130
131 ejvr.stack[ejvr.frame].mode = 0
132 ejvr.stack[ejvr.frame].vType = 0
133 ejvr.stack[ejvr.frame].depth = 0
134 }
135
136 func (ejvr *extJSONValueReader) pushDocument() {
137 ejvr.advanceFrame()
138
139 ejvr.stack[ejvr.frame].mode = mDocument
140 ejvr.stack[ejvr.frame].depth = ejvr.p.depth
141 }
142
143 func (ejvr *extJSONValueReader) pushCodeWithScope() {
144 ejvr.advanceFrame()
145
146 ejvr.stack[ejvr.frame].mode = mCodeWithScope
147 }
148
149 func (ejvr *extJSONValueReader) pushArray() {
150 ejvr.advanceFrame()
151
152 ejvr.stack[ejvr.frame].mode = mArray
153 }
154
155 func (ejvr *extJSONValueReader) push(m mode, t bsontype.Type) {
156 ejvr.advanceFrame()
157
158 ejvr.stack[ejvr.frame].mode = m
159 ejvr.stack[ejvr.frame].vType = t
160 }
161
162 func (ejvr *extJSONValueReader) pop() {
163 switch ejvr.stack[ejvr.frame].mode {
164 case mElement, mValue:
165 ejvr.frame--
166 case mDocument, mArray, mCodeWithScope:
167 ejvr.frame -= 2
168 }
169 }
170
171 func (ejvr *extJSONValueReader) skipObject() {
172
173 depth := 1
174 for depth > 0 {
175 ejvr.p.advanceState()
176
177
178
179
180
181
182
183
184 if ejvr.p.emptyObject {
185 if ejvr.p.s == jpsSawComma {
186 ejvr.p.emptyObject = false
187 ejvr.p.advanceState()
188 }
189 depth--
190 continue
191 }
192
193 switch ejvr.p.s {
194 case jpsSawBeginObject, jpsSawBeginArray:
195 depth++
196 case jpsSawEndObject, jpsSawEndArray:
197 depth--
198 }
199 }
200 }
201
202 func (ejvr *extJSONValueReader) invalidTransitionErr(destination mode, name string, modes []mode) error {
203 te := TransitionError{
204 name: name,
205 current: ejvr.stack[ejvr.frame].mode,
206 destination: destination,
207 modes: modes,
208 action: "read",
209 }
210 if ejvr.frame != 0 {
211 te.parent = ejvr.stack[ejvr.frame-1].mode
212 }
213 return te
214 }
215
216 func (ejvr *extJSONValueReader) typeError(t bsontype.Type) error {
217 return fmt.Errorf("positioned on %s, but attempted to read %s", ejvr.stack[ejvr.frame].vType, t)
218 }
219
220 func (ejvr *extJSONValueReader) ensureElementValue(t bsontype.Type, destination mode, callerName string, addModes ...mode) error {
221 switch ejvr.stack[ejvr.frame].mode {
222 case mElement, mValue:
223 if ejvr.stack[ejvr.frame].vType != t {
224 return ejvr.typeError(t)
225 }
226 default:
227 modes := []mode{mElement, mValue}
228 if addModes != nil {
229 modes = append(modes, addModes...)
230 }
231 return ejvr.invalidTransitionErr(destination, callerName, modes)
232 }
233
234 return nil
235 }
236
237 func (ejvr *extJSONValueReader) Type() bsontype.Type {
238 return ejvr.stack[ejvr.frame].vType
239 }
240
241 func (ejvr *extJSONValueReader) Skip() error {
242 switch ejvr.stack[ejvr.frame].mode {
243 case mElement, mValue:
244 default:
245 return ejvr.invalidTransitionErr(0, "Skip", []mode{mElement, mValue})
246 }
247
248 defer ejvr.pop()
249
250 t := ejvr.stack[ejvr.frame].vType
251 switch t {
252 case bsontype.Array, bsontype.EmbeddedDocument, bsontype.CodeWithScope:
253
254 ejvr.skipObject()
255 default:
256 _, err := ejvr.p.readValue(t)
257 if err != nil {
258 return err
259 }
260 }
261
262 return nil
263 }
264
265 func (ejvr *extJSONValueReader) ReadArray() (ArrayReader, error) {
266 switch ejvr.stack[ejvr.frame].mode {
267 case mTopLevel:
268 case mArray:
269 return ejvr, nil
270 default:
271 if err := ejvr.ensureElementValue(bsontype.Array, mArray, "ReadArray", mTopLevel, mArray); err != nil {
272 return nil, err
273 }
274 }
275
276 ejvr.pushArray()
277
278 return ejvr, nil
279 }
280
281 func (ejvr *extJSONValueReader) ReadBinary() (b []byte, btype byte, err error) {
282 if err := ejvr.ensureElementValue(bsontype.Binary, 0, "ReadBinary"); err != nil {
283 return nil, 0, err
284 }
285
286 v, err := ejvr.p.readValue(bsontype.Binary)
287 if err != nil {
288 return nil, 0, err
289 }
290
291 b, btype, err = v.parseBinary()
292
293 ejvr.pop()
294 return b, btype, err
295 }
296
297 func (ejvr *extJSONValueReader) ReadBoolean() (bool, error) {
298 if err := ejvr.ensureElementValue(bsontype.Boolean, 0, "ReadBoolean"); err != nil {
299 return false, err
300 }
301
302 v, err := ejvr.p.readValue(bsontype.Boolean)
303 if err != nil {
304 return false, err
305 }
306
307 if v.t != bsontype.Boolean {
308 return false, fmt.Errorf("expected type bool, but got type %s", v.t)
309 }
310
311 ejvr.pop()
312 return v.v.(bool), nil
313 }
314
315 func (ejvr *extJSONValueReader) ReadDocument() (DocumentReader, error) {
316 switch ejvr.stack[ejvr.frame].mode {
317 case mTopLevel:
318 return ejvr, nil
319 case mElement, mValue:
320 if ejvr.stack[ejvr.frame].vType != bsontype.EmbeddedDocument {
321 return nil, ejvr.typeError(bsontype.EmbeddedDocument)
322 }
323
324 ejvr.pushDocument()
325 return ejvr, nil
326 default:
327 return nil, ejvr.invalidTransitionErr(mDocument, "ReadDocument", []mode{mTopLevel, mElement, mValue})
328 }
329 }
330
331 func (ejvr *extJSONValueReader) ReadCodeWithScope() (code string, dr DocumentReader, err error) {
332 if err = ejvr.ensureElementValue(bsontype.CodeWithScope, 0, "ReadCodeWithScope"); err != nil {
333 return "", nil, err
334 }
335
336 v, err := ejvr.p.readValue(bsontype.CodeWithScope)
337 if err != nil {
338 return "", nil, err
339 }
340
341 code, err = v.parseJavascript()
342
343 ejvr.pushCodeWithScope()
344 return code, ejvr, err
345 }
346
347 func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid primitive.ObjectID, err error) {
348 if err = ejvr.ensureElementValue(bsontype.DBPointer, 0, "ReadDBPointer"); err != nil {
349 return "", primitive.NilObjectID, err
350 }
351
352 v, err := ejvr.p.readValue(bsontype.DBPointer)
353 if err != nil {
354 return "", primitive.NilObjectID, err
355 }
356
357 ns, oid, err = v.parseDBPointer()
358
359 ejvr.pop()
360 return ns, oid, err
361 }
362
363 func (ejvr *extJSONValueReader) ReadDateTime() (int64, error) {
364 if err := ejvr.ensureElementValue(bsontype.DateTime, 0, "ReadDateTime"); err != nil {
365 return 0, err
366 }
367
368 v, err := ejvr.p.readValue(bsontype.DateTime)
369 if err != nil {
370 return 0, err
371 }
372
373 d, err := v.parseDateTime()
374
375 ejvr.pop()
376 return d, err
377 }
378
379 func (ejvr *extJSONValueReader) ReadDecimal128() (primitive.Decimal128, error) {
380 if err := ejvr.ensureElementValue(bsontype.Decimal128, 0, "ReadDecimal128"); err != nil {
381 return primitive.Decimal128{}, err
382 }
383
384 v, err := ejvr.p.readValue(bsontype.Decimal128)
385 if err != nil {
386 return primitive.Decimal128{}, err
387 }
388
389 d, err := v.parseDecimal128()
390
391 ejvr.pop()
392 return d, err
393 }
394
395 func (ejvr *extJSONValueReader) ReadDouble() (float64, error) {
396 if err := ejvr.ensureElementValue(bsontype.Double, 0, "ReadDouble"); err != nil {
397 return 0, err
398 }
399
400 v, err := ejvr.p.readValue(bsontype.Double)
401 if err != nil {
402 return 0, err
403 }
404
405 d, err := v.parseDouble()
406
407 ejvr.pop()
408 return d, err
409 }
410
411 func (ejvr *extJSONValueReader) ReadInt32() (int32, error) {
412 if err := ejvr.ensureElementValue(bsontype.Int32, 0, "ReadInt32"); err != nil {
413 return 0, err
414 }
415
416 v, err := ejvr.p.readValue(bsontype.Int32)
417 if err != nil {
418 return 0, err
419 }
420
421 i, err := v.parseInt32()
422
423 ejvr.pop()
424 return i, err
425 }
426
427 func (ejvr *extJSONValueReader) ReadInt64() (int64, error) {
428 if err := ejvr.ensureElementValue(bsontype.Int64, 0, "ReadInt64"); err != nil {
429 return 0, err
430 }
431
432 v, err := ejvr.p.readValue(bsontype.Int64)
433 if err != nil {
434 return 0, err
435 }
436
437 i, err := v.parseInt64()
438
439 ejvr.pop()
440 return i, err
441 }
442
443 func (ejvr *extJSONValueReader) ReadJavascript() (code string, err error) {
444 if err = ejvr.ensureElementValue(bsontype.JavaScript, 0, "ReadJavascript"); err != nil {
445 return "", err
446 }
447
448 v, err := ejvr.p.readValue(bsontype.JavaScript)
449 if err != nil {
450 return "", err
451 }
452
453 code, err = v.parseJavascript()
454
455 ejvr.pop()
456 return code, err
457 }
458
459 func (ejvr *extJSONValueReader) ReadMaxKey() error {
460 if err := ejvr.ensureElementValue(bsontype.MaxKey, 0, "ReadMaxKey"); err != nil {
461 return err
462 }
463
464 v, err := ejvr.p.readValue(bsontype.MaxKey)
465 if err != nil {
466 return err
467 }
468
469 err = v.parseMinMaxKey("max")
470
471 ejvr.pop()
472 return err
473 }
474
475 func (ejvr *extJSONValueReader) ReadMinKey() error {
476 if err := ejvr.ensureElementValue(bsontype.MinKey, 0, "ReadMinKey"); err != nil {
477 return err
478 }
479
480 v, err := ejvr.p.readValue(bsontype.MinKey)
481 if err != nil {
482 return err
483 }
484
485 err = v.parseMinMaxKey("min")
486
487 ejvr.pop()
488 return err
489 }
490
491 func (ejvr *extJSONValueReader) ReadNull() error {
492 if err := ejvr.ensureElementValue(bsontype.Null, 0, "ReadNull"); err != nil {
493 return err
494 }
495
496 v, err := ejvr.p.readValue(bsontype.Null)
497 if err != nil {
498 return err
499 }
500
501 if v.t != bsontype.Null {
502 return fmt.Errorf("expected type null but got type %s", v.t)
503 }
504
505 ejvr.pop()
506 return nil
507 }
508
509 func (ejvr *extJSONValueReader) ReadObjectID() (primitive.ObjectID, error) {
510 if err := ejvr.ensureElementValue(bsontype.ObjectID, 0, "ReadObjectID"); err != nil {
511 return primitive.ObjectID{}, err
512 }
513
514 v, err := ejvr.p.readValue(bsontype.ObjectID)
515 if err != nil {
516 return primitive.ObjectID{}, err
517 }
518
519 oid, err := v.parseObjectID()
520
521 ejvr.pop()
522 return oid, err
523 }
524
525 func (ejvr *extJSONValueReader) ReadRegex() (pattern string, options string, err error) {
526 if err = ejvr.ensureElementValue(bsontype.Regex, 0, "ReadRegex"); err != nil {
527 return "", "", err
528 }
529
530 v, err := ejvr.p.readValue(bsontype.Regex)
531 if err != nil {
532 return "", "", err
533 }
534
535 pattern, options, err = v.parseRegex()
536
537 ejvr.pop()
538 return pattern, options, err
539 }
540
541 func (ejvr *extJSONValueReader) ReadString() (string, error) {
542 if err := ejvr.ensureElementValue(bsontype.String, 0, "ReadString"); err != nil {
543 return "", err
544 }
545
546 v, err := ejvr.p.readValue(bsontype.String)
547 if err != nil {
548 return "", err
549 }
550
551 if v.t != bsontype.String {
552 return "", fmt.Errorf("expected type string but got type %s", v.t)
553 }
554
555 ejvr.pop()
556 return v.v.(string), nil
557 }
558
559 func (ejvr *extJSONValueReader) ReadSymbol() (symbol string, err error) {
560 if err = ejvr.ensureElementValue(bsontype.Symbol, 0, "ReadSymbol"); err != nil {
561 return "", err
562 }
563
564 v, err := ejvr.p.readValue(bsontype.Symbol)
565 if err != nil {
566 return "", err
567 }
568
569 symbol, err = v.parseSymbol()
570
571 ejvr.pop()
572 return symbol, err
573 }
574
575 func (ejvr *extJSONValueReader) ReadTimestamp() (t uint32, i uint32, err error) {
576 if err = ejvr.ensureElementValue(bsontype.Timestamp, 0, "ReadTimestamp"); err != nil {
577 return 0, 0, err
578 }
579
580 v, err := ejvr.p.readValue(bsontype.Timestamp)
581 if err != nil {
582 return 0, 0, err
583 }
584
585 t, i, err = v.parseTimestamp()
586
587 ejvr.pop()
588 return t, i, err
589 }
590
591 func (ejvr *extJSONValueReader) ReadUndefined() error {
592 if err := ejvr.ensureElementValue(bsontype.Undefined, 0, "ReadUndefined"); err != nil {
593 return err
594 }
595
596 v, err := ejvr.p.readValue(bsontype.Undefined)
597 if err != nil {
598 return err
599 }
600
601 err = v.parseUndefined()
602
603 ejvr.pop()
604 return err
605 }
606
607 func (ejvr *extJSONValueReader) ReadElement() (string, ValueReader, error) {
608 switch ejvr.stack[ejvr.frame].mode {
609 case mTopLevel, mDocument, mCodeWithScope:
610 default:
611 return "", nil, ejvr.invalidTransitionErr(mElement, "ReadElement", []mode{mTopLevel, mDocument, mCodeWithScope})
612 }
613
614 name, t, err := ejvr.p.readKey()
615
616 if err != nil {
617 if errors.Is(err, ErrEOD) {
618 if ejvr.stack[ejvr.frame].mode == mCodeWithScope {
619 _, err := ejvr.p.peekType()
620 if err != nil {
621 return "", nil, err
622 }
623 }
624
625 ejvr.pop()
626 }
627
628 return "", nil, err
629 }
630
631 ejvr.push(mElement, t)
632 return name, ejvr, nil
633 }
634
635 func (ejvr *extJSONValueReader) ReadValue() (ValueReader, error) {
636 switch ejvr.stack[ejvr.frame].mode {
637 case mArray:
638 default:
639 return nil, ejvr.invalidTransitionErr(mValue, "ReadValue", []mode{mArray})
640 }
641
642 t, err := ejvr.p.peekType()
643 if err != nil {
644 if errors.Is(err, ErrEOA) {
645 ejvr.pop()
646 }
647
648 return nil, err
649 }
650
651 ejvr.push(mValue, t)
652 return ejvr, nil
653 }
654
View as plain text