github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/gopkg.in/mgo.v2/bson/json.go (about)

     1  package bson
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"fmt"
     7  	"gopkg.in/mgo.v2/internal/json"
     8  	"strconv"
     9  	"time"
    10  )
    11  
    12  // UnmarshalJSON unmarshals a JSON value that may hold non-standard
    13  // syntax as defined in BSON's extended JSON specification.
    14  func UnmarshalJSON(data []byte, value interface{}) error {
    15  	d := json.NewDecoder(bytes.NewBuffer(data))
    16  	d.Extend(&jsonExt)
    17  	return d.Decode(value)
    18  }
    19  
    20  // MarshalJSON marshals a JSON value that may hold non-standard
    21  // syntax as defined in BSON's extended JSON specification.
    22  func MarshalJSON(value interface{}) ([]byte, error) {
    23  	var buf bytes.Buffer
    24  	e := json.NewEncoder(&buf)
    25  	e.Extend(&jsonExt)
    26  	err := e.Encode(value)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	return buf.Bytes(), nil
    31  }
    32  
    33  // jdec is used internally by the JSON decoding functions
    34  // so they may unmarshal functions without getting into endless
    35  // recursion due to keyed objects.
    36  func jdec(data []byte, value interface{}) error {
    37  	d := json.NewDecoder(bytes.NewBuffer(data))
    38  	d.Extend(&funcExt)
    39  	return d.Decode(value)
    40  }
    41  
    42  var jsonExt json.Extension
    43  var funcExt json.Extension
    44  
    45  // TODO
    46  // - Shell regular expressions ("/regexp/opts")
    47  
    48  func init() {
    49  	jsonExt.DecodeUnquotedKeys(true)
    50  	jsonExt.DecodeTrailingCommas(true)
    51  
    52  	funcExt.DecodeFunc("BinData", "$binaryFunc", "$type", "$binary")
    53  	jsonExt.DecodeKeyed("$binary", jdecBinary)
    54  	jsonExt.DecodeKeyed("$binaryFunc", jdecBinary)
    55  	jsonExt.EncodeType([]byte(nil), jencBinarySlice)
    56  	jsonExt.EncodeType(Binary{}, jencBinaryType)
    57  
    58  	funcExt.DecodeFunc("ISODate", "$dateFunc", "S")
    59  	funcExt.DecodeFunc("new Date", "$dateFunc", "S")
    60  	jsonExt.DecodeKeyed("$date", jdecDate)
    61  	jsonExt.DecodeKeyed("$dateFunc", jdecDate)
    62  	jsonExt.EncodeType(time.Time{}, jencDate)
    63  
    64  	funcExt.DecodeFunc("Timestamp", "$timestamp", "t", "i")
    65  	jsonExt.DecodeKeyed("$timestamp", jdecTimestamp)
    66  	jsonExt.EncodeType(MongoTimestamp(0), jencTimestamp)
    67  
    68  	funcExt.DecodeConst("undefined", Undefined)
    69  
    70  	jsonExt.DecodeKeyed("$regex", jdecRegEx)
    71  	jsonExt.EncodeType(RegEx{}, jencRegEx)
    72  
    73  	funcExt.DecodeFunc("ObjectId", "$oidFunc", "Id")
    74  	jsonExt.DecodeKeyed("$oid", jdecObjectId)
    75  	jsonExt.DecodeKeyed("$oidFunc", jdecObjectId)
    76  	jsonExt.EncodeType(ObjectId(""), jencObjectId)
    77  
    78  	funcExt.DecodeFunc("DBRef", "$dbrefFunc", "$ref", "$id")
    79  	jsonExt.DecodeKeyed("$dbrefFunc", jdecDBRef)
    80  
    81  	funcExt.DecodeFunc("NumberLong", "$numberLongFunc", "N")
    82  	jsonExt.DecodeKeyed("$numberLong", jdecNumberLong)
    83  	jsonExt.DecodeKeyed("$numberLongFunc", jdecNumberLong)
    84  	jsonExt.EncodeType(int64(0), jencNumberLong)
    85  	jsonExt.EncodeType(int(0), jencInt)
    86  
    87  	funcExt.DecodeConst("MinKey", MinKey)
    88  	funcExt.DecodeConst("MaxKey", MaxKey)
    89  	jsonExt.DecodeKeyed("$minKey", jdecMinKey)
    90  	jsonExt.DecodeKeyed("$maxKey", jdecMaxKey)
    91  	jsonExt.EncodeType(orderKey(0), jencMinMaxKey)
    92  
    93  	jsonExt.DecodeKeyed("$undefined", jdecUndefined)
    94  	jsonExt.EncodeType(Undefined, jencUndefined)
    95  
    96  	jsonExt.Extend(&funcExt)
    97  }
    98  
    99  func fbytes(format string, args ...interface{}) []byte {
   100  	var buf bytes.Buffer
   101  	fmt.Fprintf(&buf, format, args...)
   102  	return buf.Bytes()
   103  }
   104  
   105  func jdecBinary(data []byte) (interface{}, error) {
   106  	var v struct {
   107  		Binary []byte `json:"$binary"`
   108  		Type   string `json:"$type"`
   109  		Func   struct {
   110  			Binary []byte `json:"$binary"`
   111  			Type   int64  `json:"$type"`
   112  		} `json:"$binaryFunc"`
   113  	}
   114  	err := jdec(data, &v)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  
   119  	var binData []byte
   120  	var binKind int64
   121  	if v.Type == "" && v.Binary == nil {
   122  		binData = v.Func.Binary
   123  		binKind = v.Func.Type
   124  	} else if v.Type == "" {
   125  		return v.Binary, nil
   126  	} else {
   127  		binData = v.Binary
   128  		binKind, err = strconv.ParseInt(v.Type, 0, 64)
   129  		if err != nil {
   130  			binKind = -1
   131  		}
   132  	}
   133  
   134  	if binKind == 0 {
   135  		return binData, nil
   136  	}
   137  	if binKind < 0 || binKind > 255 {
   138  		return nil, fmt.Errorf("invalid type in binary object: %s", data)
   139  	}
   140  
   141  	return Binary{Kind: byte(binKind), Data: binData}, nil
   142  }
   143  
   144  func jencBinarySlice(v interface{}) ([]byte, error) {
   145  	in := v.([]byte)
   146  	out := make([]byte, base64.StdEncoding.EncodedLen(len(in)))
   147  	base64.StdEncoding.Encode(out, in)
   148  	return fbytes(`{"$binary":"%s","$type":"0x0"}`, out), nil
   149  }
   150  
   151  func jencBinaryType(v interface{}) ([]byte, error) {
   152  	in := v.(Binary)
   153  	out := make([]byte, base64.StdEncoding.EncodedLen(len(in.Data)))
   154  	base64.StdEncoding.Encode(out, in.Data)
   155  	return fbytes(`{"$binary":"%s","$type":"0x%x"}`, out, in.Kind), nil
   156  }
   157  
   158  const jdateFormat = "2006-01-02T15:04:05.999Z"
   159  
   160  func jdecDate(data []byte) (interface{}, error) {
   161  	var v struct {
   162  		S    string `json:"$date"`
   163  		Func struct {
   164  			S string
   165  		} `json:"$dateFunc"`
   166  	}
   167  	_ = jdec(data, &v)
   168  	if v.S == "" {
   169  		v.S = v.Func.S
   170  	}
   171  	if v.S != "" {
   172  		for _, format := range []string{jdateFormat, "2006-01-02"} {
   173  			t, err := time.Parse(format, v.S)
   174  			if err == nil {
   175  				return t, nil
   176  			}
   177  		}
   178  		return nil, fmt.Errorf("cannot parse date: %q", v.S)
   179  	}
   180  
   181  	var vn struct {
   182  		Date struct {
   183  			N int64 `json:"$numberLong,string"`
   184  		} `json:"$date"`
   185  		Func struct {
   186  			S int64
   187  		} `json:"$dateFunc"`
   188  	}
   189  	err := jdec(data, &vn)
   190  	if err != nil {
   191  		return nil, fmt.Errorf("cannot parse date: %q", data)
   192  	}
   193  	n := vn.Date.N
   194  	if n == 0 {
   195  		n = vn.Func.S
   196  	}
   197  	return time.Unix(n/1000, n%1000*1e6).UTC(), nil
   198  }
   199  
   200  func jencDate(v interface{}) ([]byte, error) {
   201  	t := v.(time.Time)
   202  	return fbytes(`{"$date":%q}`, t.Format(jdateFormat)), nil
   203  }
   204  
   205  func jdecTimestamp(data []byte) (interface{}, error) {
   206  	var v struct {
   207  		Func struct {
   208  			T int32 `json:"t"`
   209  			I int32 `json:"i"`
   210  		} `json:"$timestamp"`
   211  	}
   212  	err := jdec(data, &v)
   213  	if err != nil {
   214  		return nil, err
   215  	}
   216  	return MongoTimestamp(uint64(v.Func.T)<<32 | uint64(uint32(v.Func.I))), nil
   217  }
   218  
   219  func jencTimestamp(v interface{}) ([]byte, error) {
   220  	ts := uint64(v.(MongoTimestamp))
   221  	return fbytes(`{"$timestamp":{"t":%d,"i":%d}}`, ts>>32, uint32(ts)), nil
   222  }
   223  
   224  func jdecRegEx(data []byte) (interface{}, error) {
   225  	var v struct {
   226  		Regex   string `json:"$regex"`
   227  		Options string `json:"$options"`
   228  	}
   229  	err := jdec(data, &v)
   230  	if err != nil {
   231  		return nil, err
   232  	}
   233  	return RegEx{v.Regex, v.Options}, nil
   234  }
   235  
   236  func jencRegEx(v interface{}) ([]byte, error) {
   237  	re := v.(RegEx)
   238  	type regex struct {
   239  		Regex   string `json:"$regex"`
   240  		Options string `json:"$options"`
   241  	}
   242  	return json.Marshal(regex{re.Pattern, re.Options})
   243  }
   244  
   245  func jdecObjectId(data []byte) (interface{}, error) {
   246  	var v struct {
   247  		Id   string `json:"$oid"`
   248  		Func struct {
   249  			Id string
   250  		} `json:"$oidFunc"`
   251  	}
   252  	err := jdec(data, &v)
   253  	if err != nil {
   254  		return nil, err
   255  	}
   256  	if v.Id == "" {
   257  		v.Id = v.Func.Id
   258  	}
   259  	return ObjectIdHex(v.Id), nil
   260  }
   261  
   262  func jencObjectId(v interface{}) ([]byte, error) {
   263  	return fbytes(`{"$oid":"%s"}`, v.(ObjectId).Hex()), nil
   264  }
   265  
   266  func jdecDBRef(data []byte) (interface{}, error) {
   267  	// TODO Support unmarshaling $ref and $id into the input value.
   268  	var v struct {
   269  		Obj map[string]interface{} `json:"$dbrefFunc"`
   270  	}
   271  	// TODO Fix this. Must not be required.
   272  	v.Obj = make(map[string]interface{})
   273  	err := jdec(data, &v)
   274  	if err != nil {
   275  		return nil, err
   276  	}
   277  	return v.Obj, nil
   278  }
   279  
   280  func jdecNumberLong(data []byte) (interface{}, error) {
   281  	var v struct {
   282  		N    int64 `json:"$numberLong,string"`
   283  		Func struct {
   284  			N int64 `json:",string"`
   285  		} `json:"$numberLongFunc"`
   286  	}
   287  	var vn struct {
   288  		N    int64 `json:"$numberLong"`
   289  		Func struct {
   290  			N int64
   291  		} `json:"$numberLongFunc"`
   292  	}
   293  	err := jdec(data, &v)
   294  	if err != nil {
   295  		err = jdec(data, &vn)
   296  		v.N = vn.N
   297  		v.Func.N = vn.Func.N
   298  	}
   299  	if err != nil {
   300  		return nil, err
   301  	}
   302  	if v.N != 0 {
   303  		return v.N, nil
   304  	}
   305  	return v.Func.N, nil
   306  }
   307  
   308  func jencNumberLong(v interface{}) ([]byte, error) {
   309  	n := v.(int64)
   310  	f := `{"$numberLong":"%d"}`
   311  	if n <= 1<<53 {
   312  		f = `{"$numberLong":%d}`
   313  	}
   314  	return fbytes(f, n), nil
   315  }
   316  
   317  func jencInt(v interface{}) ([]byte, error) {
   318  	n := v.(int)
   319  	f := `{"$numberLong":"%d"}`
   320  	if int64(n) <= 1<<53 {
   321  		f = `%d`
   322  	}
   323  	return fbytes(f, n), nil
   324  }
   325  
   326  func jdecMinKey(data []byte) (interface{}, error) {
   327  	var v struct {
   328  		N int64 `json:"$minKey"`
   329  	}
   330  	err := jdec(data, &v)
   331  	if err != nil {
   332  		return nil, err
   333  	}
   334  	if v.N != 1 {
   335  		return nil, fmt.Errorf("invalid $minKey object: %s", data)
   336  	}
   337  	return MinKey, nil
   338  }
   339  
   340  func jdecMaxKey(data []byte) (interface{}, error) {
   341  	var v struct {
   342  		N int64 `json:"$maxKey"`
   343  	}
   344  	err := jdec(data, &v)
   345  	if err != nil {
   346  		return nil, err
   347  	}
   348  	if v.N != 1 {
   349  		return nil, fmt.Errorf("invalid $maxKey object: %s", data)
   350  	}
   351  	return MaxKey, nil
   352  }
   353  
   354  func jencMinMaxKey(v interface{}) ([]byte, error) {
   355  	switch v.(orderKey) {
   356  	case MinKey:
   357  		return []byte(`{"$minKey":1}`), nil
   358  	case MaxKey:
   359  		return []byte(`{"$maxKey":1}`), nil
   360  	}
   361  	panic(fmt.Sprintf("invalid $minKey/$maxKey value: %d", v))
   362  }
   363  
   364  func jdecUndefined(data []byte) (interface{}, error) {
   365  	var v struct {
   366  		B bool `json:"$undefined"`
   367  	}
   368  	err := jdec(data, &v)
   369  	if err != nil {
   370  		return nil, err
   371  	}
   372  	if !v.B {
   373  		return nil, fmt.Errorf("invalid $undefined object: %s", data)
   374  	}
   375  	return Undefined, nil
   376  }
   377  
   378  func jencUndefined(v interface{}) ([]byte, error) {
   379  	return []byte(`{"$undefined":true}`), nil
   380  }