@@ -103,32 +103,17 @@ object Lexer {
103
103
matrix.first(bs)
104
104
}
105
105
106
- private [this ] val ull : Array [Char ] = " ull" .toCharArray
107
106
private [this ] val alse : Array [Char ] = " alse" .toCharArray
108
107
private [this ] val rue : Array [Char ] = " rue" .toCharArray
109
108
110
109
def skipValue (trace : List [JsonError ], in : RetractReader ): Unit =
111
110
(in.nextNonWhitespace(): @ switch) match {
112
- case 'n' => readChars(trace, in, ull, " null" )
113
- case 'f' => readChars(trace, in, alse, " false" )
114
- case 't' => readChars(trace, in, rue, " true" )
115
- case '{' =>
116
- if (firstField(trace, in)) {
117
- while ({
118
- {
119
- char(trace, in, '"' )
120
- skipString(trace, in)
121
- char(trace, in, ':' )
122
- skipValue(trace, in)
123
- }; nextField(trace, in)
124
- }) ()
125
- }
126
- case '[' =>
127
- if (firstArrayElement(in)) {
128
- while ({ skipValue(trace, in); nextArrayElement(trace, in) }) ()
129
- }
111
+ case 'n' | 't' => skipFixedChars(in, 3 )
112
+ case 'f' => skipFixedChars(in, 4 )
113
+ case '{' => skipObject(in, 0 )
114
+ case '[' => skipArray(in, 0 )
130
115
case '"' =>
131
- skipString(trace, in )
116
+ skipString(in, evenBackSlashes = true )
132
117
case '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
133
118
skipNumber(in)
134
119
case c => throw UnsafeJson (JsonError .Message (s " unexpected ' $c' " ) :: trace)
@@ -139,10 +124,43 @@ object Lexer {
139
124
in.retract()
140
125
}
141
126
142
- def skipString (trace : List [JsonError ], in : OneCharReader ): Unit = {
143
- val stream = new EscapedString (trace, in)
144
- var i : Int = 0
145
- while ({ i = stream.read(); i != - 1 }) ()
127
+ def skipString (trace : List [JsonError ], in : OneCharReader ): Unit =
128
+ skipString(in, evenBackSlashes = true )
129
+
130
+ @ tailrec
131
+ private def skipFixedChars (in : OneCharReader , n : Int ): Unit =
132
+ if (n > 0 ) {
133
+ in.readChar()
134
+ skipFixedChars(in, n - 1 )
135
+ }
136
+
137
+ @ tailrec
138
+ private def skipString (in : OneCharReader , evenBackSlashes : Boolean ): Unit =
139
+ if (evenBackSlashes) {
140
+ val ch = in.readChar()
141
+ if (ch != '"' ) skipString(in, ch != '\\ ' )
142
+ } else skipString(in, evenBackSlashes = true )
143
+
144
+ @ tailrec
145
+ private def skipObject (in : OneCharReader , level : Int = 0 ): Unit = {
146
+ val ch = in.readChar()
147
+ if (ch == '"' ) {
148
+ skipString(in, evenBackSlashes = true )
149
+ skipObject(in, level)
150
+ } else if (ch == '{' ) skipObject(in, level + 1 )
151
+ else if (ch != '}' ) skipObject(in, level)
152
+ else if (level != 0 ) skipObject(in, level - 1 )
153
+ }
154
+
155
+ @ tailrec
156
+ private def skipArray (in : OneCharReader , level : Int = 0 ): Unit = {
157
+ val b = in.readChar()
158
+ if (b == '"' ) {
159
+ skipString(in, evenBackSlashes = true )
160
+ skipArray(in, level)
161
+ } else if (b == '[' ) skipArray(in, level + 1 )
162
+ else if (b != ']' ) skipArray(in, level)
163
+ else if (level != 0 ) skipArray(in, level - 1 )
146
164
}
147
165
148
166
// useful for embedded documents, e.g. CSV contained inside JSON
0 commit comments