--- /dev/null
+
+/* ====================================================================
+ 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;
+
+/**
+ * <p>A class describing attributes of the Big Block Size</p>
+ */
+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;
+ }
+}
/**
* <p>A repository for constants shared by POI classes.</p>
- *
- * @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;
--- /dev/null
+/* ====================================================================
+ 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<Math.min(16, data_blocks.blockCount()); i++) {
+ ListManagedBlock block = (ListManagedBlock)gbm.invoke(data_blocks, new Integer(i));
+ byte[] data = new byte[Math.min(48, block.getData().length)];
+ System.arraycopy(block.getData(), 0, data, 0, data.length);
+
+ System.out.println(" Block #" + i + ":");
+ System.out.println(HexDump.dump(data, 0, 0));
+ }
+
+ System.out.println("");
+ }
+
+ public static void displayBATReader(BlockAllocationTableReader batReader) throws Exception {
+ System.out.println("Sectors, as referenced from the FAT:");
+ Field entriesF = batReader.getClass().getDeclaredField("_entries");
+ entriesF.setAccessible(true);
+ IntList entries = (IntList)entriesF.get(batReader);
+
+ for(int i=0; i<entries.size(); i++) {
+ int bn = entries.get(i);
+ String bnS = Integer.toString(bn);
+ if(bn == POIFSConstants.END_OF_CHAIN) {
+ bnS = "End Of Chain";
+ } else if(bn == POIFSConstants.DIFAT_SECTOR_BLOCK) {
+ bnS = "DI Fat Block";
+ } else if(bn == POIFSConstants.FAT_SECTOR_BLOCK) {
+ bnS = "Normal Fat Block";
+ }
+
+ System.out.println(" Block # " + i + " -> " + bnS);
+ }
+
+ System.out.println("");
+ }
+}
// 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(),
// 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());
}
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;
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
*/
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);
}
*/
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);
}
* @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
* @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<DocumentBlock> blocks = new ArrayList<DocumentBlock>();
_size = 0;
+ _bigBigBlockSize = bigBlockSize;
while (true) {
- DocumentBlock block = new DocumentBlock(stream);
+ DocumentBlock block = new DocumentBlock(stream, bigBlockSize);
int blockSize = block.size();
if (blockSize > 0) {
}
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
* @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
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;
* @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;
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;
}
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;
* @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;
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;
}
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++) {
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;
}
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;
* 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;
}
// 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(),
// 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,
// 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
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);
* @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 ********** */
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;
* @author Marc Johnson (mjohnson at apache dot org)
*/
public final class PropertyTable implements BATManaged, BlockWritable {
- private int _start_block;
- private List<Property> _properties;
- private BlockWritable[] _blocks;
+ private POIFSBigBlockSize _bigBigBlockSize;
+ private int _start_block;
+ private List<Property> _properties;
+ private BlockWritable[] _blocks;
- public PropertyTable()
+ public PropertyTable(POIFSBigBlockSize bigBlockSize)
{
+ _bigBigBlockSize = bigBlockSize;
_start_block = POIFSConstants.END_OF_CHAIN;
_properties = new ArrayList<Property>();
addProperty(new RootProperty());
* @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 =
}
// 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++)
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;
* @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;
* 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;
* @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);
* @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);
}
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;
}
* @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;
}
* @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);
}
* 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);
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
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;
*/
private static final int MAX_BLOCK_COUNT = 65535;
private final IntList _entries;
+ private POIFSBigBlockSize bigBlockSize;
/**
* create a BlockAllocationTableReader for an existing filesystem. Side
* @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
"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
*
* @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();
}
* 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++)
{
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;
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 ];
}
/**
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))
*/
void simpleCreateBlocks()
{
- _blocks = BATBlock.createBATBlocks(_entries.toArray());
+ _blocks = BATBlock.createBATBlocks(_bigBlockSize, _entries.toArray());
}
/**
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;
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;
}
* @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
* 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);
}
public boolean partiallyRead()
{
- return _bytes_read != POIFSConstants.BIG_BLOCK_SIZE;
+ return _bytes_read != bigBlockSize.getBigBlockSize();
}
/**
* 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);
}
}
{
Arrays.fill(rval[ k ]._data, _default_value);
}
- offset += POIFSConstants.BIG_BLOCK_SIZE;
+ offset += bigBlockSize.getBigBlockSize();
}
return rval;
}
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
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;
* 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).
// 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);
/**
* @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
*/
- public int getBigBlockSize() {
+ public POIFSBigBlockSize getBigBlockSize() {
return bigBlockSize;
}
}
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;
* 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);
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);
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);
* @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;
}
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;
* @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;
/**
* @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 ];
}
*/
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;
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;
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);
*/
public RawDataBlock(final InputStream stream)
throws IOException {
- this(stream, POIFSConstants.BIG_BLOCK_SIZE);
+ this(stream, POIFSConstants.SMALLER_BIG_BLOCK_SIZE);
}
/**
* Constructor RawDataBlock
}
return _data;
}
+
+ /**
+ * What's the big block size?
+ */
+ public int getBigBlockSize() {
+ return _data.length;
+ }
/* ********** END implementation of ListManagedBlock ********** */
} // end public class RawDataBlock
import java.util.*;
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+
/**
* A list of RawDataBlocks instances, and methods to manage the list
*
* block is read
*/
- public RawDataBlockList(final InputStream stream, int bigBlockSize)
+ public RawDataBlockList(final InputStream stream, POIFSBigBlockSize bigBlockSize)
throws IOException
{
- List blocks = new ArrayList();
+ List<RawDataBlock> blocks = new ArrayList<RawDataBlock>();
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()) {
break;
}
}
- setBlocks(( RawDataBlock [] ) blocks.toArray(new RawDataBlock[ 0 ]));
+ setBlocks( blocks.toArray(new RawDataBlock[ blocks.size() ]) );
}
} // end public class RawDataBlockList
import java.io.IOException;
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
import org.apache.poi.poifs.property.RootProperty;
/**
* @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;
}
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;
* @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();
}
_sbat.simpleCreateBlocks();
_root.setSize(_small_blocks.size());
- _big_block_count = SmallDocumentBlock.fill(_small_blocks);
+ _big_block_count = SmallDocumentBlock.fill(bigBlockSize,_small_blocks);
}
/**
import java.util.Arrays;
import java.util.List;
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
import org.apache.poi.poifs.common.POIFSConstants;
/**
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
* @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 =
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);
*
* @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;
for (; count < full_count; count++)
{
- blocks.add(makeEmptySmallDocumentBlock());
+ blocks.add(makeEmptySmallDocumentBlock(bigBlockSize));
}
return big_block_count;
}
* @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
{
for (int index = 0; index < rval.length; index++)
{
- rval[ index ] = new SmallDocumentBlock(data, index);
+ rval[ index ] = new SmallDocumentBlock(bigBlockSize, data, index);
}
return rval;
}
*
* @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++)
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;
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;
public byte [] getData() {
return _data;
}
+
+ public POIFSBigBlockSize getBigBlockSize() {
+ return _bigBlockSize;
+ }
}
public SmallDocumentBlockList(final List blocks)
{
setBlocks(( SmallDocumentBlock [] ) blocks
- .toArray(new SmallDocumentBlock[ 0 ]));
+ .toArray(new SmallDocumentBlock[ blocks.size() ]));
}
} // end public class SmallDocumentBlockList
// 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.
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);
// 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();
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);
// 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();
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);
}
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;
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
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);
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
};
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;
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<RawDataBlock>();
_array = null;
}
import java.io.IOException;
import java.util.Arrays;
+import org.apache.poi.poifs.common.POIFSConstants;
+
import junit.framework.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);
}
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);
}
{
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());
}
}
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;
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,
}
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) {
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 };
*/
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(
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
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
}
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);
* 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++)
{
import junit.framework.TestCase;
+import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
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)
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
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import org.apache.poi.poifs.common.POIFSConstants;
+
import junit.framework.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();
import junit.framework.TestCase;
+import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
* 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);
* 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);
* 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);
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);
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();
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();
import java.util.ArrayList;
import java.util.List;
+import org.apache.poi.poifs.common.POIFSConstants;
+
import junit.framework.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 ];
// 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';
// 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';
// 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++)
{
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);
}
/**
// 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());
}
}
};
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);
}
}
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;
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
import java.util.Iterator;
import java.util.List;
+import org.apache.poi.poifs.common.POIFSConstants;
+
import junit.framework.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())
}
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: ",
{
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();
{
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,
{
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;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import org.apache.poi.poifs.common.POIFSConstants;
+
import junit.framework.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++)