feature_any.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package jsoniter
  2. import "fmt"
  3. type Any interface {
  4. LastError() error
  5. ToBool() bool
  6. ToInt() int
  7. ToInt32() int32
  8. ToInt64() int64
  9. ToFloat32() float32
  10. ToFloat64() float64
  11. ToString() string
  12. }
  13. func (iter *Iterator) ReadAny() Any {
  14. valueType := iter.WhatIsNext()
  15. switch valueType {
  16. case Nil:
  17. iter.skipFixedBytes(4)
  18. return &nilAny{}
  19. case Number:
  20. return iter.readNumberAny()
  21. case String:
  22. return iter.readStringAny()
  23. }
  24. iter.reportError("ReadAny", fmt.Sprintf("unexpected value type: %v", valueType))
  25. return &invalidAny{}
  26. }
  27. func (iter *Iterator) readNumberAny() Any {
  28. dotFound := false
  29. var lazyBuf []byte
  30. for {
  31. for i := iter.head; i < iter.tail; i++ {
  32. c := iter.buf[i]
  33. if c == '.' {
  34. dotFound = true
  35. continue
  36. }
  37. switch c {
  38. case ' ', '\n', '\r', '\t', ',', '}', ']':
  39. lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...)
  40. iter.head = i
  41. if dotFound {
  42. return &floatLazyAny{lazyBuf, nil, nil, 0}
  43. } else {
  44. return &intLazyAny{lazyBuf, nil, nil, 0}
  45. }
  46. }
  47. }
  48. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  49. if !iter.loadMore() {
  50. iter.head = iter.tail
  51. if dotFound {
  52. return &floatLazyAny{lazyBuf, nil, nil, 0}
  53. } else {
  54. return &intLazyAny{lazyBuf, nil, nil, 0}
  55. }
  56. }
  57. }
  58. }
  59. func (iter *Iterator) readStringAny() Any {
  60. iter.head++
  61. lazyBuf := make([]byte, 1, 8)
  62. lazyBuf[0] = '"'
  63. for {
  64. end, escaped := iter.findStringEnd()
  65. if end == -1 {
  66. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  67. if !iter.loadMore() {
  68. iter.reportError("readStringAny", "incomplete string")
  69. return &invalidAny{}
  70. }
  71. if escaped {
  72. iter.head = 1 // skip the first char as last char read is \
  73. }
  74. } else {
  75. lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...)
  76. iter.head = end
  77. return &stringLazyAny{lazyBuf, nil, nil, ""}
  78. }
  79. }
  80. }