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 }