summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/src/github.com/mongodb/mongo-tools/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/src/github.com/mongodb/mongo-tools/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go')
-rw-r--r--src/mongo/gotools/src/github.com/mongodb/mongo-tools/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go1015
1 files changed, 0 insertions, 1015 deletions
diff --git a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go b/src/mongo/gotools/src/github.com/mongodb/mongo-tools/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
deleted file mode 100644
index ca29815495c..00000000000
--- a/src/mongo/gotools/src/github.com/mongodb/mongo-tools/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
+++ /dev/null
@@ -1,1015 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-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 bsoncore
-
-import (
- "bytes"
- "encoding/base64"
- "fmt"
- "math"
- "sort"
- "strconv"
- "strings"
- "time"
- "unicode/utf8"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-// ElementTypeError specifies that a method to obtain a BSON value an incorrect type was called on a bson.Value.
-type ElementTypeError struct {
- Method string
- Type bsontype.Type
-}
-
-// Error implements the error interface.
-func (ete ElementTypeError) Error() string {
- return "Call of " + ete.Method + " on " + ete.Type.String() + " type"
-}
-
-// Value represents a BSON value with a type and raw bytes.
-type Value struct {
- Type bsontype.Type
- Data []byte
-}
-
-// Validate ensures the value is a valid BSON value.
-func (v Value) Validate() error {
- _, _, valid := readValue(v.Data, v.Type)
- if !valid {
- return NewInsufficientBytesError(v.Data, v.Data)
- }
- return nil
-}
-
-// IsNumber returns true if the type of v is a numeric BSON type.
-func (v Value) IsNumber() bool {
- switch v.Type {
- case bsontype.Double, bsontype.Int32, bsontype.Int64, bsontype.Decimal128:
- return true
- default:
- return false
- }
-}
-
-// AsInt32 returns a BSON number as an int32. If the BSON type is not a numeric one, this method
-// will panic.
-//
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsInt32() int32 {
- if !v.IsNumber() {
- panic(ElementTypeError{"bsoncore.Value.AsInt32", v.Type})
- }
- var i32 int32
- switch v.Type {
- case bsontype.Double:
- f64, _, ok := ReadDouble(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- i32 = int32(f64)
- case bsontype.Int32:
- var ok bool
- i32, _, ok = ReadInt32(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- case bsontype.Int64:
- i64, _, ok := ReadInt64(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- i32 = int32(i64)
- case bsontype.Decimal128:
- panic(ElementTypeError{"bsoncore.Value.AsInt32", v.Type})
- }
- return i32
-}
-
-// AsInt32OK functions the same as AsInt32 but returns a boolean instead of panicking. False
-// indicates an error.
-//
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsInt32OK() (int32, bool) {
- if !v.IsNumber() {
- return 0, false
- }
- var i32 int32
- switch v.Type {
- case bsontype.Double:
- f64, _, ok := ReadDouble(v.Data)
- if !ok {
- return 0, false
- }
- i32 = int32(f64)
- case bsontype.Int32:
- var ok bool
- i32, _, ok = ReadInt32(v.Data)
- if !ok {
- return 0, false
- }
- case bsontype.Int64:
- i64, _, ok := ReadInt64(v.Data)
- if !ok {
- return 0, false
- }
- i32 = int32(i64)
- case bsontype.Decimal128:
- return 0, false
- }
- return i32, true
-}
-
-// AsInt64 returns a BSON number as an int64. If the BSON type is not a numeric one, this method
-// will panic.
-//
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsInt64() int64 {
- if !v.IsNumber() {
- panic(ElementTypeError{"bsoncore.Value.AsInt64", v.Type})
- }
- var i64 int64
- switch v.Type {
- case bsontype.Double:
- f64, _, ok := ReadDouble(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- i64 = int64(f64)
- case bsontype.Int32:
- var ok bool
- i32, _, ok := ReadInt32(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- i64 = int64(i32)
- case bsontype.Int64:
- var ok bool
- i64, _, ok = ReadInt64(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- case bsontype.Decimal128:
- panic(ElementTypeError{"bsoncore.Value.AsInt64", v.Type})
- }
- return i64
-}
-
-// AsInt64OK functions the same as AsInt64 but returns a boolean instead of panicking. False
-// indicates an error.
-//
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsInt64OK() (int64, bool) {
- if !v.IsNumber() {
- return 0, false
- }
- var i64 int64
- switch v.Type {
- case bsontype.Double:
- f64, _, ok := ReadDouble(v.Data)
- if !ok {
- return 0, false
- }
- i64 = int64(f64)
- case bsontype.Int32:
- var ok bool
- i32, _, ok := ReadInt32(v.Data)
- if !ok {
- return 0, false
- }
- i64 = int64(i32)
- case bsontype.Int64:
- var ok bool
- i64, _, ok = ReadInt64(v.Data)
- if !ok {
- return 0, false
- }
- case bsontype.Decimal128:
- return 0, false
- }
- return i64, true
-}
-
-// AsFloat64 returns a BSON number as an float64. If the BSON type is not a numeric one, this method
-// will panic.
-//
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsFloat64() float64 { return 0 }
-
-// AsFloat64OK functions the same as AsFloat64 but returns a boolean instead of panicking. False
-// indicates an error.
-//
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsFloat64OK() (float64, bool) { return 0, false }
-
-// Add will add this value to another. This is currently only implemented for strings and numbers.
-// If either value is a string, the other type is coerced into a string and added to the other.
-//
-// This method will alter v and will attempt to reuse the []byte of v. If the []byte is too small,
-// it will be expanded.
-func (v *Value) Add(v2 Value) error { return nil }
-
-// Equal compaes v to v2 and returns true if they are equal.
-func (v Value) Equal(v2 Value) bool {
- if v.Type != v2.Type {
- return false
- }
-
- return bytes.Equal(v.Data, v2.Data)
-}
-
-// String implements the fmt.String interface. This method will return values in extended JSON
-// format. If the value is not valid, this returns an empty string
-func (v Value) String() string {
- switch v.Type {
- case bsontype.Double:
- f64, ok := v.DoubleOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$numberDouble":"%s"}`, formatDouble(f64))
- case bsontype.String:
- str, ok := v.StringValueOK()
- if !ok {
- return ""
- }
- return escapeString(str)
- case bsontype.EmbeddedDocument:
- doc, ok := v.DocumentOK()
- if !ok {
- return ""
- }
- return doc.String()
- case bsontype.Array:
- arr, ok := v.ArrayOK()
- if !ok {
- return ""
- }
- return docAsArray(arr, false)
- case bsontype.Binary:
- subtype, data, ok := v.BinaryOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$binary":{"base64":"%s","subType":"%02x"}}`, base64.StdEncoding.EncodeToString(data), subtype)
- case bsontype.Undefined:
- return `{"$undefined":true}`
- case bsontype.ObjectID:
- oid, ok := v.ObjectIDOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$oid":"%s"}`, oid.Hex())
- case bsontype.Boolean:
- b, ok := v.BooleanOK()
- if !ok {
- return ""
- }
- return strconv.FormatBool(b)
- case bsontype.DateTime:
- dt, ok := v.DateTimeOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$date":{"$numberLong":"%d"}}`, dt)
- case bsontype.Null:
- return "null"
- case bsontype.Regex:
- pattern, options, ok := v.RegexOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(
- `{"$regularExpression":{"pattern":%s,"options":"%s"}}`,
- escapeString(pattern), sortStringAlphebeticAscending(options),
- )
- case bsontype.DBPointer:
- ns, pointer, ok := v.DBPointerOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$dbPointer":{"$ref":%s,"$id":{"$oid":"%s"}}}`, escapeString(ns), pointer.Hex())
- case bsontype.JavaScript:
- js, ok := v.JavaScriptOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$code":%s}`, escapeString(js))
- case bsontype.Symbol:
- symbol, ok := v.SymbolOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$symbol":%s}`, escapeString(symbol))
- case bsontype.CodeWithScope:
- code, scope, ok := v.CodeWithScopeOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope)
- case bsontype.Int32:
- i32, ok := v.Int32OK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$numberInt":"%d"}`, i32)
- case bsontype.Timestamp:
- t, i, ok := v.TimestampOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$timestamp":{"t":"%s","i":"%s"}}`, strconv.FormatUint(uint64(t), 10), strconv.FormatUint(uint64(i), 10))
- case bsontype.Int64:
- i64, ok := v.Int64OK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$numberLong":"%d"}`, i64)
- case bsontype.Decimal128:
- d128, ok := v.Decimal128OK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$numberDecimal":"%s"}`, d128.String())
- case bsontype.MinKey:
- return `{"$minKey":1}`
- case bsontype.MaxKey:
- return `{"$maxKey":1}`
- default:
- return ""
- }
-}
-
-// DebugString outputs a human readable version of Document. It will attempt to stringify the
-// valid components of the document even if the entire document is not valid.
-func (v Value) DebugString() string {
- switch v.Type {
- case bsontype.String:
- str, ok := v.StringValueOK()
- if !ok {
- return "<malformed>"
- }
- return escapeString(str)
- case bsontype.EmbeddedDocument:
- doc, ok := v.DocumentOK()
- if !ok {
- return "<malformed>"
- }
- return doc.DebugString()
- case bsontype.Array:
- arr, ok := v.ArrayOK()
- if !ok {
- return "<malformed>"
- }
- return docAsArray(arr, true)
- case bsontype.CodeWithScope:
- code, scope, ok := v.CodeWithScopeOK()
- if !ok {
- return ""
- }
- return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope.DebugString())
- default:
- str := v.String()
- if str == "" {
- return "<malformed>"
- }
- return str
- }
-}
-
-// Double returns the float64 value for this element.
-// It panics if e's BSON type is not bsontype.Double.
-func (v Value) Double() float64 {
- if v.Type != bsontype.Double {
- panic(ElementTypeError{"bsoncore.Value.Double", v.Type})
- }
- f64, _, ok := ReadDouble(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return f64
-}
-
-// DoubleOK is the same as Double, but returns a boolean instead of panicking.
-func (v Value) DoubleOK() (float64, bool) {
- if v.Type != bsontype.Double {
- return 0, false
- }
- f64, _, ok := ReadDouble(v.Data)
- if !ok {
- return 0, false
- }
- return f64, true
-}
-
-// StringValue returns the string balue for this element.
-// It panics if e's BSON type is not bsontype.String.
-//
-// NOTE: This method is called StringValue to avoid a collision with the String method which
-// implements the fmt.Stringer interface.
-func (v Value) StringValue() string {
- if v.Type != bsontype.String {
- panic(ElementTypeError{"bsoncore.Value.StringValue", v.Type})
- }
- str, _, ok := ReadString(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return str
-}
-
-// StringValueOK is the same as StringValue, but returns a boolean instead of
-// panicking.
-func (v Value) StringValueOK() (string, bool) {
- if v.Type != bsontype.String {
- return "", false
- }
- str, _, ok := ReadString(v.Data)
- if !ok {
- return "", false
- }
- return str, true
-}
-
-// Document returns the BSON document the Value represents as a Document. It panics if the
-// value is a BSON type other than document.
-func (v Value) Document() Document {
- if v.Type != bsontype.EmbeddedDocument {
- panic(ElementTypeError{"bsoncore.Value.Document", v.Type})
- }
- doc, _, ok := ReadDocument(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return doc
-}
-
-// DocumentOK is the same as Document, except it returns a boolean
-// instead of panicking.
-func (v Value) DocumentOK() (Document, bool) {
- if v.Type != bsontype.EmbeddedDocument {
- return nil, false
- }
- doc, _, ok := ReadDocument(v.Data)
- if !ok {
- return nil, false
- }
- return doc, true
-}
-
-// Array returns the BSON array the Value represents as an Array. It panics if the
-// value is a BSON type other than array.
-func (v Value) Array() Document {
- if v.Type != bsontype.Array {
- panic(ElementTypeError{"bsoncore.Value.Array", v.Type})
- }
- arr, _, ok := ReadArray(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return arr
-}
-
-// ArrayOK is the same as Array, except it returns a boolean instead
-// of panicking.
-func (v Value) ArrayOK() (Document, bool) {
- if v.Type != bsontype.Array {
- return nil, false
- }
- arr, _, ok := ReadArray(v.Data)
- if !ok {
- return nil, false
- }
- return arr, true
-}
-
-// Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type
-// other than binary.
-func (v Value) Binary() (subtype byte, data []byte) {
- if v.Type != bsontype.Binary {
- panic(ElementTypeError{"bsoncore.Value.Binary", v.Type})
- }
- subtype, data, _, ok := ReadBinary(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return subtype, data
-}
-
-// BinaryOK is the same as Binary, except it returns a boolean instead of
-// panicking.
-func (v Value) BinaryOK() (subtype byte, data []byte, ok bool) {
- if v.Type != bsontype.Binary {
- return 0x00, nil, false
- }
- subtype, data, _, ok = ReadBinary(v.Data)
- if !ok {
- return 0x00, nil, false
- }
- return subtype, data, true
-}
-
-// ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON
-// type other than objectid.
-func (v Value) ObjectID() primitive.ObjectID {
- if v.Type != bsontype.ObjectID {
- panic(ElementTypeError{"bsoncore.Value.ObjectID", v.Type})
- }
- oid, _, ok := ReadObjectID(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return oid
-}
-
-// ObjectIDOK is the same as ObjectID, except it returns a boolean instead of
-// panicking.
-func (v Value) ObjectIDOK() (primitive.ObjectID, bool) {
- if v.Type != bsontype.ObjectID {
- return primitive.ObjectID{}, false
- }
- oid, _, ok := ReadObjectID(v.Data)
- if !ok {
- return primitive.ObjectID{}, false
- }
- return oid, true
-}
-
-// Boolean returns the boolean value the Value represents. It panics if the
-// value is a BSON type other than boolean.
-func (v Value) Boolean() bool {
- if v.Type != bsontype.Boolean {
- panic(ElementTypeError{"bsoncore.Value.Boolean", v.Type})
- }
- b, _, ok := ReadBoolean(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return b
-}
-
-// BooleanOK is the same as Boolean, except it returns a boolean instead of
-// panicking.
-func (v Value) BooleanOK() (bool, bool) {
- if v.Type != bsontype.Boolean {
- return false, false
- }
- b, _, ok := ReadBoolean(v.Data)
- if !ok {
- return false, false
- }
- return b, true
-}
-
-// DateTime returns the BSON datetime value the Value represents as a
-// unix timestamp. It panics if the value is a BSON type other than datetime.
-func (v Value) DateTime() int64 {
- if v.Type != bsontype.DateTime {
- panic(ElementTypeError{"bsoncore.Value.DateTime", v.Type})
- }
- dt, _, ok := ReadDateTime(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return dt
-}
-
-// DateTimeOK is the same as DateTime, except it returns a boolean instead of
-// panicking.
-func (v Value) DateTimeOK() (int64, bool) {
- if v.Type != bsontype.DateTime {
- return 0, false
- }
- dt, _, ok := ReadDateTime(v.Data)
- if !ok {
- return 0, false
- }
- return dt, true
-}
-
-// Time returns the BSON datetime value the Value represents. It panics if the value is a BSON
-// type other than datetime.
-func (v Value) Time() time.Time {
- if v.Type != bsontype.DateTime {
- panic(ElementTypeError{"bsoncore.Value.Time", v.Type})
- }
- dt, _, ok := ReadDateTime(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return time.Unix(int64(dt)/1000, int64(dt)%1000*1000000)
-}
-
-// TimeOK is the same as Time, except it returns a boolean instead of
-// panicking.
-func (v Value) TimeOK() (time.Time, bool) {
- if v.Type != bsontype.DateTime {
- return time.Time{}, false
- }
- dt, _, ok := ReadDateTime(v.Data)
- if !ok {
- return time.Time{}, false
- }
- return time.Unix(int64(dt)/1000, int64(dt)%1000*1000000), true
-}
-
-// Regex returns the BSON regex value the Value represents. It panics if the value is a BSON
-// type other than regex.
-func (v Value) Regex() (pattern, options string) {
- if v.Type != bsontype.Regex {
- panic(ElementTypeError{"bsoncore.Value.Regex", v.Type})
- }
- pattern, options, _, ok := ReadRegex(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return pattern, options
-}
-
-// RegexOK is the same as Regex, except it returns a boolean instead of
-// panicking.
-func (v Value) RegexOK() (pattern, options string, ok bool) {
- if v.Type != bsontype.Regex {
- return "", "", false
- }
- pattern, options, _, ok = ReadRegex(v.Data)
- if !ok {
- return "", "", false
- }
- return pattern, options, true
-}
-
-// DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON
-// type other than DBPointer.
-func (v Value) DBPointer() (string, primitive.ObjectID) {
- if v.Type != bsontype.DBPointer {
- panic(ElementTypeError{"bsoncore.Value.DBPointer", v.Type})
- }
- ns, pointer, _, ok := ReadDBPointer(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return ns, pointer
-}
-
-// DBPointerOK is the same as DBPoitner, except that it returns a boolean
-// instead of panicking.
-func (v Value) DBPointerOK() (string, primitive.ObjectID, bool) {
- if v.Type != bsontype.DBPointer {
- return "", primitive.ObjectID{}, false
- }
- ns, pointer, _, ok := ReadDBPointer(v.Data)
- if !ok {
- return "", primitive.ObjectID{}, false
- }
- return ns, pointer, true
-}
-
-// JavaScript returns the BSON JavaScript code value the Value represents. It panics if the value is
-// a BSON type other than JavaScript code.
-func (v Value) JavaScript() string {
- if v.Type != bsontype.JavaScript {
- panic(ElementTypeError{"bsoncore.Value.JavaScript", v.Type})
- }
- js, _, ok := ReadJavaScript(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return js
-}
-
-// JavaScriptOK is the same as Javascript, excepti that it returns a boolean
-// instead of panicking.
-func (v Value) JavaScriptOK() (string, bool) {
- if v.Type != bsontype.JavaScript {
- return "", false
- }
- js, _, ok := ReadJavaScript(v.Data)
- if !ok {
- return "", false
- }
- return js, true
-}
-
-// Symbol returns the BSON symbol value the Value represents. It panics if the value is a BSON
-// type other than symbol.
-func (v Value) Symbol() string {
- if v.Type != bsontype.Symbol {
- panic(ElementTypeError{"bsoncore.Value.Symbol", v.Type})
- }
- symbol, _, ok := ReadSymbol(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return symbol
-}
-
-// SymbolOK is the same as Symbol, excepti that it returns a boolean
-// instead of panicking.
-func (v Value) SymbolOK() (string, bool) {
- if v.Type != bsontype.Symbol {
- return "", false
- }
- symbol, _, ok := ReadSymbol(v.Data)
- if !ok {
- return "", false
- }
- return symbol, true
-}
-
-// CodeWithScope returns the BSON JavaScript code with scope the Value represents.
-// It panics if the value is a BSON type other than JavaScript code with scope.
-func (v Value) CodeWithScope() (string, Document) {
- if v.Type != bsontype.CodeWithScope {
- panic(ElementTypeError{"bsoncore.Value.CodeWithScope", v.Type})
- }
- code, scope, _, ok := ReadCodeWithScope(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return code, scope
-}
-
-// CodeWithScopeOK is the same as CodeWithScope, except that it returns a boolean instead of
-// panicking.
-func (v Value) CodeWithScopeOK() (string, Document, bool) {
- if v.Type != bsontype.CodeWithScope {
- return "", nil, false
- }
- code, scope, _, ok := ReadCodeWithScope(v.Data)
- if !ok {
- return "", nil, false
- }
- return code, scope, true
-}
-
-// Int32 returns the int32 the Value represents. It panics if the value is a BSON type other than
-// int32.
-func (v Value) Int32() int32 {
- if v.Type != bsontype.Int32 {
- panic(ElementTypeError{"bsoncore.Value.Int32", v.Type})
- }
- i32, _, ok := ReadInt32(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return i32
-}
-
-// Int32OK is the same as Int32, except that it returns a boolean instead of
-// panicking.
-func (v Value) Int32OK() (int32, bool) {
- if v.Type != bsontype.Int32 {
- return 0, false
- }
- i32, _, ok := ReadInt32(v.Data)
- if !ok {
- return 0, false
- }
- return i32, true
-}
-
-// Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a
-// BSON type other than timestamp.
-func (v Value) Timestamp() (t, i uint32) {
- if v.Type != bsontype.Timestamp {
- panic(ElementTypeError{"bsoncore.Value.Timestamp", v.Type})
- }
- t, i, _, ok := ReadTimestamp(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return t, i
-}
-
-// TimestampOK is the same as Timestamp, except that it returns a boolean
-// instead of panicking.
-func (v Value) TimestampOK() (t, i uint32, ok bool) {
- if v.Type != bsontype.Timestamp {
- return 0, 0, false
- }
- t, i, _, ok = ReadTimestamp(v.Data)
- if !ok {
- return 0, 0, false
- }
- return t, i, true
-}
-
-// Int64 returns the int64 the Value represents. It panics if the value is a BSON type other than
-// int64.
-func (v Value) Int64() int64 {
- if v.Type != bsontype.Int64 {
- panic(ElementTypeError{"bsoncore.Value.Int64", v.Type})
- }
- i64, _, ok := ReadInt64(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return i64
-}
-
-// Int64OK is the same as Int64, except that it returns a boolean instead of
-// panicking.
-func (v Value) Int64OK() (int64, bool) {
- if v.Type != bsontype.Int64 {
- return 0, false
- }
- i64, _, ok := ReadInt64(v.Data)
- if !ok {
- return 0, false
- }
- return i64, true
-}
-
-// Decimal128 returns the decimal the Value represents. It panics if the value is a BSON type other than
-// decimal.
-func (v Value) Decimal128() primitive.Decimal128 {
- if v.Type != bsontype.Decimal128 {
- panic(ElementTypeError{"bsoncore.Value.Decimal128", v.Type})
- }
- d128, _, ok := ReadDecimal128(v.Data)
- if !ok {
- panic(NewInsufficientBytesError(v.Data, v.Data))
- }
- return d128
-}
-
-// Decimal128OK is the same as Decimal128, except that it returns a boolean
-// instead of panicking.
-func (v Value) Decimal128OK() (primitive.Decimal128, bool) {
- if v.Type != bsontype.Decimal128 {
- return primitive.Decimal128{}, false
- }
- d128, _, ok := ReadDecimal128(v.Data)
- if !ok {
- return primitive.Decimal128{}, false
- }
- return d128, true
-}
-
-var hexChars = "0123456789abcdef"
-
-func escapeString(s string) string {
- escapeHTML := true
- var buf bytes.Buffer
- buf.WriteByte('"')
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
- i++
- continue
- }
- if start < i {
- buf.WriteString(s[start:i])
- }
- switch b {
- case '\\', '"':
- buf.WriteByte('\\')
- buf.WriteByte(b)
- case '\n':
- buf.WriteByte('\\')
- buf.WriteByte('n')
- case '\r':
- buf.WriteByte('\\')
- buf.WriteByte('r')
- case '\t':
- buf.WriteByte('\\')
- buf.WriteByte('t')
- case '\b':
- buf.WriteByte('\\')
- buf.WriteByte('b')
- case '\f':
- buf.WriteByte('\\')
- buf.WriteByte('f')
- default:
- // This encodes bytes < 0x20 except for \t, \n and \r.
- // If escapeHTML is set, it also escapes <, >, and &
- // because they can lead to security holes when
- // user-controlled strings are rendered into JSON
- // and served to some browsers.
- buf.WriteString(`\u00`)
- buf.WriteByte(hexChars[b>>4])
- buf.WriteByte(hexChars[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRuneInString(s[i:])
- if c == utf8.RuneError && size == 1 {
- if start < i {
- buf.WriteString(s[start:i])
- }
- buf.WriteString(`\ufffd`)
- i += size
- start = i
- continue
- }
- // U+2028 is LINE SEPARATOR.
- // U+2029 is PARAGRAPH SEPARATOR.
- // They are both technically valid characters in JSON strings,
- // but don't work in JSONP, which has to be evaluated as JavaScript,
- // and can lead to security holes there. It is valid JSON to
- // escape them, so we do so unconditionally.
- // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
- if c == '\u2028' || c == '\u2029' {
- if start < i {
- buf.WriteString(s[start:i])
- }
- buf.WriteString(`\u202`)
- buf.WriteByte(hexChars[c&0xF])
- i += size
- start = i
- continue
- }
- i += size
- }
- if start < len(s) {
- buf.WriteString(s[start:])
- }
- buf.WriteByte('"')
- return buf.String()
-}
-
-func formatDouble(f float64) string {
- var s string
- if math.IsInf(f, 1) {
- s = "Infinity"
- } else if math.IsInf(f, -1) {
- s = "-Infinity"
- } else if math.IsNaN(f) {
- s = "NaN"
- } else {
- // Print exactly one decimalType place for integers; otherwise, print as many are necessary to
- // perfectly represent it.
- s = strconv.FormatFloat(f, 'G', -1, 64)
- if !strings.ContainsRune(s, '.') {
- s += ".0"
- }
- }
-
- return s
-}
-
-type sortableString []rune
-
-func (ss sortableString) Len() int {
- return len(ss)
-}
-
-func (ss sortableString) Less(i, j int) bool {
- return ss[i] < ss[j]
-}
-
-func (ss sortableString) Swap(i, j int) {
- oldI := ss[i]
- ss[i] = ss[j]
- ss[j] = oldI
-}
-
-func sortStringAlphebeticAscending(s string) string {
- ss := sortableString([]rune(s))
- sort.Sort(ss)
- return string([]rune(ss))
-}
-
-func docAsArray(d Document, debug bool) string {
- if len(d) < 5 {
- return ""
- }
- var buf bytes.Buffer
- buf.WriteByte('[')
-
- length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
-
- length -= 4
-
- var elem Element
- var ok bool
- first := true
- for length > 1 {
- if !first {
- buf.WriteByte(',')
- }
- elem, rem, ok = ReadElement(rem)
- length -= int32(len(elem))
- if !ok {
- return ""
- }
- if debug {
- fmt.Fprintf(&buf, "%s ", elem.Value().DebugString())
- } else {
- fmt.Fprintf(&buf, "%s", elem.Value())
- }
- first = false
- }
- buf.WriteByte(']')
-
- return buf.String()
-}