diff options
Diffstat (limited to 'src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/boolean.go')
-rw-r--r-- | src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/boolean.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/boolean.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/boolean.go new file mode 100644 index 00000000000..2cae19de10d --- /dev/null +++ b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/common/json/boolean.go @@ -0,0 +1,79 @@ +// 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 Boolean. +// Adapted from encoding/json/scanner.go. + +// stateBo is the state after reading `Bo`. +func stateBo(s *scanner, c int) int { + if c == 'o' { + s.step = generateState("Boolean", []byte("lean"), stateConstructor) + return scanContinue + } + return s.error(c, "in literal Boolean (expecting 'o')") +} + +// Decodes a Boolean literal stored in the underlying byte data into v. +func (d *decodeState) storeBoolean(v reflect.Value) { + res := d.getBoolean() + switch kind := v.Kind(); kind { + case reflect.Interface, reflect.Bool: + v.Set(reflect.ValueOf(res)) + default: + d.error(fmt.Errorf("cannot store bool value into %v type", kind)) + } +} + +// Returns a Boolean literal from the underlying byte data. +func (d *decodeState) getBoolean() 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 len(args) == 0 { + return false + } + + // Ignore all but the first argument. + switch v := args[0].(type) { + case bool: + return v + case Number: + d.useNumber = useNumber + + // First try Int64 so hex numbers work, then if that fails try Float64. + num, err := v.Int64() + if err == nil { + return (num != 0) + } + + numF, err := v.Float64() + if err != nil { + d.error(fmt.Errorf("expected float64 for numeric argument of Boolean constructor, got err: %v", err)) + } + return (numF != 0) + case string: + return (v != "") + case Undefined, nil: + return false + // Parameter values of any other types should yield true. + default: + return true + } +} |