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     */
017    package org.apache.commons.io.input;
018    
019    import java.io.DataInput;
020    import java.io.EOFException;
021    import java.io.IOException;
022    import java.io.InputStream;
023    
024    import 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     * @author <a href="mailto:peter@apache.org">Peter Donald</a>
034     * @version CVS $Revision: 995160 $ $Date: 2010-09-08 13:15:52 -0400 (Wed, 08 Sep 2010) $
035     */
036    public class SwappedDataInputStream extends ProxyInputStream
037        implements DataInput
038    {
039    
040        /**
041         * Constructs a SwappedDataInputStream.
042         *
043         * @param input InputStream to read from
044         */
045        public SwappedDataInputStream( InputStream input )
046        {
047            super( input );
048        }
049    
050        /**
051         * Return <code>{@link #readByte()} != 0</code>
052         * @return false if the byte read is zero, otherwise true
053         * @throws IOException if an I/O error occurs
054         * @throws EOFException if an end of file is reached unexpectedly
055         */
056        public boolean readBoolean()
057            throws IOException, EOFException
058        {
059            return ( 0 != readByte() );
060        }
061    
062        /**
063         * Invokes the delegate's <code>read()</code> method.
064         * @return the byte read or -1 if the end of stream
065         * @throws IOException if an I/O error occurs
066         * @throws EOFException if an end of file is reached unexpectedly
067         */
068        public byte readByte()
069            throws IOException, EOFException
070        {
071            return (byte)in.read();
072        }
073    
074        /**
075         * Reads a character delegating to {@link #readShort()}.
076         * @return the byte read or -1 if the end of stream
077         * @throws IOException if an I/O error occurs
078         * @throws EOFException if an end of file is reached unexpectedly
079         */
080        public char readChar()
081            throws IOException, EOFException
082        {
083            return (char)readShort();
084        }
085    
086        /**
087         * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}. 
088         * @return the read long
089         * @throws IOException if an I/O error occurs
090         * @throws EOFException if an end of file is reached unexpectedly
091         */
092        public double readDouble()
093            throws IOException, EOFException
094        {
095            return EndianUtils.readSwappedDouble( in );
096        }
097    
098        /**
099         * 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    }