SwappedDataInputStream.java

  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.  */
  17. package org.apache.commons.io.input;

  18. import static org.apache.commons.io.IOUtils.EOF;

  19. import java.io.DataInput;
  20. import java.io.EOFException;
  21. import java.io.IOException;
  22. import java.io.InputStream;

  23. import org.apache.commons.io.EndianUtils;

  24. /**
  25.  * DataInput for systems relying on little-endian data formats. When read, values will be changed from little-endian to
  26.  * big-endian formats for internal usage.
  27.  * <p>
  28.  * Provenance: Avalon Excalibur (IO)
  29.  * </p>
  30.  */
  31. public class SwappedDataInputStream extends ProxyInputStream implements DataInput {

  32.     /**
  33.      * Constructs a SwappedDataInputStream.
  34.      *
  35.      * @param input InputStream to read from
  36.      */
  37.     public SwappedDataInputStream(final InputStream input) {
  38.         super(input);
  39.     }

  40.     /**
  41.      * Return <code>{@link #readByte()} != 0</code>
  42.      *
  43.      * @return false if the byte read is zero, otherwise true
  44.      * @throws IOException if an I/O error occurs.
  45.      * @throws EOFException if an end of file is reached unexpectedly
  46.      */
  47.     @Override
  48.     public boolean readBoolean() throws IOException, EOFException {
  49.         return 0 != readByte();
  50.     }

  51.     /**
  52.      * Invokes the delegate's {@code read()} method.
  53.      *
  54.      * @return the byte read or -1 if the end of stream
  55.      * @throws IOException if an I/O error occurs.
  56.      * @throws EOFException if an end of file is reached unexpectedly
  57.      */
  58.     @Override
  59.     public byte readByte() throws IOException, EOFException {
  60.         return (byte) in.read();
  61.     }

  62.     /**
  63.      * Reads a 2 byte, unsigned, little endian UTF-16 code point.
  64.      *
  65.      * @return the UTF-16 code point read or -1 if the end of stream
  66.      * @throws IOException if an I/O error occurs.
  67.      * @throws EOFException if an end of file is reached unexpectedly
  68.      */
  69.     @Override
  70.     public char readChar() throws IOException, EOFException {
  71.         return (char) readShort();
  72.     }

  73.     /**
  74.      * Reads an 8 byte, two's complement, little-endian long.
  75.      *
  76.      * @return the read long
  77.      * @throws IOException if an I/O error occurs.
  78.      * @throws EOFException if an end of file is reached unexpectedly
  79.      */
  80.     @Override
  81.     public double readDouble() throws IOException, EOFException {
  82.         return EndianUtils.readSwappedDouble(in);
  83.     }

  84.     /**
  85.      * Reads a 4 byte, IEEE 754, little-endian float.
  86.      *
  87.      * @return the read float
  88.      * @throws IOException if an I/O error occurs.
  89.      * @throws EOFException if an end of file is reached unexpectedly
  90.      */
  91.     @Override
  92.     public float readFloat() throws IOException, EOFException {
  93.         return EndianUtils.readSwappedFloat(in);
  94.     }

  95.     /**
  96.      * Invokes the delegate's {@code read(byte[] data, int, int)} method.
  97.      *
  98.      * @param data the buffer to read the bytes into
  99.      * @throws EOFException if an end of file is reached unexpectedly
  100.      * @throws IOException if an I/O error occurs.
  101.      */
  102.     @Override
  103.     public void readFully(final byte[] data) throws IOException, EOFException {
  104.         readFully(data, 0, data.length);
  105.     }

  106.     /**
  107.      * Invokes the delegate's {@code read(byte[] data, int, int)} method.
  108.      *
  109.      * @param data the buffer to read the bytes into
  110.      * @param offset The start offset
  111.      * @param length The number of bytes to read
  112.      * @throws EOFException if an end of file is reached unexpectedly
  113.      * @throws IOException if an I/O error occurs.
  114.      */
  115.     @Override
  116.     public void readFully(final byte[] data, final int offset, final int length) throws IOException, EOFException {
  117.         int remaining = length;

  118.         while (remaining > 0) {
  119.             final int location = offset + length - remaining;
  120.             final int count = read(data, location, remaining);

  121.             if (EOF == count) {
  122.                 throw new EOFException();
  123.             }

  124.             remaining -= count;
  125.         }
  126.     }

  127.     /**
  128.      * Reads a 4 byte, two's complement little-endian integer.
  129.      *
  130.      * @return the read int
  131.      * @throws EOFException if an end of file is reached unexpectedly
  132.      * @throws IOException if an I/O error occurs.
  133.      */
  134.     @Override
  135.     public int readInt() throws IOException, EOFException {
  136.         return EndianUtils.readSwappedInteger(in);
  137.     }

  138.     /**
  139.      * Not currently supported - throws {@link UnsupportedOperationException}.
  140.      *
  141.      * @return the line read
  142.      * @throws EOFException if an end of file is reached unexpectedly
  143.      * @throws IOException if an I/O error occurs
  144.      * @throws UnsupportedOperationException always
  145.      */
  146.     @Override
  147.     public String readLine() throws IOException, EOFException {
  148.         throw UnsupportedOperationExceptions.method("readLine");
  149.     }

  150.     /**
  151.      * Reads an 8 byte, two's complement little-endian integer.
  152.      *
  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.     @Override
  158.     public long readLong() throws IOException, EOFException {
  159.         return EndianUtils.readSwappedLong(in);
  160.     }

  161.     /**
  162.      * Reads a 2 byte, two's complement, little-endian integer.
  163.      *
  164.      * @return the read short
  165.      * @throws EOFException if an end of file is reached unexpectedly
  166.      * @throws IOException if an I/O error occurs.
  167.      */
  168.     @Override
  169.     public short readShort() throws IOException, EOFException {
  170.         return EndianUtils.readSwappedShort(in);
  171.     }

  172.     /**
  173.      * Invokes the delegate's {@code read()} method.
  174.      *
  175.      * @return the byte read or -1 if the end of stream
  176.      * @throws EOFException if an end of file is reached unexpectedly
  177.      * @throws IOException if an I/O error occurs.
  178.      */
  179.     @Override
  180.     public int readUnsignedByte() throws IOException, EOFException {
  181.         return in.read();
  182.     }

  183.     /**
  184.      * Reads a 2 byte, unsigned, little-endian integer.
  185.      *
  186.      * @return the read short
  187.      * @throws EOFException if an end of file is reached unexpectedly
  188.      * @throws IOException if an I/O error occurs.
  189.      */
  190.     @Override
  191.     public int readUnsignedShort() throws IOException, EOFException {
  192.         return EndianUtils.readSwappedUnsignedShort(in);
  193.     }

  194.     /**
  195.      * Not currently supported - throws {@link UnsupportedOperationException}.
  196.      *
  197.      * @return never
  198.      * @throws EOFException if an end of file is reached unexpectedly
  199.      * @throws IOException if an I/O error occurs
  200.      * @throws UnsupportedOperationException always
  201.      */
  202.     @Override
  203.     public String readUTF() throws IOException, EOFException {
  204.         throw UnsupportedOperationExceptions.method("readUTF");
  205.     }

  206.     /**
  207.      * Invokes the delegate's {@code skip(int)} method.
  208.      *
  209.      * @param count the number of bytes to skip
  210.      * @return the number of bytes skipped or -1 if the end of stream
  211.      * @throws IOException if an I/O error occurs
  212.      */
  213.     @Override
  214.     public int skipBytes(final int count) throws IOException {
  215.         return (int) in.skip(count);
  216.     }

  217. }