feature_any.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. c := iter.nextToken()
  15. switch c {
  16. case '"':
  17. return iter.readStringAny()
  18. case 'n':
  19. iter.skipFixedBytes(3) // null
  20. return &nilAny{}
  21. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  22. iter.unreadByte()
  23. return iter.readNumberAny()
  24. case 't':
  25. iter.skipFixedBytes(3) // true
  26. return &trueAny{}
  27. case 'f':
  28. iter.skipFixedBytes(4) // false
  29. return &falseAny{}
  30. }
  31. iter.reportError("ReadAny", fmt.Sprintf("unexpected character: %v", c))
  32. return &invalidAny{}
  33. }
  34. func (iter *Iterator) readNumberAny() Any {
  35. dotFound := false
  36. var lazyBuf []byte
  37. for {
  38. for i := iter.head; i < iter.tail; i++ {
  39. c := iter.buf[i]
  40. if c == '.' {
  41. dotFound = true
  42. continue
  43. }
  44. switch c {
  45. case ' ', '\n', '\r', '\t', ',', '}', ']':
  46. lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...)
  47. iter.head = i
  48. if dotFound {
  49. return &floatLazyAny{lazyBuf, nil, nil, 0}
  50. } else {
  51. return &intLazyAny{lazyBuf, nil, nil, 0}
  52. }
  53. }
  54. }
  55. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  56. if !iter.loadMore() {
  57. iter.head = iter.tail
  58. if dotFound {
  59. return &floatLazyAny{lazyBuf, nil, nil, 0}
  60. } else {
  61. return &intLazyAny{lazyBuf, nil, nil, 0}
  62. }
  63. }
  64. }
  65. }
  66. func (iter *Iterator) readStringAny() Any {
  67. lazyBuf := make([]byte, 1, 8)
  68. lazyBuf[0] = '"'
  69. for {
  70. end, escaped := iter.findStringEnd()
  71. if end == -1 {
  72. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  73. if !iter.loadMore() {
  74. iter.reportError("readStringAny", "incomplete string")
  75. return &invalidAny{}
  76. }
  77. if escaped {
  78. iter.head = 1 // skip the first char as last char read is \
  79. }
  80. } else {
  81. lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...)
  82. iter.head = end
  83. return &stringLazyAny{lazyBuf, nil, nil, ""}
  84. }
  85. }
  86. }