1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.io.input;
18
19 import static org.apache.commons.io.IOUtils.EOF;
20
21 import java.io.DataInput;
22 import java.io.EOFException;
23 import java.io.IOException;
24 import java.io.InputStream;
25
26 import org.apache.commons.io.EndianUtils;
27
28 /**
29 * DataInput for systems relying on little-endian data formats. When read, values will be changed from little-endian to
30 * big-endian formats for internal usage.
31 * <p>
32 * Provenance: Avalon Excalibur (IO)
33 * </p>
34 */
35 public class SwappedDataInputStream extends ProxyInputStream implements DataInput {
36
37 /**
38 * Constructs a SwappedDataInputStream.
39 *
40 * @param input InputStream to read from
41 */
42 public SwappedDataInputStream(final InputStream input) {
43 super(input);
44 }
45
46 /**
47 * Return {@code {@link #readByte()} != 0}
48 *
49 * @return false if the byte read is zero, otherwise true
50 * @throws IOException if an I/O error occurs.
51 * @throws EOFException if an end of file is reached unexpectedly
52 */
53 @Override
54 public boolean readBoolean() throws IOException, EOFException {
55 return 0 != readByte();
56 }
57
58 /**
59 * Invokes the delegate's {@code read()} method.
60 *
61 * @return the byte read or -1 if the end of stream
62 * @throws IOException if an I/O error occurs.
63 * @throws EOFException if an end of file is reached unexpectedly
64 */
65 @Override
66 public byte readByte() throws IOException, EOFException {
67 return (byte) in.read();
68 }
69
70 /**
71 * Reads a 2 byte, unsigned, little-endian UTF-16 code point.
72 *
73 * @return the UTF-16 code point read or -1 if the end of stream
74 * @throws IOException if an I/O error occurs.
75 * @throws EOFException if an end of file is reached unexpectedly
76 */
77 @Override
78 public char readChar() throws IOException, EOFException {
79 return (char) readShort();
80 }
81
82 /**
83 * Reads an 8 byte, two's complement, little-endian long.
84 *
85 * @return the read long
86 * @throws IOException if an I/O error occurs.
87 * @throws EOFException if an end of file is reached unexpectedly
88 */
89 @Override
90 public double readDouble() throws IOException, EOFException {
91 return EndianUtils.readSwappedDouble(in);
92 }
93
94 /**
95 * Reads a 4 byte, IEEE 754, little-endian float.
96 *
97 * @return the read float
98 * @throws IOException if an I/O error occurs.
99 * @throws EOFException if an end of file is reached unexpectedly
100 */
101 @Override
102 public float readFloat() throws IOException, EOFException {
103 return EndianUtils.readSwappedFloat(in);
104 }
105
106 /**
107 * Invokes the delegate's {@code read(byte[] data, int, int)} method.
108 *
109 * @param data the buffer to read the bytes into
110 * @throws EOFException if an end of file is reached unexpectedly
111 * @throws IOException if an I/O error occurs.
112 */
113 @Override
114 public void readFully(final byte[] data) throws IOException, EOFException {
115 readFully(data, 0, data.length);
116 }
117
118 /**
119 * Invokes the delegate's {@code read(byte[] data, int, int)} method.
120 *
121 * @param data the buffer to read the bytes into
122 * @param offset The start offset
123 * @param length The number of bytes to read
124 * @throws EOFException if an end of file is reached unexpectedly
125 * @throws IOException if an I/O error occurs.
126 */
127 @Override
128 public void readFully(final byte[] data, final int offset, final int length) throws IOException, EOFException {
129 int remaining = length;
130
131 while (remaining > 0) {
132 final int location = offset + length - remaining;
133 final int count = read(data, location, remaining);
134
135 if (EOF == count) {
136 throw new EOFException();
137 }
138
139 remaining -= count;
140 }
141 }
142
143 /**
144 * Reads a 4 byte, two's complement little-endian integer.
145 *
146 * @return the read int
147 * @throws EOFException if an end of file is reached unexpectedly
148 * @throws IOException if an I/O error occurs.
149 */
150 @Override
151 public int readInt() throws IOException, EOFException {
152 return EndianUtils.readSwappedInteger(in);
153 }
154
155 /**
156 * Not currently supported - throws {@link UnsupportedOperationException}.
157 *
158 * @return the line read
159 * @throws EOFException if an end of file is reached unexpectedly
160 * @throws IOException if an I/O error occurs
161 * @throws UnsupportedOperationException always
162 */
163 @Override
164 public String readLine() throws IOException, EOFException {
165 throw UnsupportedOperationExceptions.method("readLine");
166 }
167
168 /**
169 * Reads an 8 byte, two's complement little-endian integer.
170 *
171 * @return the read long
172 * @throws EOFException if an end of file is reached unexpectedly
173 * @throws IOException if an I/O error occurs.
174 */
175 @Override
176 public long readLong() throws IOException, EOFException {
177 return EndianUtils.readSwappedLong(in);
178 }
179
180 /**
181 * Reads a 2 byte, two's complement, little-endian integer.
182 *
183 * @return the read short
184 * @throws EOFException if an end of file is reached unexpectedly
185 * @throws IOException if an I/O error occurs.
186 */
187 @Override
188 public short readShort() throws IOException, EOFException {
189 return EndianUtils.readSwappedShort(in);
190 }
191
192 /**
193 * Invokes the delegate's {@code read()} method.
194 *
195 * @return the byte read or -1 if the end of stream
196 * @throws EOFException if an end of file is reached unexpectedly
197 * @throws IOException if an I/O error occurs.
198 */
199 @Override
200 public int readUnsignedByte() throws IOException, EOFException {
201 return in.read();
202 }
203
204 /**
205 * Reads a 2 byte, unsigned, little-endian integer.
206 *
207 * @return the read short
208 * @throws EOFException if an end of file is reached unexpectedly
209 * @throws IOException if an I/O error occurs.
210 */
211 @Override
212 public int readUnsignedShort() throws IOException, EOFException {
213 return EndianUtils.readSwappedUnsignedShort(in);
214 }
215
216 /**
217 * Not currently supported - throws {@link UnsupportedOperationException}.
218 *
219 * @return never
220 * @throws EOFException if an end of file is reached unexpectedly
221 * @throws IOException if an I/O error occurs
222 * @throws UnsupportedOperationException always
223 */
224 @Override
225 public String readUTF() throws IOException, EOFException {
226 throw UnsupportedOperationExceptions.method("readUTF");
227 }
228
229 /**
230 * Invokes the delegate's {@code skip(int)} method.
231 *
232 * @param count the number of bytes to skip
233 * @return the number of bytes skipped or -1 if the end of stream
234 * @throws IOException if an I/O error occurs
235 */
236 @Override
237 public int skipBytes(final int count) throws IOException {
238 return (int) in.skip(count);
239 }
240
241 }