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 19 import static org.apache.commons.io.IOUtils.EOF; 20 21 import java.io.DataInput; 22 import java.io.EOFException; 23 import java.io.IOException; 24 import java.io.InputStream; 25 26 import org.apache.commons.io.EndianUtils; 27 28 /** 29 * DataInput for systems relying on little-endian data formats. When read, values will be changed from little-endian to 30 * big-endian formats for internal usage. 31 * <p> 32 * Provenance: Avalon Excalibur (IO) 33 * </p> 34 */ 35 public class SwappedDataInputStream extends ProxyInputStream implements DataInput { 36 37 /** 38 * Constructs a SwappedDataInputStream. 39 * 40 * @param input InputStream to read from 41 */ 42 public SwappedDataInputStream(final InputStream input) { 43 super(input); 44 } 45 46 /** 47 * Return <code>{@link #readByte()} != 0</code> 48 * 49 * @return false if the byte read is zero, otherwise true 50 * @throws IOException if an I/O error occurs. 51 * @throws EOFException if an end of file is reached unexpectedly 52 */ 53 @Override 54 public boolean readBoolean() throws IOException, EOFException { 55 return 0 != readByte(); 56 } 57 58 /** 59 * Invokes the delegate's {@code read()} method. 60 * 61 * @return the byte read or -1 if the end of stream 62 * @throws IOException if an I/O error occurs. 63 * @throws EOFException if an end of file is reached unexpectedly 64 */ 65 @Override 66 public byte readByte() throws IOException, EOFException { 67 return (byte) in.read(); 68 } 69 70 /** 71 * Reads a 2 byte, unsigned, little endian UTF-16 code point. 72 * 73 * @return the UTF-16 code point read or -1 if the end of stream 74 * @throws IOException if an I/O error occurs. 75 * @throws EOFException if an end of file is reached unexpectedly 76 */ 77 @Override 78 public char readChar() throws IOException, EOFException { 79 return (char) readShort(); 80 } 81 82 /** 83 * Reads an 8 byte, two's complement, little-endian long. 84 * 85 * @return the read long 86 * @throws IOException if an I/O error occurs. 87 * @throws EOFException if an end of file is reached unexpectedly 88 */ 89 @Override 90 public double readDouble() throws IOException, EOFException { 91 return EndianUtils.readSwappedDouble(in); 92 } 93 94 /** 95 * Reads a 4 byte, IEEE 754, little-endian float. 96 * 97 * @return the read float 98 * @throws IOException if an I/O error occurs. 99 * @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 }