19
19
import java .io .InputStream ;
20
20
import java .io .InputStreamReader ;
21
21
import java .nio .CharBuffer ;
22
+ import java .nio .charset .Charset ;
22
23
import org .json .JSONException ;
23
24
24
25
/**
27
28
* <p>The class takes a bundle stream and presents abstractions to read bundled elements out of the
28
29
* underlying content.
29
30
*/
30
- public class BundleReader extends BundleElement {
31
+ public class BundleReader {
31
32
/** The capacity for the internal char buffer. */
32
33
protected static final int BUFFER_CAPACITY = 1024 ;
33
34
@@ -40,8 +41,10 @@ public class BundleReader extends BundleElement {
40
41
41
42
public BundleReader (BundleSerializer serializer , InputStream data ) {
42
43
this .serializer = serializer ;
43
- dataReader = new InputStreamReader (data );
44
+ dataReader = new InputStreamReader (data , Charset . forName ( "UTF-8" ) );
44
45
buffer = CharBuffer .allocate (BUFFER_CAPACITY );
46
+
47
+ buffer .flip (); // Start the buffer in "reading mode"
45
48
}
46
49
47
50
/** Returns the metadata element from the bundle. */
@@ -91,23 +94,23 @@ public void close() throws IOException {
91
94
*/
92
95
@ Nullable
93
96
private BundleElement readNextElement () throws IOException , JSONException {
94
- int length = readLength ();
95
- if (length == - 1 ) {
97
+ String lengthPrefix = readLengthPrefix ();
98
+ if (lengthPrefix == null ) {
96
99
return null ;
97
100
}
98
101
99
- String json = readJsonString (length );
100
- bytesRead += ( int ) ( Math . log10 ( length ) + 1 ) + length ;
102
+ String json = readJsonString (Integer . parseInt ( lengthPrefix ) );
103
+ bytesRead += lengthPrefix . length ( ) + json . length () ;
101
104
return BundleElement .fromJson (serializer , json );
102
105
}
103
106
104
107
/**
105
108
* Reads the length prefix from the beginning of the internal buffer until the first '{'. Returns
106
109
* the integer-decoded length.
107
110
*
108
- * <p>If it reached the end of the stream, returns -1 .
111
+ * <p>If it reached the end of the stream, returns null .
109
112
*/
110
- private int readLength () throws IOException {
113
+ private @ Nullable String readLengthPrefix () throws IOException {
111
114
int nextOpenBracket ;
112
115
113
116
while ((nextOpenBracket = indexOfOpenBracket ()) == -1 ) {
@@ -119,7 +122,7 @@ private int readLength() throws IOException {
119
122
// We broke out of the loop because underlying stream is closed, and there happens to be no
120
123
// more data to process.
121
124
if (buffer .remaining () == 0 ) {
122
- return - 1 ;
125
+ return null ;
123
126
}
124
127
125
128
// We broke out of the loop because underlying stream is closed, but still cannot find an
@@ -130,14 +133,14 @@ private int readLength() throws IOException {
130
133
131
134
char [] c = new char [nextOpenBracket ];
132
135
buffer .get (c );
133
- return Integer . parseInt ( new String (c ) );
136
+ return new String (c );
134
137
}
135
138
136
139
/** Returns the index of the first open bracket, or -1 if none is found. */
137
140
private int indexOfOpenBracket () {
138
141
buffer .mark ();
139
142
try {
140
- for (int i = 0 ; i < buffer .limit (); ++i ) {
143
+ for (int i = 0 ; i < buffer .remaining (); ++i ) {
141
144
if (buffer .get () == '{' ) {
142
145
return i ;
143
146
}
@@ -155,20 +158,22 @@ private int indexOfOpenBracket() {
155
158
* <p>Returns a string decoded from the read bytes.
156
159
*/
157
160
private String readJsonString (int length ) throws IOException {
158
- char [] c = new char [length ];
159
-
160
- int read = Math .min (length , buffer .remaining ());
161
- buffer .get (c , 0 , read );
161
+ StringBuilder json = new StringBuilder ();
162
162
163
- while (read < length ) {
163
+ int remaining = length ;
164
+ while (remaining > 0 ) {
164
165
if (!pullMoreData ()) {
165
166
raiseError ("Reached the end of bundle when more data was expected." );
166
167
}
167
- int toRead = Math .min (length , buffer .remaining ());
168
- buffer .get (c , read , toRead );
169
- read += toRead ;
168
+
169
+ int read = Math .min (remaining , buffer .remaining ());
170
+ json .append (buffer , 0 , read );
171
+ buffer .position (buffer .position () + read );
172
+
173
+ remaining -= read ;
170
174
}
171
- return new String (c );
175
+
176
+ return json .toString ();
172
177
}
173
178
174
179
/**
@@ -179,14 +184,9 @@ private String readJsonString(int length) throws IOException {
179
184
private boolean pullMoreData () throws IOException {
180
185
if (buffer .remaining () == 0 ) {
181
186
buffer .compact ();
187
+ dataReader .read (buffer );
188
+ buffer .flip ();
182
189
}
183
-
184
- int read ;
185
- do {
186
- read = dataReader .read (buffer );
187
- } while (read > 0 );
188
- buffer .flip ();
189
-
190
190
return buffer .remaining () > 0 ;
191
191
}
192
192
0 commit comments