github.com/vmware/govmomi@v0.37.1/vim25/json/stream.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package json 6 7 import ( 8 "bytes" 9 "errors" 10 "io" 11 ) 12 13 // A Decoder reads and decodes JSON values from an input stream. 14 type Decoder struct { 15 r io.Reader 16 buf []byte 17 d decodeState 18 scanp int // start of unread data in buf 19 scanned int64 // amount of data already scanned 20 scan scanner 21 err error 22 23 tokenState int 24 tokenStack []int 25 } 26 27 // NewDecoder returns a new decoder that reads from r. 28 // 29 // The decoder introduces its own buffering and may 30 // read data from r beyond the JSON values requested. 31 func NewDecoder(r io.Reader) *Decoder { 32 return &Decoder{r: r} 33 } 34 35 // UseNumber causes the Decoder to unmarshal a number into an interface{} as a 36 // Number instead of as a float64. 37 func (dec *Decoder) UseNumber() { dec.d.useNumber = true } 38 39 // DisallowUnknownFields causes the Decoder to return an error when the destination 40 // is a struct and the input contains object keys which do not match any 41 // non-ignored, exported fields in the destination. 42 func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true } 43 44 // SetDiscriminator tells the decoder to check if JSON objects include a 45 // discriminator that specifies the Go type into which the object should be 46 // decoded. 47 // Map and struct values are encoded as JSON objects as normal, but with an 48 // additional field (typeFieldName) that specifies the object's Go type. 49 // All other values are encoded inside an outer JSON object with a field 50 // (typeFieldName) that specifies the value's Go type and a field 51 // (valueFieldName) that specifies the actual value. 52 // An optional typeFn may be provided to enable looking up custom types based 53 // on type name strings. Built-in types are handled automatically and will be 54 // ignored if they are returned by the typeFn. 55 // Calling SetDiscriminator("", "", nil) disables the discriminator. 56 func (dec *Decoder) SetDiscriminator(typeFieldName, valueFieldName string, typeFn DiscriminatorToTypeFunc) { 57 dec.d.discriminatorTypeFieldName = typeFieldName 58 dec.d.discriminatorValueFieldName = valueFieldName 59 dec.d.discriminatorToTypeFn = typeFn 60 } 61 62 // Decode reads the next JSON-encoded value from its 63 // input and stores it in the value pointed to by v. 64 // 65 // See the documentation for Unmarshal for details about 66 // the conversion of JSON into a Go value. 67 func (dec *Decoder) Decode(v interface{}) error { 68 if dec.err != nil { 69 return dec.err 70 } 71 72 if err := dec.tokenPrepareForDecode(); err != nil { 73 return err 74 } 75 76 if !dec.tokenValueAllowed() { 77 return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()} 78 } 79 80 // Read whole value into buffer. 81 n, err := dec.readValue() 82 if err != nil { 83 return err 84 } 85 dec.d.init(dec.buf[dec.scanp : dec.scanp+n]) 86 dec.scanp += n 87 88 // Don't save err from unmarshal into dec.err: 89 // the connection is still usable since we read a complete JSON 90 // object from it before the error happened. 91 err = dec.d.unmarshal(v) 92 93 // fixup token streaming state 94 dec.tokenValueEnd() 95 96 return err 97 } 98 99 // Buffered returns a reader of the data remaining in the Decoder's 100 // buffer. The reader is valid until the next call to Decode. 101 func (dec *Decoder) Buffered() io.Reader { 102 return bytes.NewReader(dec.buf[dec.scanp:]) 103 } 104 105 // readValue reads a JSON value into dec.buf. 106 // It returns the length of the encoding. 107 func (dec *Decoder) readValue() (int, error) { 108 dec.scan.reset() 109 110 scanp := dec.scanp 111 var err error 112 Input: 113 // help the compiler see that scanp is never negative, so it can remove 114 // some bounds checks below. 115 for scanp >= 0 { 116 117 // Look in the buffer for a new value. 118 for ; scanp < len(dec.buf); scanp++ { 119 c := dec.buf[scanp] 120 dec.scan.bytes++ 121 switch dec.scan.step(&dec.scan, c) { 122 case scanEnd: 123 // scanEnd is delayed one byte so we decrement 124 // the scanner bytes count by 1 to ensure that 125 // this value is correct in the next call of Decode. 126 dec.scan.bytes-- 127 break Input 128 case scanEndObject, scanEndArray: 129 // scanEnd is delayed one byte. 130 // We might block trying to get that byte from src, 131 // so instead invent a space byte. 132 if stateEndValue(&dec.scan, ' ') == scanEnd { 133 scanp++ 134 break Input 135 } 136 case scanError: 137 dec.err = dec.scan.err 138 return 0, dec.scan.err 139 } 140 } 141 142 // Did the last read have an error? 143 // Delayed until now to allow buffer scan. 144 if err != nil { 145 if err == io.EOF { 146 if dec.scan.step(&dec.scan, ' ') == scanEnd { 147 break Input 148 } 149 if nonSpace(dec.buf) { 150 err = io.ErrUnexpectedEOF 151 } 152 } 153 dec.err = err 154 return 0, err 155 } 156 157 n := scanp - dec.scanp 158 err = dec.refill() 159 scanp = dec.scanp + n 160 } 161 return scanp - dec.scanp, nil 162 } 163 164 func (dec *Decoder) refill() error { 165 // Make room to read more into the buffer. 166 // First slide down data already consumed. 167 if dec.scanp > 0 { 168 dec.scanned += int64(dec.scanp) 169 n := copy(dec.buf, dec.buf[dec.scanp:]) 170 dec.buf = dec.buf[:n] 171 dec.scanp = 0 172 } 173 174 // Grow buffer if not large enough. 175 const minRead = 512 176 if cap(dec.buf)-len(dec.buf) < minRead { 177 newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead) 178 copy(newBuf, dec.buf) 179 dec.buf = newBuf 180 } 181 182 // Read. Delay error for next iteration (after scan). 183 n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)]) 184 dec.buf = dec.buf[0 : len(dec.buf)+n] 185 186 return err 187 } 188 189 func nonSpace(b []byte) bool { 190 for _, c := range b { 191 if !isSpace(c) { 192 return true 193 } 194 } 195 return false 196 } 197 198 // An Encoder writes JSON values to an output stream. 199 type Encoder struct { 200 w io.Writer 201 err error 202 escapeHTML bool 203 204 indentBuf *bytes.Buffer 205 indentPrefix string 206 indentValue string 207 208 discriminatorTypeFieldName string 209 discriminatorValueFieldName string 210 discriminatorEncodeMode DiscriminatorEncodeMode 211 typeToDiscriminatorFn TypeToDiscriminatorFunc 212 } 213 214 // NewEncoder returns a new encoder that writes to w. 215 func NewEncoder(w io.Writer) *Encoder { 216 return &Encoder{w: w, escapeHTML: true} 217 } 218 219 // Encode writes the JSON encoding of v to the stream, 220 // followed by a newline character. 221 // 222 // See the documentation for Marshal for details about the 223 // conversion of Go values to JSON. 224 func (enc *Encoder) Encode(v interface{}) error { 225 if enc.err != nil { 226 return enc.err 227 } 228 e := newEncodeState() 229 err := e.marshal(v, encOpts{ 230 escapeHTML: enc.escapeHTML, 231 discriminatorTypeFieldName: enc.discriminatorTypeFieldName, 232 discriminatorValueFieldName: enc.discriminatorValueFieldName, 233 discriminatorEncodeMode: enc.discriminatorEncodeMode, 234 discriminatorValueFn: enc.typeToDiscriminatorFn, 235 }) 236 if err != nil { 237 return err 238 } 239 240 // Terminate each value with a newline. 241 // This makes the output look a little nicer 242 // when debugging, and some kind of space 243 // is required if the encoded value was a number, 244 // so that the reader knows there aren't more 245 // digits coming. 246 e.WriteByte('\n') 247 248 b := e.Bytes() 249 if enc.indentPrefix != "" || enc.indentValue != "" { 250 if enc.indentBuf == nil { 251 enc.indentBuf = new(bytes.Buffer) 252 } 253 enc.indentBuf.Reset() 254 err = Indent(enc.indentBuf, b, enc.indentPrefix, enc.indentValue) 255 if err != nil { 256 return err 257 } 258 b = enc.indentBuf.Bytes() 259 } 260 if _, err = enc.w.Write(b); err != nil { 261 enc.err = err 262 } 263 encodeStatePool.Put(e) 264 return err 265 } 266 267 // SetIndent instructs the encoder to format each subsequent encoded 268 // value as if indented by the package-level function Indent(dst, src, prefix, indent). 269 // Calling SetIndent("", "") disables indentation. 270 func (enc *Encoder) SetIndent(prefix, indent string) { 271 enc.indentPrefix = prefix 272 enc.indentValue = indent 273 } 274 275 // SetEscapeHTML specifies whether problematic HTML characters 276 // should be escaped inside JSON quoted strings. 277 // The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e 278 // to avoid certain safety problems that can arise when embedding JSON in HTML. 279 // 280 // In non-HTML settings where the escaping interferes with the readability 281 // of the output, SetEscapeHTML(false) disables this behavior. 282 func (enc *Encoder) SetEscapeHTML(on bool) { 283 enc.escapeHTML = on 284 } 285 286 // SetDiscriminator specifies that a value stored in an interface should be 287 // encoded with information about the value's Go type. 288 // Map and struct values are encoded as JSON objects as normal, but with an 289 // additional field (typeFieldName) that specifies the object's Go type. 290 // All other values are encoded inside an outer JSON object with a field 291 // (typeFieldName) that specifies the value's Go type and a field 292 // (valueFieldName) that specifies the actual value. 293 // A mask (mode) is available to control the encoder's behavior. 294 // Calling SetDiscriminator("", "", 0) disables the discriminator. 295 func (enc *Encoder) SetDiscriminator(typeFieldName, valueFieldName string, mode DiscriminatorEncodeMode) { 296 enc.discriminatorTypeFieldName = typeFieldName 297 enc.discriminatorValueFieldName = valueFieldName 298 enc.discriminatorEncodeMode = mode 299 enc.typeToDiscriminatorFn = DefaultDiscriminatorFunc 300 } 301 302 // SetTypeToDiscriminatorFunc allows for customizing the discriminator value for 303 // different types. This may be useful if the golang struct names do not match 304 // the desired values. One example would be if discriminator values in a 305 // protocol require special characters or start with lowercase letter. The 306 // TypeToDiscriminatorFunc implementation may return empty string to suppress 307 // the rendering of discriminator for specific type(s). 308 func (enc *Encoder) SetTypeToDiscriminatorFunc(f TypeToDiscriminatorFunc) { 309 if f == nil { 310 enc.typeToDiscriminatorFn = DefaultDiscriminatorFunc 311 return 312 } 313 enc.typeToDiscriminatorFn = f 314 } 315 316 // RawMessage is a raw encoded JSON value. 317 // It implements Marshaler and Unmarshaler and can 318 // be used to delay JSON decoding or precompute a JSON encoding. 319 type RawMessage []byte 320 321 // MarshalJSON returns m as the JSON encoding of m. 322 func (m RawMessage) MarshalJSON() ([]byte, error) { 323 if m == nil { 324 return []byte("null"), nil 325 } 326 return m, nil 327 } 328 329 // UnmarshalJSON sets *m to a copy of data. 330 func (m *RawMessage) UnmarshalJSON(data []byte) error { 331 if m == nil { 332 return errors.New("json.RawMessage: UnmarshalJSON on nil pointer") 333 } 334 *m = append((*m)[0:0], data...) 335 return nil 336 } 337 338 var _ Marshaler = (*RawMessage)(nil) 339 var _ Unmarshaler = (*RawMessage)(nil) 340 341 // A Token holds a value of one of these types: 342 // 343 // Delim, for the four JSON delimiters [ ] { } 344 // bool, for JSON booleans 345 // float64, for JSON numbers 346 // Number, for JSON numbers 347 // string, for JSON string literals 348 // nil, for JSON null 349 type Token interface{} 350 351 const ( 352 tokenTopValue = iota 353 tokenArrayStart 354 tokenArrayValue 355 tokenArrayComma 356 tokenObjectStart 357 tokenObjectKey 358 tokenObjectColon 359 tokenObjectValue 360 tokenObjectComma 361 ) 362 363 // advance tokenstate from a separator state to a value state 364 func (dec *Decoder) tokenPrepareForDecode() error { 365 // Note: Not calling peek before switch, to avoid 366 // putting peek into the standard Decode path. 367 // peek is only called when using the Token API. 368 switch dec.tokenState { 369 case tokenArrayComma: 370 c, err := dec.peek() 371 if err != nil { 372 return err 373 } 374 if c != ',' { 375 return &SyntaxError{"expected comma after array element", dec.InputOffset()} 376 } 377 dec.scanp++ 378 dec.tokenState = tokenArrayValue 379 case tokenObjectColon: 380 c, err := dec.peek() 381 if err != nil { 382 return err 383 } 384 if c != ':' { 385 return &SyntaxError{"expected colon after object key", dec.InputOffset()} 386 } 387 dec.scanp++ 388 dec.tokenState = tokenObjectValue 389 } 390 return nil 391 } 392 393 func (dec *Decoder) tokenValueAllowed() bool { 394 switch dec.tokenState { 395 case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue: 396 return true 397 } 398 return false 399 } 400 401 func (dec *Decoder) tokenValueEnd() { 402 switch dec.tokenState { 403 case tokenArrayStart, tokenArrayValue: 404 dec.tokenState = tokenArrayComma 405 case tokenObjectValue: 406 dec.tokenState = tokenObjectComma 407 } 408 } 409 410 // A Delim is a JSON array or object delimiter, one of [ ] { or }. 411 type Delim rune 412 413 func (d Delim) String() string { 414 return string(d) 415 } 416 417 // Token returns the next JSON token in the input stream. 418 // At the end of the input stream, Token returns nil, io.EOF. 419 // 420 // Token guarantees that the delimiters [ ] { } it returns are 421 // properly nested and matched: if Token encounters an unexpected 422 // delimiter in the input, it will return an error. 423 // 424 // The input stream consists of basic JSON values—bool, string, 425 // number, and null—along with delimiters [ ] { } of type Delim 426 // to mark the start and end of arrays and objects. 427 // Commas and colons are elided. 428 func (dec *Decoder) Token() (Token, error) { 429 for { 430 c, err := dec.peek() 431 if err != nil { 432 return nil, err 433 } 434 switch c { 435 case '[': 436 if !dec.tokenValueAllowed() { 437 return dec.tokenError(c) 438 } 439 dec.scanp++ 440 dec.tokenStack = append(dec.tokenStack, dec.tokenState) 441 dec.tokenState = tokenArrayStart 442 return Delim('['), nil 443 444 case ']': 445 if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma { 446 return dec.tokenError(c) 447 } 448 dec.scanp++ 449 dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1] 450 dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1] 451 dec.tokenValueEnd() 452 return Delim(']'), nil 453 454 case '{': 455 if !dec.tokenValueAllowed() { 456 return dec.tokenError(c) 457 } 458 dec.scanp++ 459 dec.tokenStack = append(dec.tokenStack, dec.tokenState) 460 dec.tokenState = tokenObjectStart 461 return Delim('{'), nil 462 463 case '}': 464 if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma { 465 return dec.tokenError(c) 466 } 467 dec.scanp++ 468 dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1] 469 dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1] 470 dec.tokenValueEnd() 471 return Delim('}'), nil 472 473 case ':': 474 if dec.tokenState != tokenObjectColon { 475 return dec.tokenError(c) 476 } 477 dec.scanp++ 478 dec.tokenState = tokenObjectValue 479 continue 480 481 case ',': 482 if dec.tokenState == tokenArrayComma { 483 dec.scanp++ 484 dec.tokenState = tokenArrayValue 485 continue 486 } 487 if dec.tokenState == tokenObjectComma { 488 dec.scanp++ 489 dec.tokenState = tokenObjectKey 490 continue 491 } 492 return dec.tokenError(c) 493 494 case '"': 495 if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey { 496 var x string 497 old := dec.tokenState 498 dec.tokenState = tokenTopValue 499 err := dec.Decode(&x) 500 dec.tokenState = old 501 if err != nil { 502 return nil, err 503 } 504 dec.tokenState = tokenObjectColon 505 return x, nil 506 } 507 fallthrough 508 509 default: 510 if !dec.tokenValueAllowed() { 511 return dec.tokenError(c) 512 } 513 var x interface{} 514 if err := dec.Decode(&x); err != nil { 515 return nil, err 516 } 517 return x, nil 518 } 519 } 520 } 521 522 func (dec *Decoder) tokenError(c byte) (Token, error) { 523 var context string 524 switch dec.tokenState { 525 case tokenTopValue: 526 context = " looking for beginning of value" 527 case tokenArrayStart, tokenArrayValue, tokenObjectValue: 528 context = " looking for beginning of value" 529 case tokenArrayComma: 530 context = " after array element" 531 case tokenObjectKey: 532 context = " looking for beginning of object key string" 533 case tokenObjectColon: 534 context = " after object key" 535 case tokenObjectComma: 536 context = " after object key:value pair" 537 } 538 return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()} 539 } 540 541 // More reports whether there is another element in the 542 // current array or object being parsed. 543 func (dec *Decoder) More() bool { 544 c, err := dec.peek() 545 return err == nil && c != ']' && c != '}' 546 } 547 548 func (dec *Decoder) peek() (byte, error) { 549 var err error 550 for { 551 for i := dec.scanp; i < len(dec.buf); i++ { 552 c := dec.buf[i] 553 if isSpace(c) { 554 continue 555 } 556 dec.scanp = i 557 return c, nil 558 } 559 // buffer has been scanned, now report any error 560 if err != nil { 561 return 0, err 562 } 563 err = dec.refill() 564 } 565 } 566 567 // InputOffset returns the input stream byte offset of the current decoder position. 568 // The offset gives the location of the end of the most recently returned token 569 // and the beginning of the next token. 570 func (dec *Decoder) InputOffset() int64 { 571 return dec.scanned + int64(dec.scanp) 572 }