Skip to content

Commit 7a0991a

Browse files
committed
Merge pull request #285 from LokeshN/readtext-jsonparser1
issue #15 - readtext in jsonparser
2 parents 780394c + ca17d2f commit 7a0991a

File tree

7 files changed

+244
-0
lines changed

7 files changed

+244
-0
lines changed

src/main/java/com/fasterxml/jackson/core/JsonParser.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,16 @@ public int currentTokenId() {
10301030
*/
10311031
public abstract String getText() throws IOException;
10321032

1033+
/**
1034+
* Method to read the textual representation of the current token in chunks and
1035+
* pass it to the given Writer
1036+
*
1037+
* @return The number of characters written to the Writer
1038+
*
1039+
* @since 2.8
1040+
*/
1041+
public abstract int readText(Writer writer) throws IOException, UnsupportedOperationException;
1042+
10331043
/**
10341044
* Method similar to {@link #getText}, but that will return
10351045
* underlying (unmodifiable) character array that contains

src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.fasterxml.jackson.core.json;
22

33
import java.io.*;
4+
import java.util.List;
45

56
import com.fasterxml.jackson.core.*;
67
import com.fasterxml.jackson.core.base.ParserBase;
@@ -273,6 +274,51 @@ public final String getText() throws IOException
273274
return _getText2(t);
274275
}
275276

277+
@Override
278+
public final int readText(Writer writer) throws IOException, UnsupportedOperationException {
279+
JsonToken t = _currToken;
280+
//Stores the length of the bytes read
281+
int len = 0;
282+
if (t == JsonToken.VALUE_STRING) {
283+
if (_tokenIncomplete) {
284+
_tokenIncomplete = false;
285+
_finishString(); // only strings can be incomplete
286+
}
287+
List<char[]> segments = _textBuffer.getCharacterSegments();
288+
289+
//Indicates the currently read text buffer index which refers to the
290+
//TextBuffer character segment
291+
int readTextBufferIndex = 0;
292+
//if there are character segments, then use them and write them to the writer
293+
while(segments != null && readTextBufferIndex < segments.size()) {
294+
writer.write(segments.get(readTextBufferIndex));
295+
len += segments.get(readTextBufferIndex).length;
296+
readTextBufferIndex++;
297+
}
298+
//if there are no character segments left, then read the string from the current segment, and
299+
//write them directly to the buffer
300+
writer.write(_textBuffer.getCurrentSegment(), 0, _textBuffer.getCurrentSegmentSize());
301+
len += _textBuffer.getCurrentSegmentSize();
302+
303+
}
304+
else if(t != null) {
305+
switch (t.id()) {
306+
case ID_FIELD_NAME:
307+
writer.write(_parsingContext.getCurrentName());
308+
break;
309+
case ID_STRING:
310+
case ID_NUMBER_INT:
311+
case ID_NUMBER_FLOAT:
312+
writer.write(_textBuffer.contentsAsString());
313+
break;
314+
default:
315+
writer.write(t.asString());
316+
}
317+
}
318+
319+
return len;
320+
}
321+
276322
// // // Let's override default impls for improved performance
277323

278324
// @since 2.1

src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.*;
44
import java.util.Arrays;
5+
import java.util.List;
56

67
import com.fasterxml.jackson.core.*;
78
import com.fasterxml.jackson.core.base.ParserBase;
@@ -184,6 +185,51 @@ public String getText() throws IOException
184185
return _getText2(_currToken);
185186
}
186187

188+
@Override
189+
public final int readText(Writer writer) throws IOException, UnsupportedOperationException {
190+
JsonToken t = _currToken;
191+
//Stores the length of the bytes read
192+
int len = 0;
193+
if (t == JsonToken.VALUE_STRING) {
194+
if (_tokenIncomplete) {
195+
_tokenIncomplete = false;
196+
_finishString(); // only strings can be incomplete
197+
}
198+
List<char[]> segments = _textBuffer.getCharacterSegments();
199+
200+
//Indicates the currently read text buffer index which refers to the
201+
//TextBuffer character segment
202+
int readTextBufferIndex = 0;
203+
//if there are character segments, then use them and write them to the writer
204+
while(segments != null && readTextBufferIndex < segments.size()) {
205+
writer.write(segments.get(readTextBufferIndex));
206+
len += segments.get(readTextBufferIndex).length;
207+
readTextBufferIndex++;
208+
}
209+
//if there are no character segments left, then read the string from the current segment, and
210+
//write them directly to the buffer
211+
writer.write(_textBuffer.getCurrentSegment(), 0, _textBuffer.getCurrentSegmentSize());
212+
len += _textBuffer.getCurrentSegmentSize();
213+
214+
}
215+
else if(t != null) {
216+
switch (t.id()) {
217+
case ID_FIELD_NAME:
218+
writer.write(_parsingContext.getCurrentName());
219+
break;
220+
case ID_STRING:
221+
case ID_NUMBER_INT:
222+
case ID_NUMBER_FLOAT:
223+
writer.write(_textBuffer.contentsAsString());
224+
break;
225+
default:
226+
writer.write(t.asString());
227+
}
228+
}
229+
230+
return len;
231+
}
232+
187233
// // // Let's override default impls for improved performance
188234
@Override
189235
public String getValueAsString() throws IOException

src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.*;
44
import java.util.Arrays;
5+
import java.util.List;
56

67
import com.fasterxml.jackson.core.*;
78
import com.fasterxml.jackson.core.base.ParserBase;
@@ -318,6 +319,51 @@ public String getText() throws IOException
318319
}
319320
return _getText2(_currToken);
320321
}
322+
323+
@Override
324+
public final int readText(Writer writer) throws IOException, UnsupportedOperationException {
325+
JsonToken t = _currToken;
326+
//Stores the length of the bytes read
327+
int len = 0;
328+
if (t == JsonToken.VALUE_STRING) {
329+
if (_tokenIncomplete) {
330+
_tokenIncomplete = false;
331+
_finishString(); // only strings can be incomplete
332+
}
333+
List<char[]> segments = _textBuffer.getCharacterSegments();
334+
335+
//Indicates the currently read text buffer index which refers to the
336+
//TextBuffer character segment
337+
int readTextBufferIndex = 0;
338+
//if there are character segments, then use them and write them to the writer
339+
while(segments != null && readTextBufferIndex < segments.size()) {
340+
writer.write(segments.get(readTextBufferIndex));
341+
len += segments.get(readTextBufferIndex).length;
342+
readTextBufferIndex++;
343+
}
344+
//if there are no character segments left, then read the string from the current segment, and
345+
//write them directly to the buffer
346+
writer.write(_textBuffer.getCurrentSegment(), 0, _textBuffer.getCurrentSegmentSize());
347+
len += _textBuffer.getCurrentSegmentSize();
348+
349+
}
350+
else if(t != null) {
351+
switch (t.id()) {
352+
case ID_FIELD_NAME:
353+
writer.write(_parsingContext.getCurrentName());
354+
break;
355+
case ID_STRING:
356+
case ID_NUMBER_INT:
357+
case ID_NUMBER_FLOAT:
358+
writer.write(_textBuffer.contentsAsString());
359+
break;
360+
default:
361+
writer.write(t.asString());
362+
}
363+
}
364+
365+
return len;
366+
}
321367

322368
// // // Let's override default impls for improved performance
323369

src/main/java/com/fasterxml/jackson/core/util/JsonParserDelegate.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.IOException;
44
import java.io.OutputStream;
5+
import java.io.Writer;
56
import java.math.BigDecimal;
67
import java.math.BigInteger;
78

@@ -143,6 +144,7 @@ public JsonParser overrideFormatFeatures(int values, int mask) {
143144
@Override public char[] getTextCharacters() throws IOException { return delegate.getTextCharacters(); }
144145
@Override public int getTextLength() throws IOException { return delegate.getTextLength(); }
145146
@Override public int getTextOffset() throws IOException { return delegate.getTextOffset(); }
147+
@Override public int readText(Writer writer) throws IOException, UnsupportedOperationException { return delegate.readText(writer); }
146148

147149
/*
148150
/**********************************************************

src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.math.BigDecimal;
44
import java.util.ArrayList;
55
import java.util.Arrays;
6+
import java.util.List;
67

78
import com.fasterxml.jackson.core.io.NumberInput;
89

@@ -506,6 +507,15 @@ public void append(String str, int offset, int len)
506507
} while (len > 0);
507508
}
508509

510+
/**
511+
* Returns the raw list of character segments
512+
*
513+
* @return The character segments
514+
*/
515+
public List<char[]> getCharacterSegments() {
516+
return _segments;
517+
}
518+
509519
/*
510520
/**********************************************************
511521
/* Raw access, for high-performance use:

src/test/java/com/fasterxml/jackson/core/read/JsonParserTest.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,90 @@ private void _testGetValueAsText(int mode, boolean delegate) throws Exception
615615
}
616616
p.close();
617617
}
618+
619+
public void testReadText() throws Exception {
620+
final String JSON = "{\"a\":\"this is a sample text for json parsing using readText() method\",\"b\":true,\"c\":null,\"d\":\"foo\"}";
621+
//create parser in reader mode..
622+
JsonParser parser = createParser(MODE_READER, JSON);
623+
//move the token until the string field
624+
parser.nextToken();
625+
parser.nextToken();
626+
parser.nextToken();
627+
628+
Writer writer = new StringWriter();
629+
int len = parser.readText(writer);
630+
631+
assertTrue("String length should be same", writer.toString().length() == "this is a sample text for json parsing using readText() method".length());
632+
assertEquals("Returned length should be same", len, writer.toString().length());
633+
634+
//create parser in stream mode..
635+
parser = createParser(MODE_INPUT_STREAM, JSON);
636+
//move the token until the string field
637+
parser.nextToken();
638+
parser.nextToken();
639+
parser.nextToken();
640+
641+
writer = new StringWriter();
642+
len = parser.readText(writer);
643+
644+
assertTrue("String length should be same", writer.toString().length() == "this is a sample text for json parsing using readText() method".length());
645+
assertEquals("Returned length should be same", len, writer.toString().length());
646+
647+
//create parser in data input mode..
648+
parser = createParser(MODE_DATA_INPUT, JSON);
649+
//move the token until the string field
650+
parser.nextToken();
651+
parser.nextToken();
652+
parser.nextToken();
653+
654+
writer = new StringWriter();
655+
len = parser.readText(writer);
656+
657+
assertTrue("String length should be same", writer.toString().length() == "this is a sample text for json parsing using readText() method".length());
658+
assertEquals("Returned length should be same", len, writer.toString().length());
659+
}
660+
661+
public void testLongerReadText() throws Exception {
662+
StringBuilder builder = new StringBuilder();
663+
for(int i= 0; i < 1000; i++) {
664+
builder.append("Sample Text"+i);
665+
}
666+
String longText = builder.toString();
667+
final String JSON = "{\"a\":\""+ longText +"\",\"b\":true,\"c\":null,\"d\":\"foo\"}";
668+
//create parser in reader mode..
669+
JsonParser parser = createParser(MODE_READER, JSON);
670+
//move the token until the string field
671+
parser.nextToken();
672+
parser.nextToken();
673+
parser.nextToken();
674+
675+
Writer writer = new StringWriter();
676+
int len = parser.readText(writer);
677+
assertEquals("Returned length should be same", len, writer.toString().length());
678+
679+
//create parser in stream mode..
680+
parser = createParser(MODE_INPUT_STREAM, JSON);
681+
//move the token until the string field
682+
parser.nextToken();
683+
parser.nextToken();
684+
parser.nextToken();
685+
686+
writer = new StringWriter();
687+
len = parser.readText(writer);
688+
assertEquals("Returned length should be same", len, writer.toString().length());
689+
690+
//create parser in data input mode..
691+
parser = createParser(MODE_DATA_INPUT, JSON);
692+
//move the token until the string field
693+
parser.nextToken();
694+
parser.nextToken();
695+
parser.nextToken();
696+
697+
writer = new StringWriter();
698+
len = parser.readText(writer);
699+
assertEquals("Returned length should be same", len, writer.toString().length());
700+
701+
}
618702

619703
/*
620704
/**********************************************************

0 commit comments

Comments
 (0)