gitea

Development moved to Codeberg

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
  114. 114
  115. 115
  116. 116
  117. 117
  118. 118
  119. 119
  120. 120
  121. 121
  122. 122
  123. 123
  124. 124
  125. 125
  126. 126
  127. 127
  128. 128
  129. 129
  130. 130
package jsoniter

import "fmt"

// ReadNil reads a json object as nil and
// returns whether it's a nil or not
func (iter *Iterator) ReadNil() (ret bool) {
	c := iter.nextToken()
	if c == 'n' {
		iter.skipThreeBytes('u', 'l', 'l') // null
		return true
	}
	iter.unreadByte()
	return false
}

// ReadBool reads a json object as BoolValue
func (iter *Iterator) ReadBool() (ret bool) {
	c := iter.nextToken()
	if c == 't' {
		iter.skipThreeBytes('r', 'u', 'e')
		return true
	}
	if c == 'f' {
		iter.skipFourBytes('a', 'l', 's', 'e')
		return false
	}
	iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
	return
}

// SkipAndReturnBytes skip next JSON element, and return its content as []byte.
// The []byte can be kept, it is a copy of data.
func (iter *Iterator) SkipAndReturnBytes() []byte {
	iter.startCapture(iter.head)
	iter.Skip()
	return iter.stopCapture()
}

// SkipAndAppendBytes skips next JSON element and appends its content to
// buffer, returning the result.
func (iter *Iterator) SkipAndAppendBytes(buf []byte) []byte {
	iter.startCaptureTo(buf, iter.head)
	iter.Skip()
	return iter.stopCapture()
}

func (iter *Iterator) startCaptureTo(buf []byte, captureStartedAt int) {
	if iter.captured != nil {
		panic("already in capture mode")
	}
	iter.captureStartedAt = captureStartedAt
	iter.captured = buf
}

func (iter *Iterator) startCapture(captureStartedAt int) {
	iter.startCaptureTo(make([]byte, 0, 32), captureStartedAt)
}

func (iter *Iterator) stopCapture() []byte {
	if iter.captured == nil {
		panic("not in capture mode")
	}
	captured := iter.captured
	remaining := iter.buf[iter.captureStartedAt:iter.head]
	iter.captureStartedAt = -1
	iter.captured = nil
	return append(captured, remaining...)
}

// Skip skips a json object and positions to relatively the next json object
func (iter *Iterator) Skip() {
	c := iter.nextToken()
	switch c {
	case '"':
		iter.skipString()
	case 'n':
		iter.skipThreeBytes('u', 'l', 'l') // null
	case 't':
		iter.skipThreeBytes('r', 'u', 'e') // true
	case 'f':
		iter.skipFourBytes('a', 'l', 's', 'e') // false
	case '0':
		iter.unreadByte()
		iter.ReadFloat32()
	case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		iter.skipNumber()
	case '[':
		iter.skipArray()
	case '{':
		iter.skipObject()
	default:
		iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
		return
	}
}

func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) {
	if iter.readByte() != b1 {
		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
		return
	}
	if iter.readByte() != b2 {
		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
		return
	}
	if iter.readByte() != b3 {
		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
		return
	}
	if iter.readByte() != b4 {
		iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
		return
	}
}

func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) {
	if iter.readByte() != b1 {
		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
		return
	}
	if iter.readByte() != b2 {
		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
		return
	}
	if iter.readByte() != b3 {
		iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
		return
	}
}