diff --git a/src/java/org/apache/poi/hssf/record/RecordInputStream.java b/src/java/org/apache/poi/hssf/record/RecordInputStream.java index 03944aae3..f9dd2c76c 100755 --- a/src/java/org/apache/poi/hssf/record/RecordInputStream.java +++ b/src/java/org/apache/poi/hssf/record/RecordInputStream.java @@ -18,7 +18,6 @@ package org.apache.poi.hssf.record; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.InputStream; import org.apache.poi.util.LittleEndian; @@ -35,20 +34,37 @@ public final class RecordInputStream extends InputStream implements LittleEndian /** Maximum size of a single record (minus the 4 byte header) without a continue*/ public final static short MAX_RECORD_DATA_SIZE = 8224; private static final int INVALID_SID_VALUE = -1; + /** + * When {@link #_currentDataLength} has this value, it means that the previous BIFF record is + * finished, the next sid has been properly read, but the data size field has not been read yet. + */ private static final int DATA_LEN_NEEDS_TO_BE_READ = -1; private static final byte[] EMPTY_BYTE_ARRAY = { }; - private final InputStream _in; - /** {@link LittleEndianInput} facet of field {@link #_in} */ + /** {@link LittleEndianInput} facet of the wrapped {@link InputStream} */ private final LittleEndianInput _le; - private int currentSid; + /** the record identifier of the BIFF record currently being read */ + private int _currentSid; + /** + * Length of the data section of the current BIFF record (always 4 less than the total record size). + * When uninitialised, this field is set to {@link #DATA_LEN_NEEDS_TO_BE_READ}. + */ private int _currentDataLength; - private int nextSid; - private int recordOffset; - private boolean autoContinue; // TODO - remove this + /** + * The BIFF record identifier for the next record is read when just as the current record + * is finished. + * This field is only really valid during the time that ({@link #_currentDataLength} == + * {@link #DATA_LEN_NEEDS_TO_BE_READ}). At most other times its value is not really the + * 'sid of the next record'. Wwhile mid-record, this field coincidentally holds the sid + * of the current record. + */ + private int _nextSid; + /** + * index within the data section of the current BIFF record + */ + private int _currentDataOffset; public RecordInputStream(InputStream in) throws RecordFormatException { - _in = in; if (in instanceof LittleEndianInput) { // accessing directly is an optimisation _le = (LittleEndianInput) in; @@ -56,22 +72,20 @@ public final class RecordInputStream extends InputStream implements LittleEndian // less optimal, but should work OK just the same. Often occurs in junit tests. _le = new LittleEndianInputStream(in); } - try { - if (_in.available() < LittleEndian.SHORT_SIZE) { - nextSid = INVALID_SID_VALUE; - } else { - nextSid = LittleEndian.readShort(in); - } - } catch (IOException ex) { - throw new RecordFormatException("Error reading bytes", ex); - } - _currentDataLength = DATA_LEN_NEEDS_TO_BE_READ; - autoContinue = true; + _nextSid = readNextSid(); + } + + /** + * @returns the number of bytes available in the current BIFF record + * @see #remaining() + */ + public int available() { + return remaining(); } public int read() { checkRecordPosition(LittleEndian.BYTE_SIZE); - recordOffset += LittleEndian.BYTE_SIZE; + _currentDataOffset += LittleEndian.BYTE_SIZE; return _le.readUByte(); } public int read(byte[] b, int off, int len) { @@ -83,14 +97,9 @@ public final class RecordInputStream extends InputStream implements LittleEndian return limit; } - public short getSid() { - return (short) currentSid; - } - - public short getLength() { // TODO - remove - return (short) _currentDataLength; - } - + public short getSid() { + return (short) _currentSid; + } /** * Note - this method is expected to be called only when completed reading the current BIFF record. @@ -98,18 +107,17 @@ public final class RecordInputStream extends InputStream implements LittleEndian * discarded */ public boolean hasNextRecord() { - if (_currentDataLength != -1 && _currentDataLength != recordOffset) { - System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(currentSid)); + if (_currentDataLength != -1 && _currentDataLength != _currentDataOffset) { + System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(_currentSid)); // discard unread data - while (recordOffset < _currentDataLength) { + while (_currentDataOffset < _currentDataLength) { readByte(); } } if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) { - nextSid = readNextSid(); - _currentDataLength = DATA_LEN_NEEDS_TO_BE_READ; + _nextSid = readNextSid(); } - return nextSid != INVALID_SID_VALUE; + return _nextSid != INVALID_SID_VALUE; } /** @@ -117,12 +125,7 @@ public final class RecordInputStream extends InputStream implements LittleEndian * @return the sid of the next record or {@link #INVALID_SID_VALUE} if at end of stream */ private int readNextSid() { - int nAvailable; - try { - nAvailable = _in.available(); - } catch (IOException e) { - throw new RecordFormatException("Error checking stream available bytes", e); - } + int nAvailable = _le.available(); if (nAvailable < EOFRecord.ENCODED_SIZE) { if (nAvailable > 0) { // some scrap left over? @@ -135,6 +138,7 @@ public final class RecordInputStream extends InputStream implements LittleEndian if (result == INVALID_SID_VALUE) { throw new RecordFormatException("Found invalid sid (" + result + ")"); } + _currentDataLength = DATA_LEN_NEEDS_TO_BE_READ; return result; } @@ -143,12 +147,14 @@ public final class RecordInputStream extends InputStream implements LittleEndian * Note: The auto continue flag is reset to true */ public void nextRecord() throws RecordFormatException { - if (nextSid == INVALID_SID_VALUE) { + if (_nextSid == INVALID_SID_VALUE) { throw new IllegalStateException("EOF - next record not available"); } - currentSid = nextSid; - autoContinue = true; - recordOffset = 0; + if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) { + throw new IllegalStateException("Cannot call nextRecord() without checking hasNextRecord() first"); + } + _currentSid = _nextSid; + _currentDataOffset = 0; _currentDataLength = _le.readUShort(); if (_currentDataLength > MAX_RECORD_DATA_SIZE) { throw new RecordFormatException("The content of an excel record cannot exceed " @@ -156,19 +162,19 @@ public final class RecordInputStream extends InputStream implements LittleEndian } } - public void setAutoContinue(boolean enable) { - this.autoContinue = enable; - } - private void checkRecordPosition(int requiredByteCount) { - if (remaining() < requiredByteCount) { - if (isContinueNext() && autoContinue) { - nextRecord(); - } else { - throw new ArrayIndexOutOfBoundsException(); - } + int nAvailable = remaining(); + if (nAvailable >= requiredByteCount) { + // all OK + return; } + if (nAvailable == 0 && isContinueNext()) { + nextRecord(); + return; + } + throw new RecordFormatException("Not enough data (" + nAvailable + + ") to read requested (" + requiredByteCount +") bytes"); } /** @@ -176,7 +182,7 @@ public final class RecordInputStream extends InputStream implements LittleEndian */ public byte readByte() { checkRecordPosition(LittleEndian.BYTE_SIZE); - recordOffset += LittleEndian.BYTE_SIZE; + _currentDataOffset += LittleEndian.BYTE_SIZE; return _le.readByte(); } @@ -185,19 +191,19 @@ public final class RecordInputStream extends InputStream implements LittleEndian */ public short readShort() { checkRecordPosition(LittleEndian.SHORT_SIZE); - recordOffset += LittleEndian.SHORT_SIZE; + _currentDataOffset += LittleEndian.SHORT_SIZE; return _le.readShort(); } public int readInt() { checkRecordPosition(LittleEndian.INT_SIZE); - recordOffset += LittleEndian.INT_SIZE; + _currentDataOffset += LittleEndian.INT_SIZE; return _le.readInt(); } public long readLong() { checkRecordPosition(LittleEndian.LONG_SIZE); - recordOffset += LittleEndian.LONG_SIZE; + _currentDataOffset += LittleEndian.LONG_SIZE; return _le.readLong(); } @@ -214,13 +220,13 @@ public final class RecordInputStream extends InputStream implements LittleEndian */ public int readUShort() { checkRecordPosition(LittleEndian.SHORT_SIZE); - recordOffset += LittleEndian.SHORT_SIZE; + _currentDataOffset += LittleEndian.SHORT_SIZE; return _le.readUShort(); } public double readDouble() { checkRecordPosition(LittleEndian.DOUBLE_SIZE); - recordOffset += LittleEndian.DOUBLE_SIZE; + _currentDataOffset += LittleEndian.DOUBLE_SIZE; long valueLongBits = _le.readLong(); double result = Double.longBitsToDouble(valueLongBits); if (Double.isNaN(result)) { @@ -235,7 +241,7 @@ public final class RecordInputStream extends InputStream implements LittleEndian public void readFully(byte[] buf, int off, int len) { checkRecordPosition(len); _le.readFully(buf, off, len); - recordOffset+=len; + _currentDataOffset+=len; } public String readString() { @@ -369,20 +375,25 @@ public final class RecordInputStream extends InputStream implements LittleEndian // already read sid of next record. so current one is finished return 0; } - return (_currentDataLength - recordOffset); + return _currentDataLength - _currentDataOffset; } /** * * @return true when a {@link ContinueRecord} is next. */ - public boolean isContinueNext() { - if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && recordOffset != _currentDataLength) { + private boolean isContinueNext() { + if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && _currentDataOffset != _currentDataLength) { throw new IllegalStateException("Should never be called before end of current record"); } if (!hasNextRecord()) { return false; } - return nextSid == ContinueRecord.sid; + // At what point are records continued? + // - Often from within the char data of long strings (caller is within readStringCommon()). + // - From UnicodeString construction (many different points - call via checkRecordPosition) + // - During TextObjectRecord construction (just before the text, perhaps within the text, + // and before the formatting run data) + return _nextSid == ContinueRecord.sid; } } diff --git a/src/java/org/apache/poi/hssf/record/SupBookRecord.java b/src/java/org/apache/poi/hssf/record/SupBookRecord.java index 30e337e2d..78d77c5cb 100644 --- a/src/java/org/apache/poi/hssf/record/SupBookRecord.java +++ b/src/java/org/apache/poi/hssf/record/SupBookRecord.java @@ -84,9 +84,11 @@ public final class SupBookRecord extends Record { * @param offset of the record's data (provided a big array of the file) */ public SupBookRecord(RecordInputStream in) { + int recLen = in.remaining(); + field_1_number_of_sheets = in.readShort(); - if(in.getLength() > SMALL_RECORD_SIZE) { + if(recLen > SMALL_RECORD_SIZE) { // 5.38.1 External References _isAddInFunctions = false; diff --git a/src/java/org/apache/poi/hssf/record/TextObjectRecord.java b/src/java/org/apache/poi/hssf/record/TextObjectRecord.java index 91780ee44..4bb065e91 100644 --- a/src/java/org/apache/poi/hssf/record/TextObjectRecord.java +++ b/src/java/org/apache/poi/hssf/record/TextObjectRecord.java @@ -131,13 +131,7 @@ public final class TextObjectRecord extends Record { _text = new HSSFRichTextString(text); if (field_7_formattingDataLength > 0) { - if (in.isContinueNext() && in.remaining() == 0) { - in.nextRecord(); - processFontRuns(in, _text, field_7_formattingDataLength); - } else { - throw new RecordFormatException( - "Expected Continue Record to hold font runs for TextObjectRecord"); - } + processFontRuns(in, _text, field_7_formattingDataLength); } } @@ -156,10 +150,6 @@ public final class TextObjectRecord extends Record { throw new RecordFormatException("Bad format run data length " + formattingRunDataLength + ")"); } - if (in.remaining() != formattingRunDataLength) { - throw new RecordFormatException("Expected " + formattingRunDataLength - + " bytes but got " + in.remaining()); - } int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE; for (int i = 0; i < nRuns; i++) { short index = in.readShort(); diff --git a/src/java/org/apache/poi/hssf/record/UnicodeString.java b/src/java/org/apache/poi/hssf/record/UnicodeString.java index 4258d0a6d..0494aa98a 100644 --- a/src/java/org/apache/poi/hssf/record/UnicodeString.java +++ b/src/java/org/apache/poi/hssf/record/UnicodeString.java @@ -36,13 +36,8 @@ import java.util.Collections; * @author Andrew C. Oliver * @author Marc Johnson (mjohnson at apache dot org) * @author Glen Stampoultzis (glens at apache.org) - * @version 2.0-pre */ - -public class UnicodeString - implements Comparable -{ - public final static short sid = 0xFFF; +public final class UnicodeString implements Comparable { private short field_1_charCount; // = 0; private byte field_2_optionflags; // = 0; private String field_3_string; // = null; @@ -53,8 +48,8 @@ public class UnicodeString private static final BitField richText = BitFieldFactory.getInstance(0x8); public static class FormatRun implements Comparable { - private short character; - private short fontIndex; + short character; + short fontIndex; public FormatRun(short character, short fontIndex) { this.character = character; @@ -102,15 +97,6 @@ public class UnicodeString setString(str); } - /** - * construct a unicode string record and fill its fields, ID is ignored - * @param in the RecordInputstream to read the record from - */ - - public UnicodeString(RecordInputStream in) - { - fillFields(in); // TODO - inline - } public int hashCode() @@ -142,9 +128,9 @@ public class UnicodeString && field_3_string.equals(other.field_3_string)); if (!eq) return false; - //Ok string appears to be equal but now lets compare formatting runs + //OK string appears to be equal but now lets compare formatting runs if ((field_4_format_runs == null) && (other.field_4_format_runs == null)) - //Strings are equal, and there are not formtting runs. + //Strings are equal, and there are not formatting runs. return true; if (((field_4_format_runs == null) && (other.field_4_format_runs != null)) || (field_4_format_runs != null) && (other.field_4_format_runs == null)) @@ -186,10 +172,10 @@ public class UnicodeString } /** + * construct a unicode string record and fill its fields, ID is ignored * @param in the RecordInputstream to read the record from */ - protected void fillFields(RecordInputStream in) - { + public UnicodeString(RecordInputStream in) { field_1_charCount = in.readShort(); field_2_optionflags = in.readByte(); @@ -206,35 +192,13 @@ public class UnicodeString extensionLength = in.readInt(); } - //Now need to get the string data. - //Turn off autocontinuation so that we can catch the continue boundary - in.setAutoContinue(false); - StringBuffer tmpString = new StringBuffer(field_1_charCount); - int stringCharCount = field_1_charCount; boolean isCompressed = ((field_2_optionflags & 1) == 0); - while (stringCharCount != 0) { - if (in.remaining() == 0) { - if (in.isContinueNext()) { - in.nextRecord(); - //Check if we are now reading, compressed or uncompressed unicode. - byte optionflags = in.readByte(); - isCompressed = ((optionflags & 1) == 0); - } else - throw new RecordFormatException("Expected continue record."); - } - if (isCompressed) { - char ch = (char)in.readUByte(); // avoid sex - tmpString.append(ch); - } else { - char ch = (char) in.readShort(); - tmpString.append(ch); - } - stringCharCount --; + if (isCompressed) { + field_3_string = in.readCompressedUnicode(field_1_charCount); + } else { + field_3_string = in.readUnicodeLEString(field_1_charCount); } - field_3_string = tmpString.toString(); - //Turn back on autocontinuation - in.setAutoContinue(true); - + if (isRichText() && (runCount > 0)) { field_4_format_runs = new ArrayList(runCount); @@ -305,13 +269,8 @@ public class UnicodeString } /** - * get the actual string this contains as a java String object - * - * - * @return String - * + * @return the actual string this contains as a java String object */ - public String getString() { return field_3_string; @@ -341,7 +300,7 @@ public class UnicodeString } } if (useUTF16) - //Set the uncomressed bit + //Set the uncompressed bit field_2_optionflags = highByte.setByte(field_2_optionflags); else field_2_optionflags = highByte.clearByte(field_2_optionflags); } @@ -392,7 +351,7 @@ public class UnicodeString //Make sure that we now say that we are a rich string field_2_optionflags = richText.setByte(field_2_optionflags); - } + } public Iterator formatIterator() { if (field_4_format_runs != null) @@ -497,8 +456,8 @@ public class UnicodeString LittleEndian.putShort(data, offset, ContinueRecord.sid); offset+=2; - //Record the location of the last continue legnth position, but dont write - //anything there yet (since we dont know what it will be!) + //Record the location of the last continue length position, but don't write + //anything there yet (since we don't know what it will be!) stats.lastLengthPos = offset; offset += 2; @@ -506,7 +465,7 @@ public class UnicodeString stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; } return offset; - } + } public int serialize(UnicodeRecordStats stats, final int offset, byte [] data) { @@ -514,7 +473,6 @@ public class UnicodeString //Basic string overhead pos = writeContinueIfRequired(stats, 3, pos, data); - // byte[] retval = new byte[ 3 + (getString().length() * charsize)]; LittleEndian.putShort(data, pos, getCharCount()); pos += 2; data[ pos ] = getOptionFlags(); @@ -568,39 +526,39 @@ public class UnicodeString //Check to see if the offset occurs mid string, if so then we need to add //the byte to start with that represents the first byte of the continue record. if (strSize > stats.remainingSize) { - //Ok the offset occurs half way through the string, that means that + //OK the offset occurs half way through the string, that means that //we need an extra byte after the continue record ie we didnt finish //writing out the string the 1st time through //But hang on, how many continue records did we span? What if this is //a REALLY long string. We need to work this all out. - int ammountThatCantFit = strSize; + int amountThatCantFit = strSize; int strPos = 0; - while (ammountThatCantFit > 0) { - int ammountWritten = Math.min(stats.remainingSize, ammountThatCantFit); - //Make sure that the ammount that cant fit takes into account + while (amountThatCantFit > 0) { + int amountWritten = Math.min(stats.remainingSize, amountThatCantFit); + //Make sure that the amount that can't fit takes into account //whether we are writing double byte unicode if (isUncompressedUnicode()) { //We have the '-1' here because whether this is the first record or //subsequent continue records, there is always the case that the - //number of bytes in a string on doube byte boundaries is actually odd. - if ( ( (ammountWritten ) % 2) == 1) - ammountWritten--; + //number of bytes in a string on double byte boundaries is actually odd. + if ( ( (amountWritten ) % 2) == 1) + amountWritten--; } - System.arraycopy(strBytes, strPos, data, pos, ammountWritten); - pos += ammountWritten; - strPos += ammountWritten; - stats.recordSize += ammountWritten; - stats.remainingSize -= ammountWritten; + System.arraycopy(strBytes, strPos, data, pos, amountWritten); + pos += amountWritten; + strPos += amountWritten; + stats.recordSize += amountWritten; + stats.remainingSize -= amountWritten; //Ok lets subtract what we can write - ammountThatCantFit -= ammountWritten; + amountThatCantFit -= amountWritten; //Each iteration of this while loop is another continue record, unless //everything now fits. - if (ammountThatCantFit > 0) { + if (amountThatCantFit > 0) { //We know that a continue WILL be requied, but use this common method - pos = writeContinueIfRequired(stats, ammountThatCantFit, pos, data); + pos = writeContinueIfRequired(stats, amountThatCantFit, pos, data); //The first byte after a continue mid string is the extra byte to //indicate if this run is compressed or not. @@ -686,7 +644,7 @@ public class UnicodeString return highByte.isSet(getOptionFlags()); } - /** Returns the size of this record, given the ammount of record space + /** Returns the size of this record, given the amount of record space * remaining, it will also include the size of writing a continue record. */ @@ -833,13 +791,6 @@ public class UnicodeString } } - - - public short getSid() - { - return sid; - } - public int compareTo(Object obj) { UnicodeString str = ( UnicodeString ) obj; @@ -877,7 +828,7 @@ public class UnicodeString } //Well the format runs are equal as well!, better check the ExtRst data - //Which by the way we dont know how to decode! + //Which by the way we don't know how to decode! if ((field_5_ext_rst == null) && (str.field_5_ext_rst == null)) return 0; if ((field_5_ext_rst == null) && (str.field_5_ext_rst != null)) diff --git a/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java index c0689bde2..ecd110a32 100644 --- a/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java @@ -89,8 +89,10 @@ public final class DocumentInputStream extends InputStream implements LittleEndi _currentBlock = getDataInputBlock(0); } - public int available() throws IOException { - dieIfClosed(); + public int available() { + if (_closed) { + throw new IllegalStateException("cannot perform requested operation on a closed stream"); + } return _document_size - _current_offset; } @@ -194,7 +196,7 @@ public final class DocumentInputStream extends InputStream implements LittleEndi private void checkAvaliable(int requestedSize) { if (_closed) { - throw new RuntimeException("cannot perform requested operation on a closed stream"); + throw new IllegalStateException("cannot perform requested operation on a closed stream"); } if (requestedSize > _document_size - _current_offset) { throw new RuntimeException("Buffer underrun - requested " + requestedSize diff --git a/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java b/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java index 2729ab773..984db5f8f 100644 --- a/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java +++ b/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java @@ -40,6 +40,9 @@ public final class LittleEndianByteArrayInputStream implements LittleEndianInput this(buf, 0, buf.length); } + public int available() { + return _endIndex - _readIndex; + } private void checkPosition(int i) { if (i > _endIndex - _readIndex) { throw new RuntimeException("Buffer overrun"); diff --git a/src/java/org/apache/poi/util/LittleEndianInput.java b/src/java/org/apache/poi/util/LittleEndianInput.java index 64bbd1862..dafa7eada 100644 --- a/src/java/org/apache/poi/util/LittleEndianInput.java +++ b/src/java/org/apache/poi/util/LittleEndianInput.java @@ -21,6 +21,7 @@ package org.apache.poi.util; * @author Josh Micich */ public interface LittleEndianInput { + int available(); byte readByte(); int readUByte(); short readShort(); diff --git a/src/java/org/apache/poi/util/LittleEndianInputStream.java b/src/java/org/apache/poi/util/LittleEndianInputStream.java index 329119bfb..622ee23cd 100644 --- a/src/java/org/apache/poi/util/LittleEndianInputStream.java +++ b/src/java/org/apache/poi/util/LittleEndianInputStream.java @@ -22,6 +22,10 @@ import java.io.IOException; import java.io.InputStream; /** + * Wraps an {@link InputStream} providing {@link LittleEndianInput}

+ * + * This class does not buffer any input, so the stream read position maintained + * by this class is consistent with that of the inner stream. * * @author Josh Micich */ @@ -29,7 +33,13 @@ public class LittleEndianInputStream extends FilterInputStream implements Little public LittleEndianInputStream(InputStream is) { super(is); } - + public int available() { + try { + return super.available(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } public byte readByte() { return (byte)readUByte(); } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java index 3f91f4208..751826e3f 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -15,18 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.poifs.filesystem; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Arrays; -import java.util.*; - -import junit.framework.*; +import junit.framework.TestCase; import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.DocumentProperty; import org.apache.poi.poifs.storage.RawDataBlock; /** @@ -35,22 +32,9 @@ import org.apache.poi.poifs.storage.RawDataBlock; * @author Marc Johnson */ -public class TestDocumentInputStream - extends TestCase -{ +public final class TestDocumentInputStream extends TestCase { - /** - * Constructor TestDocumentInputStream - * - * @param name - * - * @exception IOException - */ - - public TestDocumentInputStream(String name) - throws IOException - { - super(name); + protected void setUp() throws Exception { int blocks = (_workbook_size + 511) / 512; _workbook_data = new byte[ 512 * blocks ]; @@ -86,13 +70,8 @@ public class TestDocumentInputStream /** * test constructor - * - * @exception IOException */ - - public void testConstructor() - throws IOException - { + public void testConstructor() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); assertEquals(_workbook_size, stream.available()); @@ -100,13 +79,8 @@ public class TestDocumentInputStream /** * test available() behavior - * - * @exception IOException */ - - public void testAvailable() - throws IOException - { + public void testAvailable() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); assertEquals(_workbook_size, stream.available()); @@ -115,9 +89,7 @@ public class TestDocumentInputStream { stream.available(); fail("Should have caught IOException"); - } - catch (IOException ignored) - { + } catch (IllegalStateException ignored) { // as expected } @@ -125,13 +97,8 @@ public class TestDocumentInputStream /** * test mark/reset/markSupported. - * - * @exception IOException */ - - public void testMarkFunctions() - throws IOException - { + public void testMarkFunctions() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); byte[] buffer = new byte[ _workbook_size / 5 ]; @@ -169,13 +136,8 @@ public class TestDocumentInputStream /** * test simple read method - * - * @exception IOException */ - - public void testReadSingleByte() - throws IOException - { + public void testReadSingleByte() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); int remaining = _workbook_size; @@ -205,13 +167,8 @@ public class TestDocumentInputStream /** * Test buffered read - * - * @exception IOException */ - - public void testBufferRead() - throws IOException - { + public void testBufferRead() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); try @@ -275,13 +232,8 @@ public class TestDocumentInputStream /** * Test complex buffered read - * - * @exception IOException */ - - public void testComplexBufferRead() - throws IOException - { + public void testComplexBufferRead() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); try { @@ -387,13 +339,8 @@ public class TestDocumentInputStream /** * test skip - * - * @exception IOException */ - - public void testSkip() - throws IOException - { + public void testSkip() throws IOException { DocumentInputStream stream = new DocumentInputStream(_workbook); assertEquals(_workbook_size, stream.available()); @@ -418,17 +365,4 @@ public class TestDocumentInputStream stream.skip(2 + ( long ) Integer.MAX_VALUE)); assertEquals(0, stream.available()); } - - /** - * main method to run the unit tests - * - * @param ignored_args - */ - - public static void main(String [] ignored_args) - { - System.out.println( - "Testing org.apache.poi.poifs.filesystem.DocumentInputStream"); - junit.textui.TestRunner.run(TestDocumentInputStream.class); - } }