feature_any.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. Get(path ...interface{}) Any
  13. Keys() []string
  14. IterateObject() (func() (string, Any, bool), bool)
  15. }
  16. type baseAny struct {}
  17. func (any *baseAny) Keys() []string {
  18. return []string{}
  19. }
  20. func (any *baseAny) IterateObject() (func() (string, Any, bool), bool) {
  21. return nil, false
  22. }
  23. func (iter *Iterator) ReadAny() Any {
  24. return iter.readAny(nil)
  25. }
  26. func (iter *Iterator) readAny(reusableIter *Iterator) Any {
  27. c := iter.nextToken()
  28. switch c {
  29. case '"':
  30. return iter.readStringAny(reusableIter)
  31. case 'n':
  32. iter.skipFixedBytes(3) // null
  33. return &nilAny{}
  34. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  35. iter.unreadByte()
  36. return iter.readNumberAny(reusableIter)
  37. case 't':
  38. iter.skipFixedBytes(3) // true
  39. return &trueAny{}
  40. case 'f':
  41. iter.skipFixedBytes(4) // false
  42. return &falseAny{}
  43. case '{':
  44. return iter.readObjectAny(reusableIter)
  45. }
  46. iter.reportError("ReadAny", fmt.Sprintf("unexpected character: %v", c))
  47. return &invalidAny{}
  48. }
  49. func (iter *Iterator) readNumberAny(reusableIter *Iterator) Any {
  50. dotFound := false
  51. var lazyBuf []byte
  52. for {
  53. for i := iter.head; i < iter.tail; i++ {
  54. c := iter.buf[i]
  55. if c == '.' {
  56. dotFound = true
  57. continue
  58. }
  59. switch c {
  60. case ' ', '\n', '\r', '\t', ',', '}', ']':
  61. lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...)
  62. iter.head = i
  63. if dotFound {
  64. return &floatLazyAny{baseAny{},lazyBuf, reusableIter, nil, 0}
  65. } else {
  66. return &intLazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
  67. }
  68. }
  69. }
  70. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  71. if !iter.loadMore() {
  72. iter.head = iter.tail
  73. if dotFound {
  74. return &floatLazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
  75. } else {
  76. return &intLazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
  77. }
  78. }
  79. }
  80. }
  81. func (iter *Iterator) readStringAny(reusableIter *Iterator) Any {
  82. lazyBuf := make([]byte, 1, 8)
  83. lazyBuf[0] = '"'
  84. for {
  85. end, escaped := iter.findStringEnd()
  86. if end == -1 {
  87. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  88. if !iter.loadMore() {
  89. iter.reportError("readStringAny", "incomplete string")
  90. return &invalidAny{}
  91. }
  92. if escaped {
  93. iter.head = 1 // skip the first char as last char read is \
  94. }
  95. } else {
  96. lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...)
  97. iter.head = end
  98. return &stringLazyAny{baseAny{}, lazyBuf, reusableIter, nil, ""}
  99. }
  100. }
  101. }
  102. func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any {
  103. level := 1
  104. lazyBuf := make([]byte, 1, 32)
  105. lazyBuf[0] = '{'
  106. for {
  107. start := iter.head
  108. for i := iter.head; i < iter.tail; i++ {
  109. switch iter.buf[i] {
  110. case '"': // If inside string, skip it
  111. iter.head = i + 1
  112. iter.skipString()
  113. i = iter.head - 1 // it will be i++ soon
  114. case '{': // If open symbol, increase level
  115. level++
  116. case '}': // If close symbol, increase level
  117. level--
  118. // If we have returned to the original level, we're done
  119. if level == 0 {
  120. iter.head = i + 1
  121. lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
  122. return &objectLazyAny{lazyBuf, reusableIter, nil, nil, lazyBuf}
  123. }
  124. }
  125. }
  126. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  127. if !iter.loadMore() {
  128. iter.reportError("skipObject", "incomplete object")
  129. return &invalidAny{}
  130. }
  131. }
  132. }