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     * @version CVS $Revision: 1302050 $
034     */
035    public 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    }