You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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