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 */
17package org.apache.commons.io.input;
18
19import java.io.DataInput;
20import java.io.EOFException;
21import java.io.IOException;
22import java.io.InputStream;
23
24import org.apache.commons.io.EndianUtils;
25
26/**
27 * DataInput for systems relying on little endian data formats.
28 * When read, values will be changed from little endian to big
29 * endian formats for internal usage.
30 * <p>
31 * <b>Origin of code: </b>Avalon Excalibur (IO)
32 *
33 * @author <a href="mailto:peter@apache.org">Peter Donald</a>
34 * @version CVS $Revision: 610010 $ $Date: 2008-01-08 14:50:59 +0000 (Tue, 08 Jan 2008) $
35 */
36public class SwappedDataInputStream extends ProxyInputStream
37    implements DataInput
38{
39
40    /**
41     * Constructs a SwappedDataInputStream.
42     *
43     * @param input InputStream to read from
44     */
45    public SwappedDataInputStream( InputStream input )
46    {
47        super( input );
48    }
49
50    /**
51     * Return <code>{@link #readByte()} == 0</code>
52     * @return the true if the byte read is zero, otherwise false
53     * @throws IOException if an I/O error occurs
54     * @throws EOFException if an end of file is reached unexpectedly
55     */
56    public boolean readBoolean()
57        throws IOException, EOFException
58    {
59        return ( 0 == readByte() );
60    }
61
62    /**
63     * Invokes the delegate's <code>read()</code> method.
64     * @return the byte read or -1 if the end of stream
65     * @throws IOException if an I/O error occurs
66     * @throws EOFException if an end of file is reached unexpectedly
67     */
68    public byte readByte()
69        throws IOException, EOFException
70    {
71        return (byte)in.read();
72    }
73
74    /**
75     * Reads a character delegating to {@link #readShort()}.
76     * @return the byte read or -1 if the end of stream
77     * @throws IOException if an I/O error occurs
78     * @throws EOFException if an end of file is reached unexpectedly
79     */
80    public char readChar()
81        throws IOException, EOFException
82    {
83        return (char)readShort();
84    }
85
86    /**
87     * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}.
88     * @return the read long
89     * @throws IOException if an I/O error occurs
90     * @throws EOFException if an end of file is reached unexpectedly
91     */
92    public double readDouble()
93        throws IOException, EOFException
94    {
95        return EndianUtils.readSwappedDouble( in );
96    }
97
98    /**
99     * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}.
100     * @return the read long
101     * @throws IOException if an I/O error occurs
102     * @throws EOFException if an end of file is reached unexpectedly
103     */
104    public float readFloat()
105        throws IOException, EOFException
106    {
107        return EndianUtils.readSwappedFloat( in );
108    }
109
110    /**
111     * Invokes the delegate's <code>read(byte[] data, int, int)</code> method.
112     *
113     * @param data the buffer to read the bytes into
114     * @throws EOFException if an end of file is reached unexpectedly
115     * @throws IOException if an I/O error occurs
116     */
117    public void readFully( byte[] data )
118        throws IOException, EOFException
119    {
120        readFully( data, 0, data.length );
121    }
122
123
124    /**
125     * Invokes the delegate's <code>read(byte[] data, int, int)</code> method.
126     *
127     * @param data the buffer to read the bytes into
128     * @param offset The start offset
129     * @param length The number of bytes to read
130     * @throws EOFException if an end of file is reached unexpectedly
131     * @throws IOException if an I/O error occurs
132     */
133    public void readFully( byte[] data, int offset, int length )
134        throws IOException, EOFException
135    {
136        int remaining = length;
137
138        while( remaining > 0 )
139        {
140            int location = offset + ( length - remaining );
141            int count = read( data, location, remaining );
142
143            if( -1 == count )
144            {
145                throw new EOFException();
146            }
147
148            remaining -= count;
149        }
150    }
151
152    /**
153     * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}.
154     * @return the read long
155     * @throws EOFException if an end of file is reached unexpectedly
156     * @throws IOException if an I/O error occurs
157     */
158    public int readInt()
159        throws IOException, EOFException
160    {
161        return EndianUtils.readSwappedInteger( in );
162    }
163
164    /**
165     * Not currently supported - throws {@link UnsupportedOperationException}.
166     * @return the line read
167     * @throws EOFException if an end of file is reached unexpectedly
168     * @throws IOException if an I/O error occurs
169     */
170    public String readLine()
171        throws IOException, EOFException
172    {
173        throw new UnsupportedOperationException(
174                "Operation not supported: readLine()" );
175    }
176
177    /**
178     * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}.
179     * @return the read long
180     * @throws EOFException if an end of file is reached unexpectedly
181     * @throws IOException if an I/O error occurs
182     */
183    public long readLong()
184        throws IOException, EOFException
185    {
186        return EndianUtils.readSwappedLong( in );
187    }
188
189    /**
190     * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}.
191     * @return the read long
192     * @throws EOFException if an end of file is reached unexpectedly
193     * @throws IOException if an I/O error occurs
194     */
195    public short readShort()
196        throws IOException, EOFException
197    {
198        return EndianUtils.readSwappedShort( in );
199    }
200
201    /**
202     * Invokes the delegate's <code>read()</code> method.
203     * @return the byte read or -1 if the end of stream
204     * @throws EOFException if an end of file is reached unexpectedly
205     * @throws IOException if an I/O error occurs
206     */
207    public int readUnsignedByte()
208        throws IOException, EOFException
209    {
210        return in.read();
211    }
212
213    /**
214     * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}.
215     * @return the read long
216     * @throws EOFException if an end of file is reached unexpectedly
217     * @throws IOException if an I/O error occurs
218     */
219    public int readUnsignedShort()
220        throws IOException, EOFException
221    {
222        return EndianUtils.readSwappedUnsignedShort( in );
223    }
224
225    /**
226     * Not currently supported - throws {@link UnsupportedOperationException}.
227     * @return UTF String read
228     * @throws EOFException if an end of file is reached unexpectedly
229     * @throws IOException if an I/O error occurs
230     */
231    public String readUTF()
232        throws IOException, EOFException
233    {
234        throw new UnsupportedOperationException(
235                "Operation not supported: readUTF()" );
236    }
237
238    /**
239     * Invokes the delegate's <code>skip(int)</code> method.
240     * @param count the number of bytes to skip
241     * @return the number of bytes to skipped or -1 if the end of stream
242     * @throws EOFException if an end of file is reached unexpectedly
243     * @throws IOException if an I/O error occurs
244     */
245    public int skipBytes( int count )
246        throws IOException, EOFException
247    {
248        return (int)in.skip( count );
249    }
250
251}
252