Skip to content

Commit 933f33c

Browse files
committed
Minor changes wrt #17 to use recyclable buffers
1 parent 0711081 commit 933f33c

File tree

6 files changed

+75
-77
lines changed

6 files changed

+75
-77
lines changed

release-notes/CREDITS

+4
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,7 @@ Brad Hess (bdhess@github)
122122
(2.9.0)
123123
* Reported #325: `DataInput` backed parser should handle `EOFException` at end of doc
124124
(2.9.0)
125+
126+
Logan Widick (uhhhh2@github)
127+
* Contributed #17: Add 'JsonGenerator.writeString(Reader r, int charLength)'
128+
(2.9.0)

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ JSON library.
1616

1717
2.9.0 (not yet released)
1818

19+
#17: Add 'JsonGenerator.writeString(Reader r, int charLength)'
20+
(constributed by Logan W)
1921
#304: Optimize `NumberOutput.outputLong()` method
2022
#312: Add `JsonProcessingException.clearLocation()` to allow clearing
2123
possibly security-sensitive information

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
*/
55
package com.fasterxml.jackson.core;
66

7-
import com.fasterxml.jackson.core.JsonParser.NumberType;
8-
import com.fasterxml.jackson.core.io.CharacterEscapes;
9-
import com.fasterxml.jackson.core.util.VersionUtil;
10-
117
import java.io.*;
128
import java.math.BigDecimal;
139
import java.math.BigInteger;
1410
import java.util.concurrent.atomic.AtomicBoolean;
1511
import java.util.concurrent.atomic.AtomicInteger;
1612
import java.util.concurrent.atomic.AtomicLong;
1713

14+
import com.fasterxml.jackson.core.JsonParser.NumberType;
15+
import com.fasterxml.jackson.core.io.CharacterEscapes;
16+
import com.fasterxml.jackson.core.util.VersionUtil;
17+
1818
import static com.fasterxml.jackson.core.JsonTokenId.*;
1919

2020
/**
@@ -941,6 +941,8 @@ public void writeArray(double[] array, int offset, int length) throws IOExceptio
941941
* If the reader is null, then write a null.
942942
* If len is < 0, then write all contents of the reader.
943943
* Otherwise, write only len characters.
944+
*
945+
* @since 2.9
944946
*/
945947
public abstract void writeString(Reader reader, int len) throws IOException;
946948

src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ public int writeBinary(Base64Variant b64variant, InputStream data, int dataLengt
341341
return 0;
342342
}
343343

344-
@Override
344+
@Override // since 2.9
345345
public void writeString(Reader reader, int len) throws IOException {
346346
// Let's implement this as "unsupported" to make it easier to add new parser impls
347347
_reportUnsupportedOperation();

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

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package com.fasterxml.jackson.core.json;
22

3+
import java.io.*;
4+
import java.math.BigDecimal;
5+
import java.math.BigInteger;
6+
37
import com.fasterxml.jackson.core.*;
48
import com.fasterxml.jackson.core.io.CharTypes;
59
import com.fasterxml.jackson.core.io.CharacterEscapes;
610
import com.fasterxml.jackson.core.io.IOContext;
711
import com.fasterxml.jackson.core.io.NumberOutput;
812

9-
import java.io.IOException;
10-
import java.io.InputStream;
11-
import java.io.OutputStream;
12-
import java.io.Reader;
13-
import java.math.BigDecimal;
14-
import java.math.BigInteger;
15-
1613
public class UTF8JsonGenerator
1714
extends JsonGeneratorImpl
1815
{
@@ -476,7 +473,6 @@ public void writeString(Reader reader, int len) throws IOException {
476473

477474
int toRead = (len >= 0) ? len : Integer.MAX_VALUE;
478475

479-
//TODO: Check that this use is OK
480476
final char[] buf = _charBuffer;
481477

482478
//Add leading quote
@@ -486,11 +482,8 @@ public void writeString(Reader reader, int len) throws IOException {
486482
_outputBuffer[_outputTail++] = _quoteChar;
487483

488484
//read
489-
while(toRead > 0){
485+
while (toRead > 0){
490486
int toReadNow = Math.min(toRead, buf.length);
491-
if(toRead <= 0){
492-
break;
493-
}
494487
int numRead = reader.read(buf, 0, toReadNow);
495488
if(numRead <= 0){
496489
break;
@@ -499,7 +492,6 @@ public void writeString(Reader reader, int len) throws IOException {
499492
_flushBuffer();
500493
}
501494
_writeStringSegments(buf, 0, numRead);
502-
503495
//decrease tracker
504496
toRead -= numRead;
505497
}
@@ -510,7 +502,7 @@ public void writeString(Reader reader, int len) throws IOException {
510502
}
511503
_outputBuffer[_outputTail++] = _quoteChar;
512504

513-
if(toRead > 0 && len >= 0){
505+
if (toRead > 0 && len >= 0){
514506
_reportError("Didn't read enough from reader");
515507
}
516508
}

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

+56-58
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package com.fasterxml.jackson.core.json;
22

3+
import java.io.*;
4+
import java.math.BigDecimal;
5+
import java.math.BigInteger;
6+
37
import com.fasterxml.jackson.core.*;
48
import com.fasterxml.jackson.core.io.CharTypes;
59
import com.fasterxml.jackson.core.io.CharacterEscapes;
610
import com.fasterxml.jackson.core.io.IOContext;
711
import com.fasterxml.jackson.core.io.NumberOutput;
812

9-
import java.io.IOException;
10-
import java.io.InputStream;
11-
import java.io.Reader;
12-
import java.io.Writer;
13-
import java.math.BigDecimal;
14-
import java.math.BigInteger;
15-
1613
/**
1714
* {@link JsonGenerator} that outputs JSON content using a {@link java.io.Writer}
1815
* which handles character encoding.
@@ -75,23 +72,20 @@ public class WriterBasedJsonGenerator
7572
*/
7673
protected char[] _entityBuffer;
7774

78-
/**
79-
* Intermediate buffer in which characters of a String are copied
80-
* before being encoded.
81-
*/
82-
protected char[] _charBuffer;
83-
84-
/**
85-
* Length of <code>_charBuffer</code>
86-
*/
87-
protected final int _charBufferLength;
88-
8975
/**
9076
* When custom escapes are used, this member variable is used
9177
* internally to hold a reference to currently used escape
9278
*/
9379
protected SerializableString _currentEscape;
9480

81+
/**
82+
* Intermediate buffer in which characters of a String are copied
83+
* before being encoded.
84+
*
85+
* @since 2.9
86+
*/
87+
protected char[] _charBuffer;
88+
9589
/*
9690
/**********************************************************
9791
/* Life-cycle
@@ -105,16 +99,14 @@ public WriterBasedJsonGenerator(IOContext ctxt, int features,
10599
_writer = w;
106100
_outputBuffer = ctxt.allocConcatBuffer();
107101
_outputEnd = _outputBuffer.length;
108-
_charBuffer = new char[_outputBuffer.length];
109-
_charBufferLength = _charBuffer.length;
110102
}
111-
103+
112104
/*
113105
/**********************************************************
114106
/* Overridden configuration, introspection methods
115107
/**********************************************************
116108
*/
117-
109+
118110
@Override
119111
public Object getOutputTarget() {
120112
return _writer;
@@ -395,46 +387,38 @@ public void writeString(Reader reader, int len) throws IOException {
395387
_verifyValueWrite(WRITE_STRING);
396388
if (reader == null) {
397389
_reportError("null reader");
398-
} else {
399-
int toRead = (len >= 0) ? len : Integer.MAX_VALUE;
400-
401-
//TODO: Check that this use is OK
402-
final char[] buf = _charBuffer;
403-
404-
//Add leading quote
405-
if ((_outputTail + len) >= _outputEnd) {
406-
_flushBuffer();
407-
}
408-
_outputBuffer[_outputTail++] = _quoteChar;
409-
410-
//read
411-
while (toRead > 0) {
412-
int toReadNow = Math.min(toRead, buf.length);
413-
if (toRead <= 0) {
414-
break;
415-
}
416-
int numRead = reader.read(buf, 0, toReadNow);
417-
if (numRead <= 0) {
418-
break;
419-
}
420-
if ((_outputTail + len) >= _outputEnd) {
421-
_flushBuffer();
422-
}
423-
_writeString(buf, 0, numRead);
390+
}
391+
int toRead = (len >= 0) ? len : Integer.MAX_VALUE;
392+
final char[] buf = _allocateCopyBuffer();
393+
//Add leading quote
394+
if ((_outputTail + len) >= _outputEnd) {
395+
_flushBuffer();
396+
}
397+
_outputBuffer[_outputTail++] = _quoteChar;
424398

425-
//decrease tracker
426-
toRead -= numRead;
399+
//read
400+
while (toRead > 0) {
401+
int toReadNow = Math.min(toRead, buf.length);
402+
int numRead = reader.read(buf, 0, toReadNow);
403+
if (numRead <= 0) {
404+
break;
427405
}
428-
429-
//Add trailing quote
430406
if ((_outputTail + len) >= _outputEnd) {
431407
_flushBuffer();
432408
}
433-
_outputBuffer[_outputTail++] = _quoteChar;
409+
_writeString(buf, 0, numRead);
434410

435-
if (toRead > 0 && len >= 0) {
436-
_reportError("Didn't read enough from reader");
437-
}
411+
//decrease tracker
412+
toRead -= numRead;
413+
}
414+
//Add trailing quote
415+
if ((_outputTail + len) >= _outputEnd) {
416+
_flushBuffer();
417+
}
418+
_outputBuffer[_outputTail++] = _quoteChar;
419+
420+
if (toRead > 0 && len >= 0) {
421+
_reportError("Didn't read enough from reader");
438422
}
439423
}
440424

@@ -957,7 +941,11 @@ protected void _releaseBuffers()
957941
_outputBuffer = null;
958942
_ioContext.releaseConcatBuffer(buf);
959943
}
960-
_charBuffer = null;
944+
buf = _charBuffer;
945+
if (buf != null) {
946+
_charBuffer = null;
947+
_ioContext.releaseNameCopyBuffer(buf);
948+
}
961949
}
962950

963951
/*
@@ -1938,7 +1926,17 @@ private char[] _allocateEntityBuffer()
19381926
_entityBuffer = buf;
19391927
return buf;
19401928
}
1941-
1929+
1930+
/**
1931+
* @since 2.9
1932+
*/
1933+
private char[] _allocateCopyBuffer() {
1934+
if (_charBuffer == null) {
1935+
_charBuffer = _ioContext.allocNameCopyBuffer(2000);
1936+
}
1937+
return _charBuffer;
1938+
}
1939+
19421940
protected void _flushBuffer() throws IOException
19431941
{
19441942
int len = _outputTail - _outputHead;

0 commit comments

Comments
 (0)