From a3899a57d8f6e1bfc6dc02d18ccdf56c813df0fc Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 25 Apr 2010 17:35:56 +0000 Subject: [PATCH] Resolve bug #49139 - don't assume that the block size is always 512 bytes. Instead of hard coding this value in, pass around the new POIFSBigBlockSize object that holds the size and various helper subsizes. Should now be possible to open 4k block files without error. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@937834 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/common/POIFSBigBlockSize.java | 58 +++++++ .../poi/poifs/common/POIFSConstants.java | 9 +- .../poi/poifs/dev/POIFSHeaderDumper.java | 159 ++++++++++++++++++ .../poifs/eventfilesystem/POIFSReader.java | 14 +- .../poi/poifs/filesystem/POIFSDocument.java | 101 +++++++---- .../poi/poifs/filesystem/POIFSFileSystem.java | 28 ++- .../poi/poifs/property/PropertyTable.java | 17 +- .../apache/poi/poifs/storage/BATBlock.java | 76 +++------ .../apache/poi/poifs/storage/BigBlock.java | 12 ++ .../storage/BlockAllocationTableReader.java | 20 ++- .../storage/BlockAllocationTableWriter.java | 20 ++- .../poi/poifs/storage/DocumentBlock.java | 32 ++-- .../poifs/storage/HeaderBlockConstants.java | 4 +- .../poi/poifs/storage/HeaderBlockReader.java | 15 +- .../poi/poifs/storage/HeaderBlockWriter.java | 27 ++- .../poi/poifs/storage/PropertyBlock.java | 17 +- .../poi/poifs/storage/RawDataBlock.java | 9 +- .../poi/poifs/storage/RawDataBlockList.java | 10 +- .../poifs/storage/SmallBlockTableReader.java | 16 +- .../poifs/storage/SmallBlockTableWriter.java | 8 +- .../poi/poifs/storage/SmallDocumentBlock.java | 48 ++++-- .../poifs/storage/SmallDocumentBlockList.java | 2 +- .../src/org/apache/poi/hwpf/HWPFDocument.java | 4 +- .../apache/poi/hwpf/model/CHPBinTable.java | 8 +- .../apache/poi/hwpf/model/PAPBinTable.java | 8 +- .../apache/poi/hwpf/model/TextPieceTable.java | 4 +- .../poifs/filesystem/TestPOIFSFileSystem.java | 33 ++++ .../poi/poifs/property/TestPropertyTable.java | 10 +- .../poifs/storage/LocalRawDataBlockList.java | 2 +- .../poi/poifs/storage/TestBATBlock.java | 32 ++-- .../TestBlockAllocationTableReader.java | 20 ++- .../TestBlockAllocationTableWriter.java | 20 +-- .../poi/poifs/storage/TestBlockListImpl.java | 7 +- .../poi/poifs/storage/TestDocumentBlock.java | 4 +- .../poifs/storage/TestHeaderBlockWriter.java | 19 ++- .../poi/poifs/storage/TestPropertyBlock.java | 12 +- .../poifs/storage/TestRawDataBlockList.java | 6 +- .../storage/TestSmallBlockTableReader.java | 9 +- .../storage/TestSmallBlockTableWriter.java | 7 +- .../poifs/storage/TestSmallDocumentBlock.java | 14 +- .../storage/TestSmallDocumentBlockList.java | 4 +- 41 files changed, 658 insertions(+), 267 deletions(-) create mode 100644 src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java create mode 100644 src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java diff --git a/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java b/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java new file mode 100644 index 000000000..19b345d71 --- /dev/null +++ b/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java @@ -0,0 +1,58 @@ + +/* ==================================================================== + 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.poifs.common; + +import org.apache.poi.util.LittleEndianConsts; + +/** + *

A class describing attributes of the Big Block Size

+ */ +public final class POIFSBigBlockSize +{ + private int bigBlockSize; + private short headerValue; + + protected POIFSBigBlockSize(int bigBlockSize, short headerValue) { + this.bigBlockSize = bigBlockSize; + this.headerValue = headerValue; + } + + public int getBigBlockSize() { + return bigBlockSize; + } + + public short getHeaderValue() { + return headerValue; + } + + public int getPropertiesPerBlock() { + return bigBlockSize / POIFSConstants.PROPERTY_SIZE; + } + + public int getBATEntriesPerBlock() { + return bigBlockSize / LittleEndianConsts.INT_SIZE; + } + public int getXBATEntriesPerBlock() { + return getBATEntriesPerBlock() - 1; + } + public int getNextXBATChainOffset() { + return getXBATEntriesPerBlock() * LittleEndianConsts.INT_SIZE; + } +} diff --git a/src/java/org/apache/poi/poifs/common/POIFSConstants.java b/src/java/org/apache/poi/poifs/common/POIFSConstants.java index 6630c2531..5a260f421 100644 --- a/src/java/org/apache/poi/poifs/common/POIFSConstants.java +++ b/src/java/org/apache/poi/poifs/common/POIFSConstants.java @@ -21,16 +21,17 @@ package org.apache.poi.poifs.common; /** *

A repository for constants shared by POI classes.

- * - * @author Marc Johnson (mjohnson at apache dot org) */ - public interface POIFSConstants { /** Most files use 512 bytes as their big block size */ - public static final int BIG_BLOCK_SIZE = 0x0200; + public static final int SMALLER_BIG_BLOCK_SIZE = 0x0200; + public static final POIFSBigBlockSize SMALLER_BIG_BLOCK_SIZE_DETAILS = + new POIFSBigBlockSize(SMALLER_BIG_BLOCK_SIZE, (short)9); /** Some use 4096 bytes */ public static final int LARGER_BIG_BLOCK_SIZE = 0x1000; + public static final POIFSBigBlockSize LARGER_BIG_BLOCK_SIZE_DETAILS = + new POIFSBigBlockSize(LARGER_BIG_BLOCK_SIZE, (short)12); public static final int PROPERTY_SIZE = 0x0080; diff --git a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java new file mode 100644 index 000000000..1967daec4 --- /dev/null +++ b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java @@ -0,0 +1,159 @@ +/* ==================================================================== + 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.poifs.dev; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Iterator; + +import org.apache.poi.poifs.common.POIFSBigBlockSize; +import org.apache.poi.poifs.common.POIFSConstants; +import org.apache.poi.poifs.filesystem.DirectoryNode; +import org.apache.poi.poifs.filesystem.DocumentNode; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.property.PropertyTable; +import org.apache.poi.poifs.storage.BlockAllocationTableReader; +import org.apache.poi.poifs.storage.BlockList; +import org.apache.poi.poifs.storage.HeaderBlockReader; +import org.apache.poi.poifs.storage.ListManagedBlock; +import org.apache.poi.poifs.storage.RawDataBlockList; +import org.apache.poi.poifs.storage.SmallBlockTableReader; +import org.apache.poi.util.HexDump; +import org.apache.poi.util.IntList; + +/** + * A very low level debugging tool, for printing out core + * information on the headers and FAT blocks. + * You probably only want to use this if you're trying + * to understand POIFS, or if you're trying to track + * down the source of corruption in a file. + */ +public class POIFSHeaderDumper { + /** + * Display the entries of multiple POIFS files + * + * @param args the names of the files to be displayed + */ + public static void main(final String args[]) throws Exception { + if (args.length == 0) { + System.err.println("Must specify at least one file to view"); + System.exit(1); + } + + for (int j = 0; j < args.length; j++) { + viewFile(args[j]); + } + } + + public static void viewFile(final String filename) throws Exception { + InputStream inp = new FileInputStream(filename); + + // Header + HeaderBlockReader header_block_reader = + new HeaderBlockReader(inp); + displayHeader(header_block_reader); + + // Raw blocks + POIFSBigBlockSize bigBlockSize = header_block_reader.getBigBlockSize(); + RawDataBlockList data_blocks = new RawDataBlockList(inp, bigBlockSize); + displayRawBlocksSummary(data_blocks); + + // Main FAT Table + BlockAllocationTableReader batReader = + new BlockAllocationTableReader( + header_block_reader.getBigBlockSize(), + header_block_reader.getBATCount(), + header_block_reader.getBATArray(), + header_block_reader.getXBATCount(), + header_block_reader.getXBATIndex(), + data_blocks); + displayBATReader(batReader); + + // Properties Table + PropertyTable properties = + new PropertyTable( + header_block_reader.getBigBlockSize(), + header_block_reader.getPropertyStart(), + data_blocks); + + // Mini Fat + BlockList sbat = + SmallBlockTableReader.getSmallDocumentBlocks( + bigBlockSize, data_blocks, properties.getRoot(), + header_block_reader.getSBATStart() + ); + } + + public static void displayHeader(HeaderBlockReader header_block_reader) throws Exception { + System.out.println("Header Details:"); + System.out.println(" Block size: " + header_block_reader.getBigBlockSize()); + System.out.println(" BAT (FAT) header blocks: " + header_block_reader.getBATArray().length); + System.out.println(" BAT (FAT) block count: " + header_block_reader.getBATCount()); + System.out.println(" XBAT (FAT) block count: " + header_block_reader.getXBATCount()); + System.out.println(" XBAT (FAT) block 1 at: " + header_block_reader.getXBATIndex()); + System.out.println(" SBAT (MiniFAT) block count: " + header_block_reader.getSBATCount()); + System.out.println(" SBAT (MiniFAT) block 1 at: " + header_block_reader.getSBATStart()); + System.out.println(" Property table at: " + header_block_reader.getPropertyStart()); + System.out.println(""); + } + + public static void displayRawBlocksSummary(RawDataBlockList data_blocks) throws Exception { + System.out.println("Raw Blocks Details:"); + System.out.println(" Number of blocks: " + data_blocks.blockCount()); + + Method gbm = data_blocks.getClass().getSuperclass().getDeclaredMethod("get", int.class); + gbm.setAccessible(true); + + for(int i=0; i " + bnS); + } + + System.out.println(""); + } +} diff --git a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java index 6a1423ea4..bb83bf815 100644 --- a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java +++ b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java @@ -82,7 +82,8 @@ public class POIFSReader // set up the block allocation table (necessary for the // data_blocks to be manageable - new BlockAllocationTableReader(header_block_reader.getBATCount(), + new BlockAllocationTableReader(header_block_reader.getBigBlockSize(), + header_block_reader.getBATCount(), header_block_reader.getBATArray(), header_block_reader.getXBATCount(), header_block_reader.getXBATIndex(), @@ -90,14 +91,17 @@ public class POIFSReader // get property table from the document PropertyTable properties = - new PropertyTable(header_block_reader.getPropertyStart(), + new PropertyTable(header_block_reader.getBigBlockSize(), + header_block_reader.getPropertyStart(), data_blocks); // process documents processProperties(SmallBlockTableReader - .getSmallDocumentBlocks(data_blocks, properties - .getRoot(), header_block_reader - .getSBATStart()), data_blocks, properties.getRoot() + .getSmallDocumentBlocks( + header_block_reader.getBigBlockSize(), + data_blocks, properties.getRoot(), + header_block_reader.getSBATStart()), + data_blocks, properties.getRoot() .getChildren(), new POIFSDocumentPath()); } diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java index 7e0df0013..c06e4dc46 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.dev.POIFSViewable; import org.apache.poi.poifs.property.DocumentProperty; @@ -48,12 +49,14 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView private static final SmallDocumentBlock[] EMPTY_SMALL_BLOCK_ARRAY = { }; private DocumentProperty _property; private int _size; + + private final POIFSBigBlockSize _bigBigBlockSize; // one of these stores will be valid private SmallBlockStore _small_store; private BigBlockStore _big_store; - - /** + + /** * Constructor from large blocks * * @param name the name of the POIFSDocument @@ -62,9 +65,18 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView */ public POIFSDocument(String name, RawDataBlock[] blocks, int length) throws IOException { _size = length; - _big_store = new BigBlockStore(convertRawBlocksToBigBlocks(blocks)); + if(blocks.length == 0) { + _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; + } else { + _bigBigBlockSize = (blocks[0].getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ? + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS : + POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS + ); + } + + _big_store = new BigBlockStore(_bigBigBlockSize, convertRawBlocksToBigBlocks(blocks)); _property = new DocumentProperty(name, _size); - _small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY); + _small_store = new SmallBlockStore(_bigBigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); _property.setDocument(this); } @@ -94,9 +106,16 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView */ public POIFSDocument(String name, SmallDocumentBlock[] blocks, int length) { _size = length; - _big_store = new BigBlockStore(EMPTY_BIG_BLOCK_ARRAY); + + if(blocks.length == 0) { + _bigBigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; + } else { + _bigBigBlockSize = blocks[0].getBigBlockSize(); + } + + _big_store = new BigBlockStore(_bigBigBlockSize, EMPTY_BIG_BLOCK_ARRAY); _property = new DocumentProperty(name, _size); - _small_store = new SmallBlockStore(blocks); + _small_store = new SmallBlockStore(_bigBigBlockSize, blocks); _property.setDocument(this); } @@ -107,18 +126,22 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView * @param blocks the small blocks making up the POIFSDocument * @param length the actual length of the POIFSDocument */ - public POIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException { + public POIFSDocument(String name, POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, int length) throws IOException { _size = length; + _bigBigBlockSize = bigBlockSize; _property = new DocumentProperty(name, _size); _property.setDocument(this); if (Property.isSmall(_size)) { - _big_store = new BigBlockStore(EMPTY_BIG_BLOCK_ARRAY); - _small_store = new SmallBlockStore(convertRawBlocksToSmallBlocks(blocks)); + _big_store = new BigBlockStore(bigBlockSize,EMPTY_BIG_BLOCK_ARRAY); + _small_store = new SmallBlockStore(bigBlockSize,convertRawBlocksToSmallBlocks(blocks)); } else { - _big_store = new BigBlockStore(convertRawBlocksToBigBlocks(blocks)); - _small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY); + _big_store = new BigBlockStore(bigBlockSize,convertRawBlocksToBigBlocks(blocks)); + _small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY); } } + public POIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException { + this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, blocks, length); + } /** * Constructor @@ -126,12 +149,13 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView * @param name the name of the POIFSDocument * @param stream the InputStream we read data from */ - public POIFSDocument(String name, InputStream stream) throws IOException { + public POIFSDocument(String name, POIFSBigBlockSize bigBlockSize, InputStream stream) throws IOException { List blocks = new ArrayList(); _size = 0; + _bigBigBlockSize = bigBlockSize; while (true) { - DocumentBlock block = new DocumentBlock(stream); + DocumentBlock block = new DocumentBlock(stream, bigBlockSize); int blockSize = block.size(); if (blockSize > 0) { @@ -144,16 +168,19 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView } DocumentBlock[] bigBlocks = blocks.toArray(new DocumentBlock[blocks.size()]); - _big_store = new BigBlockStore(bigBlocks); + _big_store = new BigBlockStore(bigBlockSize,bigBlocks); _property = new DocumentProperty(name, _size); _property.setDocument(this); if (_property.shouldUseSmallBlocks()) { - _small_store = new SmallBlockStore(SmallDocumentBlock.convert(bigBlocks, _size)); - _big_store = new BigBlockStore(new DocumentBlock[0]); + _small_store = new SmallBlockStore(bigBlockSize,SmallDocumentBlock.convert(bigBlockSize,bigBlocks, _size)); + _big_store = new BigBlockStore(bigBlockSize,new DocumentBlock[0]); } else { - _small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY); + _small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY); } } + public POIFSDocument(String name, InputStream stream) throws IOException { + this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, stream); + } /** * Constructor @@ -163,18 +190,22 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView * @param path the path of the POIFSDocument * @param writer the writer who will eventually write the document contents */ - public POIFSDocument(String name, int size, POIFSDocumentPath path, POIFSWriterListener writer) { + public POIFSDocument(String name, int size, POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, POIFSWriterListener writer) { _size = size; + _bigBigBlockSize = bigBlockSize; _property = new DocumentProperty(name, _size); _property.setDocument(this); if (_property.shouldUseSmallBlocks()) { - _small_store = new SmallBlockStore(path, name, size, writer); - _big_store = new BigBlockStore(EMPTY_BIG_BLOCK_ARRAY); + _small_store = new SmallBlockStore(_bigBigBlockSize, path, name, size, writer); + _big_store = new BigBlockStore(_bigBigBlockSize, EMPTY_BIG_BLOCK_ARRAY); } else { - _small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY); - _big_store = new BigBlockStore(path, name, size, writer); + _small_store = new SmallBlockStore(_bigBigBlockSize, EMPTY_SMALL_BLOCK_ARRAY); + _big_store = new BigBlockStore(_bigBigBlockSize, path, name, size, writer); } } + public POIFSDocument(String name, int size, POIFSDocumentPath path, POIFSWriterListener writer) { + this(name, size, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, path, writer); + } /** * @return array of SmallDocumentBlocks; may be empty, cannot be null @@ -381,13 +412,15 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView private final String _name; private final int _size; private final POIFSWriterListener _writer; + private final POIFSBigBlockSize _bigBlockSize; /** * Constructor * * @param blocks blocks to construct the store from */ - SmallBlockStore(SmallDocumentBlock[] blocks) { + SmallBlockStore(POIFSBigBlockSize bigBlockSize, SmallDocumentBlock[] blocks) { + _bigBlockSize = bigBlockSize; _smallBlocks = blocks.clone(); this._path = null; this._name = null; @@ -403,7 +436,9 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView * @param size length of the document * @param writer the object that will eventually write the document */ - SmallBlockStore(POIFSDocumentPath path, String name, int size, POIFSWriterListener writer) { + SmallBlockStore(POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, + String name, int size, POIFSWriterListener writer) { + _bigBlockSize = bigBlockSize; _smallBlocks = new SmallDocumentBlock[0]; this._path = path; this._name = name; @@ -427,7 +462,7 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView DocumentOutputStream dstream = new DocumentOutputStream(stream, _size); _writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, _path, _name, _size)); - _smallBlocks = SmallDocumentBlock.convert(stream.toByteArray(), _size); + _smallBlocks = SmallDocumentBlock.convert(_bigBlockSize, stream.toByteArray(), _size); } return _smallBlocks; } @@ -439,13 +474,15 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView private final String _name; private final int _size; private final POIFSWriterListener _writer; + private final POIFSBigBlockSize _bigBlockSize; /** * Constructor * * @param blocks the blocks making up the store */ - BigBlockStore(DocumentBlock[] blocks) { + BigBlockStore(POIFSBigBlockSize bigBlockSize, DocumentBlock[] blocks) { + _bigBlockSize = bigBlockSize; bigBlocks = blocks.clone(); _path = null; _name = null; @@ -461,7 +498,9 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView * @param size length of the document * @param writer the object that will eventually write the document */ - BigBlockStore(POIFSDocumentPath path, String name, int size, POIFSWriterListener writer) { + BigBlockStore(POIFSBigBlockSize bigBlockSize, POIFSDocumentPath path, + String name, int size, POIFSWriterListener writer) { + _bigBlockSize = bigBlockSize; bigBlocks = new DocumentBlock[0]; _path = path; _name = name; @@ -485,7 +524,7 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView DocumentOutputStream dstream = new DocumentOutputStream(stream, _size); _writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, _path, _name, _size)); - bigBlocks = DocumentBlock.convert(stream.toByteArray(), _size); + bigBlocks = DocumentBlock.convert(_bigBlockSize, stream.toByteArray(), _size); } return bigBlocks; } @@ -501,7 +540,7 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView DocumentOutputStream dstream = new DocumentOutputStream(stream, _size); _writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, _path, _name, _size)); - dstream.writeFiller(countBlocks() * POIFSConstants.BIG_BLOCK_SIZE, + dstream.writeFiller(countBlocks() * _bigBlockSize.getBigBlockSize(), DocumentBlock.getFillByte()); } else { for (int k = 0; k < bigBlocks.length; k++) { @@ -520,8 +559,8 @@ public final class POIFSDocument implements BATManaged, BlockWritable, POIFSView if (_writer == null) { return bigBlocks.length; } - return (_size + POIFSConstants.BIG_BLOCK_SIZE - 1) - / POIFSConstants.BIG_BLOCK_SIZE; + return (_size + _bigBlockSize.getBigBlockSize() - 1) + / _bigBlockSize.getBigBlockSize(); } return 0; } diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java index 9c52a67b1..0a5f97844 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.dev.POIFSViewable; import org.apache.poi.poifs.property.DirectoryProperty; @@ -97,14 +98,15 @@ public class POIFSFileSystem * What big block size the file uses. Most files * use 512 bytes, but a few use 4096 */ - private int bigBlockSize = POIFSConstants.BIG_BLOCK_SIZE; + private POIFSBigBlockSize bigBlockSize = + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; /** * Constructor, intended for writing */ public POIFSFileSystem() { - _property_table = new PropertyTable(); + _property_table = new PropertyTable(bigBlockSize); _documents = new ArrayList(); _root = null; } @@ -161,7 +163,8 @@ public class POIFSFileSystem // set up the block allocation table (necessary for the // data_blocks to be manageable - new BlockAllocationTableReader(header_block_reader.getBATCount(), + new BlockAllocationTableReader(header_block_reader.getBigBlockSize(), + header_block_reader.getBATCount(), header_block_reader.getBATArray(), header_block_reader.getXBATCount(), header_block_reader.getXBATIndex(), @@ -169,13 +172,14 @@ public class POIFSFileSystem // get property table from the document PropertyTable properties = - new PropertyTable(header_block_reader.getPropertyStart(), + new PropertyTable(bigBlockSize, + header_block_reader.getPropertyStart(), data_blocks); // init documents processProperties( SmallBlockTableReader.getSmallDocumentBlocks( - data_blocks, properties.getRoot(), + bigBlockSize, data_blocks, properties.getRoot(), header_block_reader.getSBATStart() ), data_blocks, @@ -315,11 +319,11 @@ public class POIFSFileSystem // create the small block store, and the SBAT SmallBlockTableWriter sbtw = - new SmallBlockTableWriter(_documents, _property_table.getRoot()); + new SmallBlockTableWriter(bigBlockSize, _documents, _property_table.getRoot()); // create the block allocation table BlockAllocationTableWriter bat = - new BlockAllocationTableWriter(); + new BlockAllocationTableWriter(bigBlockSize); // create a list of BATManaged objects: the documents plus the // property table and the small block table @@ -357,7 +361,7 @@ public class POIFSFileSystem int batStartBlock = bat.createBlocks(); // get the extended block allocation table blocks - HeaderBlockWriter header_block_writer = new HeaderBlockWriter(); + HeaderBlockWriter header_block_writer = new HeaderBlockWriter(bigBlockSize); BATBlock[] xbat_blocks = header_block_writer.setBATBlocks(bat.countBlocks(), batStartBlock); @@ -612,7 +616,13 @@ public class POIFSFileSystem * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes */ public int getBigBlockSize() { - return bigBlockSize; + return bigBlockSize.getBigBlockSize(); + } + /** + * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes + */ + public POIFSBigBlockSize getBigBlockSizeDetails() { + return bigBlockSize; } /* ********** END begin implementation of POIFSViewable ********** */ diff --git a/src/java/org/apache/poi/poifs/property/PropertyTable.java b/src/java/org/apache/poi/poifs/property/PropertyTable.java index 09e447b05..3fe40d528 100644 --- a/src/java/org/apache/poi/poifs/property/PropertyTable.java +++ b/src/java/org/apache/poi/poifs/property/PropertyTable.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Stack; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.BATManaged; import org.apache.poi.poifs.storage.BlockWritable; @@ -37,12 +38,14 @@ import org.apache.poi.poifs.storage.RawDataBlockList; * @author Marc Johnson (mjohnson at apache dot org) */ public final class PropertyTable implements BATManaged, BlockWritable { - private int _start_block; - private List _properties; - private BlockWritable[] _blocks; + private POIFSBigBlockSize _bigBigBlockSize; + private int _start_block; + private List _properties; + private BlockWritable[] _blocks; - public PropertyTable() + public PropertyTable(POIFSBigBlockSize bigBlockSize) { + _bigBigBlockSize = bigBlockSize; _start_block = POIFSConstants.END_OF_CHAIN; _properties = new ArrayList(); addProperty(new RootProperty()); @@ -60,10 +63,12 @@ public final class PropertyTable implements BATManaged, BlockWritable { * @exception IOException if anything goes wrong (which should be * a result of the input being NFG) */ - public PropertyTable(final int startBlock, + public PropertyTable(final POIFSBigBlockSize bigBlockSize, + final int startBlock, final RawDataBlockList blockList) throws IOException { + _bigBigBlockSize = bigBlockSize; _start_block = POIFSConstants.END_OF_CHAIN; _blocks = null; _properties = @@ -118,7 +123,7 @@ public final class PropertyTable implements BATManaged, BlockWritable { } // allocate the blocks for the property table - _blocks = PropertyBlock.createPropertyBlockArray(_properties); + _blocks = PropertyBlock.createPropertyBlockArray(_bigBigBlockSize, _properties); // prepare each property for writing for (int k = 0; k < properties.length; k++) diff --git a/src/java/org/apache/poi/poifs/storage/BATBlock.java b/src/java/org/apache/poi/poifs/storage/BATBlock.java index 949a5254a..cfda4da91 100644 --- a/src/java/org/apache/poi/poifs/storage/BATBlock.java +++ b/src/java/org/apache/poi/poifs/storage/BATBlock.java @@ -22,6 +22,7 @@ import java.io.OutputStream; import java.util.Arrays; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.IntegerField; import org.apache.poi.util.LittleEndianConsts; @@ -33,12 +34,6 @@ import org.apache.poi.util.LittleEndianConsts; * @author Marc Johnson (mjohnson at apache dot org) */ public final class BATBlock extends BigBlock { - private static final int _entries_per_block = - POIFSConstants.BIG_BLOCK_SIZE / LittleEndianConsts.INT_SIZE; - private static final int _entries_per_xbat_block = _entries_per_block - - 1; - private static final int _xbat_chain_offset = - _entries_per_xbat_block * LittleEndianConsts.INT_SIZE; private static final byte _default_value = ( byte ) 0xFF; private IntegerField[] _fields; private byte[] _data; @@ -47,9 +42,13 @@ public final class BATBlock extends BigBlock { * Create a single instance initialized with default values */ - private BATBlock() + private BATBlock(POIFSBigBlockSize bigBlockSize) { - _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ]; + super(bigBlockSize); + + int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); + + _data = new byte[ bigBlockSize.getBigBlockSize() ]; Arrays.fill(_data, _default_value); _fields = new IntegerField[ _entries_per_block ]; int offset = 0; @@ -70,16 +69,17 @@ public final class BATBlock extends BigBlock { * @return the newly created array of BATBlocks */ - public static BATBlock [] createBATBlocks(final int [] entries) + public static BATBlock [] createBATBlocks(final POIFSBigBlockSize bigBlockSize, final int [] entries) { - int block_count = calculateStorageRequirements(entries.length); + int block_count = calculateStorageRequirements(bigBlockSize, entries.length); BATBlock[] blocks = new BATBlock[ block_count ]; int index = 0; int remaining = entries.length; + int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); for (int j = 0; j < entries.length; j += _entries_per_block) { - blocks[ index++ ] = new BATBlock(entries, j, + blocks[ index++ ] = new BATBlock(bigBlockSize, entries, j, (remaining > _entries_per_block) ? j + _entries_per_block : entries.length); @@ -98,21 +98,23 @@ public final class BATBlock extends BigBlock { * @return the newly created array of BATBlocks */ - public static BATBlock [] createXBATBlocks(final int [] entries, + public static BATBlock [] createXBATBlocks(final POIFSBigBlockSize bigBlockSize, + final int [] entries, final int startBlock) { int block_count = - calculateXBATStorageRequirements(entries.length); + calculateXBATStorageRequirements(bigBlockSize, entries.length); BATBlock[] blocks = new BATBlock[ block_count ]; int index = 0; int remaining = entries.length; + int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); if (block_count != 0) { for (int j = 0; j < entries.length; j += _entries_per_xbat_block) { blocks[ index++ ] = - new BATBlock(entries, j, + new BATBlock(bigBlockSize, entries, j, (remaining > _entries_per_xbat_block) ? j + _entries_per_xbat_block : entries.length); @@ -120,9 +122,9 @@ public final class BATBlock extends BigBlock { } for (index = 0; index < blocks.length - 1; index++) { - blocks[ index ].setXBATChain(startBlock + index + 1); + blocks[ index ].setXBATChain(bigBlockSize, startBlock + index + 1); } - blocks[ index ].setXBATChain(POIFSConstants.END_OF_CHAIN); + blocks[ index ].setXBATChain(bigBlockSize, POIFSConstants.END_OF_CHAIN); } return blocks; } @@ -136,8 +138,9 @@ public final class BATBlock extends BigBlock { * @return the number of BATBlocks needed */ - public static int calculateStorageRequirements(final int entryCount) + public static int calculateStorageRequirements(final POIFSBigBlockSize bigBlockSize, final int entryCount) { + int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); return (entryCount + _entries_per_block - 1) / _entries_per_block; } @@ -150,41 +153,16 @@ public final class BATBlock extends BigBlock { * @return the number of XBATBlocks needed */ - public static int calculateXBATStorageRequirements(final int entryCount) + public static int calculateXBATStorageRequirements(final POIFSBigBlockSize bigBlockSize, final int entryCount) { + int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); return (entryCount + _entries_per_xbat_block - 1) / _entries_per_xbat_block; } - /** - * @return number of entries per block - */ - - public static final int entriesPerBlock() - { - return _entries_per_block; - } - - /** - * @return number of entries per XBAT block - */ - - public static final int entriesPerXBATBlock() - { - return _entries_per_xbat_block; - } - - /** - * @return offset of chain index of XBAT block - */ - - public static final int getXBATChainOffset() - { - return _xbat_chain_offset; - } - - private void setXBATChain(int chainIndex) + private void setXBATChain(final POIFSBigBlockSize bigBlockSize, int chainIndex) { + int _entries_per_xbat_block = bigBlockSize.getXBATEntriesPerBlock(); _fields[ _entries_per_xbat_block ].set(chainIndex, _data); } @@ -199,10 +177,10 @@ public final class BATBlock extends BigBlock { * k, start_index <= k < end_index) */ - private BATBlock(final int [] entries, final int start_index, - final int end_index) + private BATBlock(POIFSBigBlockSize bigBlockSize, final int [] entries, + final int start_index, final int end_index) { - this(); + this(bigBlockSize); for (int k = start_index; k < end_index; k++) { _fields[ k - start_index ].set(entries[ k ], _data); diff --git a/src/java/org/apache/poi/poifs/storage/BigBlock.java b/src/java/org/apache/poi/poifs/storage/BigBlock.java index 2ca0d307d..e9b41928b 100644 --- a/src/java/org/apache/poi/poifs/storage/BigBlock.java +++ b/src/java/org/apache/poi/poifs/storage/BigBlock.java @@ -33,9 +33,21 @@ package org.apache.poi.poifs.storage; import java.io.IOException; import java.io.OutputStream; +import org.apache.poi.poifs.common.POIFSBigBlockSize; +import org.apache.poi.poifs.common.POIFSConstants; + abstract class BigBlock implements BlockWritable { + /** + * Either 512 bytes ({@link POIFSConstants#SMALLER_BIG_BLOCK_SIZE}) + * or 4096 bytes ({@link POIFSConstants#LARGER_BIG_BLOCK_SIZE}) + */ + protected POIFSBigBlockSize bigBlockSize; + + protected BigBlock(POIFSBigBlockSize bigBlockSize) { + this.bigBlockSize = bigBlockSize; + } /** * Default implementation of write for extending classes that diff --git a/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java b/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java index ae5efe312..f2c511200 100644 --- a/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java +++ b/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.*; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.IntList; import org.apache.poi.util.LittleEndian; @@ -56,6 +57,7 @@ public final class BlockAllocationTableReader { */ private static final int MAX_BLOCK_COUNT = 65535; private final IntList _entries; + private POIFSBigBlockSize bigBlockSize; /** * create a BlockAllocationTableReader for an existing filesystem. Side @@ -75,9 +77,10 @@ public final class BlockAllocationTableReader { * @exception IOException if, in trying to create the table, we * encounter logic errors */ - public BlockAllocationTableReader(int block_count, int [] block_array, + public BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, int block_count, int [] block_array, int xbat_count, int xbat_index, BlockList raw_block_list) throws IOException { - this(); + this(bigBlockSize); + if (block_count <= 0) { throw new IOException( "Illegal block count; minimum count is 1, got " + block_count @@ -128,8 +131,8 @@ public final class BlockAllocationTableReader { "BAT count exceeds limit, yet XBAT index indicates no valid entries"); } int chain_index = xbat_index; - int max_entries_per_block = BATBlock.entriesPerXBATBlock(); - int chain_index_offset = BATBlock.getXBATChainOffset(); + int max_entries_per_block = bigBlockSize.getXBATEntriesPerBlock(); + int chain_index_offset = bigBlockSize.getNextXBATChainOffset(); // Each XBAT block contains either: // (maximum number of sector indexes) + index of next XBAT @@ -173,13 +176,14 @@ public final class BlockAllocationTableReader { * * @exception IOException */ - BlockAllocationTableReader(ListManagedBlock[] blocks, BlockList raw_block_list) + BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, BlockList raw_block_list) throws IOException { - this(); + this(bigBlockSize); setEntries(blocks, raw_block_list); } - BlockAllocationTableReader() { + BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize) { + this.bigBlockSize = bigBlockSize; _entries = new IntList(); } @@ -279,7 +283,7 @@ public final class BlockAllocationTableReader { * blocks will be eliminated from the list */ private void setEntries(ListManagedBlock[] blocks, BlockList raw_blocks) throws IOException { - int limit = BATBlock.entriesPerBlock(); + int limit = bigBlockSize.getBATEntriesPerBlock(); for (int block_index = 0; block_index < blocks.length; block_index++) { diff --git a/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java b/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java index e2adcb766..12a88c34d 100644 --- a/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java +++ b/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java @@ -20,6 +20,7 @@ package org.apache.poi.poifs.storage; import java.io.IOException; import java.io.OutputStream; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.BATManaged; import org.apache.poi.util.IntList; @@ -43,15 +44,17 @@ public final class BlockAllocationTableWriter implements BlockWritable, BATManag private IntList _entries; private BATBlock[] _blocks; private int _start_block; + private POIFSBigBlockSize _bigBlockSize; /** * create a BlockAllocationTableWriter */ - public BlockAllocationTableWriter() + public BlockAllocationTableWriter(POIFSBigBlockSize bigBlockSize) { - _start_block = POIFSConstants.END_OF_CHAIN; - _entries = new IntList(); - _blocks = new BATBlock[ 0 ]; + _bigBlockSize = bigBlockSize; + _start_block = POIFSConstants.END_OF_CHAIN; + _entries = new IntList(); + _blocks = new BATBlock[ 0 ]; } /** @@ -67,12 +70,13 @@ public final class BlockAllocationTableWriter implements BlockWritable, BATManag while (true) { int calculated_bat_blocks = - BATBlock.calculateStorageRequirements(bat_blocks + BATBlock.calculateStorageRequirements(_bigBlockSize, + bat_blocks + xbat_blocks + _entries.size()); int calculated_xbat_blocks = - HeaderBlockWriter - .calculateXBATStorageRequirements(calculated_bat_blocks); + HeaderBlockWriter.calculateXBATStorageRequirements( + _bigBlockSize, calculated_bat_blocks); if ((bat_blocks == calculated_bat_blocks) && (xbat_blocks == calculated_xbat_blocks)) @@ -131,7 +135,7 @@ public final class BlockAllocationTableWriter implements BlockWritable, BATManag */ void simpleCreateBlocks() { - _blocks = BATBlock.createBATBlocks(_entries.toArray()); + _blocks = BATBlock.createBATBlocks(_bigBlockSize, _entries.toArray()); } /** diff --git a/src/java/org/apache/poi/poifs/storage/DocumentBlock.java b/src/java/org/apache/poi/poifs/storage/DocumentBlock.java index 7c1f028ed..3f84fa6e6 100644 --- a/src/java/org/apache/poi/poifs/storage/DocumentBlock.java +++ b/src/java/org/apache/poi/poifs/storage/DocumentBlock.java @@ -22,6 +22,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.IOUtils; @@ -50,6 +51,11 @@ public final class DocumentBlock extends BigBlock { public DocumentBlock(final RawDataBlock block) throws IOException { + super( + block.getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ? + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS : + POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS + ); _data = block.getData(); _bytes_read = _data.length; } @@ -62,10 +68,10 @@ public final class DocumentBlock extends BigBlock { * @exception IOException */ - public DocumentBlock(final InputStream stream) + public DocumentBlock(final InputStream stream, POIFSBigBlockSize bigBlockSize) throws IOException { - this(); + this(bigBlockSize); int count = IOUtils.readFully(stream, _data); _bytes_read = (count == -1) ? 0 @@ -76,9 +82,10 @@ public final class DocumentBlock extends BigBlock { * Create a single instance initialized with default values */ - private DocumentBlock() + private DocumentBlock(POIFSBigBlockSize bigBlockSize) { - _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ]; + super(bigBlockSize); + _data = new byte[ bigBlockSize.getBigBlockSize() ]; Arrays.fill(_data, _default_value); } @@ -101,7 +108,7 @@ public final class DocumentBlock extends BigBlock { public boolean partiallyRead() { - return _bytes_read != POIFSConstants.BIG_BLOCK_SIZE; + return _bytes_read != bigBlockSize.getBigBlockSize(); } /** @@ -124,26 +131,27 @@ public final class DocumentBlock extends BigBlock { * input array */ - public static DocumentBlock [] convert(final byte [] array, + public static DocumentBlock [] convert(final POIFSBigBlockSize bigBlockSize, + final byte [] array, final int size) { DocumentBlock[] rval = - new DocumentBlock[ (size + POIFSConstants.BIG_BLOCK_SIZE - 1) / POIFSConstants.BIG_BLOCK_SIZE ]; + new DocumentBlock[ (size + bigBlockSize.getBigBlockSize() - 1) / bigBlockSize.getBigBlockSize() ]; int offset = 0; for (int k = 0; k < rval.length; k++) { - rval[ k ] = new DocumentBlock(); + rval[ k ] = new DocumentBlock(bigBlockSize); if (offset < array.length) { - int length = Math.min(POIFSConstants.BIG_BLOCK_SIZE, + int length = Math.min(bigBlockSize.getBigBlockSize(), array.length - offset); System.arraycopy(array, offset, rval[ k ]._data, 0, length); - if (length != POIFSConstants.BIG_BLOCK_SIZE) + if (length != bigBlockSize.getBigBlockSize()) { Arrays.fill(rval[ k ]._data, length, - POIFSConstants.BIG_BLOCK_SIZE, + bigBlockSize.getBigBlockSize(), _default_value); } } @@ -151,7 +159,7 @@ public final class DocumentBlock extends BigBlock { { Arrays.fill(rval[ k ]._data, _default_value); } - offset += POIFSConstants.BIG_BLOCK_SIZE; + offset += bigBlockSize.getBigBlockSize(); } return rval; } diff --git a/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java b/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java index d5f327a52..27e4b41e8 100644 --- a/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java +++ b/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java @@ -30,8 +30,8 @@ public interface HeaderBlockConstants public static final long _signature = 0xE11AB1A1E011CFD0L; public static final int _bat_array_offset = 0x4c; public static final int _max_bats_in_header = - (POIFSConstants.BIG_BLOCK_SIZE - _bat_array_offset) - / LittleEndianConsts.INT_SIZE; + (POIFSConstants.SMALLER_BIG_BLOCK_SIZE - _bat_array_offset) + / LittleEndianConsts.INT_SIZE; // If 4k blocks, rest is blank // Note - in Microsoft terms: // BAT ~= FAT diff --git a/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java b/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java index a6961a27d..46e6e57f7 100644 --- a/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java +++ b/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java @@ -31,6 +31,7 @@ import static org.apache.poi.poifs.storage.HeaderBlockConstants._xbat_start_offs import java.io.IOException; import java.io.InputStream; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.OfficeXmlFileException; import org.apache.poi.util.HexDump; @@ -48,7 +49,7 @@ public final class HeaderBlockReader { * What big block size the file uses. Most files * use 512 bytes, but a few use 4096 */ - private final int bigBlockSize; + private final POIFSBigBlockSize bigBlockSize; /** * number of big block allocation table blocks (int). @@ -130,20 +131,20 @@ public final class HeaderBlockReader { // Figure out our block size switch (blockStart[30]) { case 12: - bigBlockSize = POIFSConstants.LARGER_BIG_BLOCK_SIZE; break; + bigBlockSize = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS; break; case 9: - bigBlockSize = POIFSConstants.BIG_BLOCK_SIZE; break; + bigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; break; default: throw new IOException("Unsupported blocksize (2^" + blockStart[30] + "). Expected 2^9 or 2^12."); } - _data = new byte[ bigBlockSize ]; + _data = new byte[ bigBlockSize.getBigBlockSize() ]; System.arraycopy(blockStart, 0, _data, 0, blockStart.length); // Now we can read the rest of our header int byte_count = IOUtils.readFully(stream, _data, blockStart.length, _data.length - blockStart.length); - if (byte_count+bsCount != bigBlockSize) { - throw alertShortRead(byte_count, bigBlockSize); + if (byte_count+bsCount != bigBlockSize.getBigBlockSize()) { + throw alertShortRead(byte_count, bigBlockSize.getBigBlockSize()); } _bat_count = getInt(_bat_count_offset, _data); @@ -237,7 +238,7 @@ public final class HeaderBlockReader { /** * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes */ - public int getBigBlockSize() { + public POIFSBigBlockSize getBigBlockSize() { return bigBlockSize; } } diff --git a/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java b/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java index 84d0036b7..acf001e15 100644 --- a/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java +++ b/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java @@ -23,6 +23,7 @@ import java.io.*; import java.util.*; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.IntegerField; import org.apache.poi.util.LittleEndianConsts; @@ -64,9 +65,11 @@ public class HeaderBlockWriter * Create a single instance initialized with default values */ - public HeaderBlockWriter() + public HeaderBlockWriter(POIFSBigBlockSize bigBlockSize) { - _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ]; + super(bigBlockSize); + + _data = new byte[ bigBlockSize.getBigBlockSize() ]; Arrays.fill(_data, _default_value); new LongField(_signature_offset, _signature, _data); new IntegerField(0x08, 0, _data); @@ -76,7 +79,15 @@ public class HeaderBlockWriter new ShortField(0x18, ( short ) 0x3b, _data); new ShortField(0x1a, ( short ) 0x3, _data); new ShortField(0x1c, ( short ) -2, _data); - new ShortField(0x1e, ( short ) 0x9, _data); + + new ShortField(0x1e, bigBlockSize.getHeaderValue(), _data); + if(bigBlockSize.getBigBlockSize() == POIFSConstants.LARGER_BIG_BLOCK_SIZE) { + // Need to fill the extra header size with zeros + for(int i=POIFSConstants.SMALLER_BIG_BLOCK_SIZE; i<_data.length; i++) { + _data[i] = 0; + } + } + new IntegerField(0x20, 0x6, _data); new IntegerField(0x24, 0, _data); new IntegerField(0x28, 0, _data); @@ -131,13 +142,13 @@ public class HeaderBlockWriter excess_block_array[ j ] = startBlock + j + _max_bats_in_header; } - rvalue = BATBlock.createXBATBlocks(excess_block_array, + rvalue = BATBlock.createXBATBlocks(bigBlockSize, excess_block_array, startBlock + blockCount); _xbat_start.set(startBlock + blockCount, _data); } else { - rvalue = BATBlock.createXBATBlocks(new int[ 0 ], 0); + rvalue = BATBlock.createXBATBlocks(bigBlockSize, new int[ 0 ], 0); _xbat_start.set(POIFSConstants.END_OF_CHAIN, _data); } _xbat_count.set(rvalue.length, _data); @@ -188,11 +199,11 @@ public class HeaderBlockWriter * @return number of XBAT blocks needed */ - static int calculateXBATStorageRequirements(final int blockCount) + static int calculateXBATStorageRequirements(POIFSBigBlockSize bigBlockSize, final int blockCount) { return (blockCount > _max_bats_in_header) - ? BATBlock.calculateXBATStorageRequirements(blockCount - - _max_bats_in_header) + ? BATBlock.calculateXBATStorageRequirements( + bigBlockSize, blockCount - _max_bats_in_header) : 0; } diff --git a/src/java/org/apache/poi/poifs/storage/PropertyBlock.java b/src/java/org/apache/poi/poifs/storage/PropertyBlock.java index c0400a552..06cb71c11 100644 --- a/src/java/org/apache/poi/poifs/storage/PropertyBlock.java +++ b/src/java/org/apache/poi/poifs/storage/PropertyBlock.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.List; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.property.Property; @@ -30,8 +31,6 @@ import org.apache.poi.poifs.property.Property; * @author Marc Johnson (mjohnson at apache dot org) */ public final class PropertyBlock extends BigBlock { - private static final int _properties_per_block = - POIFSConstants.BIG_BLOCK_SIZE / POIFSConstants.PROPERTY_SIZE; private Property[] _properties; /** @@ -41,10 +40,12 @@ public final class PropertyBlock extends BigBlock { * @param offset the offset into the properties array */ - private PropertyBlock(final Property [] properties, final int offset) + private PropertyBlock(final POIFSBigBlockSize bigBlockSize, final Property [] properties, final int offset) { - _properties = new Property[ _properties_per_block ]; - for (int j = 0; j < _properties_per_block; j++) + super(bigBlockSize); + + _properties = new Property[ bigBlockSize.getPropertiesPerBlock() ]; + for (int j = 0; j < _properties.length; j++) { _properties[ j ] = properties[ j + offset ]; } @@ -62,8 +63,9 @@ public final class PropertyBlock extends BigBlock { */ public static BlockWritable [] createPropertyBlockArray( - final List properties) + final POIFSBigBlockSize bigBlockSize, final List properties) { + int _properties_per_block = bigBlockSize.getPropertiesPerBlock(); int block_count = (properties.size() + _properties_per_block - 1) / _properties_per_block; @@ -93,7 +95,7 @@ public final class PropertyBlock extends BigBlock { for (int j = 0; j < block_count; j++) { - rvalue[ j ] = new PropertyBlock(to_be_written, + rvalue[ j ] = new PropertyBlock(bigBlockSize, to_be_written, j * _properties_per_block); } return rvalue; @@ -114,6 +116,7 @@ public final class PropertyBlock extends BigBlock { void writeData(final OutputStream stream) throws IOException { + int _properties_per_block = bigBlockSize.getPropertiesPerBlock(); for (int j = 0; j < _properties_per_block; j++) { _properties[ j ].writeData(stream); diff --git a/src/java/org/apache/poi/poifs/storage/RawDataBlock.java b/src/java/org/apache/poi/poifs/storage/RawDataBlock.java index a375885f9..07832db26 100644 --- a/src/java/org/apache/poi/poifs/storage/RawDataBlock.java +++ b/src/java/org/apache/poi/poifs/storage/RawDataBlock.java @@ -51,7 +51,7 @@ public class RawDataBlock */ public RawDataBlock(final InputStream stream) throws IOException { - this(stream, POIFSConstants.BIG_BLOCK_SIZE); + this(stream, POIFSConstants.SMALLER_BIG_BLOCK_SIZE); } /** * Constructor RawDataBlock @@ -134,6 +134,13 @@ public class RawDataBlock } return _data; } + + /** + * What's the big block size? + */ + public int getBigBlockSize() { + return _data.length; + } /* ********** END implementation of ListManagedBlock ********** */ } // end public class RawDataBlock diff --git a/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java b/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java index 66eb237a8..eb8bcc085 100644 --- a/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java +++ b/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java @@ -23,6 +23,8 @@ import java.io.*; import java.util.*; +import org.apache.poi.poifs.common.POIFSBigBlockSize; + /** * A list of RawDataBlocks instances, and methods to manage the list * @@ -43,14 +45,14 @@ public class RawDataBlockList * block is read */ - public RawDataBlockList(final InputStream stream, int bigBlockSize) + public RawDataBlockList(final InputStream stream, POIFSBigBlockSize bigBlockSize) throws IOException { - List blocks = new ArrayList(); + List blocks = new ArrayList(); while (true) { - RawDataBlock block = new RawDataBlock(stream, bigBlockSize); + RawDataBlock block = new RawDataBlock(stream, bigBlockSize.getBigBlockSize()); // If there was data, add the block to the list if(block.hasData()) { @@ -62,7 +64,7 @@ public class RawDataBlockList break; } } - setBlocks(( RawDataBlock [] ) blocks.toArray(new RawDataBlock[ 0 ])); + setBlocks( blocks.toArray(new RawDataBlock[ blocks.size() ]) ); } } // end public class RawDataBlockList diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java index c77b8fc1a..8b6efd36e 100644 --- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java +++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java @@ -19,6 +19,7 @@ package org.apache.poi.poifs.storage; import java.io.IOException; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.property.RootProperty; /** @@ -43,15 +44,22 @@ public final class SmallBlockTableReader { * @exception IOException */ public static BlockList getSmallDocumentBlocks( + final POIFSBigBlockSize bigBlockSize, final RawDataBlockList blockList, final RootProperty root, final int sbatStart) throws IOException { - BlockList list = - new SmallDocumentBlockList(SmallDocumentBlock - .extract(blockList.fetchBlocks(root.getStartBlock(), -1))); + // Fetch the blocks which hold the Small Blocks stream + ListManagedBlock [] smallBlockBlocks = + blockList.fetchBlocks(root.getStartBlock(), -1); + + // Turn that into a list + BlockList list =new SmallDocumentBlockList( + SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks)); - new BlockAllocationTableReader(blockList.fetchBlocks(sbatStart, -1), + // Process + new BlockAllocationTableReader(bigBlockSize, + blockList.fetchBlocks(sbatStart, -1), list); return list; } diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java index 4f89af154..2db7bf4c7 100644 --- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java +++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java @@ -19,6 +19,7 @@ package org.apache.poi.poifs.storage; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.BATManaged; import org.apache.poi.poifs.filesystem.POIFSDocument; @@ -50,10 +51,11 @@ public class SmallBlockTableWriter * @param root the Filesystem's root property */ - public SmallBlockTableWriter(final List documents, + public SmallBlockTableWriter(final POIFSBigBlockSize bigBlockSize, + final List documents, final RootProperty root) { - _sbat = new BlockAllocationTableWriter(); + _sbat = new BlockAllocationTableWriter(bigBlockSize); _small_blocks = new ArrayList(); _root = root; Iterator iter = documents.iterator(); @@ -76,7 +78,7 @@ public class SmallBlockTableWriter } _sbat.simpleCreateBlocks(); _root.setSize(_small_blocks.size()); - _big_block_count = SmallDocumentBlock.fill(_small_blocks); + _big_block_count = SmallDocumentBlock.fill(bigBlockSize,_small_blocks); } /** diff --git a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java index d0ecb1f19..e7762ffbf 100644 --- a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java +++ b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; /** @@ -40,19 +41,26 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock private static final int _block_size = 1 << BLOCK_SHIFT; private static final int BLOCK_MASK = _block_size-1; - private static final int _blocks_per_big_block = - POIFSConstants.BIG_BLOCK_SIZE / _block_size; + private final int _blocks_per_big_block; + private final POIFSBigBlockSize _bigBlockSize; - private SmallDocumentBlock(final byte [] data, final int index) + private SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize, final byte [] data, final int index) { - this(); + this(bigBlockSize); System.arraycopy(data, index * _block_size, _data, 0, _block_size); } - private SmallDocumentBlock() + private SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize) { + _bigBlockSize = bigBlockSize; + _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize); _data = new byte[ _block_size ]; } + + private static int getBlocksPerBigBlock(final POIFSBigBlockSize bigBlockSize) + { + return bigBlockSize.getBigBlockSize() / _block_size; + } /** * convert a single long array into an array of SmallDocumentBlock @@ -64,7 +72,8 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock * @return an array of SmallDocumentBlock instances, filled from * the array */ - public static SmallDocumentBlock [] convert(byte [] array, + public static SmallDocumentBlock [] convert(POIFSBigBlockSize bigBlockSize, + byte [] array, int size) { SmallDocumentBlock[] rval = @@ -73,7 +82,7 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock for (int k = 0; k < rval.length; k++) { - rval[ k ] = new SmallDocumentBlock(); + rval[ k ] = new SmallDocumentBlock(bigBlockSize); if (offset < array.length) { int length = Math.min(_block_size, array.length - offset); @@ -102,8 +111,10 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock * * @return number of big blocks the list encompasses */ - public static int fill(List blocks) + public static int fill(POIFSBigBlockSize bigBlockSize, List blocks) { + int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize); + int count = blocks.size(); int big_block_count = (count + _blocks_per_big_block - 1) / _blocks_per_big_block; @@ -111,7 +122,7 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock for (; count < full_count; count++) { - blocks.add(makeEmptySmallDocumentBlock()); + blocks.add(makeEmptySmallDocumentBlock(bigBlockSize)); } return big_block_count; } @@ -128,7 +139,8 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock * @exception ArrayIndexOutOfBoundsException if, somehow, the store * contains less data than size indicates */ - public static SmallDocumentBlock [] convert(BlockWritable [] store, + public static SmallDocumentBlock [] convert(POIFSBigBlockSize bigBlockSize, + BlockWritable [] store, int size) throws IOException, ArrayIndexOutOfBoundsException { @@ -144,7 +156,7 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock for (int index = 0; index < rval.length; index++) { - rval[ index ] = new SmallDocumentBlock(data, index); + rval[ index ] = new SmallDocumentBlock(bigBlockSize, data, index); } return rval; } @@ -157,9 +169,11 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock * * @return a List of SmallDocumentBlock's extracted from the input */ - public static List extract(ListManagedBlock [] blocks) + public static List extract(POIFSBigBlockSize bigBlockSize, ListManagedBlock [] blocks) throws IOException { + int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize); + List sdbs = new ArrayList(); for (int j = 0; j < blocks.length; j++) @@ -168,7 +182,7 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock for (int k = 0; k < _blocks_per_big_block; k++) { - sdbs.add(new SmallDocumentBlock(data, k)); + sdbs.add(new SmallDocumentBlock(bigBlockSize, data, k)); } } return sdbs; @@ -192,9 +206,9 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock return size * _block_size; } - private static SmallDocumentBlock makeEmptySmallDocumentBlock() + private static SmallDocumentBlock makeEmptySmallDocumentBlock(POIFSBigBlockSize bigBlockSize) { - SmallDocumentBlock block = new SmallDocumentBlock(); + SmallDocumentBlock block = new SmallDocumentBlock(bigBlockSize); Arrays.fill(block._data, _default_fill); return block; @@ -230,4 +244,8 @@ public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock public byte [] getData() { return _data; } + + public POIFSBigBlockSize getBigBlockSize() { + return _bigBlockSize; + } } diff --git a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java index b83ac224f..a510f8e8f 100644 --- a/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java +++ b/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java @@ -40,7 +40,7 @@ public class SmallDocumentBlockList public SmallDocumentBlockList(final List blocks) { setBlocks(( SmallDocumentBlock [] ) blocks - .toArray(new SmallDocumentBlock[ 0 ])); + .toArray(new SmallDocumentBlock[ blocks.size() ])); } } // end public class SmallDocumentBlockList diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index db4acdd09..289044474 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -448,8 +448,8 @@ public final class HWPFDocument extends POIDocument // determine the FileInformationBLock size int fibSize = _fib.getSize(); - fibSize += POIFSConstants.BIG_BLOCK_SIZE - - (fibSize % POIFSConstants.BIG_BLOCK_SIZE); + fibSize += POIFSConstants.SMALLER_BIG_BLOCK_SIZE - + (fibSize % POIFSConstants.SMALLER_BIG_BLOCK_SIZE); // preserve space for the FileInformationBlock because we will be writing // it after we write everything else. diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java index d8b51036b..e19f99fde 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java @@ -65,7 +65,7 @@ public final class CHPBinTable GenericPropertyNode node = binTable.getProperty(x); int pageNum = LittleEndian.getInt(node.getBytes()); - int pageOffset = POIFSConstants.BIG_BLOCK_SIZE * pageNum; + int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(documentStream, pageOffset, fcMin, tpt); @@ -187,16 +187,16 @@ public final class CHPBinTable // each FKP must start on a 512 byte page. int docOffset = docStream.getOffset(); - int mod = docOffset % POIFSConstants.BIG_BLOCK_SIZE; + int mod = docOffset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE; if (mod != 0) { - byte[] padding = new byte[POIFSConstants.BIG_BLOCK_SIZE - mod]; + byte[] padding = new byte[POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod]; docStream.write(padding); } // get the page number for the first fkp docOffset = docStream.getOffset(); - int pageNum = docOffset/POIFSConstants.BIG_BLOCK_SIZE; + int pageNum = docOffset/POIFSConstants.SMALLER_BIG_BLOCK_SIZE; // get the ending fc int endingFc = ((PropertyNode)_textRuns.get(_textRuns.size() - 1)).getEnd(); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java index 1aaeec0cf..9c24e48b8 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java @@ -58,7 +58,7 @@ public final class PAPBinTable GenericPropertyNode node = binTable.getProperty(x); int pageNum = LittleEndian.getInt(node.getBytes()); - int pageOffset = POIFSConstants.BIG_BLOCK_SIZE * pageNum; + int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(documentStream, dataStream, pageOffset, fcMin, tpt); @@ -195,16 +195,16 @@ public final class PAPBinTable // each FKP must start on a 512 byte page. int docOffset = docStream.getOffset(); - int mod = docOffset % POIFSConstants.BIG_BLOCK_SIZE; + int mod = docOffset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE; if (mod != 0) { - byte[] padding = new byte[POIFSConstants.BIG_BLOCK_SIZE - mod]; + byte[] padding = new byte[POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod]; docStream.write(padding); } // get the page number for the first fkp docOffset = docStream.getOffset(); - int pageNum = docOffset/POIFSConstants.BIG_BLOCK_SIZE; + int pageNum = docOffset/POIFSConstants.SMALLER_BIG_BLOCK_SIZE; // get the ending fc int endingFc = ((PropertyNode)_paragraphs.get(_paragraphs.size() - 1)).getEnd(); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java index 65dc9e191..0bc211975 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java @@ -172,9 +172,9 @@ public final class TextPieceTable implements CharIndexTranslator { PieceDescriptor pd = next.getPieceDescriptor(); int offset = docStream.getOffset(); - int mod = (offset % POIFSConstants.BIG_BLOCK_SIZE); + int mod = (offset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE); if (mod != 0) { - mod = POIFSConstants.BIG_BLOCK_SIZE - mod; + mod = POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod; byte[] buf = new byte[mod]; docStream.write(buf); } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java index 033ef7a02..46e47ca42 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java @@ -18,6 +18,8 @@ package org.apache.poi.poifs.filesystem; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -25,6 +27,9 @@ import junit.framework.TestCase; import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.poifs.common.POIFSBigBlockSize; +import org.apache.poi.poifs.storage.HeaderBlockReader; +import org.apache.poi.poifs.storage.RawDataBlockList; /** * Tests for POIFSFileSystem @@ -168,6 +173,34 @@ public final class TestPOIFSFileSystem extends TestCase { assertTrue(msg.startsWith("Your file contains 695 sectors")); } } + + /** + * Most OLE2 files use 512byte blocks. However, a small number + * use 4k blocks. Check that we can open these. + * DISABLED until we get a sample 4k block file that's under 22mb... + */ + public void DISABLEDtest4KBlocks() throws Exception { + InputStream inp = new FileInputStream(new File("/home/nick/Downloads/IP-ConvertImage-01.zvi")); + + // First up, check that we can process the header properly + HeaderBlockReader header_block_reader = new HeaderBlockReader(inp); + POIFSBigBlockSize bigBlockSize = header_block_reader.getBigBlockSize(); + assertEquals(4096, bigBlockSize.getBigBlockSize()); + + // Check the fat info looks sane + assertEquals(109, header_block_reader.getBATArray().length); + assertTrue(header_block_reader.getBATCount() > 5); + assertEquals(0, header_block_reader.getXBATCount()); + + // Now check we can get the basic fat + RawDataBlockList data_blocks = new RawDataBlockList(inp, bigBlockSize); + + + // Now try and open properly + POIFSFileSystem fs = new POIFSFileSystem( + new FileInputStream(new File("/home/nick/Downloads/IP-ConvertImage-01.zvi")) + ); + } private static InputStream openSampleStream(String sampleFileName) { return HSSFTestDataSamples.openSampleFileStream(sampleFileName); diff --git a/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java b/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java index 306822da6..0e404d488 100644 --- a/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java +++ b/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java @@ -70,7 +70,7 @@ public final class TestPropertyTable extends TestCase { public void testWriterPropertyTable() throws IOException { // create the PropertyTable - PropertyTable table = new PropertyTable(); + PropertyTable table = new PropertyTable(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); // create three DocumentProperty instances and add them to the // PropertyTable @@ -430,15 +430,17 @@ public final class TestPropertyTable extends TestCase { }; RawDataBlockList data_blocks = new RawDataBlockList(new ByteArrayInputStream(RawDataUtil - .decode(raw_data_array)), POIFSConstants.BIG_BLOCK_SIZE); + .decode(raw_data_array)), POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); int[] bat_array = { 15 }; // need to initialize the block list with a block allocation // table - new BlockAllocationTableReader(1, bat_array, 0, -2, data_blocks); + new BlockAllocationTableReader( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1, bat_array, 0, -2, data_blocks); // get property table from the document - PropertyTable table = new PropertyTable(0, data_blocks); + PropertyTable table = new PropertyTable( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 0, data_blocks); assertEquals(30 * 64, table.getRoot().getSize()); int count = 0; diff --git a/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java b/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java index a0f1ec347..42a9d2c5f 100644 --- a/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java +++ b/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java @@ -38,7 +38,7 @@ public final class LocalRawDataBlockList extends RawDataBlockList { public LocalRawDataBlockList() throws IOException { - super(new ByteArrayInputStream(new byte[ 0 ]), POIFSConstants.BIG_BLOCK_SIZE); + super(new ByteArrayInputStream(new byte[ 0 ]), POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); _list = new ArrayList(); _array = null; } diff --git a/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java index 950c0c0d7..c0b8b8813 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java @@ -21,6 +21,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; +import org.apache.poi.poifs.common.POIFSConstants; + import junit.framework.TestCase; /** @@ -39,27 +41,27 @@ public final class TestBATBlock extends TestCase { public void testCreateBATBlocks() throws IOException { // test 0 length array (basic sanity) - BATBlock[] rvalue = BATBlock.createBATBlocks(createTestArray(0)); + BATBlock[] rvalue = BATBlock.createBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(0)); assertEquals(0, rvalue.length); // test array of length 1 - rvalue = BATBlock.createBATBlocks(createTestArray(1)); + rvalue = BATBlock.createBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(1)); assertEquals(1, rvalue.length); verifyContents(rvalue, 1); // test array of length 127 - rvalue = BATBlock.createBATBlocks(createTestArray(127)); + rvalue = BATBlock.createBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(127)); assertEquals(1, rvalue.length); verifyContents(rvalue, 127); // test array of length 128 - rvalue = BATBlock.createBATBlocks(createTestArray(128)); + rvalue = BATBlock.createBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(128)); assertEquals(1, rvalue.length); verifyContents(rvalue, 128); // test array of length 129 - rvalue = BATBlock.createBATBlocks(createTestArray(129)); + rvalue = BATBlock.createBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(129)); assertEquals(2, rvalue.length); verifyContents(rvalue, 129); } @@ -105,32 +107,32 @@ public final class TestBATBlock extends TestCase { public void testCreateXBATBlocks() throws IOException { // test 0 length array (basic sanity) - BATBlock[] rvalue = BATBlock.createXBATBlocks(createTestArray(0), 1); + BATBlock[] rvalue = BATBlock.createXBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(0), 1); assertEquals(0, rvalue.length); // test array of length 1 - rvalue = BATBlock.createXBATBlocks(createTestArray(1), 1); + rvalue = BATBlock.createXBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(1), 1); assertEquals(1, rvalue.length); verifyXBATContents(rvalue, 1, 1); // test array of length 127 - rvalue = BATBlock.createXBATBlocks(createTestArray(127), 1); + rvalue = BATBlock.createXBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(127), 1); assertEquals(1, rvalue.length); verifyXBATContents(rvalue, 127, 1); // test array of length 128 - rvalue = BATBlock.createXBATBlocks(createTestArray(128), 1); + rvalue = BATBlock.createXBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(128), 1); assertEquals(2, rvalue.length); verifyXBATContents(rvalue, 128, 1); // test array of length 254 - rvalue = BATBlock.createXBATBlocks(createTestArray(254), 1); + rvalue = BATBlock.createXBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(254), 1); assertEquals(2, rvalue.length); verifyXBATContents(rvalue, 254, 1); // test array of length 255 - rvalue = BATBlock.createXBATBlocks(createTestArray(255), 1); + rvalue = BATBlock.createXBATBlocks(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, createTestArray(255), 1); assertEquals(3, rvalue.length); verifyXBATContents(rvalue, 255, 1); } @@ -193,17 +195,17 @@ public final class TestBATBlock extends TestCase { { assertEquals( "requirement for " + blockCounts[ j ], requirements[ j ], - BATBlock.calculateXBATStorageRequirements(blockCounts[ j ])); + BATBlock.calculateXBATStorageRequirements(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, blockCounts[ j ])); } } public void testEntriesPerBlock() { - assertEquals(128, BATBlock.entriesPerBlock()); + assertEquals(128, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS.getBATEntriesPerBlock()); } public void testEntriesPerXBATBlock() { - assertEquals(127, BATBlock.entriesPerXBATBlock()); + assertEquals(127, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS.getXBATEntriesPerBlock()); } public void testGetXBATChainOffset() { - assertEquals(508, BATBlock.getXBATChainOffset()); + assertEquals(508, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS.getNextXBATChainOffset()); } } diff --git a/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java b/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java index 9acef41df..45dd34c26 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java @@ -25,6 +25,7 @@ import java.util.Arrays; import junit.framework.AssertionFailedError; import junit.framework.TestCase; +import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.HexRead; import org.apache.poi.util.LittleEndian; @@ -187,8 +188,9 @@ public final class TestBlockAllocationTableReader extends TestCase { sbts[j] = new RawDataBlock(sbt_input); } SmallDocumentBlockList small_blocks = new SmallDocumentBlockList(SmallDocumentBlock - .extract(sbts)); - BlockAllocationTableReader sbat = new BlockAllocationTableReader(sbats, small_blocks); + .extract(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, sbts)); + BlockAllocationTableReader sbat = new BlockAllocationTableReader( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, sbats, small_blocks); boolean[] isUsed = { false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, @@ -271,7 +273,8 @@ public final class TestBlockAllocationTableReader extends TestCase { } list.fill(132); int[] blocks = { 2, 3 }; - BlockAllocationTableReader table = new BlockAllocationTableReader(130, blocks, 2, 0, list); + BlockAllocationTableReader table = new BlockAllocationTableReader( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 130, blocks, 2, 0, list); for (int i = 0; i < (130 * 128); i++) { if (i % 256 == 0) { @@ -353,7 +356,8 @@ public final class TestBlockAllocationTableReader extends TestCase { list.add(new RawDataBlock(new ByteArrayInputStream(data))); list.fill(1); int[] blocks = { 0 }; - BlockAllocationTableReader table = new BlockAllocationTableReader(1, blocks, 0, -2, list); + BlockAllocationTableReader table = new BlockAllocationTableReader( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1, blocks, 0, -2, list); int[] start_blocks = { -2, 1, 2, 3, 5, 7, 9, 11, 12 }; int[] expected_length = { 0, 1, -1, -1, -1, -1, -1, -1, 116 }; @@ -384,6 +388,9 @@ public final class TestBlockAllocationTableReader extends TestCase { */ public void testBadSectorAllocationTableSize_bug48085() { int BLOCK_SIZE = 512; + POIFSBigBlockSize bigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; + assertEquals(BLOCK_SIZE, bigBlockSize.getBigBlockSize()); + // 512 bytes take from the start of bugzilla attachment 24444 byte[] initData = HexRead.readFromString( @@ -402,12 +409,13 @@ public final class TestBlockAllocationTableReader extends TestCase { RawDataBlockList dataBlocks; try { hb = new HeaderBlockReader(stream); - dataBlocks = new RawDataBlockList(stream, BLOCK_SIZE); + dataBlocks = new RawDataBlockList(stream, bigBlockSize); } catch (IOException e) { throw new RuntimeException(e); } try { - new BlockAllocationTableReader(hb.getBATCount(), hb.getBATArray(), hb.getXBATCount(), + new BlockAllocationTableReader(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, + hb.getBATCount(), hb.getBATArray(), hb.getXBATCount(), hb.getXBATIndex(), dataBlocks); } catch (IOException e) { // expected during successful test diff --git a/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableWriter.java b/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableWriter.java index 69dd5943b..4539c60b3 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableWriter.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableWriter.java @@ -36,7 +36,7 @@ public final class TestBlockAllocationTableWriter extends TestCase { public void testAllocateSpace() { BlockAllocationTableWriter table = - new BlockAllocationTableWriter(); + new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); int[] blockSizes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 @@ -51,36 +51,36 @@ public final class TestBlockAllocationTableWriter extends TestCase { } public void testCreateBlocks() { - BlockAllocationTableWriter table = new BlockAllocationTableWriter(); + BlockAllocationTableWriter table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(127); table.createBlocks(); verifyBlocksCreated(table, 1); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(128); table.createBlocks(); verifyBlocksCreated(table, 2); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(254); table.createBlocks(); verifyBlocksCreated(table, 2); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(255); table.createBlocks(); verifyBlocksCreated(table, 3); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(13843); table.createBlocks(); verifyBlocksCreated(table, 109); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(13844); table.createBlocks(); verifyBlocksCreated(table, 110); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(13969); table.createBlocks(); verifyBlocksCreated(table, 110); - table = new BlockAllocationTableWriter(); + table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); table.allocateSpace(13970); table.createBlocks(); verifyBlocksCreated(table, 111); @@ -90,7 +90,7 @@ public final class TestBlockAllocationTableWriter extends TestCase { * Test content produced by BlockAllocationTableWriter */ public void testProduct() throws IOException { - BlockAllocationTableWriter table = new BlockAllocationTableWriter(); + BlockAllocationTableWriter table = new BlockAllocationTableWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); for (int k = 1; k <= 22; k++) { diff --git a/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java b/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java index 03f57c311..2a36dd0a4 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java @@ -25,6 +25,7 @@ import java.util.List; import junit.framework.TestCase; +import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndianConsts; @@ -142,10 +143,10 @@ public final class TestBlockListImpl extends TestCase { BlockListImpl list = create(); list.setBAT(null); - list.setBAT(new BlockAllocationTableReader()); + list.setBAT(new BlockAllocationTableReader(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS)); try { - list.setBAT(new BlockAllocationTableReader()); + list.setBAT(new BlockAllocationTableReader(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS)); fail("second attempt should have failed"); } catch (IOException ignored) @@ -233,7 +234,7 @@ public final class TestBlockListImpl extends TestCase { 0 }; BlockAllocationTableReader table = - new BlockAllocationTableReader(1, blocks, 0, -2, list); + new BlockAllocationTableReader(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1, blocks, 0, -2, list); int[] start_blocks = { -2, 1, 2, 3, 5, 7, 9, 11, 12 diff --git a/src/testcases/org/apache/poi/poifs/storage/TestDocumentBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestDocumentBlock.java index 3c15e2dea..313d92cb4 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestDocumentBlock.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestDocumentBlock.java @@ -21,6 +21,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.apache.poi.poifs.common.POIFSConstants; + import junit.framework.TestCase; /** @@ -55,7 +57,7 @@ public final class TestDocumentBlock extends TestCase { byte[] data = new byte[ Math.min(_testdata.length - index, 512) ]; System.arraycopy(_testdata, index, data, 0, data.length); - DocumentBlock block = new DocumentBlock(input); + DocumentBlock block = new DocumentBlock(input, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); verifyOutput(block, data); size += block.size(); diff --git a/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java b/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java index 213295541..456d30c52 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java @@ -23,6 +23,7 @@ import java.io.IOException; import junit.framework.TestCase; +import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndianConsts; @@ -46,7 +47,7 @@ public final class TestHeaderBlockWriter extends TestCase { * Test creating a HeaderBlockWriter */ public void testConstructors() throws IOException { - HeaderBlockWriter block = new HeaderBlockWriter(); + HeaderBlockWriter block = new HeaderBlockWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); ByteArrayOutputStream output = new ByteArrayOutputStream(512); block.writeBlocks(output); @@ -85,7 +86,7 @@ public final class TestHeaderBlockWriter extends TestCase { * Test setting the SBAT start block */ public void testSetSBATStart() throws IOException { - HeaderBlockWriter block = new HeaderBlockWriter(); + HeaderBlockWriter block = new HeaderBlockWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); block.setSBATStart(0x01234567); ByteArrayOutputStream output = new ByteArrayOutputStream(512); @@ -117,7 +118,7 @@ public final class TestHeaderBlockWriter extends TestCase { * test setPropertyStart and getPropertyStart */ public void testSetPropertyStart() throws IOException { - HeaderBlockWriter block = new HeaderBlockWriter(); + HeaderBlockWriter block = new HeaderBlockWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); block.setPropertyStart(0x01234567); ByteArrayOutputStream output = new ByteArrayOutputStream(512); @@ -152,11 +153,11 @@ public final class TestHeaderBlockWriter extends TestCase { public void testSetBATBlocks() throws IOException { // first, a small set of blocks - HeaderBlockWriter block = new HeaderBlockWriter(); + HeaderBlockWriter block = new HeaderBlockWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); BATBlock[] xbats = block.setBATBlocks(5, 0x01234567); assertEquals(0, xbats.length); - assertEquals(0, HeaderBlockWriter.calculateXBATStorageRequirements(5)); + assertEquals(0, HeaderBlockWriter.calculateXBATStorageRequirements(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,5)); ByteArrayOutputStream output = new ByteArrayOutputStream(512); block.writeBlocks(output); @@ -183,10 +184,10 @@ public final class TestHeaderBlockWriter extends TestCase { confirmEqual(expected, copy); // second, a full set of blocks (109 blocks) - block = new HeaderBlockWriter(); + block = new HeaderBlockWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); xbats = block.setBATBlocks(109, 0x01234567); assertEquals(0, xbats.length); - assertEquals(0, HeaderBlockWriter.calculateXBATStorageRequirements(109)); + assertEquals(0, HeaderBlockWriter.calculateXBATStorageRequirements(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,109)); output = new ByteArrayOutputStream(512); block.writeBlocks(output); copy = output.toByteArray(); @@ -211,10 +212,10 @@ public final class TestHeaderBlockWriter extends TestCase { confirmEqual(expected2, copy); // finally, a really large set of blocks (256 blocks) - block = new HeaderBlockWriter(); + block = new HeaderBlockWriter(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); xbats = block.setBATBlocks(256, 0x01234567); assertEquals(2, xbats.length); - assertEquals(2, HeaderBlockWriter.calculateXBATStorageRequirements(256)); + assertEquals(2, HeaderBlockWriter.calculateXBATStorageRequirements(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,256)); output = new ByteArrayOutputStream(512); block.writeBlocks(output); copy = output.toByteArray(); diff --git a/src/testcases/org/apache/poi/poifs/storage/TestPropertyBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestPropertyBlock.java index 2bbec9e62..0cf8398ab 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestPropertyBlock.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestPropertyBlock.java @@ -22,6 +22,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.apache.poi.poifs.common.POIFSConstants; + import junit.framework.TestCase; /** @@ -36,13 +38,13 @@ public final class TestPropertyBlock extends TestCase { // test with 0 properties List properties = new ArrayList(); BlockWritable[] blocks = - PropertyBlock.createPropertyBlockArray(properties); + PropertyBlock.createPropertyBlockArray(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,properties); assertEquals(0, blocks.length); // test with 1 property properties.add(new LocalProperty("Root Entry")); - blocks = PropertyBlock.createPropertyBlockArray(properties); + blocks = PropertyBlock.createPropertyBlockArray(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,properties); assertEquals(1, blocks.length); byte[] testblock = new byte[ 512 ]; @@ -66,7 +68,7 @@ public final class TestPropertyBlock extends TestCase { // test with 3 properties properties.add(new LocalProperty("workbook")); properties.add(new LocalProperty("summary")); - blocks = PropertyBlock.createPropertyBlockArray(properties); + blocks = PropertyBlock.createPropertyBlockArray(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,properties); assertEquals(1, blocks.length); testblock[ 0x0080 ] = ( byte ) 'w'; testblock[ 0x0082 ] = ( byte ) 'o'; @@ -89,7 +91,7 @@ public final class TestPropertyBlock extends TestCase { // test with 4 properties properties.add(new LocalProperty("wintery")); - blocks = PropertyBlock.createPropertyBlockArray(properties); + blocks = PropertyBlock.createPropertyBlockArray(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,properties); assertEquals(1, blocks.length); testblock[ 0x0180 ] = ( byte ) 'w'; testblock[ 0x0182 ] = ( byte ) 'i'; @@ -103,7 +105,7 @@ public final class TestPropertyBlock extends TestCase { // test with 5 properties properties.add(new LocalProperty("foo")); - blocks = PropertyBlock.createPropertyBlockArray(properties); + blocks = PropertyBlock.createPropertyBlockArray(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,properties); assertEquals(2, blocks.length); testblock = new byte[ 1024 ]; for (int j = 0; j < 8; j++) diff --git a/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlockList.java b/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlockList.java index ec07c3864..6dabfc043 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlockList.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlockList.java @@ -51,14 +51,14 @@ public final class TestRawDataBlockList extends TestCase { { data[ j ] = ( byte ) j; } - new RawDataBlockList(new ByteArrayInputStream(data), POIFSConstants.BIG_BLOCK_SIZE); + new RawDataBlockList(new ByteArrayInputStream(data), POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); } /** * Test creating an empty RawDataBlockList */ public void testEmptyConstructor() throws IOException { - new RawDataBlockList(new ByteArrayInputStream(new byte[ 0 ]), POIFSConstants.BIG_BLOCK_SIZE); + new RawDataBlockList(new ByteArrayInputStream(new byte[ 0 ]), POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); } /** @@ -84,7 +84,7 @@ public final class TestRawDataBlockList extends TestCase { // Check we logged the error logger.reset(); - new RawDataBlockList(new ByteArrayInputStream(data), POIFSConstants.BIG_BLOCK_SIZE); + new RawDataBlockList(new ByteArrayInputStream(data), POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); assertEquals(1, logger.logged.size()); } } diff --git a/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableReader.java b/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableReader.java index 02c10423b..3d254f826 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableReader.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableReader.java @@ -296,17 +296,18 @@ public final class TestSmallBlockTableReader extends TestCase { }; RawDataBlockList data_blocks = new RawDataBlockList(new ByteArrayInputStream(RawDataUtil - .decode(raw_data_array)), POIFSConstants.BIG_BLOCK_SIZE); + .decode(raw_data_array)), POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); int[] bat_array = { 15 }; // need to initialize the block list with a block allocation // table - new BlockAllocationTableReader(1, bat_array, 0, -2, data_blocks); + new BlockAllocationTableReader(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1, bat_array, 0, -2, data_blocks); // get property table from the document - PropertyTable properties = new PropertyTable(0, data_blocks); + PropertyTable properties = new PropertyTable(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 0, data_blocks); RootProperty root = properties.getRoot(); - BlockList bl = SmallBlockTableReader.getSmallDocumentBlocks(data_blocks, root, 14); + BlockList bl = SmallBlockTableReader.getSmallDocumentBlocks( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, data_blocks, root, 14); assertNotNull(bl); } } diff --git a/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java b/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java index 5b2534b28..bef253622 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java @@ -24,6 +24,7 @@ import java.util.List; import junit.framework.TestCase; +import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.POIFSDocument; import org.apache.poi.poifs.property.PropertyTable; import org.apache.poi.poifs.property.RootProperty; @@ -74,9 +75,9 @@ public final class TestSmallBlockTableWriter extends TestCase { documents .add(new POIFSDocument("doc9", new ByteArrayInputStream(new byte[ 9 ]))); - RootProperty root = new PropertyTable().getRoot(); - SmallBlockTableWriter sbtw = new SmallBlockTableWriter(documents, - root); + RootProperty root = new PropertyTable(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS).getRoot(); + SmallBlockTableWriter sbtw = new SmallBlockTableWriter( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, documents,root); BlockAllocationTableWriter bat = sbtw.getSBAT(); // 15 small blocks: 6 for doc340, 0 for doc5000 (too big), 0 diff --git a/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java index dfbfbb4e5..b061483c6 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.apache.poi.poifs.common.POIFSConstants; + import junit.framework.TestCase; /** @@ -55,7 +57,7 @@ public final class TestSmallDocumentBlock extends TestCase { while (true) { - DocumentBlock block = new DocumentBlock(stream); + DocumentBlock block = new DocumentBlock(stream,POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); documents.add(block); if (block.partiallyRead()) @@ -65,7 +67,7 @@ public final class TestSmallDocumentBlock extends TestCase { } SmallDocumentBlock[] results = SmallDocumentBlock - .convert(( BlockWritable [] ) documents + .convert(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,( BlockWritable [] ) documents .toArray(new DocumentBlock[ 0 ]), _testdata_size); assertEquals("checking correct result size: ", @@ -108,8 +110,8 @@ public final class TestSmallDocumentBlock extends TestCase { { array[ k ] = ( byte ) k; } - SmallDocumentBlock[] blocks = SmallDocumentBlock.convert(array, - 319); + SmallDocumentBlock[] blocks = SmallDocumentBlock.convert( + POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, array, 319); assertEquals(5, blocks.length); ByteArrayOutputStream stream = new ByteArrayOutputStream(); @@ -146,7 +148,7 @@ public final class TestSmallDocumentBlock extends TestCase { { foo.add(new Object()); } - int result = SmallDocumentBlock.fill(foo); + int result = SmallDocumentBlock.fill(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,foo); assertEquals("correct big block count: ", (j + 7) / 8, result); assertEquals("correct small block count: ", 8 * result, @@ -206,7 +208,7 @@ public final class TestSmallDocumentBlock extends TestCase { { new RawDataBlock(new ByteArrayInputStream(data)) }; - List output = SmallDocumentBlock.extract(blocks); + List output = SmallDocumentBlock.extract(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,blocks); Iterator iter = output.iterator(); offset = 0; diff --git a/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlockList.java b/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlockList.java index 02403a362..5301214e9 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlockList.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlockList.java @@ -20,6 +20,8 @@ package org.apache.poi.poifs.storage; import java.io.ByteArrayInputStream; import java.io.IOException; +import org.apache.poi.poifs.common.POIFSConstants; + import junit.framework.TestCase; /** @@ -44,7 +46,7 @@ public final class TestSmallDocumentBlockList extends TestCase { blocks[ j ] = new RawDataBlock(stream); } SmallDocumentBlockList sdbl = - new SmallDocumentBlockList(SmallDocumentBlock.extract(blocks)); + new SmallDocumentBlockList(SmallDocumentBlock.extract(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS,blocks)); // proof we added the blocks for (int j = 0; j < 40; j++)