File: new.go

package info (click to toggle)
mongo-tools 3.2.11-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 10,612 kB
  • ctags: 10,571
  • sloc: python: 5,428; ansic: 589; sh: 397; makefile: 62; lisp: 19
file content (92 lines) | stat: -rw-r--r-- 2,327 bytes parent folder | download
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
package json

import (
	"fmt"
	"reflect"
)

// Transition functions for recognizing new.
// Adapted from encoding/json/scanner.go.

// stateNe is the state after reading `ne`.
func stateNe(s *scanner, c int) int {
	if c == 'w' {
		s.step = stateNew
		return scanContinue
	}
	return s.error(c, "in literal new (expecting 'w')")
}

// stateNew is the state after reading `new`.
// Ensures that there is a space after the new keyword.
func stateNew(s *scanner, c int) int {
	if c <= ' ' && isSpace(rune(c)) {
		s.step = stateBeginObjectValue
		return scanContinue
	}
	return s.error(c, "expected space after new keyword")
}

// stateBeginObjectValue is the state after reading `new`.
func stateBeginObjectValue(s *scanner, c int) int {
	if c <= ' ' && isSpace(rune(c)) {
		return scanSkipSpace
	}
	switch c {
	case 'B': // beginning of BinData
		s.step = stateB
	case 'D': // beginning of Date
		s.step = stateD
	case 'N': // beginning of NumberInt or NumberLong
		s.step = stateNumberUpperN
	case 'O': // beginning of ObjectId
		s.step = stateO
	case 'R': // beginning of RegExp
		s.step = stateR
	case 'T': // beginning of Timestamp
		s.step = stateUpperT
	default:
		return s.error(c, "looking for beginning of value")
	}

	return scanBeginLiteral
}

// stateNumberUpperN is the state after reading `N`.
func stateNumberUpperN(s *scanner, c int) int {
	if c == 'u' {
		s.step = stateUpperNu
		return scanContinue
	}
	return s.error(c, "in literal NumberInt or NumberLong (expecting 'u')")
}

// Decodes a literal stored in the underlying byte data into v.
func (d *decodeState) storeNewLiteral(v reflect.Value, fromQuoted bool) {
	op := d.scanWhile(scanSkipSpace)
	if op != scanBeginLiteral {
		d.error(fmt.Errorf("expected beginning of constructor"))
	}

	// Read constructor identifier
	start := d.off - 1
	op = d.scanWhile(scanContinue)
	if op != scanBeginCtor {
		d.error(fmt.Errorf("expected beginning of constructor"))
	}

	// Back up so d.ctor can have the byte we just read.
	d.off--
	d.scan.undo(op)

	d.literalStore(d.data[start:d.off-1], v, fromQuoted)
}

// Returns a literal from the underlying byte data.
func (d *decodeState) getNewLiteral() interface{} {
	op := d.scanWhile(scanSkipSpace)
	if op != scanBeginLiteral {
		d.error(fmt.Errorf("expected beginning of constructor"))
	}
	return d.literalInterface()
}