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 * Provenance: 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 2 byte, unsigned, little endian UTF-16 code point. 072 * 073 * @return the UTF-16 code point 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 * Reads an 8 byte, two's complement, little-endian long. 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 * Reads a 4 byte, IEEE 754, little-endian float. 096 * 097 * @return the read float 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 * Reads a 4 byte, two's complement little-endian integer. 145 * 146 * @return the read int 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 * @throws UnsupportedOperationException always 162 */ 163 @Override 164 public String readLine() throws IOException, EOFException { 165 throw UnsupportedOperationExceptions.method("readLine"); 166 } 167 168 /** 169 * Reads an 8 byte, two's complement little-endian integer. 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 * Reads a 2 byte, two's complement, little-endian integer. 182 * 183 * @return the read short 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 * Reads a 2 byte, unsigned, little-endian integer. 206 * 207 * @return the read short 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 never 220 * @throws EOFException if an end of file is reached unexpectedly 221 * @throws IOException if an I/O error occurs 222 * @throws UnsupportedOperationException always 223 */ 224 @Override 225 public String readUTF() throws IOException, EOFException { 226 throw UnsupportedOperationExceptions.method("readUTF"); 227 } 228 229 /** 230 * Invokes the delegate's {@code skip(int)} method. 231 * 232 * @param count the number of bytes to skip 233 * @return the number of bytes skipped or -1 if the end of stream 234 * @throws IOException if an I/O error occurs 235 */ 236 @Override 237 public int skipBytes(final int count) throws IOException { 238 return (int) in.skip(count); 239 } 240 241}