33import com .jsoniter .any .Any ;
44import com .jsoniter .spi .*;
55
6- import java .io .ByteArrayOutputStream ;
76import java .io .IOException ;
87import java .io .OutputStream ;
9- import java .io .UnsupportedEncodingException ;
108import java .lang .reflect .Type ;
119
1210public class JsonStream extends OutputStream {
@@ -30,44 +28,54 @@ public void reset(OutputStream out) {
3028 this .count = 0 ;
3129 }
3230
33- public final void write (int b ) throws IOException {
34- if (count == buf .length ) {
35- flushBuffer ();
31+ final void ensure (int minimal ) throws IOException {
32+ int available = buf .length - count ;
33+ if (available < minimal ) {
34+ if (count > 1024 ) {
35+ flushBuffer ();
36+ }
37+ growAtLeast (minimal );
3638 }
39+ }
40+
41+ private final void growAtLeast (int minimal ) {
42+ int toGrow = buf .length ;
43+ if (toGrow < minimal ) {
44+ toGrow = minimal ;
45+ }
46+ byte [] newBuf = new byte [buf .length + toGrow ];
47+ System .arraycopy (buf , 0 , newBuf , 0 , buf .length );
48+ buf = newBuf ;
49+ }
50+
51+ public final void write (int b ) throws IOException {
52+ ensure (1 );
3753 buf [count ++] = (byte ) b ;
3854 }
3955
4056 public final void write (byte b1 , byte b2 ) throws IOException {
41- if (count >= buf .length - 1 ) {
42- flushBuffer ();
43- }
57+ ensure (2 );
4458 buf [count ++] = b1 ;
4559 buf [count ++] = b2 ;
4660 }
4761
4862 public final void write (byte b1 , byte b2 , byte b3 ) throws IOException {
49- if (count >= buf .length - 2 ) {
50- flushBuffer ();
51- }
63+ ensure (3 );
5264 buf [count ++] = b1 ;
5365 buf [count ++] = b2 ;
5466 buf [count ++] = b3 ;
5567 }
5668
5769 public final void write (byte b1 , byte b2 , byte b3 , byte b4 ) throws IOException {
58- if (count >= buf .length - 3 ) {
59- flushBuffer ();
60- }
70+ ensure (4 );
6171 buf [count ++] = b1 ;
6272 buf [count ++] = b2 ;
6373 buf [count ++] = b3 ;
6474 buf [count ++] = b4 ;
6575 }
6676
6777 public final void write (byte b1 , byte b2 , byte b3 , byte b4 , byte b5 ) throws IOException {
68- if (count >= buf .length - 4 ) {
69- flushBuffer ();
70- }
78+ ensure (5 );
7179 buf [count ++] = b1 ;
7280 buf [count ++] = b2 ;
7381 buf [count ++] = b3 ;
@@ -76,9 +84,7 @@ public final void write(byte b1, byte b2, byte b3, byte b4, byte b5) throws IOEx
7684 }
7785
7886 public final void write (byte b1 , byte b2 , byte b3 , byte b4 , byte b5 , byte b6 ) throws IOException {
79- if (count >= buf .length - 5 ) {
80- flushBuffer ();
81- }
87+ ensure (6 );
8288 buf [count ++] = b1 ;
8389 buf [count ++] = b2 ;
8490 buf [count ++] = b3 ;
@@ -88,16 +94,20 @@ public final void write(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6) th
8894 }
8995
9096 public final void write (byte b [], int off , int len ) throws IOException {
91- if (len >= buf .length - count ) {
92- if (len >= buf .length ) {
97+ if (out == null ) {
98+ ensure (len );
99+ } else {
100+ if (len >= buf .length - count ) {
101+ if (len >= buf .length ) {
93102 /* If the request length exceeds the size of the output buffer,
94103 flush the output buffer and then write the data directly.
95104 In this way buffered streams will cascade harmlessly. */
105+ flushBuffer ();
106+ out .write (b , off , len );
107+ return ;
108+ }
96109 flushBuffer ();
97- out .write (b , off , len );
98- return ;
99110 }
100- flushBuffer ();
101111 }
102112 System .arraycopy (b , off , buf , count , len );
103113 count += len ;
@@ -142,6 +152,12 @@ public final void writeRaw(String val) throws IOException {
142152 }
143153
144154 public final void writeRaw (String val , int remaining ) throws IOException {
155+ if (out == null ) {
156+ ensure (remaining );
157+ val .getBytes (0 , remaining , buf , count );
158+ count += remaining ;
159+ return ;
160+ }
145161 int i = 0 ;
146162 for (; ; ) {
147163 int available = buf .length - count ;
@@ -288,16 +304,9 @@ private void writeIndention(int delta) throws IOException {
288304 }
289305 write ('\n' );
290306 int toWrite = indention - delta ;
291- int i = 0 ;
292- for (; ; ) {
293- for (; i < toWrite && count < buf .length ; i ++) {
294- buf [count ++] = ' ' ;
295- }
296- if (i == toWrite ) {
297- break ;
298- } else {
299- flushBuffer ();
300- }
307+ ensure (toWrite );
308+ for (int i = 0 ; i < toWrite && count < buf .length ; i ++) {
309+ buf [count ++] = ' ' ;
301310 }
302311 }
303312
@@ -496,4 +505,7 @@ public static void registerNativeEncoder(Class clazz, Encoder.ReflectionEncoder
496505 CodegenImplNative .NATIVE_ENCODERS .put (clazz , encoder );
497506 }
498507
508+ public Slice buffer () {
509+ return new Slice (buf , 0 , count );
510+ }
499511}
0 commit comments