View Javadoc
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    *      http://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</code>
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 }