source: josm/trunk/src/com/drew/lang/SequentialReader.java@ 10862

Last change on this file since 10862 was 10862, checked in by Don-vip, 8 years ago

update to metadata-extractor 2.9.1

File size: 10.8 KB
Line 
1/*
2 * Copyright 2002-2016 Drew Noakes
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * More information about this project is available at:
17 *
18 * https://drewnoakes.com/code/exif/
19 * https://github.com/drewnoakes/metadata-extractor
20 */
21
22package com.drew.lang;
23
24import com.drew.lang.annotations.NotNull;
25
26import java.io.EOFException;
27import java.io.IOException;
28import java.io.UnsupportedEncodingException;
29
30/**
31 * @author Drew Noakes https://drewnoakes.com
32 */
33public abstract class SequentialReader
34{
35 // TODO review whether the masks are needed (in both this and RandomAccessReader)
36
37 private boolean _isMotorolaByteOrder = true;
38
39 /**
40 * Gets the next byte in the sequence.
41 *
42 * @return The read byte value
43 */
44 protected abstract byte getByte() throws IOException;
45
46 /**
47 * Returns the required number of bytes from the sequence.
48 *
49 * @param count The number of bytes to be returned
50 * @return The requested bytes
51 */
52 @NotNull
53 public abstract byte[] getBytes(int count) throws IOException;
54
55 /**
56 * Skips forward in the sequence. If the sequence ends, an {@link EOFException} is thrown.
57 *
58 * @param n the number of byte to skip. Must be zero or greater.
59 * @throws EOFException the end of the sequence is reached.
60 * @throws IOException an error occurred reading from the underlying source.
61 */
62 public abstract void skip(long n) throws IOException;
63
64 /**
65 * Skips forward in the sequence, returning a boolean indicating whether the skip succeeded, or whether the sequence ended.
66 *
67 * @param n the number of byte to skip. Must be zero or greater.
68 * @return a boolean indicating whether the skip succeeded, or whether the sequence ended.
69 * @throws IOException an error occurred reading from the underlying source.
70 */
71 public abstract boolean trySkip(long n) throws IOException;
72
73 /**
74 * Sets the endianness of this reader.
75 * <ul>
76 * <li><code>true</code> for Motorola (or big) endianness (also known as network byte order), with MSB before LSB.</li>
77 * <li><code>false</code> for Intel (or little) endianness, with LSB before MSB.</li>
78 * </ul>
79 *
80 * @param motorolaByteOrder <code>true</code> for Motorola/big endian, <code>false</code> for Intel/little endian
81 */
82 public void setMotorolaByteOrder(boolean motorolaByteOrder)
83 {
84 _isMotorolaByteOrder = motorolaByteOrder;
85 }
86
87 /**
88 * Gets the endianness of this reader.
89 * <ul>
90 * <li><code>true</code> for Motorola (or big) endianness (also known as network byte order), with MSB before LSB.</li>
91 * <li><code>false</code> for Intel (or little) endianness, with LSB before MSB.</li>
92 * </ul>
93 */
94 public boolean isMotorolaByteOrder()
95 {
96 return _isMotorolaByteOrder;
97 }
98
99 /**
100 * Returns an unsigned 8-bit int calculated from the next byte of the sequence.
101 *
102 * @return the 8 bit int value, between 0 and 255
103 */
104 public short getUInt8() throws IOException
105 {
106 return (short) (getByte() & 0xFF);
107 }
108
109 /**
110 * Returns a signed 8-bit int calculated from the next byte the sequence.
111 *
112 * @return the 8 bit int value, between 0x00 and 0xFF
113 */
114 public byte getInt8() throws IOException
115 {
116 return getByte();
117 }
118
119 /**
120 * Returns an unsigned 16-bit int calculated from the next two bytes of the sequence.
121 *
122 * @return the 16 bit int value, between 0x0000 and 0xFFFF
123 */
124 public int getUInt16() throws IOException
125 {
126 if (_isMotorolaByteOrder) {
127 // Motorola - MSB first
128 return (getByte() << 8 & 0xFF00) |
129 (getByte() & 0xFF);
130 } else {
131 // Intel ordering - LSB first
132 return (getByte() & 0xFF) |
133 (getByte() << 8 & 0xFF00);
134 }
135 }
136
137 /**
138 * Returns a signed 16-bit int calculated from two bytes of data (MSB, LSB).
139 *
140 * @return the 16 bit int value, between 0x0000 and 0xFFFF
141 * @throws IOException the buffer does not contain enough bytes to service the request
142 */
143 public short getInt16() throws IOException
144 {
145 if (_isMotorolaByteOrder) {
146 // Motorola - MSB first
147 return (short) (((short)getByte() << 8 & (short)0xFF00) |
148 ((short)getByte() & (short)0xFF));
149 } else {
150 // Intel ordering - LSB first
151 return (short) (((short)getByte() & (short)0xFF) |
152 ((short)getByte() << 8 & (short)0xFF00));
153 }
154 }
155
156 /**
157 * Get a 32-bit unsigned integer from the buffer, returning it as a long.
158 *
159 * @return the unsigned 32-bit int value as a long, between 0x00000000 and 0xFFFFFFFF
160 * @throws IOException the buffer does not contain enough bytes to service the request
161 */
162 public long getUInt32() throws IOException
163 {
164 if (_isMotorolaByteOrder) {
165 // Motorola - MSB first (big endian)
166 return (((long)getByte()) << 24 & 0xFF000000L) |
167 (((long)getByte()) << 16 & 0xFF0000L) |
168 (((long)getByte()) << 8 & 0xFF00L) |
169 (((long)getByte()) & 0xFFL);
170 } else {
171 // Intel ordering - LSB first (little endian)
172 return (((long)getByte()) & 0xFFL) |
173 (((long)getByte()) << 8 & 0xFF00L) |
174 (((long)getByte()) << 16 & 0xFF0000L) |
175 (((long)getByte()) << 24 & 0xFF000000L);
176 }
177 }
178
179 /**
180 * Returns a signed 32-bit integer from four bytes of data.
181 *
182 * @return the signed 32 bit int value, between 0x00000000 and 0xFFFFFFFF
183 * @throws IOException the buffer does not contain enough bytes to service the request
184 */
185 public int getInt32() throws IOException
186 {
187 if (_isMotorolaByteOrder) {
188 // Motorola - MSB first (big endian)
189 return (getByte() << 24 & 0xFF000000) |
190 (getByte() << 16 & 0xFF0000) |
191 (getByte() << 8 & 0xFF00) |
192 (getByte() & 0xFF);
193 } else {
194 // Intel ordering - LSB first (little endian)
195 return (getByte() & 0xFF) |
196 (getByte() << 8 & 0xFF00) |
197 (getByte() << 16 & 0xFF0000) |
198 (getByte() << 24 & 0xFF000000);
199 }
200 }
201
202 /**
203 * Get a signed 64-bit integer from the buffer.
204 *
205 * @return the 64 bit int value, between 0x0000000000000000 and 0xFFFFFFFFFFFFFFFF
206 * @throws IOException the buffer does not contain enough bytes to service the request
207 */
208 public long getInt64() throws IOException
209 {
210 if (_isMotorolaByteOrder) {
211 // Motorola - MSB first
212 return ((long)getByte() << 56 & 0xFF00000000000000L) |
213 ((long)getByte() << 48 & 0xFF000000000000L) |
214 ((long)getByte() << 40 & 0xFF0000000000L) |
215 ((long)getByte() << 32 & 0xFF00000000L) |
216 ((long)getByte() << 24 & 0xFF000000L) |
217 ((long)getByte() << 16 & 0xFF0000L) |
218 ((long)getByte() << 8 & 0xFF00L) |
219 ((long)getByte() & 0xFFL);
220 } else {
221 // Intel ordering - LSB first
222 return ((long)getByte() & 0xFFL) |
223 ((long)getByte() << 8 & 0xFF00L) |
224 ((long)getByte() << 16 & 0xFF0000L) |
225 ((long)getByte() << 24 & 0xFF000000L) |
226 ((long)getByte() << 32 & 0xFF00000000L) |
227 ((long)getByte() << 40 & 0xFF0000000000L) |
228 ((long)getByte() << 48 & 0xFF000000000000L) |
229 ((long)getByte() << 56 & 0xFF00000000000000L);
230 }
231 }
232
233 /**
234 * Gets a s15.16 fixed point float from the buffer.
235 * <p>
236 * This particular fixed point encoding has one sign bit, 15 numerator bits and 16 denominator bits.
237 *
238 * @return the floating point value
239 * @throws IOException the buffer does not contain enough bytes to service the request
240 */
241 public float getS15Fixed16() throws IOException
242 {
243 if (_isMotorolaByteOrder) {
244 float res = (getByte() & 0xFF) << 8 |
245 (getByte() & 0xFF);
246 int d = (getByte() & 0xFF) << 8 |
247 (getByte() & 0xFF);
248 return (float)(res + d/65536.0);
249 } else {
250 // this particular branch is untested
251 int d = (getByte() & 0xFF) |
252 (getByte() & 0xFF) << 8;
253 float res = (getByte() & 0xFF) |
254 (getByte() & 0xFF) << 8;
255 return (float)(res + d/65536.0);
256 }
257 }
258
259 public float getFloat32() throws IOException
260 {
261 return Float.intBitsToFloat(getInt32());
262 }
263
264 public double getDouble64() throws IOException
265 {
266 return Double.longBitsToDouble(getInt64());
267 }
268
269 @NotNull
270 public String getString(int bytesRequested) throws IOException
271 {
272 return new String(getBytes(bytesRequested));
273 }
274
275 @NotNull
276 public String getString(int bytesRequested, String charset) throws IOException
277 {
278 byte[] bytes = getBytes(bytesRequested);
279 try {
280 return new String(bytes, charset);
281 } catch (UnsupportedEncodingException e) {
282 return new String(bytes);
283 }
284 }
285
286 /**
287 * Creates a String from the stream, ending where <code>byte=='\0'</code> or where <code>length==maxLength</code>.
288 *
289 * @param maxLengthBytes The maximum number of bytes to read. If a zero-byte is not reached within this limit,
290 * reading will stop and the string will be truncated to this length.
291 * @return The read string.
292 * @throws IOException The buffer does not contain enough bytes to satisfy this request.
293 */
294 @NotNull
295 public String getNullTerminatedString(int maxLengthBytes) throws IOException
296 {
297 // NOTE currently only really suited to single-byte character strings
298
299 byte[] bytes = new byte[maxLengthBytes];
300
301 // Count the number of non-null bytes
302 int length = 0;
303 while (length < bytes.length && (bytes[length] = getByte()) != '\0')
304 length++;
305
306 return new String(bytes, 0, length);
307 }
308}
Note: See TracBrowser for help on using the repository browser.