@@ -14,23 +14,31 @@ private const val DEFAULT_THRESHOLD = 128
14
14
* For some reason this hand-rolled implementation is faster than
15
15
* fun ArrayAsSequence(s: CharArray): CharSequence = java.nio.CharBuffer.wrap(s, 0, length)
16
16
*/
17
- private class ArrayAsSequence (private val source : CharArray ) : CharSequence {
18
- override val length: Int = source .size
17
+ internal class ArrayAsSequence (val buffer : CharArray ) : CharSequence {
18
+ override var length: Int = buffer .size
19
19
20
- override fun get (index : Int ): Char = source [index]
20
+ override fun get (index : Int ): Char = buffer [index]
21
21
22
22
override fun subSequence (startIndex : Int , endIndex : Int ): CharSequence {
23
- return source.concatToString(startIndex, endIndex)
23
+ return buffer.concatToString(startIndex, minOf(endIndex, length))
24
+ }
25
+
26
+ fun substring (startIndex : Int , endIndex : Int ): String {
27
+ return buffer.concatToString(startIndex, minOf(endIndex, length))
28
+ }
29
+
30
+ fun trim (newSize : Int ) {
31
+ length = minOf(buffer.size, newSize)
24
32
}
25
33
}
26
34
27
35
internal class ReaderJsonLexer (
28
36
private val reader : SerialReader ,
29
- private var _source : CharArray = CharArray (BATCH_SIZE )
37
+ charsBuffer : CharArray = CharArray (BATCH_SIZE )
30
38
) : AbstractJsonLexer() {
31
39
private var threshold: Int = DEFAULT_THRESHOLD // chars
32
40
33
- override var source: CharSequence = ArrayAsSequence (_source )
41
+ override val source: ArrayAsSequence = ArrayAsSequence (charsBuffer )
34
42
35
43
init {
36
44
preload(0 )
@@ -65,22 +73,22 @@ internal class ReaderJsonLexer(
65
73
return false
66
74
}
67
75
68
- private fun preload (spaceLeft : Int ) {
69
- val buffer = _source
70
- buffer.copyInto(buffer, 0 , currentPosition, currentPosition + spaceLeft)
71
- var read = spaceLeft
72
- val sizeTotal = _source .size
73
- while (read != sizeTotal) {
74
- val actual = reader.read(buffer, read, sizeTotal - read)
76
+ private fun preload (unprocessedCount : Int ) {
77
+ val buffer = source.buffer
78
+ if (unprocessedCount != 0 ) {
79
+ buffer.copyInto(buffer, 0 , currentPosition, currentPosition + unprocessedCount)
80
+ }
81
+ var filledCount = unprocessedCount
82
+ val sizeTotal = source.length
83
+ while (filledCount != sizeTotal) {
84
+ val actual = reader.read(buffer, filledCount, sizeTotal - filledCount)
75
85
if (actual == - 1 ) {
76
86
// EOF, resizing the array so it matches input size
77
- // Can also be done by extracting source.length to a separate var
78
- _source = _source .copyOf(read)
79
- source = ArrayAsSequence (_source )
87
+ source.trim(filledCount)
80
88
threshold = - 1
81
89
break
82
90
}
83
- read + = actual
91
+ filledCount + = actual
84
92
}
85
93
currentPosition = 0
86
94
}
@@ -115,7 +123,7 @@ internal class ReaderJsonLexer(
115
123
116
124
override fun ensureHaveChars () {
117
125
val cur = currentPosition
118
- val oldSize = _source .size
126
+ val oldSize = source.length
119
127
val spaceLeft = oldSize - cur
120
128
if (spaceLeft > threshold) return
121
129
// warning: current position is not updated during string consumption
@@ -152,19 +160,19 @@ internal class ReaderJsonLexer(
152
160
}
153
161
154
162
override fun indexOf (char : Char , startPos : Int ): Int {
155
- val src = _source
156
- for (i in startPos until src.size ) {
163
+ val src = source
164
+ for (i in startPos until src.length ) {
157
165
if (src[i] == char) return i
158
166
}
159
167
return - 1
160
168
}
161
169
162
170
override fun substring (startPos : Int , endPos : Int ): String {
163
- return _source .concatToString (startPos, endPos)
171
+ return source.substring (startPos, endPos)
164
172
}
165
173
166
174
override fun appendRange (fromIndex : Int , toIndex : Int ) {
167
- escapedString.appendRange(_source , fromIndex, toIndex)
175
+ escapedString.appendRange(source.buffer , fromIndex, toIndex)
168
176
}
169
177
170
178
// Can be carefully implemented but postponed for now
0 commit comments