summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/number.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/number.go')
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/number.go142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/number.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/number.go
new file mode 100644
index 00000000000..ae888143cb7
--- /dev/null
+++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/number.go
@@ -0,0 +1,142 @@
+// Copyright (C) MongoDB, Inc. 2014-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 json
+
+import (
+ "fmt"
+ "reflect"
+)
+
+// Transition functions for recognizing NumberInt and NumberLong.
+// Adapted from encoding/json/scanner.go.
+
+// stateUpperNu is the state after reading `Nu`.
+func stateUpperNu(s *scanner, c int) int {
+ if c == 'm' {
+ s.step = generateState("Number", []byte("ber"), stateUpperNumber)
+ return scanContinue
+ }
+ return s.error(c, "in literal Number (expecting 'm')")
+}
+
+// stateUpperNumber is the state after reading `Number`.
+func stateUpperNumber(s *scanner, c int) int {
+ if c == 'I' {
+ s.step = generateState("NumberInt", []byte("nt"), stateConstructor)
+ return scanContinue
+ }
+ if c == 'L' {
+ s.step = generateState("NumberLong", []byte("ong"), stateConstructor)
+ return scanContinue
+ }
+ return s.error(c, "in literal NumberInt or NumberLong (expecting 'I' or 'L')")
+}
+
+// Decodes a NumberInt literal stored in the underlying byte data into v.
+func (d *decodeState) storeNumberInt(v reflect.Value) {
+ op := d.scanWhile(scanSkipSpace)
+ if op != scanBeginCtor {
+ d.error(fmt.Errorf("expected beginning of constructor"))
+ }
+
+ args, err := d.ctor("NumberInt", []reflect.Type{numberIntType})
+ if err != nil {
+ d.error(err)
+ }
+ switch kind := v.Kind(); kind {
+ case reflect.Interface:
+ v.Set(args[0])
+ default:
+ d.error(fmt.Errorf("cannot store %v value into %v type", numberIntType, kind))
+ }
+}
+
+// Returns a NumberInt literal from the underlying byte data.
+func (d *decodeState) getNumberInt() interface{} {
+ op := d.scanWhile(scanSkipSpace)
+ if op != scanBeginCtor {
+ d.error(fmt.Errorf("expected beginning of constructor"))
+ }
+
+ // Prevent d.convertNumber() from parsing the argument as a float64.
+ useNumber := d.useNumber
+ d.useNumber = true
+
+ args := d.ctorInterface()
+ if err := ctorNumArgsMismatch("NumberInt", 1, len(args)); err != nil {
+ d.error(err)
+ }
+ var number Number
+ switch v := args[0].(type) {
+ case Number:
+ number = v
+ case string:
+ number = Number(v)
+ default:
+ d.error(fmt.Errorf("expected int32 for first argument of NumberInt constructor, got %T (value was %v)", v, v))
+ }
+
+ d.useNumber = useNumber
+ arg0, err := number.Int32()
+ if err != nil {
+ d.error(fmt.Errorf("expected int32 for first argument of NumberInt constructor, got %T (value was %v)", number, number))
+ }
+ return NumberInt(arg0)
+}
+
+// Decodes a NumberLong literal stored in the underlying byte data into v.
+func (d *decodeState) storeNumberLong(v reflect.Value) {
+ op := d.scanWhile(scanSkipSpace)
+ if op != scanBeginCtor {
+ d.error(fmt.Errorf("expected beginning of constructor"))
+ }
+
+ args, err := d.ctor("NumberLong", []reflect.Type{numberLongType})
+ if err != nil {
+ d.error(err)
+ }
+ switch kind := v.Kind(); kind {
+ case reflect.Interface:
+ v.Set(args[0])
+ default:
+ d.error(fmt.Errorf("cannot store %v value into %v type", numberLongType, kind))
+ }
+}
+
+// Returns a NumberLong literal from the underlying byte data.
+func (d *decodeState) getNumberLong() interface{} {
+ op := d.scanWhile(scanSkipSpace)
+ if op != scanBeginCtor {
+ d.error(fmt.Errorf("expected beginning of constructor"))
+ }
+
+ // Prevent d.convertNumber() from parsing the argument as a float64.
+ useNumber := d.useNumber
+ d.useNumber = true
+
+ args := d.ctorInterface()
+ if err := ctorNumArgsMismatch("NumberLong", 1, len(args)); err != nil {
+ d.error(err)
+ }
+ var number Number
+ switch v := args[0].(type) {
+ case Number:
+ number = v
+ case string:
+ number = Number(v)
+
+ default:
+ d.error(fmt.Errorf("expected int64 for first argument of NumberLong constructor, got %T (value was %v)", v, v))
+ }
+
+ d.useNumber = useNumber
+ arg0, err := number.Int64()
+ if err != nil {
+ d.error(fmt.Errorf("expected int64 for first argument of NumberLong constructor, got %T (value was %v)", number, number))
+ }
+ return NumberLong(arg0)
+}