    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 static org.apache.commons.io.IOUtils.EOF;
    020
    021import java.io.DataInput;
    022import java.io.EOFException;
    023import java.io.IOException;
    024import java.io.InputStream;
    025
    026import org.apache.commons.io.EndianUtils;
    027
    028/**
    029 * DataInput for systems relying on little endian data formats.
    030 * When read, values will be changed from little endian to big
    031 * endian formats for internal usage.
    032 * <p>
    033 * <b>Origin of code: </b>Avalon Excalibur (IO)
    034 *
    035 */
    036public 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( final 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    @Override
    057    public boolean readBoolean()
    058        throws IOException, EOFException
    059    {
    060        return 0 != readByte();
    061    }
    062
    063    /**
    064     * Invokes the delegate's <code>read()</code> method.
    065     * @return the byte read or -1 if the end of stream
    066     * @throws IOException if an I/O error occurs
    067     * @throws EOFException if an end of file is reached unexpectedly
    068     */
    069    @Override
    070    public byte readByte()
    071        throws IOException, EOFException
    072    {
    073        return (byte)in.read();
    074    }
    075
    076    /**
    077     * Reads a character delegating to {@link #readShort()}.
    078     * @return the byte read or -1 if the end of stream
    079     * @throws IOException if an I/O error occurs
    080     * @throws EOFException if an end of file is reached unexpectedly
    081     */
    082    @Override
    083    public char readChar()
    084        throws IOException, EOFException
    085    {
    086        return (char)readShort();
    087    }
    088
    089    /**
    090     * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}.
    091     * @return the read long
    092     * @throws IOException if an I/O error occurs
    093     * @throws EOFException if an end of file is reached unexpectedly
    094     */
    095    @Override
    096    public double readDouble()
    097        throws IOException, EOFException
    098    {
    099        return EndianUtils.readSwappedDouble( in );
    100    }
    101
    102    /**
    103     * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}.
    104     * @return the read long
    105     * @throws IOException if an I/O error occurs
    106     * @throws EOFException if an end of file is reached unexpectedly
    107     */
    108    @Override
    109    public float readFloat()
    110        throws IOException, EOFException
    111    {
    112        return EndianUtils.readSwappedFloat( in );
    113    }
    114
    115    /**
    116     * Invokes the delegate's <code>read(byte[] data, int, int)</code> method.
    117     *
    118     * @param data the buffer to read the bytes into
    119     * @throws EOFException if an end of file is reached unexpectedly
    120     * @throws IOException if an I/O error occurs
    121     */
    122    @Override
    123    public void readFully( final byte[] data )
    124        throws IOException, EOFException
    125    {
    126        readFully( data, 0, data.length );
    127    }
    128
    129
    130    /**
    131     * Invokes the delegate's <code>read(byte[] data, int, int)</code> method.
    132     *
    133     * @param data the buffer to read the bytes into
    134     * @param offset The start offset
    135     * @param length The number of bytes to read
    136     * @throws EOFException if an end of file is reached unexpectedly
    137     * @throws IOException if an I/O error occurs
    138     */
    139    @Override
    140    public void readFully( final byte[] data, final int offset, final int length )
    141        throws IOException, EOFException
    142    {
    143        int remaining = length;
    144
    145        while( remaining > 0 )
    146        {
    147            final int location = offset + length - remaining;
    148            final int count = read( data, location, remaining );
    149
    150            if (EOF == count)
    151            {
    152                throw new EOFException();
    153            }
    154
    155            remaining -= count;
    156        }
    157    }
    158
    159    /**
    160     * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}.
    161     * @return the read long
    162     * @throws EOFException if an end of file is reached unexpectedly
    163     * @throws IOException if an I/O error occurs
    164     */
    165    @Override
    166    public int readInt()
    167        throws IOException, EOFException
    168    {
    169        return EndianUtils.readSwappedInteger( in );
    170    }
    171
    172    /**
    173     * Not currently supported - throws {@link UnsupportedOperationException}.
    174     * @return the line read
    175     * @throws EOFException if an end of file is reached unexpectedly
    176     * @throws IOException if an I/O error occurs
    177     */
    178    @Override
    179    public String readLine()
    180        throws IOException, EOFException
    181    {
    182        throw new UnsupportedOperationException(
    183                "Operation not supported: readLine()" );
    184    }
    185
    186    /**
    187     * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}.
    188     * @return the read long
    189     * @throws EOFException if an end of file is reached unexpectedly
    190     * @throws IOException if an I/O error occurs
    191     */
    192    @Override
    193    public long readLong()
    194        throws IOException, EOFException
    195    {
    196        return EndianUtils.readSwappedLong( in );
    197    }
    198
    199    /**
    200     * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}.
    201     * @return the read long
    202     * @throws EOFException if an end of file is reached unexpectedly
    203     * @throws IOException if an I/O error occurs
    204     */
    205    @Override
    206    public short readShort()
    207        throws IOException, EOFException
    208    {
    209        return EndianUtils.readSwappedShort( in );
    210    }
    211
    212    /**
    213     * Invokes the delegate's <code>read()</code> method.
    214     * @return the byte read or -1 if the end of stream
    215     * @throws EOFException if an end of file is reached unexpectedly
    216     * @throws IOException if an I/O error occurs
    217     */
    218    @Override
    219    public int readUnsignedByte()
    220        throws IOException, EOFException
    221    {
    222        return in.read();
    223    }
    224
    225    /**
    226     * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}.
    227     * @return the read long
    228     * @throws EOFException if an end of file is reached unexpectedly
    229     * @throws IOException if an I/O error occurs
    230     */
    231    @Override
    232    public int readUnsignedShort()
    233        throws IOException, EOFException
    234    {
    235        return EndianUtils.readSwappedUnsignedShort( in );
    236    }
    237
    238    /**
    239     * Not currently supported - throws {@link UnsupportedOperationException}.
    240     * @return UTF String read
    241     * @throws EOFException if an end of file is reached unexpectedly
    242     * @throws IOException if an I/O error occurs
    243     */
    244    @Override
    245    public String readUTF()
    246        throws IOException, EOFException
    247    {
    248        throw new UnsupportedOperationException(
    249                "Operation not supported: readUTF()" );
    250    }
    251
    252    /**
    253     * Invokes the delegate's <code>skip(int)</code> method.
    254     * @param count the number of bytes to skip
    255     * @return the number of bytes to skipped or -1 if the end of stream
    256     * @throws EOFException if an end of file is reached unexpectedly
    257     * @throws IOException if an I/O error occurs
    258     */
    259    @Override
    260    public int skipBytes( final int count )
    261        throws IOException, EOFException
    262    {
    263        return (int)in.skip( count );
    264    }
    265
    266}