1// Copyright (C) MongoDB, Inc. 2017-present. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7package bson 8 9import ( 10 "bytes" 11 12 "go.mongodb.org/mongo-driver/bson/bsoncodec" 13 "go.mongodb.org/mongo-driver/bson/bsonrw" 14 "go.mongodb.org/mongo-driver/bson/bsontype" 15) 16 17// Unmarshaler is an interface implemented by types that can unmarshal a BSON 18// document representation of themselves. The BSON bytes can be assumed to be 19// valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data 20// after returning. 21type Unmarshaler interface { 22 UnmarshalBSON([]byte) error 23} 24 25// ValueUnmarshaler is an interface implemented by types that can unmarshal a 26// BSON value representaiton of themselves. The BSON bytes and type can be 27// assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it 28// wishes to retain the data after returning. 29type ValueUnmarshaler interface { 30 UnmarshalBSONValue(bsontype.Type, []byte) error 31} 32 33// Unmarshal parses the BSON-encoded data and stores the result in the value 34// pointed to by val. If val is nil or not a pointer, Unmarshal returns 35// InvalidUnmarshalError. 36func Unmarshal(data []byte, val interface{}) error { 37 return UnmarshalWithRegistry(DefaultRegistry, data, val) 38} 39 40// UnmarshalWithRegistry parses the BSON-encoded data using Registry r and 41// stores the result in the value pointed to by val. If val is nil or not 42// a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError. 43func UnmarshalWithRegistry(r *bsoncodec.Registry, data []byte, val interface{}) error { 44 vr := bsonrw.NewBSONDocumentReader(data) 45 return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, vr, val) 46} 47 48// UnmarshalWithContext parses the BSON-encoded data using DecodeContext dc and 49// stores the result in the value pointed to by val. If val is nil or not 50// a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError. 51func UnmarshalWithContext(dc bsoncodec.DecodeContext, data []byte, val interface{}) error { 52 vr := bsonrw.NewBSONDocumentReader(data) 53 return unmarshalFromReader(dc, vr, val) 54} 55 56// UnmarshalExtJSON parses the extended JSON-encoded data and stores the result 57// in the value pointed to by val. If val is nil or not a pointer, Unmarshal 58// returns InvalidUnmarshalError. 59func UnmarshalExtJSON(data []byte, canonical bool, val interface{}) error { 60 return UnmarshalExtJSONWithRegistry(DefaultRegistry, data, canonical, val) 61} 62 63// UnmarshalExtJSONWithRegistry parses the extended JSON-encoded data using 64// Registry r and stores the result in the value pointed to by val. If val is 65// nil or not a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError. 66func UnmarshalExtJSONWithRegistry(r *bsoncodec.Registry, data []byte, canonical bool, val interface{}) error { 67 ejvr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), canonical) 68 if err != nil { 69 return err 70 } 71 72 return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, ejvr, val) 73} 74 75// UnmarshalExtJSONWithContext parses the extended JSON-encoded data using 76// DecodeContext dc and stores the result in the value pointed to by val. If val is 77// nil or not a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError. 78func UnmarshalExtJSONWithContext(dc bsoncodec.DecodeContext, data []byte, canonical bool, val interface{}) error { 79 ejvr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), canonical) 80 if err != nil { 81 return err 82 } 83 84 return unmarshalFromReader(dc, ejvr, val) 85} 86 87func unmarshalFromReader(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val interface{}) error { 88 dec := decPool.Get().(*Decoder) 89 defer decPool.Put(dec) 90 91 err := dec.Reset(vr) 92 if err != nil { 93 return err 94 } 95 err = dec.SetContext(dc) 96 if err != nil { 97 return err 98 } 99 100 return dec.Decode(val) 101} 102