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. When read, values will be changed from little endian to 030 * big endian formats for internal usage. 031 * <p> 032 * <b>Origin of code: </b>Avalon Excalibur (IO) 033 * </p> 034 */ 035public class SwappedDataInputStream extends ProxyInputStream implements DataInput { 036 037 /** 038 * Constructs a SwappedDataInputStream. 039 * 040 * @param input InputStream to read from 041 */ 042 public SwappedDataInputStream(final InputStream input) { 043 super(input); 044 } 045 046 /** 047 * Return <code>{@link #readByte()} != 0</code> 048 * 049 * @return false if the byte read is zero, otherwise true 050 * @throws IOException if an I/O error occurs. 051 * @throws EOFException if an end of file is reached unexpectedly 052 */ 053 @Override 054 public boolean readBoolean() throws IOException, EOFException { 055 return 0 != readByte(); 056 } 057 058 /** 059 * Invokes the delegate's {@code read()} method. 060 * 061 * @return the byte read or -1 if the end of stream 062 * @throws IOException if an I/O error occurs. 063 * @throws EOFException if an end of file is reached unexpectedly 064 */ 065 @Override 066 public byte readByte() throws IOException, EOFException { 067 return (byte) in.read(); 068 } 069 070 /** 071 * Reads a character delegating to {@link #readShort()}. 072 * 073 * @return the byte read or -1 if the end of stream 074 * @throws IOException if an I/O error occurs. 075 * @throws EOFException if an end of file is reached unexpectedly 076 */ 077 @Override 078 public char readChar() throws IOException, EOFException { 079 return (char) readShort(); 080 } 081 082 /** 083 * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}. 084 * 085 * @return the read long 086 * @throws IOException if an I/O error occurs. 087 * @throws EOFException if an end of file is reached unexpectedly 088 */ 089 @Override 090 public double readDouble() throws IOException, EOFException { 091 return EndianUtils.readSwappedDouble(in); 092 } 093 094 /** 095 * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}. 096 * 097 * @return the read long 098 * @throws IOException if an I/O error occurs. 099 * @throws EOFException if an end of file is reached unexpectedly 100 */ 101 @Override 102 public float readFloat() throws IOException, EOFException { 103 return EndianUtils.readSwappedFloat(in); 104 } 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 * @throws EOFException if an end of file is reached unexpectedly 111 * @throws IOException if an I/O error occurs. 112 */ 113 @Override 114 public void readFully(final byte[] data) throws IOException, EOFException { 115 readFully(data, 0, data.length); 116 } 117 118 /** 119 * Invokes the delegate's {@code read(byte[] data, int, int)} method. 120 * 121 * @param data the buffer to read the bytes into 122 * @param offset The start offset 123 * @param length The number of bytes to read 124 * @throws EOFException if an end of file is reached unexpectedly 125 * @throws IOException if an I/O error occurs. 126 */ 127 @Override 128 public void readFully(final byte[] data, final int offset, final int length) throws IOException, EOFException { 129 int remaining = length; 130 131 while (remaining > 0) { 132 final int location = offset + length - remaining; 133 final int count = read(data, location, remaining); 134 135 if (EOF == count) { 136 throw new EOFException(); 137 } 138 139 remaining -= count; 140 } 141 } 142 143 /** 144 * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}. 145 * 146 * @return the read long 147 * @throws EOFException if an end of file is reached unexpectedly 148 * @throws IOException if an I/O error occurs. 149 */ 150 @Override 151 public int readInt() throws IOException, EOFException { 152 return EndianUtils.readSwappedInteger(in); 153 } 154 155 /** 156 * Not currently supported - throws {@link UnsupportedOperationException}. 157 * 158 * @return the line read 159 * @throws EOFException if an end of file is reached unexpectedly 160 * @throws IOException if an I/O error occurs. 161 */ 162 @Override 163 public String readLine() throws IOException, EOFException { 164 throw UnsupportedOperationExceptions.method("readLine"); 165 } 166 167 /** 168 * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}. 169 * 170 * @return the read long 171 * @throws EOFException if an end of file is reached unexpectedly 172 * @throws IOException if an I/O error occurs. 173 */ 174 @Override 175 public long readLong() throws IOException, EOFException { 176 return EndianUtils.readSwappedLong(in); 177 } 178 179 /** 180 * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}. 181 * 182 * @return the read long 183 * @throws EOFException if an end of file is reached unexpectedly 184 * @throws IOException if an I/O error occurs. 185 */ 186 @Override 187 public short readShort() throws IOException, EOFException { 188 return EndianUtils.readSwappedShort(in); 189 } 190 191 /** 192 * Invokes the delegate's {@code read()} method. 193 * 194 * @return the byte read or -1 if the end of stream 195 * @throws EOFException if an end of file is reached unexpectedly 196 * @throws IOException if an I/O error occurs. 197 */ 198 @Override 199 public int readUnsignedByte() throws IOException, EOFException { 200 return in.read(); 201 } 202 203 /** 204 * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}. 205 * 206 * @return the read long 207 * @throws EOFException if an end of file is reached unexpectedly 208 * @throws IOException if an I/O error occurs. 209 */ 210 @Override 211 public int readUnsignedShort() throws IOException, EOFException { 212 return EndianUtils.readSwappedUnsignedShort(in); 213 } 214 215 /** 216 * Not currently supported - throws {@link UnsupportedOperationException}. 217 * 218 * @return UTF String read 219 * @throws EOFException if an end of file is reached unexpectedly 220 * @throws IOException if an I/O error occurs. 221 */ 222 @Override 223 public String readUTF() throws IOException, EOFException { 224 throw UnsupportedOperationExceptions.method("readUTF"); 225 } 226 227 /** 228 * Invokes the delegate's {@code skip(int)} method. 229 * 230 * @param count the number of bytes to skip 231 * @return the number of bytes to skipped or -1 if the end of stream 232 * @throws EOFException if an end of file is reached unexpectedly 233 * @throws IOException if an I/O error occurs. 234 */ 235 @Override 236 public int skipBytes(final int count) throws IOException, EOFException { 237 return (int) in.skip(count); 238 } 239 240}