1616package org .glavo .nbt .internal .input ;
1717
1818import org .glavo .nbt .MinecraftEdition ;
19- import org .glavo .nbt .internal .IOUtils ;
20- import org .glavo .nbt .internal .StringCache ;
21- import org .jetbrains .annotations .Nullable ;
2219
2320import java .io .Closeable ;
2421import java .io .IOException ;
2522import java .nio .ByteBuffer ;
2623import java .nio .charset .StandardCharsets ;
2724
28- public final class NBTReader implements Closeable {
29-
30- // Used for reading UTF-8 strings
31- private static final StringCache CACHE = new StringCache (
32- "data" , "Data" , "DataVersion"
33- // TODO: More tag names
34- );
35-
36- private final InputSource source ;
37- private final InputBuffer buffer ;
38- private final MinecraftEdition edition ;
39- private final long initialPosition ;
40-
41- /// Used for reading UTF-8 strings
42- private @ Nullable StringBuilder charsBuffer ;
43-
44- public NBTReader (InputSource source , MinecraftEdition edition ) throws IOException {
45- this .source = source ;
46- this .buffer = InputBuffer .allocate (IOUtils .DEFAULT_BUFFER_SIZE , source .supportDirectBuffer (), edition .byteOrder ());
47- this .edition = edition ;
48-
49- try {
50- this .initialPosition = source .position ();
51- } catch (Throwable e ) {
52- try {
53- source .close ();
54- } catch (IOException e2 ) {
55- e .addSuppressed (e2 );
56- }
57- throw e ;
58- }
59- }
25+ public abstract class DataReader implements Closeable {
26+ final InputContext context ;
27+ final InputBuffer buffer ;
28+ long remainingInput = -1L ;
6029
61- public MinecraftEdition getEdition () {
62- return edition ;
30+ protected DataReader (InputContext context , InputBuffer buffer ) {
31+ this .context = context ;
32+ this .buffer = buffer ;
6333 }
6434
35+ public abstract void ensureBufferRemaining (int required ) throws IOException ;
36+
6537 @ Override
6638 public void close () throws IOException {
67- source .close ();
68- }
69-
70- private void fillBuffer (int required ) throws IOException {
71- source .fillBuffer (buffer , required );
39+ if (remainingInput > 0 ) {
40+ int bufferRemaining = context .rawReader .buffer .remaining ();
41+ if (bufferRemaining > 0 ) {
42+ int bytesDrop = (int ) Math .min (bufferRemaining , remainingInput );
43+ context .rawReader .buffer .drop (bytesDrop );
44+ }
45+ this .remainingInput -= bufferRemaining ;
46+ }
7247 }
7348
7449 public byte [] readByteArray () throws IOException {
@@ -77,7 +52,7 @@ public byte[] readByteArray() throws IOException {
7752 throw new IOException ("Array length too large" );
7853 }
7954
80- fillBuffer (len );
55+ ensureBufferRemaining (len );
8156 return buffer .getByteArray (len );
8257 }
8358
@@ -87,7 +62,7 @@ public int[] readIntArray() throws IOException {
8762 throw new IOException ("Array length too large" );
8863 }
8964
90- fillBuffer (len * Integer .BYTES );
65+ ensureBufferRemaining (len * Integer .BYTES );
9166 return buffer .getIntArray (len );
9267 }
9368
@@ -97,13 +72,13 @@ public long[] readLongArray() throws IOException {
9772 throw new IOException ("Array length too large" );
9873 }
9974
100- fillBuffer (len * Long .BYTES );
75+ ensureBufferRemaining (len * Long .BYTES );
10176 return buffer .getLongArray (len );
10277 }
10378
10479 /// Read a byte from the input stream.
10580 public byte readByte () throws IOException {
106- fillBuffer (Byte .BYTES );
81+ ensureBufferRemaining (Byte .BYTES );
10782 return buffer .getByte ();
10883 }
10984
@@ -114,7 +89,7 @@ public int readUnsignedByte() throws IOException {
11489
11590 /// Read a short from the input stream.
11691 public short readShort () throws IOException {
117- fillBuffer (Short .BYTES );
92+ ensureBufferRemaining (Short .BYTES );
11893 return buffer .getShort ();
11994 }
12095
@@ -125,7 +100,7 @@ public int readUnsignedShort() throws IOException {
125100
126101 /// Read an int from the input stream.
127102 public int readInt () throws IOException {
128- fillBuffer (Integer .BYTES );
103+ ensureBufferRemaining (Integer .BYTES );
129104 return buffer .getInt ();
130105 }
131106
@@ -136,24 +111,24 @@ public long readUnsignedInt() throws IOException {
136111
137112 /// Read a long from the input stream.
138113 public long readLong () throws IOException {
139- fillBuffer (Long .BYTES );
114+ ensureBufferRemaining (Long .BYTES );
140115 return buffer .getLong ();
141116 }
142117
143118 /// Read a float from the input stream.
144119 public float readFloat () throws IOException {
145- fillBuffer (Float .BYTES );
120+ ensureBufferRemaining (Float .BYTES );
146121 return buffer .getFloat ();
147122 }
148123
149124 /// Read a double from the input stream.
150125 public double readDouble () throws IOException {
151- fillBuffer (Double .BYTES );
126+ ensureBufferRemaining (Double .BYTES );
152127 return buffer .getDouble ();
153128 }
154129
155130 private String getUTF8 (ByteBuffer buffer , int offset , int length ) {
156- String cached = CACHE .get (buffer , offset , length );
131+ String cached = context . stringCache .get (buffer , offset , length );
157132 if (cached != null ) {
158133 return cached ;
159134 }
@@ -178,7 +153,7 @@ public String readString() throws IOException {
178153 return "" ;
179154 }
180155
181- fillBuffer (len );
156+ ensureBufferRemaining (len );
182157
183158 ByteBuffer bytes = buffer .bytesBuffer ();
184159 int offset = bytes .position ();
@@ -187,7 +162,7 @@ public String readString() throws IOException {
187162 bytes .position (limit );
188163
189164 // For Minecraft Bedrock Edition, the string is encoded in standard UTF-8
190- if (edition == MinecraftEdition .BEDROCK_EDITION ) {
165+ if (context . edition == MinecraftEdition .BEDROCK_EDITION ) {
191166 return getUTF8 (bytes , offset , len );
192167 }
193168
@@ -207,10 +182,13 @@ public String readString() throws IOException {
207182 }
208183
209184 // Slow path
210- if (charsBuffer != null ) {
211- charsBuffer .setLength (0 );
185+ StringBuilder charsBuffer ;
186+ if (context .charsBuffer != null ) {
187+ charsBuffer = context .charsBuffer ;
188+ context .charsBuffer .setLength (0 );
212189 } else {
213190 charsBuffer = new StringBuilder (len );
191+ context .charsBuffer = charsBuffer ;
214192 }
215193
216194 int c , char2 , char3 ;
@@ -262,5 +240,4 @@ public String readString() throws IOException {
262240 }
263241 return charsBuffer .toString ();
264242 }
265-
266243}
0 commit comments