bson.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. // BSON library for Go
  2. //
  3. // Copyright (c) 2010-2012 - Gustavo Niemeyer <gustavo@niemeyer.net>
  4. //
  5. // All rights reserved.
  6. //
  7. // Redistribution and use in source and binary forms, with or without
  8. // modification, are permitted provided that the following conditions are met:
  9. //
  10. // 1. Redistributions of source code must retain the above copyright notice, this
  11. // list of conditions and the following disclaimer.
  12. // 2. Redistributions in binary form must reproduce the above copyright notice,
  13. // this list of conditions and the following disclaimer in the documentation
  14. // and/or other materials provided with the distribution.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  20. // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. // Package bson is an implementation of the BSON specification for Go:
  27. //
  28. // http://bsonspec.org
  29. //
  30. // It was created as part of the mgo MongoDB driver for Go, but is standalone
  31. // and may be used on its own without the driver.
  32. package bson
  33. import (
  34. "bytes"
  35. "crypto/md5"
  36. "crypto/rand"
  37. "encoding/binary"
  38. "encoding/hex"
  39. "encoding/json"
  40. "errors"
  41. "fmt"
  42. "io"
  43. "math"
  44. "os"
  45. "reflect"
  46. "runtime"
  47. "strings"
  48. "sync"
  49. "sync/atomic"
  50. "time"
  51. )
  52. //go:generate go run bson_corpus_spec_test_generator.go
  53. // --------------------------------------------------------------------------
  54. // The public API.
  55. // Element types constants from BSON specification.
  56. const (
  57. ElementFloat64 byte = 0x01
  58. ElementString byte = 0x02
  59. ElementDocument byte = 0x03
  60. ElementArray byte = 0x04
  61. ElementBinary byte = 0x05
  62. Element06 byte = 0x06
  63. ElementObjectId byte = 0x07
  64. ElementBool byte = 0x08
  65. ElementDatetime byte = 0x09
  66. ElementNil byte = 0x0A
  67. ElementRegEx byte = 0x0B
  68. ElementDBPointer byte = 0x0C
  69. ElementJavaScriptWithoutScope byte = 0x0D
  70. ElementSymbol byte = 0x0E
  71. ElementJavaScriptWithScope byte = 0x0F
  72. ElementInt32 byte = 0x10
  73. ElementTimestamp byte = 0x11
  74. ElementInt64 byte = 0x12
  75. ElementDecimal128 byte = 0x13
  76. ElementMinKey byte = 0xFF
  77. ElementMaxKey byte = 0x7F
  78. BinaryGeneric byte = 0x00
  79. BinaryFunction byte = 0x01
  80. BinaryBinaryOld byte = 0x02
  81. BinaryUUIDOld byte = 0x03
  82. BinaryUUID byte = 0x04
  83. BinaryMD5 byte = 0x05
  84. BinaryUserDefined byte = 0x80
  85. )
  86. // Getter interface: a value implementing the bson.Getter interface will have its GetBSON
  87. // method called when the given value has to be marshalled, and the result
  88. // of this method will be marshaled in place of the actual object.
  89. //
  90. // If GetBSON returns return a non-nil error, the marshalling procedure
  91. // will stop and error out with the provided value.
  92. type Getter interface {
  93. GetBSON() (interface{}, error)
  94. }
  95. // Setter interface: a value implementing the bson.Setter interface will receive the BSON
  96. // value via the SetBSON method during unmarshaling, and the object
  97. // itself will not be changed as usual.
  98. //
  99. // If setting the value works, the method should return nil or alternatively
  100. // bson.ErrSetZero to set the respective field to its zero value (nil for
  101. // pointer types). If SetBSON returns a value of type bson.TypeError, the
  102. // BSON value will be omitted from a map or slice being decoded and the
  103. // unmarshalling will continue. If it returns any other non-nil error, the
  104. // unmarshalling procedure will stop and error out with the provided value.
  105. //
  106. // This interface is generally useful in pointer receivers, since the method
  107. // will want to change the receiver. A type field that implements the Setter
  108. // interface doesn't have to be a pointer, though.
  109. //
  110. // Unlike the usual behavior, unmarshalling onto a value that implements a
  111. // Setter interface will NOT reset the value to its zero state. This allows
  112. // the value to decide by itself how to be unmarshalled.
  113. //
  114. // For example:
  115. //
  116. // type MyString string
  117. //
  118. // func (s *MyString) SetBSON(raw bson.Raw) error {
  119. // return raw.Unmarshal(s)
  120. // }
  121. //
  122. type Setter interface {
  123. SetBSON(raw Raw) error
  124. }
  125. // ErrSetZero may be returned from a SetBSON method to have the value set to
  126. // its respective zero value. When used in pointer values, this will set the
  127. // field to nil rather than to the pre-allocated value.
  128. var ErrSetZero = errors.New("set to zero")
  129. // M is a convenient alias for a map[string]interface{} map, useful for
  130. // dealing with BSON in a native way. For instance:
  131. //
  132. // bson.M{"a": 1, "b": true}
  133. //
  134. // There's no special handling for this type in addition to what's done anyway
  135. // for an equivalent map type. Elements in the map will be dumped in an
  136. // undefined ordered. See also the bson.D type for an ordered alternative.
  137. type M map[string]interface{}
  138. // D represents a BSON document containing ordered elements. For example:
  139. //
  140. // bson.D{{"a", 1}, {"b", true}}
  141. //
  142. // In some situations, such as when creating indexes for MongoDB, the order in
  143. // which the elements are defined is important. If the order is not important,
  144. // using a map is generally more comfortable. See bson.M and bson.RawD.
  145. type D []DocElem
  146. // DocElem is an element of the bson.D document representation.
  147. type DocElem struct {
  148. Name string
  149. Value interface{}
  150. }
  151. // Map returns a map out of the ordered element name/value pairs in d.
  152. func (d D) Map() (m M) {
  153. m = make(M, len(d))
  154. for _, item := range d {
  155. m[item.Name] = item.Value
  156. }
  157. return m
  158. }
  159. // The Raw type represents raw unprocessed BSON documents and elements.
  160. // Kind is the kind of element as defined per the BSON specification, and
  161. // Data is the raw unprocessed data for the respective element.
  162. // Using this type it is possible to unmarshal or marshal values partially.
  163. //
  164. // Relevant documentation:
  165. //
  166. // http://bsonspec.org/#/specification
  167. //
  168. type Raw struct {
  169. Kind byte
  170. Data []byte
  171. }
  172. // RawD represents a BSON document containing raw unprocessed elements.
  173. // This low-level representation may be useful when lazily processing
  174. // documents of uncertain content, or when manipulating the raw content
  175. // documents in general.
  176. type RawD []RawDocElem
  177. // RawDocElem elements of RawD type.
  178. type RawDocElem struct {
  179. Name string
  180. Value Raw
  181. }
  182. // ObjectId is a unique ID identifying a BSON value. It must be exactly 12 bytes
  183. // long. MongoDB objects by default have such a property set in their "_id"
  184. // property.
  185. //
  186. // http://www.mongodb.org/display/DOCS/Object+Ids
  187. type ObjectId string
  188. // ObjectIdHex returns an ObjectId from the provided hex representation.
  189. // Calling this function with an invalid hex representation will
  190. // cause a runtime panic. See the IsObjectIdHex function.
  191. func ObjectIdHex(s string) ObjectId {
  192. d, err := hex.DecodeString(s)
  193. if err != nil || len(d) != 12 {
  194. panic(fmt.Sprintf("invalid input to ObjectIdHex: %q", s))
  195. }
  196. return ObjectId(d)
  197. }
  198. // IsObjectIdHex returns whether s is a valid hex representation of
  199. // an ObjectId. See the ObjectIdHex function.
  200. func IsObjectIdHex(s string) bool {
  201. if len(s) != 24 {
  202. return false
  203. }
  204. _, err := hex.DecodeString(s)
  205. return err == nil
  206. }
  207. // objectIdCounter is atomically incremented when generating a new ObjectId
  208. // using NewObjectId() function. It's used as a counter part of an id.
  209. var objectIdCounter = readRandomUint32()
  210. // readRandomUint32 returns a random objectIdCounter.
  211. func readRandomUint32() uint32 {
  212. var b [4]byte
  213. _, err := io.ReadFull(rand.Reader, b[:])
  214. if err != nil {
  215. panic(fmt.Errorf("cannot read random object id: %v", err))
  216. }
  217. return uint32((uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24))
  218. }
  219. // machineId stores machine id generated once and used in subsequent calls
  220. // to NewObjectId function.
  221. var machineId = readMachineId()
  222. var processId = os.Getpid()
  223. // readMachineId generates and returns a machine id.
  224. // If this function fails to get the hostname it will cause a runtime error.
  225. func readMachineId() []byte {
  226. var sum [3]byte
  227. id := sum[:]
  228. hostname, err1 := os.Hostname()
  229. if err1 != nil {
  230. _, err2 := io.ReadFull(rand.Reader, id)
  231. if err2 != nil {
  232. panic(fmt.Errorf("cannot get hostname: %v; %v", err1, err2))
  233. }
  234. return id
  235. }
  236. hw := md5.New()
  237. hw.Write([]byte(hostname))
  238. copy(id, hw.Sum(nil))
  239. return id
  240. }
  241. // NewObjectId returns a new unique ObjectId.
  242. func NewObjectId() ObjectId {
  243. var b [12]byte
  244. // Timestamp, 4 bytes, big endian
  245. binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix()))
  246. // Machine, first 3 bytes of md5(hostname)
  247. b[4] = machineId[0]
  248. b[5] = machineId[1]
  249. b[6] = machineId[2]
  250. // Pid, 2 bytes, specs don't specify endianness, but we use big endian.
  251. b[7] = byte(processId >> 8)
  252. b[8] = byte(processId)
  253. // Increment, 3 bytes, big endian
  254. i := atomic.AddUint32(&objectIdCounter, 1)
  255. b[9] = byte(i >> 16)
  256. b[10] = byte(i >> 8)
  257. b[11] = byte(i)
  258. return ObjectId(b[:])
  259. }
  260. // NewObjectIdWithTime returns a dummy ObjectId with the timestamp part filled
  261. // with the provided number of seconds from epoch UTC, and all other parts
  262. // filled with zeroes. It's not safe to insert a document with an id generated
  263. // by this method, it is useful only for queries to find documents with ids
  264. // generated before or after the specified timestamp.
  265. func NewObjectIdWithTime(t time.Time) ObjectId {
  266. var b [12]byte
  267. binary.BigEndian.PutUint32(b[:4], uint32(t.Unix()))
  268. return ObjectId(string(b[:]))
  269. }
  270. // String returns a hex string representation of the id.
  271. // Example: ObjectIdHex("4d88e15b60f486e428412dc9").
  272. func (id ObjectId) String() string {
  273. return fmt.Sprintf(`ObjectIdHex("%x")`, string(id))
  274. }
  275. // Hex returns a hex representation of the ObjectId.
  276. func (id ObjectId) Hex() string {
  277. return hex.EncodeToString([]byte(id))
  278. }
  279. // MarshalJSON turns a bson.ObjectId into a json.Marshaller.
  280. func (id ObjectId) MarshalJSON() ([]byte, error) {
  281. return []byte(fmt.Sprintf(`"%x"`, string(id))), nil
  282. }
  283. var nullBytes = []byte("null")
  284. // UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller.
  285. func (id *ObjectId) UnmarshalJSON(data []byte) error {
  286. if len(data) > 0 && (data[0] == '{' || data[0] == 'O') {
  287. var v struct {
  288. Id json.RawMessage `json:"$oid"`
  289. Func struct {
  290. Id json.RawMessage
  291. } `json:"$oidFunc"`
  292. }
  293. err := jdec(data, &v)
  294. if err == nil {
  295. if len(v.Id) > 0 {
  296. data = []byte(v.Id)
  297. } else {
  298. data = []byte(v.Func.Id)
  299. }
  300. }
  301. }
  302. if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) {
  303. *id = ""
  304. return nil
  305. }
  306. if len(data) != 26 || data[0] != '"' || data[25] != '"' {
  307. return fmt.Errorf("invalid ObjectId in JSON: %s", string(data))
  308. }
  309. var buf [12]byte
  310. _, err := hex.Decode(buf[:], data[1:25])
  311. if err != nil {
  312. return fmt.Errorf("invalid ObjectId in JSON: %s (%s)", string(data), err)
  313. }
  314. *id = ObjectId(string(buf[:]))
  315. return nil
  316. }
  317. // MarshalText turns bson.ObjectId into an encoding.TextMarshaler.
  318. func (id ObjectId) MarshalText() ([]byte, error) {
  319. return []byte(fmt.Sprintf("%x", string(id))), nil
  320. }
  321. // UnmarshalText turns *bson.ObjectId into an encoding.TextUnmarshaler.
  322. func (id *ObjectId) UnmarshalText(data []byte) error {
  323. if len(data) == 1 && data[0] == ' ' || len(data) == 0 {
  324. *id = ""
  325. return nil
  326. }
  327. if len(data) != 24 {
  328. return fmt.Errorf("invalid ObjectId: %s", data)
  329. }
  330. var buf [12]byte
  331. _, err := hex.Decode(buf[:], data[:])
  332. if err != nil {
  333. return fmt.Errorf("invalid ObjectId: %s (%s)", data, err)
  334. }
  335. *id = ObjectId(string(buf[:]))
  336. return nil
  337. }
  338. // Valid returns true if id is valid. A valid id must contain exactly 12 bytes.
  339. func (id ObjectId) Valid() bool {
  340. return len(id) == 12
  341. }
  342. // byteSlice returns byte slice of id from start to end.
  343. // Calling this function with an invalid id will cause a runtime panic.
  344. func (id ObjectId) byteSlice(start, end int) []byte {
  345. if len(id) != 12 {
  346. panic(fmt.Sprintf("invalid ObjectId: %q", string(id)))
  347. }
  348. return []byte(string(id)[start:end])
  349. }
  350. // Time returns the timestamp part of the id.
  351. // It's a runtime error to call this method with an invalid id.
  352. func (id ObjectId) Time() time.Time {
  353. // First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch.
  354. secs := int64(binary.BigEndian.Uint32(id.byteSlice(0, 4)))
  355. return time.Unix(secs, 0)
  356. }
  357. // Machine returns the 3-byte machine id part of the id.
  358. // It's a runtime error to call this method with an invalid id.
  359. func (id ObjectId) Machine() []byte {
  360. return id.byteSlice(4, 7)
  361. }
  362. // Pid returns the process id part of the id.
  363. // It's a runtime error to call this method with an invalid id.
  364. func (id ObjectId) Pid() uint16 {
  365. return binary.BigEndian.Uint16(id.byteSlice(7, 9))
  366. }
  367. // Counter returns the incrementing value part of the id.
  368. // It's a runtime error to call this method with an invalid id.
  369. func (id ObjectId) Counter() int32 {
  370. b := id.byteSlice(9, 12)
  371. // Counter is stored as big-endian 3-byte value
  372. return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
  373. }
  374. // The Symbol type is similar to a string and is used in languages with a
  375. // distinct symbol type.
  376. type Symbol string
  377. // Now returns the current time with millisecond precision. MongoDB stores
  378. // timestamps with the same precision, so a Time returned from this method
  379. // will not change after a roundtrip to the database. That's the only reason
  380. // why this function exists. Using the time.Now function also works fine
  381. // otherwise.
  382. func Now() time.Time {
  383. return time.Unix(0, time.Now().UnixNano()/1e6*1e6)
  384. }
  385. // MongoTimestamp is a special internal type used by MongoDB that for some
  386. // strange reason has its own datatype defined in BSON.
  387. type MongoTimestamp int64
  388. // Time returns the time part of ts which is stored with second precision.
  389. func (ts MongoTimestamp) Time() time.Time {
  390. return time.Unix(int64(uint64(ts)>>32), 0)
  391. }
  392. // Counter returns the counter part of ts.
  393. func (ts MongoTimestamp) Counter() uint32 {
  394. return uint32(ts)
  395. }
  396. // NewMongoTimestamp creates a timestamp using the given
  397. // date `t` (with second precision) and counter `c` (unique for `t`).
  398. //
  399. // Returns an error if time `t` is not between 1970-01-01T00:00:00Z
  400. // and 2106-02-07T06:28:15Z (inclusive).
  401. //
  402. // Note that two MongoTimestamps should never have the same (time, counter) combination:
  403. // the caller must ensure the counter `c` is increased if creating multiple MongoTimestamp
  404. // values for the same time `t` (ignoring fractions of seconds).
  405. func NewMongoTimestamp(t time.Time, c uint32) (MongoTimestamp, error) {
  406. u := t.Unix()
  407. if u < 0 || u > math.MaxUint32 {
  408. return -1, errors.New("invalid value for time")
  409. }
  410. i := int64(u<<32 | int64(c))
  411. return MongoTimestamp(i), nil
  412. }
  413. type orderKey int64
  414. // MaxKey is a special value that compares higher than all other possible BSON
  415. // values in a MongoDB database.
  416. var MaxKey = orderKey(1<<63 - 1)
  417. // MinKey is a special value that compares lower than all other possible BSON
  418. // values in a MongoDB database.
  419. var MinKey = orderKey(-1 << 63)
  420. type undefined struct{}
  421. // Undefined represents the undefined BSON value.
  422. var Undefined undefined
  423. // Binary is a representation for non-standard binary values. Any kind should
  424. // work, but the following are known as of this writing:
  425. //
  426. // 0x00 - Generic. This is decoded as []byte(data), not Binary{0x00, data}.
  427. // 0x01 - Function (!?)
  428. // 0x02 - Obsolete generic.
  429. // 0x03 - UUID
  430. // 0x05 - MD5
  431. // 0x80 - User defined.
  432. //
  433. type Binary struct {
  434. Kind byte
  435. Data []byte
  436. }
  437. // RegEx represents a regular expression. The Options field may contain
  438. // individual characters defining the way in which the pattern should be
  439. // applied, and must be sorted. Valid options as of this writing are 'i' for
  440. // case insensitive matching, 'm' for multi-line matching, 'x' for verbose
  441. // mode, 'l' to make \w, \W, and similar be locale-dependent, 's' for dot-all
  442. // mode (a '.' matches everything), and 'u' to make \w, \W, and similar match
  443. // unicode. The value of the Options parameter is not verified before being
  444. // marshaled into the BSON format.
  445. type RegEx struct {
  446. Pattern string
  447. Options string
  448. }
  449. // JavaScript is a type that holds JavaScript code. If Scope is non-nil, it
  450. // will be marshaled as a mapping from identifiers to values that may be
  451. // used when evaluating the provided Code.
  452. type JavaScript struct {
  453. Code string
  454. Scope interface{}
  455. }
  456. // DBPointer refers to a document id in a namespace.
  457. //
  458. // This type is deprecated in the BSON specification and should not be used
  459. // except for backwards compatibility with ancient applications.
  460. type DBPointer struct {
  461. Namespace string
  462. Id ObjectId
  463. }
  464. const initialBufferSize = 64
  465. func handleErr(err *error) {
  466. if r := recover(); r != nil {
  467. if _, ok := r.(runtime.Error); ok {
  468. panic(r)
  469. } else if _, ok := r.(externalPanic); ok {
  470. panic(r)
  471. } else if s, ok := r.(string); ok {
  472. *err = errors.New(s)
  473. } else if e, ok := r.(error); ok {
  474. *err = e
  475. } else {
  476. panic(r)
  477. }
  478. }
  479. }
  480. // Marshal serializes the in value, which may be a map or a struct value.
  481. // In the case of struct values, only exported fields will be serialized,
  482. // and the order of serialized fields will match that of the struct itself.
  483. // The lowercased field name is used as the key for each exported field,
  484. // but this behavior may be changed using the respective field tag.
  485. // The tag may also contain flags to tweak the marshalling behavior for
  486. // the field. The tag formats accepted are:
  487. //
  488. // "[<key>][,<flag1>[,<flag2>]]"
  489. //
  490. // `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
  491. //
  492. // The following flags are currently supported:
  493. //
  494. // omitempty Only include the field if it's not set to the zero
  495. // value for the type or to empty slices or maps.
  496. //
  497. // minsize Marshal an int64 value as an int32, if that's feasible
  498. // while preserving the numeric value.
  499. //
  500. // inline Inline the field, which must be a struct or a map,
  501. // causing all of its fields or keys to be processed as if
  502. // they were part of the outer struct. For maps, keys must
  503. // not conflict with the bson keys of other struct fields.
  504. //
  505. // Some examples:
  506. //
  507. // type T struct {
  508. // A bool
  509. // B int "myb"
  510. // C string "myc,omitempty"
  511. // D string `bson:",omitempty" json:"jsonkey"`
  512. // E int64 ",minsize"
  513. // F int64 "myf,omitempty,minsize"
  514. // }
  515. //
  516. func Marshal(in interface{}) (out []byte, err error) {
  517. return MarshalBuffer(in, make([]byte, 0, initialBufferSize))
  518. }
  519. // MarshalBuffer behaves the same way as Marshal, except that instead of
  520. // allocating a new byte slice it tries to use the received byte slice and
  521. // only allocates more memory if necessary to fit the marshaled value.
  522. func MarshalBuffer(in interface{}, buf []byte) (out []byte, err error) {
  523. defer handleErr(&err)
  524. e := &encoder{buf}
  525. e.addDoc(reflect.ValueOf(in))
  526. return e.out, nil
  527. }
  528. // Unmarshal deserializes data from in into the out value. The out value
  529. // must be a map, a pointer to a struct, or a pointer to a bson.D value.
  530. // In the case of struct values, only exported fields will be deserialized.
  531. // The lowercased field name is used as the key for each exported field,
  532. // but this behavior may be changed using the respective field tag.
  533. // The tag may also contain flags to tweak the marshalling behavior for
  534. // the field. The tag formats accepted are:
  535. //
  536. // "[<key>][,<flag1>[,<flag2>]]"
  537. //
  538. // `(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)`
  539. //
  540. // The following flags are currently supported during unmarshal (see the
  541. // Marshal method for other flags):
  542. //
  543. // inline Inline the field, which must be a struct or a map.
  544. // Inlined structs are handled as if its fields were part
  545. // of the outer struct. An inlined map causes keys that do
  546. // not match any other struct field to be inserted in the
  547. // map rather than being discarded as usual.
  548. //
  549. // The target field or element types of out may not necessarily match
  550. // the BSON values of the provided data. The following conversions are
  551. // made automatically:
  552. //
  553. // - Numeric types are converted if at least the integer part of the
  554. // value would be preserved correctly
  555. // - Bools are converted to numeric types as 1 or 0
  556. // - Numeric types are converted to bools as true if not 0 or false otherwise
  557. // - Binary and string BSON data is converted to a string, array or byte slice
  558. //
  559. // If the value would not fit the type and cannot be converted, it's
  560. // silently skipped.
  561. //
  562. // Pointer values are initialized when necessary.
  563. func Unmarshal(in []byte, out interface{}) (err error) {
  564. if raw, ok := out.(*Raw); ok {
  565. raw.Kind = 3
  566. raw.Data = in
  567. return nil
  568. }
  569. defer handleErr(&err)
  570. v := reflect.ValueOf(out)
  571. switch v.Kind() {
  572. case reflect.Ptr:
  573. fallthrough
  574. case reflect.Map:
  575. d := newDecoder(in)
  576. d.readDocTo(v)
  577. if d.i < len(d.in) {
  578. return errors.New("document is corrupted")
  579. }
  580. case reflect.Struct:
  581. return errors.New("unmarshal can't deal with struct values. Use a pointer")
  582. default:
  583. return errors.New("unmarshal needs a map or a pointer to a struct")
  584. }
  585. return nil
  586. }
  587. // Unmarshal deserializes raw into the out value. If the out value type
  588. // is not compatible with raw, a *bson.TypeError is returned.
  589. //
  590. // See the Unmarshal function documentation for more details on the
  591. // unmarshalling process.
  592. func (raw Raw) Unmarshal(out interface{}) (err error) {
  593. defer handleErr(&err)
  594. v := reflect.ValueOf(out)
  595. switch v.Kind() {
  596. case reflect.Ptr:
  597. v = v.Elem()
  598. fallthrough
  599. case reflect.Map:
  600. d := newDecoder(raw.Data)
  601. good := d.readElemTo(v, raw.Kind)
  602. if !good {
  603. return &TypeError{v.Type(), raw.Kind}
  604. }
  605. case reflect.Struct:
  606. return errors.New("raw Unmarshal can't deal with struct values. Use a pointer")
  607. default:
  608. return errors.New("raw Unmarshal needs a map or a valid pointer")
  609. }
  610. return nil
  611. }
  612. // TypeError store details for type error occuring
  613. // during unmarshaling
  614. type TypeError struct {
  615. Type reflect.Type
  616. Kind byte
  617. }
  618. func (e *TypeError) Error() string {
  619. return fmt.Sprintf("BSON kind 0x%02x isn't compatible with type %s", e.Kind, e.Type.String())
  620. }
  621. // --------------------------------------------------------------------------
  622. // Maintain a mapping of keys to structure field indexes
  623. type structInfo struct {
  624. FieldsMap map[string]fieldInfo
  625. FieldsList []fieldInfo
  626. InlineMap int
  627. Zero reflect.Value
  628. }
  629. type fieldInfo struct {
  630. Key string
  631. Num int
  632. OmitEmpty bool
  633. MinSize bool
  634. Inline []int
  635. }
  636. var structMap = make(map[reflect.Type]*structInfo)
  637. var structMapMutex sync.RWMutex
  638. type externalPanic string
  639. func (e externalPanic) String() string {
  640. return string(e)
  641. }
  642. func getStructInfo(st reflect.Type) (*structInfo, error) {
  643. structMapMutex.RLock()
  644. sinfo, found := structMap[st]
  645. structMapMutex.RUnlock()
  646. if found {
  647. return sinfo, nil
  648. }
  649. n := st.NumField()
  650. fieldsMap := make(map[string]fieldInfo)
  651. fieldsList := make([]fieldInfo, 0, n)
  652. inlineMap := -1
  653. for i := 0; i != n; i++ {
  654. field := st.Field(i)
  655. if field.PkgPath != "" && !field.Anonymous {
  656. continue // Private field
  657. }
  658. info := fieldInfo{Num: i}
  659. tag := field.Tag.Get("bson")
  660. // Fall-back to JSON struct tag, if feature flag is set.
  661. if tag == "" && useJSONTagFallback {
  662. tag = field.Tag.Get("json")
  663. }
  664. // If there's no bson/json tag available.
  665. if tag == "" {
  666. // If there's no tag, and also no tag: value splits (i.e. no colon)
  667. // then assume the entire tag is the value
  668. if strings.Index(string(field.Tag), ":") < 0 {
  669. tag = string(field.Tag)
  670. }
  671. }
  672. if tag == "-" {
  673. continue
  674. }
  675. inline := false
  676. fields := strings.Split(tag, ",")
  677. if len(fields) > 1 {
  678. for _, flag := range fields[1:] {
  679. switch flag {
  680. case "omitempty":
  681. info.OmitEmpty = true
  682. case "minsize":
  683. info.MinSize = true
  684. case "inline":
  685. inline = true
  686. default:
  687. msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)
  688. panic(externalPanic(msg))
  689. }
  690. }
  691. tag = fields[0]
  692. }
  693. if inline {
  694. switch field.Type.Kind() {
  695. case reflect.Map:
  696. if inlineMap >= 0 {
  697. return nil, errors.New("Multiple ,inline maps in struct " + st.String())
  698. }
  699. if field.Type.Key() != reflect.TypeOf("") {
  700. return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
  701. }
  702. inlineMap = info.Num
  703. case reflect.Ptr:
  704. // allow only pointer to struct
  705. if kind := field.Type.Elem().Kind(); kind != reflect.Struct {
  706. return nil, errors.New("Option ,inline allows a pointer only to a struct, was given pointer to " + kind.String())
  707. }
  708. field.Type = field.Type.Elem()
  709. fallthrough
  710. case reflect.Struct:
  711. sinfo, err := getStructInfo(field.Type)
  712. if err != nil {
  713. return nil, err
  714. }
  715. for _, finfo := range sinfo.FieldsList {
  716. if _, found := fieldsMap[finfo.Key]; found {
  717. msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
  718. return nil, errors.New(msg)
  719. }
  720. if finfo.Inline == nil {
  721. finfo.Inline = []int{i, finfo.Num}
  722. } else {
  723. finfo.Inline = append([]int{i}, finfo.Inline...)
  724. }
  725. fieldsMap[finfo.Key] = finfo
  726. fieldsList = append(fieldsList, finfo)
  727. }
  728. default:
  729. panic("Option ,inline needs a struct value or a pointer to a struct or map field")
  730. }
  731. continue
  732. }
  733. if tag != "" {
  734. info.Key = tag
  735. } else {
  736. info.Key = strings.ToLower(field.Name)
  737. }
  738. if _, found = fieldsMap[info.Key]; found {
  739. msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
  740. return nil, errors.New(msg)
  741. }
  742. fieldsList = append(fieldsList, info)
  743. fieldsMap[info.Key] = info
  744. }
  745. sinfo = &structInfo{
  746. fieldsMap,
  747. fieldsList,
  748. inlineMap,
  749. reflect.New(st).Elem(),
  750. }
  751. structMapMutex.Lock()
  752. structMap[st] = sinfo
  753. structMapMutex.Unlock()
  754. return sinfo, nil
  755. }