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