11package mil .nga .sf .util ;
22
3- import java .io .UnsupportedEncodingException ;
3+ import java .io .ByteArrayInputStream ;
4+ import java .io .IOException ;
5+ import java .io .InputStream ;
46import java .nio .ByteBuffer ;
57import java .nio .ByteOrder ;
8+ import java .util .logging .Level ;
9+ import java .util .logging .Logger ;
610
711/**
812 * Read through a byte array
1115 */
1216public class ByteReader {
1317
18+ /**
19+ * Logger
20+ */
21+ private static final Logger logger = Logger
22+ .getLogger (ByteReader .class .getName ());
23+
1424 /**
1525 * Character set
1626 */
1727 private static final String CHAR_SET = "UTF-8" ;
1828
1929 /**
20- * Next byte index to read
30+ * Bytes to read from
2131 */
22- private int nextByte = 0 ;
32+ private final byte [] bytes ;
2333
2434 /**
25- * Bytes to read
35+ * Input stream to read bytes from
2636 */
27- private final byte [] bytes ;
37+ private final InputStream inputStream ;
38+
39+ /**
40+ * Next byte index to read
41+ */
42+ private int nextByte = 0 ;
2843
2944 /**
3045 * Byte order
@@ -39,6 +54,83 @@ public class ByteReader {
3954 */
4055 public ByteReader (byte [] bytes ) {
4156 this .bytes = bytes ;
57+ inputStream = new ByteArrayInputStream (bytes );
58+ }
59+
60+ /**
61+ * Constructor
62+ *
63+ * @param inputStream
64+ * input stream
65+ * @since 2.0.3
66+ */
67+ public ByteReader (InputStream inputStream ) {
68+ this .bytes = null ;
69+ this .inputStream = inputStream ;
70+ }
71+
72+ /**
73+ * Constructor
74+ *
75+ * @param bytes
76+ * bytes
77+ * @param byteOrder
78+ * byte order
79+ * @since 2.0.3
80+ */
81+ public ByteReader (byte [] bytes , ByteOrder byteOrder ) {
82+ this (bytes );
83+ this .byteOrder = byteOrder ;
84+ }
85+
86+ /**
87+ * Constructor
88+ *
89+ * @param inputStream
90+ * input stream
91+ * @param byteOrder
92+ * byte order
93+ * @since 2.0.3
94+ */
95+ public ByteReader (InputStream inputStream , ByteOrder byteOrder ) {
96+ this (inputStream );
97+ this .byteOrder = byteOrder ;
98+ }
99+
100+ /**
101+ * Get the bytes
102+ *
103+ * @return bytes
104+ *
105+ * @since 2.0.3
106+ */
107+ public byte [] getBytes () {
108+ return bytes ;
109+ }
110+
111+ /**
112+ * Get the output stream
113+ *
114+ * @return output stream
115+ *
116+ * @since 2.0.3
117+ */
118+ public InputStream getInputStream () {
119+ return inputStream ;
120+ }
121+
122+ /**
123+ * Close the byte reader
124+ *
125+ * @since 2.0.3
126+ */
127+ public void close () {
128+ try {
129+ inputStream .close ();
130+ } catch (IOException e ) {
131+ logger .log (Level .WARNING ,
132+ "Failed to close byte reader intput stream" , e );
133+ }
42134 }
43135
44136 /**
@@ -75,47 +167,60 @@ public void setByteOrder(ByteOrder byteOrder) {
75167 * @param num
76168 * number of bytes
77169 * @return String
78- * @throws UnsupportedEncodingException
170+ * @throws IOException
171+ * upon error
172+ */
173+ public String readString (int num ) throws IOException {
174+ return new String (readBytes (num ), CHAR_SET );
175+ }
176+
177+ /**
178+ * Read the number of bytes
179+ *
180+ * @param num
181+ * number of bytes
182+ * @return bytes
183+ * @throws IOException
79184 * upon error
80185 */
81- public String readString (int num ) throws UnsupportedEncodingException {
186+ public byte [] readBytes (int num ) throws IOException {
82187 verifyRemainingBytes (num );
83- String value = new String (bytes , nextByte , num , CHAR_SET );
188+ byte [] bytes = new byte [num ];
189+ inputStream .read (bytes );
84190 nextByte += num ;
85- return value ;
191+ return bytes ;
86192 }
87193
88194 /**
89195 * Read a byte
90196 *
91197 * @return byte
198+ * @throws IOException
199+ * upon error
92200 */
93- public byte readByte () {
94- verifyRemainingBytes (1 );
95- byte value = bytes [nextByte ];
96- nextByte ++;
97- return value ;
201+ public byte readByte () throws IOException {
202+ return readBytes (1 )[0 ];
98203 }
99204
100205 /**
101206 * Read an integer
102207 *
103208 * @return integer
209+ * @throws IOException
210+ * upon error
104211 */
105- public int readInt () {
106- verifyRemainingBytes (4 );
107- int value = ByteBuffer .wrap (bytes , nextByte , 4 ).order (byteOrder )
108- .getInt ();
109- nextByte += 4 ;
110- return value ;
212+ public int readInt () throws IOException {
213+ return ByteBuffer .wrap (readBytes (4 )).order (byteOrder ).getInt ();
111214 }
112215
113216 /**
114217 * Read an unsigned integer
115218 *
116219 * @return unsigned integer
220+ * @throws IOException
221+ * upon error
117222 */
118- public long readUnsignedInt () {
223+ public long readUnsignedInt () throws IOException {
119224 int intValue = readInt ();
120225 long value = intValue & 0xffffffffL ;
121226 return value ;
@@ -125,13 +230,11 @@ public long readUnsignedInt() {
125230 * Read a double
126231 *
127232 * @return double
233+ * @throws IOException
234+ * upon error
128235 */
129- public double readDouble () {
130- verifyRemainingBytes (8 );
131- double value = ByteBuffer .wrap (bytes , nextByte , 8 ).order (byteOrder )
132- .getDouble ();
133- nextByte += 8 ;
134- return value ;
236+ public double readDouble () throws IOException {
237+ return ByteBuffer .wrap (readBytes (8 )).order (byteOrder ).getDouble ();
135238 }
136239
137240 /**
@@ -142,11 +245,11 @@ public double readDouble() {
142245 * number of bytes to read
143246 */
144247 private void verifyRemainingBytes (int bytesToRead ) {
145- if (nextByte + bytesToRead > bytes .length ) {
248+ if (bytes != null && nextByte + bytesToRead > bytes .length ) {
146249 throw new SFException (
147250 "No more remaining bytes to read. Total Bytes: "
148- + bytes .length + ", Bytes already read: "
149- + nextByte + ", Attempted to read: " + bytesToRead );
251+ + bytes .length + ", Bytes already read: " + nextByte
252+ + ", Attempted to read: " + bytesToRead );
150253 }
151254 }
152255
0 commit comments