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

value.go 25 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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 bsonx
  7. import (
  8. "bytes"
  9. "encoding/binary"
  10. "errors"
  11. "fmt"
  12. "math"
  13. "time"
  14. "go.mongodb.org/mongo-driver/bson/bsontype"
  15. "go.mongodb.org/mongo-driver/bson/primitive"
  16. "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
  17. )
  18. // Val represents a BSON value.
  19. type Val struct {
  20. // NOTE: The bootstrap is a small amount of space that'll be on the stack. At 15 bytes this
  21. // doesn't make this type any larger, since there are 7 bytes of padding and we want an int64 to
  22. // store small values (e.g. boolean, double, int64, etc...). The primitive property is where all
  23. // of the larger values go. They will use either Go primitives or the primitive.* types.
  24. t bsontype.Type
  25. bootstrap [15]byte
  26. primitive interface{}
  27. }
  28. func (v Val) reset() Val {
  29. v.primitive = nil // clear out any pointers so we don't accidentally stop them from being garbage collected.
  30. v.t = bsontype.Type(0)
  31. v.bootstrap[0] = 0x00
  32. v.bootstrap[1] = 0x00
  33. v.bootstrap[2] = 0x00
  34. v.bootstrap[3] = 0x00
  35. v.bootstrap[4] = 0x00
  36. v.bootstrap[5] = 0x00
  37. v.bootstrap[6] = 0x00
  38. v.bootstrap[7] = 0x00
  39. v.bootstrap[8] = 0x00
  40. v.bootstrap[9] = 0x00
  41. v.bootstrap[10] = 0x00
  42. v.bootstrap[11] = 0x00
  43. v.bootstrap[12] = 0x00
  44. v.bootstrap[13] = 0x00
  45. v.bootstrap[14] = 0x00
  46. return v
  47. }
  48. func (v Val) string() string {
  49. if v.primitive != nil {
  50. return v.primitive.(string)
  51. }
  52. // The string will either end with a null byte or it fills the entire bootstrap space.
  53. length := uint8(v.bootstrap[0])
  54. return string(v.bootstrap[1 : length+1])
  55. }
  56. func (v Val) writestring(str string) Val {
  57. switch {
  58. case len(str) < 15:
  59. v.bootstrap[0] = uint8(len(str))
  60. copy(v.bootstrap[1:], str)
  61. default:
  62. v.primitive = str
  63. }
  64. return v
  65. }
  66. func (v Val) i64() int64 {
  67. return int64(v.bootstrap[0]) | int64(v.bootstrap[1])<<8 | int64(v.bootstrap[2])<<16 |
  68. int64(v.bootstrap[3])<<24 | int64(v.bootstrap[4])<<32 | int64(v.bootstrap[5])<<40 |
  69. int64(v.bootstrap[6])<<48 | int64(v.bootstrap[7])<<56
  70. }
  71. func (v Val) writei64(i64 int64) Val {
  72. v.bootstrap[0] = byte(i64)
  73. v.bootstrap[1] = byte(i64 >> 8)
  74. v.bootstrap[2] = byte(i64 >> 16)
  75. v.bootstrap[3] = byte(i64 >> 24)
  76. v.bootstrap[4] = byte(i64 >> 32)
  77. v.bootstrap[5] = byte(i64 >> 40)
  78. v.bootstrap[6] = byte(i64 >> 48)
  79. v.bootstrap[7] = byte(i64 >> 56)
  80. return v
  81. }
  82. // IsZero returns true if this value is zero or a BSON null.
  83. func (v Val) IsZero() bool { return v.t == bsontype.Type(0) || v.t == bsontype.Null }
  84. func (v Val) String() string {
  85. // TODO(GODRIVER-612): When bsoncore has appenders for extended JSON use that here.
  86. return fmt.Sprintf("%v", v.Interface())
  87. }
  88. // Interface returns the Go value of this Value as an empty interface.
  89. //
  90. // This method will return nil if it is empty, otherwise it will return a Go primitive or a
  91. // primitive.* instance.
  92. func (v Val) Interface() interface{} {
  93. switch v.Type() {
  94. case bsontype.Double:
  95. return v.Double()
  96. case bsontype.String:
  97. return v.StringValue()
  98. case bsontype.EmbeddedDocument:
  99. switch v.primitive.(type) {
  100. case Doc:
  101. return v.primitive.(Doc)
  102. case MDoc:
  103. return v.primitive.(MDoc)
  104. default:
  105. return primitive.Null{}
  106. }
  107. case bsontype.Array:
  108. return v.Array()
  109. case bsontype.Binary:
  110. return v.primitive.(primitive.Binary)
  111. case bsontype.Undefined:
  112. return primitive.Undefined{}
  113. case bsontype.ObjectID:
  114. return v.ObjectID()
  115. case bsontype.Boolean:
  116. return v.Boolean()
  117. case bsontype.DateTime:
  118. return v.DateTime()
  119. case bsontype.Null:
  120. return primitive.Null{}
  121. case bsontype.Regex:
  122. return v.primitive.(primitive.Regex)
  123. case bsontype.DBPointer:
  124. return v.primitive.(primitive.DBPointer)
  125. case bsontype.JavaScript:
  126. return v.JavaScript()
  127. case bsontype.Symbol:
  128. return v.Symbol()
  129. case bsontype.CodeWithScope:
  130. return v.primitive.(primitive.CodeWithScope)
  131. case bsontype.Int32:
  132. return v.Int32()
  133. case bsontype.Timestamp:
  134. t, i := v.Timestamp()
  135. return primitive.Timestamp{T: t, I: i}
  136. case bsontype.Int64:
  137. return v.Int64()
  138. case bsontype.Decimal128:
  139. return v.Decimal128()
  140. case bsontype.MinKey:
  141. return primitive.MinKey{}
  142. case bsontype.MaxKey:
  143. return primitive.MaxKey{}
  144. default:
  145. return primitive.Null{}
  146. }
  147. }
  148. // MarshalBSONValue implements the bsoncodec.ValueMarshaler interface.
  149. func (v Val) MarshalBSONValue() (bsontype.Type, []byte, error) {
  150. return v.MarshalAppendBSONValue(nil)
  151. }
  152. // MarshalAppendBSONValue is similar to MarshalBSONValue, but allows the caller to specify a slice
  153. // to add the bytes to.
  154. func (v Val) MarshalAppendBSONValue(dst []byte) (bsontype.Type, []byte, error) {
  155. t := v.Type()
  156. switch v.Type() {
  157. case bsontype.Double:
  158. dst = bsoncore.AppendDouble(dst, v.Double())
  159. case bsontype.String:
  160. dst = bsoncore.AppendString(dst, v.String())
  161. case bsontype.EmbeddedDocument:
  162. switch v.primitive.(type) {
  163. case Doc:
  164. t, dst, _ = v.primitive.(Doc).MarshalBSONValue() // Doc.MarshalBSONValue never returns an error.
  165. case MDoc:
  166. t, dst, _ = v.primitive.(MDoc).MarshalBSONValue() // MDoc.MarshalBSONValue never returns an error.
  167. }
  168. case bsontype.Array:
  169. t, dst, _ = v.Array().MarshalBSONValue() // Arr.MarshalBSON never returns an error.
  170. case bsontype.Binary:
  171. subtype, bindata := v.Binary()
  172. dst = bsoncore.AppendBinary(dst, subtype, bindata)
  173. case bsontype.Undefined:
  174. case bsontype.ObjectID:
  175. dst = bsoncore.AppendObjectID(dst, v.ObjectID())
  176. case bsontype.Boolean:
  177. dst = bsoncore.AppendBoolean(dst, v.Boolean())
  178. case bsontype.DateTime:
  179. dst = bsoncore.AppendDateTime(dst, int64(v.DateTime()))
  180. case bsontype.Null:
  181. case bsontype.Regex:
  182. pattern, options := v.Regex()
  183. dst = bsoncore.AppendRegex(dst, pattern, options)
  184. case bsontype.DBPointer:
  185. ns, ptr := v.DBPointer()
  186. dst = bsoncore.AppendDBPointer(dst, ns, ptr)
  187. case bsontype.JavaScript:
  188. dst = bsoncore.AppendJavaScript(dst, string(v.JavaScript()))
  189. case bsontype.Symbol:
  190. dst = bsoncore.AppendSymbol(dst, string(v.Symbol()))
  191. case bsontype.CodeWithScope:
  192. code, doc := v.CodeWithScope()
  193. var scope []byte
  194. scope, _ = doc.MarshalBSON() // Doc.MarshalBSON never returns an error.
  195. dst = bsoncore.AppendCodeWithScope(dst, code, scope)
  196. case bsontype.Int32:
  197. dst = bsoncore.AppendInt32(dst, v.Int32())
  198. case bsontype.Timestamp:
  199. t, i := v.Timestamp()
  200. dst = bsoncore.AppendTimestamp(dst, t, i)
  201. case bsontype.Int64:
  202. dst = bsoncore.AppendInt64(dst, v.Int64())
  203. case bsontype.Decimal128:
  204. dst = bsoncore.AppendDecimal128(dst, v.Decimal128())
  205. case bsontype.MinKey:
  206. case bsontype.MaxKey:
  207. default:
  208. panic(fmt.Errorf("invalid BSON type %v", t))
  209. }
  210. return t, dst, nil
  211. }
  212. // UnmarshalBSONValue implements the bsoncodec.ValueUnmarshaler interface.
  213. func (v *Val) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
  214. if v == nil {
  215. return errors.New("cannot unmarshal into nil Value")
  216. }
  217. var err error
  218. var ok = true
  219. var rem []byte
  220. switch t {
  221. case bsontype.Double:
  222. var f64 float64
  223. f64, rem, ok = bsoncore.ReadDouble(data)
  224. *v = Double(f64)
  225. case bsontype.String:
  226. var str string
  227. str, rem, ok = bsoncore.ReadString(data)
  228. *v = String(str)
  229. case bsontype.EmbeddedDocument:
  230. var raw []byte
  231. var doc Doc
  232. raw, rem, ok = bsoncore.ReadDocument(data)
  233. doc, err = ReadDoc(raw)
  234. *v = Document(doc)
  235. case bsontype.Array:
  236. var raw []byte
  237. arr := make(Arr, 0)
  238. raw, rem, ok = bsoncore.ReadArray(data)
  239. err = arr.UnmarshalBSONValue(t, raw)
  240. *v = Array(arr)
  241. case bsontype.Binary:
  242. var subtype byte
  243. var bindata []byte
  244. subtype, bindata, rem, ok = bsoncore.ReadBinary(data)
  245. *v = Binary(subtype, bindata)
  246. case bsontype.Undefined:
  247. *v = Undefined()
  248. case bsontype.ObjectID:
  249. var oid primitive.ObjectID
  250. oid, rem, ok = bsoncore.ReadObjectID(data)
  251. *v = ObjectID(oid)
  252. case bsontype.Boolean:
  253. var b bool
  254. b, rem, ok = bsoncore.ReadBoolean(data)
  255. *v = Boolean(b)
  256. case bsontype.DateTime:
  257. var dt int64
  258. dt, rem, ok = bsoncore.ReadDateTime(data)
  259. *v = DateTime(dt)
  260. case bsontype.Null:
  261. *v = Null()
  262. case bsontype.Regex:
  263. var pattern, options string
  264. pattern, options, rem, ok = bsoncore.ReadRegex(data)
  265. *v = Regex(pattern, options)
  266. case bsontype.DBPointer:
  267. var ns string
  268. var ptr primitive.ObjectID
  269. ns, ptr, rem, ok = bsoncore.ReadDBPointer(data)
  270. *v = DBPointer(ns, ptr)
  271. case bsontype.JavaScript:
  272. var js string
  273. js, rem, ok = bsoncore.ReadJavaScript(data)
  274. *v = JavaScript(js)
  275. case bsontype.Symbol:
  276. var symbol string
  277. symbol, rem, ok = bsoncore.ReadSymbol(data)
  278. *v = Symbol(symbol)
  279. case bsontype.CodeWithScope:
  280. var raw []byte
  281. var code string
  282. var scope Doc
  283. code, raw, rem, ok = bsoncore.ReadCodeWithScope(data)
  284. scope, err = ReadDoc(raw)
  285. *v = CodeWithScope(code, scope)
  286. case bsontype.Int32:
  287. var i32 int32
  288. i32, rem, ok = bsoncore.ReadInt32(data)
  289. *v = Int32(i32)
  290. case bsontype.Timestamp:
  291. var i, t uint32
  292. t, i, rem, ok = bsoncore.ReadTimestamp(data)
  293. *v = Timestamp(t, i)
  294. case bsontype.Int64:
  295. var i64 int64
  296. i64, rem, ok = bsoncore.ReadInt64(data)
  297. *v = Int64(i64)
  298. case bsontype.Decimal128:
  299. var d128 primitive.Decimal128
  300. d128, rem, ok = bsoncore.ReadDecimal128(data)
  301. *v = Decimal128(d128)
  302. case bsontype.MinKey:
  303. *v = MinKey()
  304. case bsontype.MaxKey:
  305. *v = MaxKey()
  306. default:
  307. err = fmt.Errorf("invalid BSON type %v", t)
  308. }
  309. if !ok && err == nil {
  310. err = bsoncore.NewInsufficientBytesError(data, rem)
  311. }
  312. return err
  313. }
  314. // Type returns the BSON type of this value.
  315. func (v Val) Type() bsontype.Type {
  316. if v.t == bsontype.Type(0) {
  317. return bsontype.Null
  318. }
  319. return v.t
  320. }
  321. // IsNumber returns true if the type of v is a numberic BSON type.
  322. func (v Val) IsNumber() bool {
  323. switch v.Type() {
  324. case bsontype.Double, bsontype.Int32, bsontype.Int64, bsontype.Decimal128:
  325. return true
  326. default:
  327. return false
  328. }
  329. }
  330. // Double returns the BSON double value the Value represents. It panics if the value is a BSON type
  331. // other than double.
  332. func (v Val) Double() float64 {
  333. if v.t != bsontype.Double {
  334. panic(ElementTypeError{"bson.Value.Double", v.t})
  335. }
  336. return math.Float64frombits(binary.LittleEndian.Uint64(v.bootstrap[0:8]))
  337. }
  338. // DoubleOK is the same as Double, but returns a boolean instead of panicking.
  339. func (v Val) DoubleOK() (float64, bool) {
  340. if v.t != bsontype.Double {
  341. return 0, false
  342. }
  343. return math.Float64frombits(binary.LittleEndian.Uint64(v.bootstrap[0:8])), true
  344. }
  345. // StringValue returns the BSON string the Value represents. It panics if the value is a BSON type
  346. // other than string.
  347. //
  348. // NOTE: This method is called StringValue to avoid it implementing the
  349. // fmt.Stringer interface.
  350. func (v Val) StringValue() string {
  351. if v.t != bsontype.String {
  352. panic(ElementTypeError{"bson.Value.StringValue", v.t})
  353. }
  354. return v.string()
  355. }
  356. // StringValueOK is the same as StringValue, but returns a boolean instead of
  357. // panicking.
  358. func (v Val) StringValueOK() (string, bool) {
  359. if v.t != bsontype.String {
  360. return "", false
  361. }
  362. return v.string(), true
  363. }
  364. func (v Val) asDoc() Doc {
  365. doc, ok := v.primitive.(Doc)
  366. if ok {
  367. return doc
  368. }
  369. mdoc := v.primitive.(MDoc)
  370. for k, v := range mdoc {
  371. doc = append(doc, Elem{k, v})
  372. }
  373. return doc
  374. }
  375. func (v Val) asMDoc() MDoc {
  376. mdoc, ok := v.primitive.(MDoc)
  377. if ok {
  378. return mdoc
  379. }
  380. mdoc = make(MDoc)
  381. doc := v.primitive.(Doc)
  382. for _, elem := range doc {
  383. mdoc[elem.Key] = elem.Value
  384. }
  385. return mdoc
  386. }
  387. // Document returns the BSON embedded document value the Value represents. It panics if the value
  388. // is a BSON type other than embedded document.
  389. func (v Val) Document() Doc {
  390. if v.t != bsontype.EmbeddedDocument {
  391. panic(ElementTypeError{"bson.Value.Document", v.t})
  392. }
  393. return v.asDoc()
  394. }
  395. // DocumentOK is the same as Document, except it returns a boolean
  396. // instead of panicking.
  397. func (v Val) DocumentOK() (Doc, bool) {
  398. if v.t != bsontype.EmbeddedDocument {
  399. return nil, false
  400. }
  401. return v.asDoc(), true
  402. }
  403. // MDocument returns the BSON embedded document value the Value represents. It panics if the value
  404. // is a BSON type other than embedded document.
  405. func (v Val) MDocument() MDoc {
  406. if v.t != bsontype.EmbeddedDocument {
  407. panic(ElementTypeError{"bson.Value.MDocument", v.t})
  408. }
  409. return v.asMDoc()
  410. }
  411. // MDocumentOK is the same as Document, except it returns a boolean
  412. // instead of panicking.
  413. func (v Val) MDocumentOK() (MDoc, bool) {
  414. if v.t != bsontype.EmbeddedDocument {
  415. return nil, false
  416. }
  417. return v.asMDoc(), true
  418. }
  419. // Array returns the BSON array value the Value represents. It panics if the value is a BSON type
  420. // other than array.
  421. func (v Val) Array() Arr {
  422. if v.t != bsontype.Array {
  423. panic(ElementTypeError{"bson.Value.Array", v.t})
  424. }
  425. return v.primitive.(Arr)
  426. }
  427. // ArrayOK is the same as Array, except it returns a boolean
  428. // instead of panicking.
  429. func (v Val) ArrayOK() (Arr, bool) {
  430. if v.t != bsontype.Array {
  431. return nil, false
  432. }
  433. return v.primitive.(Arr), true
  434. }
  435. // Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type
  436. // other than binary.
  437. func (v Val) Binary() (byte, []byte) {
  438. if v.t != bsontype.Binary {
  439. panic(ElementTypeError{"bson.Value.Binary", v.t})
  440. }
  441. bin := v.primitive.(primitive.Binary)
  442. return bin.Subtype, bin.Data
  443. }
  444. // BinaryOK is the same as Binary, except it returns a boolean instead of
  445. // panicking.
  446. func (v Val) BinaryOK() (byte, []byte, bool) {
  447. if v.t != bsontype.Binary {
  448. return 0x00, nil, false
  449. }
  450. bin := v.primitive.(primitive.Binary)
  451. return bin.Subtype, bin.Data, true
  452. }
  453. // Undefined returns the BSON undefined the Value represents. It panics if the value is a BSON type
  454. // other than binary.
  455. func (v Val) Undefined() {
  456. if v.t != bsontype.Undefined {
  457. panic(ElementTypeError{"bson.Value.Undefined", v.t})
  458. }
  459. return
  460. }
  461. // UndefinedOK is the same as Undefined, except it returns a boolean instead of
  462. // panicking.
  463. func (v Val) UndefinedOK() bool {
  464. if v.t != bsontype.Undefined {
  465. return false
  466. }
  467. return true
  468. }
  469. // ObjectID returns the BSON ObjectID the Value represents. It panics if the value is a BSON type
  470. // other than ObjectID.
  471. func (v Val) ObjectID() primitive.ObjectID {
  472. if v.t != bsontype.ObjectID {
  473. panic(ElementTypeError{"bson.Value.ObjectID", v.t})
  474. }
  475. var oid primitive.ObjectID
  476. copy(oid[:], v.bootstrap[:12])
  477. return oid
  478. }
  479. // ObjectIDOK is the same as ObjectID, except it returns a boolean instead of
  480. // panicking.
  481. func (v Val) ObjectIDOK() (primitive.ObjectID, bool) {
  482. if v.t != bsontype.ObjectID {
  483. return primitive.ObjectID{}, false
  484. }
  485. var oid primitive.ObjectID
  486. copy(oid[:], v.bootstrap[:12])
  487. return oid, true
  488. }
  489. // Boolean returns the BSON boolean the Value represents. It panics if the value is a BSON type
  490. // other than boolean.
  491. func (v Val) Boolean() bool {
  492. if v.t != bsontype.Boolean {
  493. panic(ElementTypeError{"bson.Value.Boolean", v.t})
  494. }
  495. return v.bootstrap[0] == 0x01
  496. }
  497. // BooleanOK is the same as Boolean, except it returns a boolean instead of
  498. // panicking.
  499. func (v Val) BooleanOK() (bool, bool) {
  500. if v.t != bsontype.Boolean {
  501. return false, false
  502. }
  503. return v.bootstrap[0] == 0x01, true
  504. }
  505. // DateTime returns the BSON datetime the Value represents. It panics if the value is a BSON type
  506. // other than datetime.
  507. func (v Val) DateTime() int64 {
  508. if v.t != bsontype.DateTime {
  509. panic(ElementTypeError{"bson.Value.DateTime", v.t})
  510. }
  511. return v.i64()
  512. }
  513. // DateTimeOK is the same as DateTime, except it returns a boolean instead of
  514. // panicking.
  515. func (v Val) DateTimeOK() (int64, bool) {
  516. if v.t != bsontype.DateTime {
  517. return 0, false
  518. }
  519. return v.i64(), true
  520. }
  521. // Time returns the BSON datetime the Value represents as time.Time. It panics if the value is a BSON
  522. // type other than datetime.
  523. func (v Val) Time() time.Time {
  524. if v.t != bsontype.DateTime {
  525. panic(ElementTypeError{"bson.Value.Time", v.t})
  526. }
  527. i := v.i64()
  528. return time.Unix(int64(i)/1000, int64(i)%1000*1000000)
  529. }
  530. // TimeOK is the same as Time, except it returns a boolean instead of
  531. // panicking.
  532. func (v Val) TimeOK() (time.Time, bool) {
  533. if v.t != bsontype.DateTime {
  534. return time.Time{}, false
  535. }
  536. i := v.i64()
  537. return time.Unix(int64(i)/1000, int64(i)%1000*1000000), true
  538. }
  539. // Null returns the BSON undefined the Value represents. It panics if the value is a BSON type
  540. // other than binary.
  541. func (v Val) Null() {
  542. if v.t != bsontype.Null && v.t != bsontype.Type(0) {
  543. panic(ElementTypeError{"bson.Value.Null", v.t})
  544. }
  545. return
  546. }
  547. // NullOK is the same as Null, except it returns a boolean instead of
  548. // panicking.
  549. func (v Val) NullOK() bool {
  550. if v.t != bsontype.Null && v.t != bsontype.Type(0) {
  551. return false
  552. }
  553. return true
  554. }
  555. // Regex returns the BSON regex the Value represents. It panics if the value is a BSON type
  556. // other than regex.
  557. func (v Val) Regex() (pattern, options string) {
  558. if v.t != bsontype.Regex {
  559. panic(ElementTypeError{"bson.Value.Regex", v.t})
  560. }
  561. regex := v.primitive.(primitive.Regex)
  562. return regex.Pattern, regex.Options
  563. }
  564. // RegexOK is the same as Regex, except that it returns a boolean
  565. // instead of panicking.
  566. func (v Val) RegexOK() (pattern, options string, ok bool) {
  567. if v.t != bsontype.Regex {
  568. return "", "", false
  569. }
  570. regex := v.primitive.(primitive.Regex)
  571. return regex.Pattern, regex.Options, true
  572. }
  573. // DBPointer returns the BSON dbpointer the Value represents. It panics if the value is a BSON type
  574. // other than dbpointer.
  575. func (v Val) DBPointer() (string, primitive.ObjectID) {
  576. if v.t != bsontype.DBPointer {
  577. panic(ElementTypeError{"bson.Value.DBPointer", v.t})
  578. }
  579. dbptr := v.primitive.(primitive.DBPointer)
  580. return dbptr.DB, dbptr.Pointer
  581. }
  582. // DBPointerOK is the same as DBPoitner, except that it returns a boolean
  583. // instead of panicking.
  584. func (v Val) DBPointerOK() (string, primitive.ObjectID, bool) {
  585. if v.t != bsontype.DBPointer {
  586. return "", primitive.ObjectID{}, false
  587. }
  588. dbptr := v.primitive.(primitive.DBPointer)
  589. return dbptr.DB, dbptr.Pointer, true
  590. }
  591. // JavaScript returns the BSON JavaScript the Value represents. It panics if the value is a BSON type
  592. // other than JavaScript.
  593. func (v Val) JavaScript() string {
  594. if v.t != bsontype.JavaScript {
  595. panic(ElementTypeError{"bson.Value.JavaScript", v.t})
  596. }
  597. return v.string()
  598. }
  599. // JavaScriptOK is the same as Javascript, except that it returns a boolean
  600. // instead of panicking.
  601. func (v Val) JavaScriptOK() (string, bool) {
  602. if v.t != bsontype.JavaScript {
  603. return "", false
  604. }
  605. return v.string(), true
  606. }
  607. // Symbol returns the BSON symbol the Value represents. It panics if the value is a BSON type
  608. // other than symbol.
  609. func (v Val) Symbol() string {
  610. if v.t != bsontype.Symbol {
  611. panic(ElementTypeError{"bson.Value.Symbol", v.t})
  612. }
  613. return v.string()
  614. }
  615. // SymbolOK is the same as Javascript, except that it returns a boolean
  616. // instead of panicking.
  617. func (v Val) SymbolOK() (string, bool) {
  618. if v.t != bsontype.Symbol {
  619. return "", false
  620. }
  621. return v.string(), true
  622. }
  623. // CodeWithScope returns the BSON code with scope value the Value represents. It panics if the
  624. // value is a BSON type other than code with scope.
  625. func (v Val) CodeWithScope() (string, Doc) {
  626. if v.t != bsontype.CodeWithScope {
  627. panic(ElementTypeError{"bson.Value.CodeWithScope", v.t})
  628. }
  629. cws := v.primitive.(primitive.CodeWithScope)
  630. return string(cws.Code), cws.Scope.(Doc)
  631. }
  632. // CodeWithScopeOK is the same as JavascriptWithScope,
  633. // except that it returns a boolean instead of panicking.
  634. func (v Val) CodeWithScopeOK() (string, Doc, bool) {
  635. if v.t != bsontype.CodeWithScope {
  636. return "", nil, false
  637. }
  638. cws := v.primitive.(primitive.CodeWithScope)
  639. return string(cws.Code), cws.Scope.(Doc), true
  640. }
  641. // Int32 returns the BSON int32 the Value represents. It panics if the value is a BSON type
  642. // other than int32.
  643. func (v Val) Int32() int32 {
  644. if v.t != bsontype.Int32 {
  645. panic(ElementTypeError{"bson.Value.Int32", v.t})
  646. }
  647. return int32(v.bootstrap[0]) | int32(v.bootstrap[1])<<8 |
  648. int32(v.bootstrap[2])<<16 | int32(v.bootstrap[3])<<24
  649. }
  650. // Int32OK is the same as Int32, except that it returns a boolean instead of
  651. // panicking.
  652. func (v Val) Int32OK() (int32, bool) {
  653. if v.t != bsontype.Int32 {
  654. return 0, false
  655. }
  656. return int32(v.bootstrap[0]) | int32(v.bootstrap[1])<<8 |
  657. int32(v.bootstrap[2])<<16 | int32(v.bootstrap[3])<<24,
  658. true
  659. }
  660. // Timestamp returns the BSON timestamp the Value represents. It panics if the value is a
  661. // BSON type other than timestamp.
  662. func (v Val) Timestamp() (t, i uint32) {
  663. if v.t != bsontype.Timestamp {
  664. panic(ElementTypeError{"bson.Value.Timestamp", v.t})
  665. }
  666. return uint32(v.bootstrap[4]) | uint32(v.bootstrap[5])<<8 |
  667. uint32(v.bootstrap[6])<<16 | uint32(v.bootstrap[7])<<24,
  668. uint32(v.bootstrap[0]) | uint32(v.bootstrap[1])<<8 |
  669. uint32(v.bootstrap[2])<<16 | uint32(v.bootstrap[3])<<24
  670. }
  671. // TimestampOK is the same as Timestamp, except that it returns a boolean
  672. // instead of panicking.
  673. func (v Val) TimestampOK() (t uint32, i uint32, ok bool) {
  674. if v.t != bsontype.Timestamp {
  675. return 0, 0, false
  676. }
  677. return uint32(v.bootstrap[4]) | uint32(v.bootstrap[5])<<8 |
  678. uint32(v.bootstrap[6])<<16 | uint32(v.bootstrap[7])<<24,
  679. uint32(v.bootstrap[0]) | uint32(v.bootstrap[1])<<8 |
  680. uint32(v.bootstrap[2])<<16 | uint32(v.bootstrap[3])<<24,
  681. true
  682. }
  683. // Int64 returns the BSON int64 the Value represents. It panics if the value is a BSON type
  684. // other than int64.
  685. func (v Val) Int64() int64 {
  686. if v.t != bsontype.Int64 {
  687. panic(ElementTypeError{"bson.Value.Int64", v.t})
  688. }
  689. return v.i64()
  690. }
  691. // Int64OK is the same as Int64, except that it returns a boolean instead of
  692. // panicking.
  693. func (v Val) Int64OK() (int64, bool) {
  694. if v.t != bsontype.Int64 {
  695. return 0, false
  696. }
  697. return v.i64(), true
  698. }
  699. // Decimal128 returns the BSON decimal128 value the Value represents. It panics if the value is a
  700. // BSON type other than decimal128.
  701. func (v Val) Decimal128() primitive.Decimal128 {
  702. if v.t != bsontype.Decimal128 {
  703. panic(ElementTypeError{"bson.Value.Decimal128", v.t})
  704. }
  705. return v.primitive.(primitive.Decimal128)
  706. }
  707. // Decimal128OK is the same as Decimal128, except that it returns a boolean
  708. // instead of panicking.
  709. func (v Val) Decimal128OK() (primitive.Decimal128, bool) {
  710. if v.t != bsontype.Decimal128 {
  711. return primitive.Decimal128{}, false
  712. }
  713. return v.primitive.(primitive.Decimal128), true
  714. }
  715. // MinKey returns the BSON minkey the Value represents. It panics if the value is a BSON type
  716. // other than binary.
  717. func (v Val) MinKey() {
  718. if v.t != bsontype.MinKey {
  719. panic(ElementTypeError{"bson.Value.MinKey", v.t})
  720. }
  721. return
  722. }
  723. // MinKeyOK is the same as MinKey, except it returns a boolean instead of
  724. // panicking.
  725. func (v Val) MinKeyOK() bool {
  726. if v.t != bsontype.MinKey {
  727. return false
  728. }
  729. return true
  730. }
  731. // MaxKey returns the BSON maxkey the Value represents. It panics if the value is a BSON type
  732. // other than binary.
  733. func (v Val) MaxKey() {
  734. if v.t != bsontype.MaxKey {
  735. panic(ElementTypeError{"bson.Value.MaxKey", v.t})
  736. }
  737. return
  738. }
  739. // MaxKeyOK is the same as MaxKey, except it returns a boolean instead of
  740. // panicking.
  741. func (v Val) MaxKeyOK() bool {
  742. if v.t != bsontype.MaxKey {
  743. return false
  744. }
  745. return true
  746. }
  747. // Equal compares v to v2 and returns true if they are equal. Unknown BSON types are
  748. // never equal. Two empty values are equal.
  749. func (v Val) Equal(v2 Val) bool {
  750. if v.Type() != v2.Type() {
  751. return false
  752. }
  753. if v.IsZero() && v2.IsZero() {
  754. return true
  755. }
  756. switch v.Type() {
  757. case bsontype.Double, bsontype.DateTime, bsontype.Timestamp, bsontype.Int64:
  758. return bytes.Equal(v.bootstrap[0:8], v2.bootstrap[0:8])
  759. case bsontype.String:
  760. return v.string() == v2.string()
  761. case bsontype.EmbeddedDocument:
  762. return v.equalDocs(v2)
  763. case bsontype.Array:
  764. return v.Array().Equal(v2.Array())
  765. case bsontype.Binary:
  766. return v.primitive.(primitive.Binary).Equal(v2.primitive.(primitive.Binary))
  767. case bsontype.Undefined:
  768. return true
  769. case bsontype.ObjectID:
  770. return bytes.Equal(v.bootstrap[0:12], v2.bootstrap[0:12])
  771. case bsontype.Boolean:
  772. return v.bootstrap[0] == v2.bootstrap[0]
  773. case bsontype.Null:
  774. return true
  775. case bsontype.Regex:
  776. return v.primitive.(primitive.Regex).Equal(v2.primitive.(primitive.Regex))
  777. case bsontype.DBPointer:
  778. return v.primitive.(primitive.DBPointer).Equal(v2.primitive.(primitive.DBPointer))
  779. case bsontype.JavaScript:
  780. return v.JavaScript() == v2.JavaScript()
  781. case bsontype.Symbol:
  782. return v.Symbol() == v2.Symbol()
  783. case bsontype.CodeWithScope:
  784. code1, scope1 := v.primitive.(primitive.CodeWithScope).Code, v.primitive.(primitive.CodeWithScope).Scope
  785. code2, scope2 := v2.primitive.(primitive.CodeWithScope).Code, v2.primitive.(primitive.CodeWithScope).Scope
  786. return code1 == code2 && v.equalInterfaceDocs(scope1, scope2)
  787. case bsontype.Int32:
  788. return v.Int32() == v2.Int32()
  789. case bsontype.Decimal128:
  790. h, l := v.Decimal128().GetBytes()
  791. h2, l2 := v2.Decimal128().GetBytes()
  792. return h == h2 && l == l2
  793. case bsontype.MinKey:
  794. return true
  795. case bsontype.MaxKey:
  796. return true
  797. default:
  798. return false
  799. }
  800. }
  801. func (v Val) equalDocs(v2 Val) bool {
  802. _, ok1 := v.primitive.(MDoc)
  803. _, ok2 := v2.primitive.(MDoc)
  804. if ok1 || ok2 {
  805. return v.asMDoc().Equal(v2.asMDoc())
  806. }
  807. return v.asDoc().Equal(v2.asDoc())
  808. }
  809. func (Val) equalInterfaceDocs(i, i2 interface{}) bool {
  810. switch d := i.(type) {
  811. case MDoc:
  812. d2, ok := i2.(IDoc)
  813. if !ok {
  814. return false
  815. }
  816. return d.Equal(d2)
  817. case Doc:
  818. d2, ok := i2.(IDoc)
  819. if !ok {
  820. return false
  821. }
  822. return d.Equal(d2)
  823. case nil:
  824. return i2 == nil
  825. default:
  826. return false
  827. }
  828. }