- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
-
- package org.apache.poi.util;
-
- import java.io.BufferedInputStream;
- import java.io.FilterInputStream;
- import java.io.IOException;
- import java.io.InputStream;
-
- /**
- * Wraps an {@link InputStream} providing {@link LittleEndianInput}<p>
- *
- * This class does not buffer any input, so the stream read position maintained
- * by this class is consistent with that of the inner stream.
- */
- public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput {
-
- private static final int BUFFERED_SIZE = 8096;
-
- private static final int EOF = -1;
- private int readIndex = 0;
- private int markIndex = -1;
-
- public LittleEndianInputStream(InputStream is) {
- super(is.markSupported() ? is : new BufferedInputStream(is, BUFFERED_SIZE));
- }
-
- @Override
- @SuppressForbidden("just delegating")
- public int available() {
- try {
- return super.available();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public byte readByte() {
- return (byte)readUByte();
- }
-
- @Override
- public int readUByte() {
- byte[] buf = new byte[1];
- try {
- checkEOF(read(buf), 1);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return LittleEndian.getUByte(buf);
- }
-
- /**
- * get a float value, reads it in little endian format
- * then converts the resulting revolting IEEE 754 (curse them) floating
- * point number to a happy java float
- *
- * @return the float (32-bit) value
- */
- public float readFloat() {
- return Float.intBitsToFloat( readInt() );
- }
-
- @Override
- public double readDouble() {
- return Double.longBitsToDouble(readLong());
- }
-
- @Override
- public int readInt() {
- byte[] buf = new byte[LittleEndianConsts.INT_SIZE];
- try {
- checkEOF(read(buf), buf.length);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return LittleEndian.getInt(buf);
- }
-
- /**
- * get an unsigned int value from an InputStream
- *
- * @return the unsigned int (32-bit) value
- * @throws RuntimeException
- * wraps any IOException thrown from reading the stream.
- */
- //@Override
- public long readUInt() {
- long retNum = readInt();
- return retNum & 0x00FFFFFFFFL;
- }
-
- @Override
- public long readLong() {
- byte[] buf = new byte[LittleEndianConsts.LONG_SIZE];
- try {
- checkEOF(read(buf), LittleEndianConsts.LONG_SIZE);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return LittleEndian.getLong(buf);
- }
-
- @Override
- public short readShort() {
- return (short)readUShort();
- }
-
- @Override
- public int readUShort() {
- byte[] buf = new byte[LittleEndianConsts.SHORT_SIZE];
- try {
- checkEOF(read(buf), LittleEndianConsts.SHORT_SIZE);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return LittleEndian.getUShort(buf);
- }
-
- private static void checkEOF(int actualBytes, int expectedBytes) {
- if (expectedBytes != 0 && (actualBytes == -1 || actualBytes != expectedBytes)) {
- throw new RuntimeException("Unexpected end-of-file");
- }
- }
-
- @Override
- public void readFully(byte[] buf) {
- readFully(buf, 0, buf.length);
- }
-
- @Override
- public void readFully(byte[] buf, int off, int len) {
- try {
- checkEOF(_read(buf, off, len), len);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int readBytes = super.read(b, off, len);
- readIndex += readBytes;
- return readBytes;
- }
-
- @Override
- public synchronized void mark(int readlimit) {
- super.mark(readlimit);
- markIndex = readIndex;
- }
-
- @Override
- public synchronized void reset() throws IOException {
- super.reset();
- if (markIndex > -1) {
- readIndex = markIndex;
- markIndex = -1;
- }
- }
-
- public int getReadIndex() {
- return readIndex;
- }
-
-
-
- //Makes repeated calls to super.read() until length is read or EOF is reached
- private int _read(byte[] buffer, int offset, int length) throws IOException {
- //lifted directly from org.apache.commons.io.IOUtils 2.4
- int remaining = length;
- while (remaining > 0) {
- int location = length - remaining;
- int count = read(buffer, offset + location, remaining);
- if (EOF == count) {
- break;
- }
- remaining -= count;
- }
-
- return length - remaining;
- }
-
- @Override
- public void readPlain(byte[] buf, int off, int len) {
- readFully(buf, off, len);
- }
-
-
- public void skipFully(int len) throws IOException {
- if (len == 0) {
- return;
- }
- long skipped = IOUtils.skipFully(this, len);
- if (skipped > Integer.MAX_VALUE) {
- throw new IOException("can't skip further than "+Integer.MAX_VALUE);
- }
- checkEOF((int)skipped, len);
- }
- }
|