1// Copyright (C) MongoDB, Inc. 2014-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 json 8 9import ( 10 "fmt" 11 "gopkg.in/mgo.v2/bson" 12 "reflect" 13) 14 15// Represents base-64 encoded binary data 16type BinData struct { 17 Type byte 18 Base64 string 19} 20 21// Represents the number of milliseconds since the Unix epoch. 22type Date int64 23 24type ISODate string 25 26type ObjectId string 27 28// Represents a reference to another document. 29type DBRef struct { 30 Collection string 31 Id interface{} 32 Database string // optional 33} 34 35// Refers to a document in some namespace by wrapping a string containing the namespace 36// and the objectId in which the _id of the document is contained 37type DBPointer struct { 38 Namespace string 39 Id bson.ObjectId 40} 41 42// Represents the literal MinKey. 43type MinKey struct{} 44 45// Represents the literal MaxKey. 46type MaxKey struct{} 47 48// Represents a signed 32-bit integer. 49type NumberInt int32 50 51// Represents a signed 64-bit integer. 52type NumberLong int64 53 54// Represents a signed 64-bit float. 55type NumberFloat float64 56 57type Decimal128 struct { 58 bson.Decimal128 59} 60 61// Represents a regular expression. 62type RegExp struct { 63 Pattern string 64 Options string 65} 66 67// Represents a timestamp value. 68type Timestamp struct { 69 Seconds uint32 70 Increment uint32 71} 72 73type JavaScript struct { 74 Code string 75 Scope interface{} 76} 77 78type Float float64 79 80// Represents the literal undefined. 81type Undefined struct{} 82 83var ( 84 // primitive types 85 byteType = reflect.TypeOf(byte(0)) 86 stringType = reflect.TypeOf(string("")) 87 uint32Type = reflect.TypeOf(uint32(0)) 88 89 // object types 90 binDataType = reflect.TypeOf(BinData{}) 91 dateType = reflect.TypeOf(Date(0)) 92 isoDateType = reflect.TypeOf(ISODate("")) 93 dbRefType = reflect.TypeOf(DBRef{}) 94 dbPointerType = reflect.TypeOf(DBPointer{}) 95 maxKeyType = reflect.TypeOf(MaxKey{}) 96 minKeyType = reflect.TypeOf(MinKey{}) 97 numberIntType = reflect.TypeOf(NumberInt(0)) 98 numberLongType = reflect.TypeOf(NumberLong(0)) 99 numberFloatType = reflect.TypeOf(NumberFloat(0)) 100 objectIdType = reflect.TypeOf(ObjectId("")) 101 regexpType = reflect.TypeOf(RegExp{}) 102 timestampType = reflect.TypeOf(Timestamp{}) 103 undefinedType = reflect.TypeOf(Undefined{}) 104 orderedBSONType = reflect.TypeOf(bson.D{}) 105 interfaceType = reflect.TypeOf((*interface{})(nil)) 106) 107 108func (d Date) isFormatable() bool { 109 return int64(d) < int64(32535215999000) 110} 111 112func stateBeginExtendedValue(s *scanner, c int) int { 113 switch c { 114 case 'u': // beginning of undefined 115 s.step = stateU 116 case 'B': // beginning of BinData or Boolean 117 s.step = stateB 118 case 'D': // beginning of Date 119 s.step = stateD 120 case 'I': // beginning of Infinity or ISODate 121 s.step = stateI 122 case 'M': // beginning of MinKey or MaxKey 123 s.step = stateM 124 case 'N': // beginning of NaN or NumberXX 125 s.step = stateUpperN 126 case 'O': // beginning of ObjectId 127 s.step = stateO 128 case 'R': // beginning of RegExp 129 s.step = stateR 130 case 'T': // beginning of Timestamp 131 s.step = stateUpperT 132 case '/': // beginning of /foo/i 133 s.step = stateInRegexpPattern 134 default: 135 return s.error(c, "looking for beginning of value") 136 } 137 138 return scanBeginLiteral 139} 140 141// stateB is the state after reading `B`. 142func stateB(s *scanner, c int) int { 143 if c == 'i' { 144 s.step = stateBi 145 return scanContinue 146 } 147 if c == 'o' { 148 s.step = stateBo 149 return scanContinue 150 } 151 return s.error(c, "in literal BinData or Boolean (expecting 'i' or 'o')") 152} 153 154// stateUpperN is the state after reading `N`. 155func stateUpperN(s *scanner, c int) int { 156 if c == 'a' { 157 s.step = stateUpperNa 158 return scanContinue 159 } 160 if c == 'u' { 161 s.step = stateUpperNu 162 return scanContinue 163 } 164 return s.error(c, "in literal NaN or Number (expecting 'a' or 'u')") 165} 166 167// stateM is the state after reading `M`. 168func stateM(s *scanner, c int) int { 169 if c == 'a' { 170 s.step = stateUpperMa 171 return scanContinue 172 } 173 if c == 'i' { 174 s.step = stateUpperMi 175 return scanContinue 176 } 177 return s.error(c, "in literal MaxKey or MinKey (expecting 'a' or 'i')") 178} 179 180// stateD is the state after reading `D`. 181func stateD(s *scanner, c int) int { 182 switch c { 183 case 'a': 184 s.step = stateDa 185 case 'B': 186 s.step = stateDB 187 case 'b': 188 s.step = stateDb 189 default: 190 return s.error(c, "in literal Date or DBRef (expecting 'a' or 'B')") 191 } 192 return scanContinue 193} 194 195// stateDB is the state after reading `DB`. 196func stateDB(s *scanner, c int) int { 197 if c == 'R' { 198 s.step = stateDBR 199 return scanContinue 200 } 201 if c == 'P' { 202 s.step = stateDBP 203 return scanContinue 204 } 205 return s.error(c, "in state DB (expecting 'R or P')") 206} 207 208// stateI is the state after reading `I`. 209func stateI(s *scanner, c int) int { 210 switch c { 211 case 'n': 212 s.step = stateIn 213 case 'S': 214 s.step = stateIS 215 default: 216 return s.error(c, "in literal Infinity or ISO (expecting 'n' or 'S')") 217 } 218 return scanContinue 219} 220 221// Decodes a literal stored in item into v. 222func (d *decodeState) storeExtendedLiteral(item []byte, v reflect.Value, fromQuoted bool) bool { 223 switch c := item[0]; c { 224 case 'n': 225 d.storeNewLiteral(v, fromQuoted) 226 227 case 'u': // undefined 228 switch kind := v.Kind(); kind { 229 case reflect.Interface: 230 v.Set(reflect.ValueOf(Undefined{})) 231 default: 232 d.error(fmt.Errorf("cannot store %v value into %v type", undefinedType, kind)) 233 } 234 235 case 'B': // BinData or Boolean 236 switch item[1] { 237 case 'i': // BinData 238 d.storeBinData(v) 239 case 'o': // Boolean 240 d.storeBoolean(v) 241 } 242 case 'D': // Date, DBRef, DBPointer, Dbpointer,or Dbref 243 switch item[1] { 244 case 'a': // Date 245 d.storeDate(v) 246 case 'b': // Dbref 247 d.storeDBRef(v) 248 case 'B': // DBRef or DBPointer 249 switch item[2] { 250 case 'R': //DBRef 251 d.storeDBRef(v) 252 case 'P': //DBPointer 253 d.storeDBPointer(v) 254 } 255 } 256 case 'I': 257 switch item[1] { 258 case 'S': // ISODate 259 d.storeISODate(v) 260 } 261 262 case 'M': // MinKey or MaxKey 263 switch item[1] { 264 case 'i': // MinKey 265 switch kind := v.Kind(); kind { 266 case reflect.Interface: 267 v.Set(reflect.ValueOf(MinKey{})) 268 default: 269 d.error(fmt.Errorf("cannot store %v value into %v type", minKeyType, kind)) 270 } 271 case 'a': // MaxKey 272 switch kind := v.Kind(); kind { 273 case reflect.Interface: 274 v.Set(reflect.ValueOf(MaxKey{})) 275 default: 276 d.error(fmt.Errorf("cannot store %v value into %v type", maxKeyType, kind)) 277 } 278 } 279 280 case 'O': // ObjectId 281 d.storeObjectId(v) 282 283 case 'N': // NumberInt or NumberLong 284 switch item[6] { 285 case 'I': // NumberInt 286 d.storeNumberInt(v) 287 case 'L': // NumberLong 288 d.storeNumberLong(v) 289 } 290 291 case 'R': // RegExp constructor 292 d.storeRegexp(v) 293 294 case 'T': // Timestamp 295 d.storeTimestamp(v) 296 297 case '/': // regular expression literal 298 op := d.scanWhile(scanSkipSpace) 299 if op != scanRegexpPattern { 300 d.error(fmt.Errorf("expected beginning of regular expression pattern")) 301 } 302 303 pattern, options, err := d.regexp() 304 if err != nil { 305 d.error(err) 306 } 307 switch kind := v.Kind(); kind { 308 case reflect.Interface: 309 v.Set(reflect.ValueOf(RegExp{pattern, options})) 310 default: 311 d.error(fmt.Errorf("cannot store %v value into %v type", regexpType, kind)) 312 } 313 314 default: 315 return false 316 } 317 318 return true 319} 320 321// Returns a literal from the underlying byte data. 322func (d *decodeState) getExtendedLiteral(item []byte) (interface{}, bool) { 323 switch c := item[0]; c { 324 case 'n': 325 return d.getNewLiteral(), true 326 327 case 'u': // undefined 328 return Undefined{}, true 329 330 case 'B': // BinData or Boolean 331 switch item[1] { 332 case 'i': // BinData 333 return d.getBinData(), true 334 case 'o': // Boolean 335 return d.getBoolean(), true 336 } 337 338 case 'D': // Date, DBRef, or Dbref 339 switch item[1] { 340 case 'a': // Date 341 return d.getDate(), true 342 case 'b': // Dbref 343 return d.getDBRef(), true 344 case 'B': // DBRef or DBPointer 345 switch item[2] { 346 case 'R': // DBRef 347 return d.getDBRef(), true 348 case 'P': // DBPointer 349 return d.getDBPointer(), true 350 } 351 } 352 353 case 'M': // MinKey or MaxKey 354 switch item[1] { 355 case 'i': // MinKey 356 return MinKey{}, true 357 case 'a': // MaxKey 358 return MaxKey{}, true 359 } 360 361 case 'O': // ObjectId 362 return d.getObjectId(), true 363 364 case 'N': // NumberInt or NumberLong 365 switch item[6] { 366 case 'I': // NumberInt 367 return d.getNumberInt(), true 368 case 'L': // NumberLong 369 return d.getNumberLong(), true 370 } 371 372 case 'R': // RegExp constructor 373 return d.getRegexp(), true 374 375 case 'T': // Timestamp 376 return d.getTimestamp(), true 377 378 case 'I': // ISO Date 379 switch item[1] { 380 case 'S': // ISODate 381 return d.getDate(), true 382 } 383 384 case '/': // regular expression literal 385 op := d.scanWhile(scanSkipSpace) 386 if op != scanRegexpPattern { 387 d.error(fmt.Errorf("expected beginning of regular expression pattern")) 388 } 389 390 pattern, options, err := d.regexp() 391 if err != nil { 392 d.error(err) 393 } 394 return RegExp{pattern, options}, true 395 } 396 397 return nil, false 398} 399