1// Copyright (C) MongoDB, Inc. 2017-present.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may
4// not use this file except in compliance with the License. You may obtain
5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
7package bsoncore
8
9import (
10	"bytes"
11	"encoding/base64"
12	"fmt"
13	"math"
14	"sort"
15	"strconv"
16	"strings"
17	"time"
18	"unicode/utf8"
19
20	"go.mongodb.org/mongo-driver/bson/bsontype"
21	"go.mongodb.org/mongo-driver/bson/primitive"
22)
23
24// ElementTypeError specifies that a method to obtain a BSON value an incorrect type was called on a bson.Value.
25type ElementTypeError struct {
26	Method string
27	Type   bsontype.Type
28}
29
30// Error implements the error interface.
31func (ete ElementTypeError) Error() string {
32	return "Call of " + ete.Method + " on " + ete.Type.String() + " type"
33}
34
35// Value represents a BSON value with a type and raw bytes.
36type Value struct {
37	Type bsontype.Type
38	Data []byte
39}
40
41// Validate ensures the value is a valid BSON value.
42func (v Value) Validate() error {
43	_, _, valid := readValue(v.Data, v.Type)
44	if !valid {
45		return NewInsufficientBytesError(v.Data, v.Data)
46	}
47	return nil
48}
49
50// IsNumber returns true if the type of v is a numeric BSON type.
51func (v Value) IsNumber() bool {
52	switch v.Type {
53	case bsontype.Double, bsontype.Int32, bsontype.Int64, bsontype.Decimal128:
54		return true
55	default:
56		return false
57	}
58}
59
60// AsInt32 returns a BSON number as an int32. If the BSON type is not a numeric one, this method
61// will panic.
62//
63// TODO(skriptble): Add support for Decimal128.
64func (v Value) AsInt32() int32 {
65	if !v.IsNumber() {
66		panic(ElementTypeError{"bsoncore.Value.AsInt32", v.Type})
67	}
68	var i32 int32
69	switch v.Type {
70	case bsontype.Double:
71		f64, _, ok := ReadDouble(v.Data)
72		if !ok {
73			panic(NewInsufficientBytesError(v.Data, v.Data))
74		}
75		i32 = int32(f64)
76	case bsontype.Int32:
77		var ok bool
78		i32, _, ok = ReadInt32(v.Data)
79		if !ok {
80			panic(NewInsufficientBytesError(v.Data, v.Data))
81		}
82	case bsontype.Int64:
83		i64, _, ok := ReadInt64(v.Data)
84		if !ok {
85			panic(NewInsufficientBytesError(v.Data, v.Data))
86		}
87		i32 = int32(i64)
88	case bsontype.Decimal128:
89		panic(ElementTypeError{"bsoncore.Value.AsInt32", v.Type})
90	}
91	return i32
92}
93
94// AsInt32OK functions the same as AsInt32 but returns a boolean instead of panicking. False
95// indicates an error.
96//
97// TODO(skriptble): Add support for Decimal128.
98func (v Value) AsInt32OK() (int32, bool) {
99	if !v.IsNumber() {
100		return 0, false
101	}
102	var i32 int32
103	switch v.Type {
104	case bsontype.Double:
105		f64, _, ok := ReadDouble(v.Data)
106		if !ok {
107			return 0, false
108		}
109		i32 = int32(f64)
110	case bsontype.Int32:
111		var ok bool
112		i32, _, ok = ReadInt32(v.Data)
113		if !ok {
114			return 0, false
115		}
116	case bsontype.Int64:
117		i64, _, ok := ReadInt64(v.Data)
118		if !ok {
119			return 0, false
120		}
121		i32 = int32(i64)
122	case bsontype.Decimal128:
123		return 0, false
124	}
125	return i32, true
126}
127
128// AsInt64 returns a BSON number as an int64. If the BSON type is not a numeric one, this method
129// will panic.
130//
131// TODO(skriptble): Add support for Decimal128.
132func (v Value) AsInt64() int64 {
133	if !v.IsNumber() {
134		panic(ElementTypeError{"bsoncore.Value.AsInt64", v.Type})
135	}
136	var i64 int64
137	switch v.Type {
138	case bsontype.Double:
139		f64, _, ok := ReadDouble(v.Data)
140		if !ok {
141			panic(NewInsufficientBytesError(v.Data, v.Data))
142		}
143		i64 = int64(f64)
144	case bsontype.Int32:
145		var ok bool
146		i32, _, ok := ReadInt32(v.Data)
147		if !ok {
148			panic(NewInsufficientBytesError(v.Data, v.Data))
149		}
150		i64 = int64(i32)
151	case bsontype.Int64:
152		var ok bool
153		i64, _, ok = ReadInt64(v.Data)
154		if !ok {
155			panic(NewInsufficientBytesError(v.Data, v.Data))
156		}
157	case bsontype.Decimal128:
158		panic(ElementTypeError{"bsoncore.Value.AsInt64", v.Type})
159	}
160	return i64
161}
162
163// AsInt64OK functions the same as AsInt64 but returns a boolean instead of panicking. False
164// indicates an error.
165//
166// TODO(skriptble): Add support for Decimal128.
167func (v Value) AsInt64OK() (int64, bool) {
168	if !v.IsNumber() {
169		return 0, false
170	}
171	var i64 int64
172	switch v.Type {
173	case bsontype.Double:
174		f64, _, ok := ReadDouble(v.Data)
175		if !ok {
176			return 0, false
177		}
178		i64 = int64(f64)
179	case bsontype.Int32:
180		var ok bool
181		i32, _, ok := ReadInt32(v.Data)
182		if !ok {
183			return 0, false
184		}
185		i64 = int64(i32)
186	case bsontype.Int64:
187		var ok bool
188		i64, _, ok = ReadInt64(v.Data)
189		if !ok {
190			return 0, false
191		}
192	case bsontype.Decimal128:
193		return 0, false
194	}
195	return i64, true
196}
197
198// AsFloat64 returns a BSON number as an float64. If the BSON type is not a numeric one, this method
199// will panic.
200//
201// TODO(skriptble): Add support for Decimal128.
202func (v Value) AsFloat64() float64 { return 0 }
203
204// AsFloat64OK functions the same as AsFloat64 but returns a boolean instead of panicking. False
205// indicates an error.
206//
207// TODO(skriptble): Add support for Decimal128.
208func (v Value) AsFloat64OK() (float64, bool) { return 0, false }
209
210// Add will add this value to another. This is currently only implemented for strings and numbers.
211// If either value is a string, the other type is coerced into a string and added to the other.
212//
213// This method will alter v and will attempt to reuse the []byte of v. If the []byte is too small,
214// it will be expanded.
215func (v *Value) Add(v2 Value) error { return nil }
216
217// Equal compaes v to v2 and returns true if they are equal.
218func (v Value) Equal(v2 Value) bool {
219	if v.Type != v2.Type {
220		return false
221	}
222
223	return bytes.Equal(v.Data, v2.Data)
224}
225
226// String implements the fmt.String interface. This method will return values in extended JSON
227// format. If the value is not valid, this returns an empty string
228func (v Value) String() string {
229	switch v.Type {
230	case bsontype.Double:
231		f64, ok := v.DoubleOK()
232		if !ok {
233			return ""
234		}
235		return fmt.Sprintf(`{"$numberDouble":"%s"}`, formatDouble(f64))
236	case bsontype.String:
237		str, ok := v.StringValueOK()
238		if !ok {
239			return ""
240		}
241		return escapeString(str)
242	case bsontype.EmbeddedDocument:
243		doc, ok := v.DocumentOK()
244		if !ok {
245			return ""
246		}
247		return doc.String()
248	case bsontype.Array:
249		arr, ok := v.ArrayOK()
250		if !ok {
251			return ""
252		}
253		return arr.String()
254	case bsontype.Binary:
255		subtype, data, ok := v.BinaryOK()
256		if !ok {
257			return ""
258		}
259		return fmt.Sprintf(`{"$binary":{"base64":"%s","subType":"%02x"}}`, base64.StdEncoding.EncodeToString(data), subtype)
260	case bsontype.Undefined:
261		return `{"$undefined":true}`
262	case bsontype.ObjectID:
263		oid, ok := v.ObjectIDOK()
264		if !ok {
265			return ""
266		}
267		return fmt.Sprintf(`{"$oid":"%s"}`, oid.Hex())
268	case bsontype.Boolean:
269		b, ok := v.BooleanOK()
270		if !ok {
271			return ""
272		}
273		return strconv.FormatBool(b)
274	case bsontype.DateTime:
275		dt, ok := v.DateTimeOK()
276		if !ok {
277			return ""
278		}
279		return fmt.Sprintf(`{"$date":{"$numberLong":"%d"}}`, dt)
280	case bsontype.Null:
281		return "null"
282	case bsontype.Regex:
283		pattern, options, ok := v.RegexOK()
284		if !ok {
285			return ""
286		}
287		return fmt.Sprintf(
288			`{"$regularExpression":{"pattern":%s,"options":"%s"}}`,
289			escapeString(pattern), sortStringAlphebeticAscending(options),
290		)
291	case bsontype.DBPointer:
292		ns, pointer, ok := v.DBPointerOK()
293		if !ok {
294			return ""
295		}
296		return fmt.Sprintf(`{"$dbPointer":{"$ref":%s,"$id":{"$oid":"%s"}}}`, escapeString(ns), pointer.Hex())
297	case bsontype.JavaScript:
298		js, ok := v.JavaScriptOK()
299		if !ok {
300			return ""
301		}
302		return fmt.Sprintf(`{"$code":%s}`, escapeString(js))
303	case bsontype.Symbol:
304		symbol, ok := v.SymbolOK()
305		if !ok {
306			return ""
307		}
308		return fmt.Sprintf(`{"$symbol":%s}`, escapeString(symbol))
309	case bsontype.CodeWithScope:
310		code, scope, ok := v.CodeWithScopeOK()
311		if !ok {
312			return ""
313		}
314		return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope)
315	case bsontype.Int32:
316		i32, ok := v.Int32OK()
317		if !ok {
318			return ""
319		}
320		return fmt.Sprintf(`{"$numberInt":"%d"}`, i32)
321	case bsontype.Timestamp:
322		t, i, ok := v.TimestampOK()
323		if !ok {
324			return ""
325		}
326		return fmt.Sprintf(`{"$timestamp":{"t":"%s","i":"%s"}}`, strconv.FormatUint(uint64(t), 10), strconv.FormatUint(uint64(i), 10))
327	case bsontype.Int64:
328		i64, ok := v.Int64OK()
329		if !ok {
330			return ""
331		}
332		return fmt.Sprintf(`{"$numberLong":"%d"}`, i64)
333	case bsontype.Decimal128:
334		d128, ok := v.Decimal128OK()
335		if !ok {
336			return ""
337		}
338		return fmt.Sprintf(`{"$numberDecimal":"%s"}`, d128.String())
339	case bsontype.MinKey:
340		return `{"$minKey":1}`
341	case bsontype.MaxKey:
342		return `{"$maxKey":1}`
343	default:
344		return ""
345	}
346}
347
348// DebugString outputs a human readable version of Document. It will attempt to stringify the
349// valid components of the document even if the entire document is not valid.
350func (v Value) DebugString() string {
351	switch v.Type {
352	case bsontype.String:
353		str, ok := v.StringValueOK()
354		if !ok {
355			return "<malformed>"
356		}
357		return escapeString(str)
358	case bsontype.EmbeddedDocument:
359		doc, ok := v.DocumentOK()
360		if !ok {
361			return "<malformed>"
362		}
363		return doc.DebugString()
364	case bsontype.Array:
365		arr, ok := v.ArrayOK()
366		if !ok {
367			return "<malformed>"
368		}
369		return arr.DebugString()
370	case bsontype.CodeWithScope:
371		code, scope, ok := v.CodeWithScopeOK()
372		if !ok {
373			return ""
374		}
375		return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope.DebugString())
376	default:
377		str := v.String()
378		if str == "" {
379			return "<malformed>"
380		}
381		return str
382	}
383}
384
385// Double returns the float64 value for this element.
386// It panics if e's BSON type is not bsontype.Double.
387func (v Value) Double() float64 {
388	if v.Type != bsontype.Double {
389		panic(ElementTypeError{"bsoncore.Value.Double", v.Type})
390	}
391	f64, _, ok := ReadDouble(v.Data)
392	if !ok {
393		panic(NewInsufficientBytesError(v.Data, v.Data))
394	}
395	return f64
396}
397
398// DoubleOK is the same as Double, but returns a boolean instead of panicking.
399func (v Value) DoubleOK() (float64, bool) {
400	if v.Type != bsontype.Double {
401		return 0, false
402	}
403	f64, _, ok := ReadDouble(v.Data)
404	if !ok {
405		return 0, false
406	}
407	return f64, true
408}
409
410// StringValue returns the string balue for this element.
411// It panics if e's BSON type is not bsontype.String.
412//
413// NOTE: This method is called StringValue to avoid a collision with the String method which
414// implements the fmt.Stringer interface.
415func (v Value) StringValue() string {
416	if v.Type != bsontype.String {
417		panic(ElementTypeError{"bsoncore.Value.StringValue", v.Type})
418	}
419	str, _, ok := ReadString(v.Data)
420	if !ok {
421		panic(NewInsufficientBytesError(v.Data, v.Data))
422	}
423	return str
424}
425
426// StringValueOK is the same as StringValue, but returns a boolean instead of
427// panicking.
428func (v Value) StringValueOK() (string, bool) {
429	if v.Type != bsontype.String {
430		return "", false
431	}
432	str, _, ok := ReadString(v.Data)
433	if !ok {
434		return "", false
435	}
436	return str, true
437}
438
439// Document returns the BSON document the Value represents as a Document. It panics if the
440// value is a BSON type other than document.
441func (v Value) Document() Document {
442	if v.Type != bsontype.EmbeddedDocument {
443		panic(ElementTypeError{"bsoncore.Value.Document", v.Type})
444	}
445	doc, _, ok := ReadDocument(v.Data)
446	if !ok {
447		panic(NewInsufficientBytesError(v.Data, v.Data))
448	}
449	return doc
450}
451
452// DocumentOK is the same as Document, except it returns a boolean
453// instead of panicking.
454func (v Value) DocumentOK() (Document, bool) {
455	if v.Type != bsontype.EmbeddedDocument {
456		return nil, false
457	}
458	doc, _, ok := ReadDocument(v.Data)
459	if !ok {
460		return nil, false
461	}
462	return doc, true
463}
464
465// Array returns the BSON array the Value represents as an Array. It panics if the
466// value is a BSON type other than array.
467func (v Value) Array() Array {
468	if v.Type != bsontype.Array {
469		panic(ElementTypeError{"bsoncore.Value.Array", v.Type})
470	}
471	arr, _, ok := ReadArray(v.Data)
472	if !ok {
473		panic(NewInsufficientBytesError(v.Data, v.Data))
474	}
475	return arr
476}
477
478// ArrayOK is the same as Array, except it returns a boolean instead
479// of panicking.
480func (v Value) ArrayOK() (Array, bool) {
481	if v.Type != bsontype.Array {
482		return nil, false
483	}
484	arr, _, ok := ReadArray(v.Data)
485	if !ok {
486		return nil, false
487	}
488	return arr, true
489}
490
491// Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type
492// other than binary.
493func (v Value) Binary() (subtype byte, data []byte) {
494	if v.Type != bsontype.Binary {
495		panic(ElementTypeError{"bsoncore.Value.Binary", v.Type})
496	}
497	subtype, data, _, ok := ReadBinary(v.Data)
498	if !ok {
499		panic(NewInsufficientBytesError(v.Data, v.Data))
500	}
501	return subtype, data
502}
503
504// BinaryOK is the same as Binary, except it returns a boolean instead of
505// panicking.
506func (v Value) BinaryOK() (subtype byte, data []byte, ok bool) {
507	if v.Type != bsontype.Binary {
508		return 0x00, nil, false
509	}
510	subtype, data, _, ok = ReadBinary(v.Data)
511	if !ok {
512		return 0x00, nil, false
513	}
514	return subtype, data, true
515}
516
517// ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON
518// type other than objectid.
519func (v Value) ObjectID() primitive.ObjectID {
520	if v.Type != bsontype.ObjectID {
521		panic(ElementTypeError{"bsoncore.Value.ObjectID", v.Type})
522	}
523	oid, _, ok := ReadObjectID(v.Data)
524	if !ok {
525		panic(NewInsufficientBytesError(v.Data, v.Data))
526	}
527	return oid
528}
529
530// ObjectIDOK is the same as ObjectID, except it returns a boolean instead of
531// panicking.
532func (v Value) ObjectIDOK() (primitive.ObjectID, bool) {
533	if v.Type != bsontype.ObjectID {
534		return primitive.ObjectID{}, false
535	}
536	oid, _, ok := ReadObjectID(v.Data)
537	if !ok {
538		return primitive.ObjectID{}, false
539	}
540	return oid, true
541}
542
543// Boolean returns the boolean value the Value represents. It panics if the
544// value is a BSON type other than boolean.
545func (v Value) Boolean() bool {
546	if v.Type != bsontype.Boolean {
547		panic(ElementTypeError{"bsoncore.Value.Boolean", v.Type})
548	}
549	b, _, ok := ReadBoolean(v.Data)
550	if !ok {
551		panic(NewInsufficientBytesError(v.Data, v.Data))
552	}
553	return b
554}
555
556// BooleanOK is the same as Boolean, except it returns a boolean instead of
557// panicking.
558func (v Value) BooleanOK() (bool, bool) {
559	if v.Type != bsontype.Boolean {
560		return false, false
561	}
562	b, _, ok := ReadBoolean(v.Data)
563	if !ok {
564		return false, false
565	}
566	return b, true
567}
568
569// DateTime returns the BSON datetime value the Value represents as a
570// unix timestamp. It panics if the value is a BSON type other than datetime.
571func (v Value) DateTime() int64 {
572	if v.Type != bsontype.DateTime {
573		panic(ElementTypeError{"bsoncore.Value.DateTime", v.Type})
574	}
575	dt, _, ok := ReadDateTime(v.Data)
576	if !ok {
577		panic(NewInsufficientBytesError(v.Data, v.Data))
578	}
579	return dt
580}
581
582// DateTimeOK is the same as DateTime, except it returns a boolean instead of
583// panicking.
584func (v Value) DateTimeOK() (int64, bool) {
585	if v.Type != bsontype.DateTime {
586		return 0, false
587	}
588	dt, _, ok := ReadDateTime(v.Data)
589	if !ok {
590		return 0, false
591	}
592	return dt, true
593}
594
595// Time returns the BSON datetime value the Value represents. It panics if the value is a BSON
596// type other than datetime.
597func (v Value) Time() time.Time {
598	if v.Type != bsontype.DateTime {
599		panic(ElementTypeError{"bsoncore.Value.Time", v.Type})
600	}
601	dt, _, ok := ReadDateTime(v.Data)
602	if !ok {
603		panic(NewInsufficientBytesError(v.Data, v.Data))
604	}
605	return time.Unix(int64(dt)/1000, int64(dt)%1000*1000000)
606}
607
608// TimeOK is the same as Time, except it returns a boolean instead of
609// panicking.
610func (v Value) TimeOK() (time.Time, bool) {
611	if v.Type != bsontype.DateTime {
612		return time.Time{}, false
613	}
614	dt, _, ok := ReadDateTime(v.Data)
615	if !ok {
616		return time.Time{}, false
617	}
618	return time.Unix(int64(dt)/1000, int64(dt)%1000*1000000), true
619}
620
621// Regex returns the BSON regex value the Value represents. It panics if the value is a BSON
622// type other than regex.
623func (v Value) Regex() (pattern, options string) {
624	if v.Type != bsontype.Regex {
625		panic(ElementTypeError{"bsoncore.Value.Regex", v.Type})
626	}
627	pattern, options, _, ok := ReadRegex(v.Data)
628	if !ok {
629		panic(NewInsufficientBytesError(v.Data, v.Data))
630	}
631	return pattern, options
632}
633
634// RegexOK is the same as Regex, except it returns a boolean instead of
635// panicking.
636func (v Value) RegexOK() (pattern, options string, ok bool) {
637	if v.Type != bsontype.Regex {
638		return "", "", false
639	}
640	pattern, options, _, ok = ReadRegex(v.Data)
641	if !ok {
642		return "", "", false
643	}
644	return pattern, options, true
645}
646
647// DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON
648// type other than DBPointer.
649func (v Value) DBPointer() (string, primitive.ObjectID) {
650	if v.Type != bsontype.DBPointer {
651		panic(ElementTypeError{"bsoncore.Value.DBPointer", v.Type})
652	}
653	ns, pointer, _, ok := ReadDBPointer(v.Data)
654	if !ok {
655		panic(NewInsufficientBytesError(v.Data, v.Data))
656	}
657	return ns, pointer
658}
659
660// DBPointerOK is the same as DBPoitner, except that it returns a boolean
661// instead of panicking.
662func (v Value) DBPointerOK() (string, primitive.ObjectID, bool) {
663	if v.Type != bsontype.DBPointer {
664		return "", primitive.ObjectID{}, false
665	}
666	ns, pointer, _, ok := ReadDBPointer(v.Data)
667	if !ok {
668		return "", primitive.ObjectID{}, false
669	}
670	return ns, pointer, true
671}
672
673// JavaScript returns the BSON JavaScript code value the Value represents. It panics if the value is
674// a BSON type other than JavaScript code.
675func (v Value) JavaScript() string {
676	if v.Type != bsontype.JavaScript {
677		panic(ElementTypeError{"bsoncore.Value.JavaScript", v.Type})
678	}
679	js, _, ok := ReadJavaScript(v.Data)
680	if !ok {
681		panic(NewInsufficientBytesError(v.Data, v.Data))
682	}
683	return js
684}
685
686// JavaScriptOK is the same as Javascript, excepti that it returns a boolean
687// instead of panicking.
688func (v Value) JavaScriptOK() (string, bool) {
689	if v.Type != bsontype.JavaScript {
690		return "", false
691	}
692	js, _, ok := ReadJavaScript(v.Data)
693	if !ok {
694		return "", false
695	}
696	return js, true
697}
698
699// Symbol returns the BSON symbol value the Value represents. It panics if the value is a BSON
700// type other than symbol.
701func (v Value) Symbol() string {
702	if v.Type != bsontype.Symbol {
703		panic(ElementTypeError{"bsoncore.Value.Symbol", v.Type})
704	}
705	symbol, _, ok := ReadSymbol(v.Data)
706	if !ok {
707		panic(NewInsufficientBytesError(v.Data, v.Data))
708	}
709	return symbol
710}
711
712// SymbolOK is the same as Symbol, excepti that it returns a boolean
713// instead of panicking.
714func (v Value) SymbolOK() (string, bool) {
715	if v.Type != bsontype.Symbol {
716		return "", false
717	}
718	symbol, _, ok := ReadSymbol(v.Data)
719	if !ok {
720		return "", false
721	}
722	return symbol, true
723}
724
725// CodeWithScope returns the BSON JavaScript code with scope the Value represents.
726// It panics if the value is a BSON type other than JavaScript code with scope.
727func (v Value) CodeWithScope() (string, Document) {
728	if v.Type != bsontype.CodeWithScope {
729		panic(ElementTypeError{"bsoncore.Value.CodeWithScope", v.Type})
730	}
731	code, scope, _, ok := ReadCodeWithScope(v.Data)
732	if !ok {
733		panic(NewInsufficientBytesError(v.Data, v.Data))
734	}
735	return code, scope
736}
737
738// CodeWithScopeOK is the same as CodeWithScope, except that it returns a boolean instead of
739// panicking.
740func (v Value) CodeWithScopeOK() (string, Document, bool) {
741	if v.Type != bsontype.CodeWithScope {
742		return "", nil, false
743	}
744	code, scope, _, ok := ReadCodeWithScope(v.Data)
745	if !ok {
746		return "", nil, false
747	}
748	return code, scope, true
749}
750
751// Int32 returns the int32 the Value represents. It panics if the value is a BSON type other than
752// int32.
753func (v Value) Int32() int32 {
754	if v.Type != bsontype.Int32 {
755		panic(ElementTypeError{"bsoncore.Value.Int32", v.Type})
756	}
757	i32, _, ok := ReadInt32(v.Data)
758	if !ok {
759		panic(NewInsufficientBytesError(v.Data, v.Data))
760	}
761	return i32
762}
763
764// Int32OK is the same as Int32, except that it returns a boolean instead of
765// panicking.
766func (v Value) Int32OK() (int32, bool) {
767	if v.Type != bsontype.Int32 {
768		return 0, false
769	}
770	i32, _, ok := ReadInt32(v.Data)
771	if !ok {
772		return 0, false
773	}
774	return i32, true
775}
776
777// Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a
778// BSON type other than timestamp.
779func (v Value) Timestamp() (t, i uint32) {
780	if v.Type != bsontype.Timestamp {
781		panic(ElementTypeError{"bsoncore.Value.Timestamp", v.Type})
782	}
783	t, i, _, ok := ReadTimestamp(v.Data)
784	if !ok {
785		panic(NewInsufficientBytesError(v.Data, v.Data))
786	}
787	return t, i
788}
789
790// TimestampOK is the same as Timestamp, except that it returns a boolean
791// instead of panicking.
792func (v Value) TimestampOK() (t, i uint32, ok bool) {
793	if v.Type != bsontype.Timestamp {
794		return 0, 0, false
795	}
796	t, i, _, ok = ReadTimestamp(v.Data)
797	if !ok {
798		return 0, 0, false
799	}
800	return t, i, true
801}
802
803// Int64 returns the int64 the Value represents. It panics if the value is a BSON type other than
804// int64.
805func (v Value) Int64() int64 {
806	if v.Type != bsontype.Int64 {
807		panic(ElementTypeError{"bsoncore.Value.Int64", v.Type})
808	}
809	i64, _, ok := ReadInt64(v.Data)
810	if !ok {
811		panic(NewInsufficientBytesError(v.Data, v.Data))
812	}
813	return i64
814}
815
816// Int64OK is the same as Int64, except that it returns a boolean instead of
817// panicking.
818func (v Value) Int64OK() (int64, bool) {
819	if v.Type != bsontype.Int64 {
820		return 0, false
821	}
822	i64, _, ok := ReadInt64(v.Data)
823	if !ok {
824		return 0, false
825	}
826	return i64, true
827}
828
829// Decimal128 returns the decimal the Value represents. It panics if the value is a BSON type other than
830// decimal.
831func (v Value) Decimal128() primitive.Decimal128 {
832	if v.Type != bsontype.Decimal128 {
833		panic(ElementTypeError{"bsoncore.Value.Decimal128", v.Type})
834	}
835	d128, _, ok := ReadDecimal128(v.Data)
836	if !ok {
837		panic(NewInsufficientBytesError(v.Data, v.Data))
838	}
839	return d128
840}
841
842// Decimal128OK is the same as Decimal128, except that it returns a boolean
843// instead of panicking.
844func (v Value) Decimal128OK() (primitive.Decimal128, bool) {
845	if v.Type != bsontype.Decimal128 {
846		return primitive.Decimal128{}, false
847	}
848	d128, _, ok := ReadDecimal128(v.Data)
849	if !ok {
850		return primitive.Decimal128{}, false
851	}
852	return d128, true
853}
854
855var hexChars = "0123456789abcdef"
856
857func escapeString(s string) string {
858	escapeHTML := true
859	var buf bytes.Buffer
860	buf.WriteByte('"')
861	start := 0
862	for i := 0; i < len(s); {
863		if b := s[i]; b < utf8.RuneSelf {
864			if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
865				i++
866				continue
867			}
868			if start < i {
869				buf.WriteString(s[start:i])
870			}
871			switch b {
872			case '\\', '"':
873				buf.WriteByte('\\')
874				buf.WriteByte(b)
875			case '\n':
876				buf.WriteByte('\\')
877				buf.WriteByte('n')
878			case '\r':
879				buf.WriteByte('\\')
880				buf.WriteByte('r')
881			case '\t':
882				buf.WriteByte('\\')
883				buf.WriteByte('t')
884			case '\b':
885				buf.WriteByte('\\')
886				buf.WriteByte('b')
887			case '\f':
888				buf.WriteByte('\\')
889				buf.WriteByte('f')
890			default:
891				// This encodes bytes < 0x20 except for \t, \n and \r.
892				// If escapeHTML is set, it also escapes <, >, and &
893				// because they can lead to security holes when
894				// user-controlled strings are rendered into JSON
895				// and served to some browsers.
896				buf.WriteString(`\u00`)
897				buf.WriteByte(hexChars[b>>4])
898				buf.WriteByte(hexChars[b&0xF])
899			}
900			i++
901			start = i
902			continue
903		}
904		c, size := utf8.DecodeRuneInString(s[i:])
905		if c == utf8.RuneError && size == 1 {
906			if start < i {
907				buf.WriteString(s[start:i])
908			}
909			buf.WriteString(`\ufffd`)
910			i += size
911			start = i
912			continue
913		}
914		// U+2028 is LINE SEPARATOR.
915		// U+2029 is PARAGRAPH SEPARATOR.
916		// They are both technically valid characters in JSON strings,
917		// but don't work in JSONP, which has to be evaluated as JavaScript,
918		// and can lead to security holes there. It is valid JSON to
919		// escape them, so we do so unconditionally.
920		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
921		if c == '\u2028' || c == '\u2029' {
922			if start < i {
923				buf.WriteString(s[start:i])
924			}
925			buf.WriteString(`\u202`)
926			buf.WriteByte(hexChars[c&0xF])
927			i += size
928			start = i
929			continue
930		}
931		i += size
932	}
933	if start < len(s) {
934		buf.WriteString(s[start:])
935	}
936	buf.WriteByte('"')
937	return buf.String()
938}
939
940func formatDouble(f float64) string {
941	var s string
942	if math.IsInf(f, 1) {
943		s = "Infinity"
944	} else if math.IsInf(f, -1) {
945		s = "-Infinity"
946	} else if math.IsNaN(f) {
947		s = "NaN"
948	} else {
949		// Print exactly one decimalType place for integers; otherwise, print as many are necessary to
950		// perfectly represent it.
951		s = strconv.FormatFloat(f, 'G', -1, 64)
952		if !strings.ContainsRune(s, '.') {
953			s += ".0"
954		}
955	}
956
957	return s
958}
959
960type sortableString []rune
961
962func (ss sortableString) Len() int {
963	return len(ss)
964}
965
966func (ss sortableString) Less(i, j int) bool {
967	return ss[i] < ss[j]
968}
969
970func (ss sortableString) Swap(i, j int) {
971	oldI := ss[i]
972	ss[i] = ss[j]
973	ss[j] = oldI
974}
975
976func sortStringAlphebeticAscending(s string) string {
977	ss := sortableString([]rune(s))
978	sort.Sort(ss)
979	return string([]rune(ss))
980}
981