001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 * 
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 * 
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.io.input;
018
019import java.io.DataInput;
020import java.io.EOFException;
021import java.io.IOException;
022import java.io.InputStream;
023
024import org.apache.commons.io.EndianUtils;
025
026/**
027 * DataInput for systems relying on little endian data formats.
028 * When read, values will be changed from little endian to big 
029 * endian formats for internal usage. 
030 * <p>
031 * <b>Origin of code: </b>Avalon Excalibur (IO)
032 *
033 * @version CVS $Revision: 1302050 $
034 */
035public class SwappedDataInputStream extends ProxyInputStream
036    implements DataInput
037{
038
039    /**
040     * Constructs a SwappedDataInputStream.
041     *
042     * @param input InputStream to read from
043     */
044    public SwappedDataInputStream( InputStream input )
045    {
046        super( input );
047    }
048
049    /**
050     * Return <code>{@link #readByte()} != 0</code>
051     * @return false if the byte read is zero, otherwise true
052     * @throws IOException if an I/O error occurs
053     * @throws EOFException if an end of file is reached unexpectedly
054     */
055    public boolean readBoolean()
056        throws IOException, EOFException
057    {
058        return 0 != readByte();
059    }
060
061    /**
062     * Invokes the delegate's <code>read()</code> method.
063     * @return the byte read or -1 if the end of stream
064     * @throws IOException if an I/O error occurs
065     * @throws EOFException if an end of file is reached unexpectedly
066     */
067    public byte readByte()
068        throws IOException, EOFException
069    {
070        return (byte)in.read();
071    }
072
073    /**
074     * Reads a character delegating to {@link #readShort()}.
075     * @return the byte read or -1 if the end of stream
076     * @throws IOException if an I/O error occurs
077     * @throws EOFException if an end of file is reached unexpectedly
078     */
079    public char readChar()
080        throws IOException, EOFException
081    {
082        return (char)readShort();
083    }
084
085    /**
086     * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}. 
087     * @return the read long
088     * @throws IOException if an I/O error occurs
089     * @throws EOFException if an end of file is reached unexpectedly
090     */
091    public double readDouble()
092        throws IOException, EOFException
093    {
094        return EndianUtils.readSwappedDouble( in );
095    }
096
097    /**
098     * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}. 
099     * @return the read long
100     * @throws IOException if an I/O error occurs
101     * @throws EOFException if an end of file is reached unexpectedly
102     */
103    public float readFloat()
104        throws IOException, EOFException
105    {
106        return EndianUtils.readSwappedFloat( in );
107    }
108
109    /**
110     * Invokes the delegate's <code>read(byte[] data, int, int)</code> method.
111     * 
112     * @param data the buffer to read the bytes into
113     * @throws EOFException if an end of file is reached unexpectedly
114     * @throws IOException if an I/O error occurs
115     */
116    public void readFully( byte[] data )
117        throws IOException, EOFException
118    {
119        readFully( data, 0, data.length );
120    }
121
122
123    /**
124     * Invokes the delegate's <code>read(byte[] data, int, int)</code> method.
125     * 
126     * @param data the buffer to read the bytes into
127     * @param offset The start offset
128     * @param length The number of bytes to read
129     * @throws EOFException if an end of file is reached unexpectedly
130     * @throws IOException if an I/O error occurs
131     */
132    public void readFully( byte[] data, int offset, int length )
133        throws IOException, EOFException
134    {
135        int remaining = length;
136
137        while( remaining > 0 )
138        {
139            int location = offset + length - remaining;
140            int count = read( data, location, remaining );
141
142            if( -1 == count )
143            {
144                throw new EOFException();
145            }
146
147            remaining -= count;
148        }
149    }
150
151    /**
152     * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}. 
153     * @return the read long
154     * @throws EOFException if an end of file is reached unexpectedly
155     * @throws IOException if an I/O error occurs
156     */
157    public int readInt()
158        throws IOException, EOFException
159    {
160        return EndianUtils.readSwappedInteger( in );
161    }
162
163    /**
164     * Not currently supported - throws {@link UnsupportedOperationException}.
165     * @return the line read
166     * @throws EOFException if an end of file is reached unexpectedly
167     * @throws IOException if an I/O error occurs
168     */
169    public String readLine()
170        throws IOException, EOFException
171    {
172        throw new UnsupportedOperationException( 
173                "Operation not supported: readLine()" );
174    }
175
176    /**
177     * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}. 
178     * @return the read long
179     * @throws EOFException if an end of file is reached unexpectedly
180     * @throws IOException if an I/O error occurs
181     */
182    public long readLong()
183        throws IOException, EOFException
184    {
185        return EndianUtils.readSwappedLong( in );
186    }
187
188    /**
189     * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}. 
190     * @return the read long
191     * @throws EOFException if an end of file is reached unexpectedly
192     * @throws IOException if an I/O error occurs
193     */
194    public short readShort()
195        throws IOException, EOFException
196    {
197        return EndianUtils.readSwappedShort( in );
198    }
199
200    /**
201     * Invokes the delegate's <code>read()</code> method.
202     * @return the byte read or -1 if the end of stream
203     * @throws EOFException if an end of file is reached unexpectedly
204     * @throws IOException if an I/O error occurs
205     */
206    public int readUnsignedByte()
207        throws IOException, EOFException
208    {
209        return in.read();
210    }
211
212    /**
213     * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}. 
214     * @return the read long
215     * @throws EOFException if an end of file is reached unexpectedly
216     * @throws IOException if an I/O error occurs
217     */
218    public int readUnsignedShort()
219        throws IOException, EOFException
220    {
221        return EndianUtils.readSwappedUnsignedShort( in );
222    }
223
224    /**
225     * Not currently supported - throws {@link UnsupportedOperationException}.
226     * @return UTF String read
227     * @throws EOFException if an end of file is reached unexpectedly
228     * @throws IOException if an I/O error occurs
229     */
230    public String readUTF()
231        throws IOException, EOFException
232    {
233        throw new UnsupportedOperationException( 
234                "Operation not supported: readUTF()" );
235    }
236
237    /**
238     * Invokes the delegate's <code>skip(int)</code> method.
239     * @param count the number of bytes to skip
240     * @return the number of bytes to skipped or -1 if the end of stream
241     * @throws EOFException if an end of file is reached unexpectedly
242     * @throws IOException if an I/O error occurs
243     */
244    public int skipBytes( int count )
245        throws IOException, EOFException
246    {
247        return (int)in.skip( count );
248    }
249
250}