You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2010/04/25 19:35:57 UTC

svn commit: r937834 [1/2] - in /poi/trunk/src: java/org/apache/poi/poifs/common/ java/org/apache/poi/poifs/dev/ java/org/apache/poi/poifs/eventfilesystem/ java/org/apache/poi/poifs/filesystem/ java/org/apache/poi/poifs/property/ java/org/apache/poi/poi...

Author: nick
Date: Sun Apr 25 17:35:56 2010
New Revision: 937834

URL: http://svn.apache.org/viewvc?rev=937834&view=rev
Log:
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.

Added:
    poi/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java
    poi/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java
Modified:
    poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java
    poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
    poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java
    poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java
    poi/trunk/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableWriter.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestDocumentBlock.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestPropertyBlock.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlockList.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableReader.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestSmallBlockTableWriter.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlockList.java

Added: poi/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java?rev=937834&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java Sun Apr 25 17:35:56 2010
@@ -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;
+
+/**
+ * <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;
+   }
+}

Modified: poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java Sun Apr 25 17:35:56 2010
@@ -21,16 +21,17 @@ package org.apache.poi.poifs.common;
 
 /**
  * <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;
     

Added: poi/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java?rev=937834&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java Sun Apr 25 17:35:56 2010
@@ -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<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("");
+   }
+}

Modified: poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java Sun Apr 25 17:35:56 2010
@@ -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());
     }
 

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java Sun Apr 25 17:35:56 2010
@@ -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 impleme
 	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 impleme
 	 */
 	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 impleme
 	 */
 	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 impleme
 	 * @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 impleme
 	 * @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) {
@@ -144,16 +168,19 @@ public final class POIFSDocument impleme
 		}
 		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 impleme
 	 * @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 impleme
 		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 impleme
 		 * @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 impleme
 				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 impleme
 		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 impleme
 		 * @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 impleme
 				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 impleme
 					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 impleme
 				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;
 		}

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java Sun Apr 25 17:35:56 2010
@@ -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 ********** */

Modified: poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java Sun Apr 25 17:35:56 2010
@@ -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.RawD
  * @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());
@@ -60,10 +63,12 @@ public final class PropertyTable impleme
      * @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 impleme
         }
 
         // 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++)

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java Sun Apr 25 17:35:56 2010
@@ -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.LittleEndianC
  * @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 BigB
      * 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 BigB
      * @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 BigB
      * @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 BigB
             }
             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 BigB
      * @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 BigB
      * @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 BigB
      *                  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);

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java Sun Apr 25 17:35:56 2010
@@ -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

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java Sun Apr 25 17:35:56 2010
@@ -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 BlockAllocationTableR
      */
     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 BlockAllocationTableR
      * @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 BlockAllocationTableR
                     "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 BlockAllocationTableR
      *
      * @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 BlockAllocationTableR
      *                   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++)
         {

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableWriter.java Sun Apr 25 17:35:56 2010
@@ -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 BlockAllocationTableW
     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 BlockAllocationTableW
         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 BlockAllocationTableW
      */
     void simpleCreateBlocks()
     {
-        _blocks = BATBlock.createBATBlocks(_entries.toArray());
+        _blocks = BATBlock.createBATBlocks(_bigBlockSize, _entries.toArray());
     }
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/DocumentBlock.java Sun Apr 25 17:35:56 2010
@@ -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
     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
      * @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
      * 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
 
     public boolean partiallyRead()
     {
-        return _bytes_read != POIFSConstants.BIG_BLOCK_SIZE;
+        return _bytes_read != bigBlockSize.getBigBlockSize();
     }
 
     /**
@@ -124,26 +131,27 @@ public final class DocumentBlock extends
      *         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
             {
                 Arrays.fill(rval[ k ]._data, _default_value);
             }
-            offset += POIFSConstants.BIG_BLOCK_SIZE;
+            offset += bigBlockSize.getBigBlockSize();
         }
         return rval;
     }

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java Sun Apr 25 17:35:56 2010
@@ -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

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java Sun Apr 25 17:35:56 2010
@@ -31,6 +31,7 @@ import static org.apache.poi.poifs.stora
 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;
 	}
 }

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java Sun Apr 25 17:35:56 2010
@@ -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;
     }
 

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/PropertyBlock.java Sun Apr 25 17:35:56 2010
@@ -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.Pro
  * @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
      * @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
      */
 
     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
 
         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
     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);

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlock.java Sun Apr 25 17:35:56 2010
@@ -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

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/RawDataBlockList.java Sun Apr 25 17:35:56 2010
@@ -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<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()) {
@@ -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
 

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java Sun Apr 25 17:35:56 2010
@@ -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;
     }

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java Sun Apr 25 17:35:56 2010
@@ -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);
     }
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java Sun Apr 25 17:35:56 2010
@@ -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 im
     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 im
      * @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 im
 
         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 im
      *
      * @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 im
 
         for (; count < full_count; count++)
         {
-            blocks.add(makeEmptySmallDocumentBlock());
+            blocks.add(makeEmptySmallDocumentBlock(bigBlockSize));
         }
         return big_block_count;
     }
@@ -128,7 +139,8 @@ public final class SmallDocumentBlock im
      * @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 im
 
         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 im
      *
      * @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 im
 
             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 im
         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 im
     public byte [] getData() {
         return _data;
     }
+    
+    public POIFSBigBlockSize getBigBlockSize() {
+       return _bigBlockSize;
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/SmallDocumentBlockList.java Sun Apr 25 17:35:56 2010
@@ -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
 

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java Sun Apr 25 17:35:56 2010
@@ -448,8 +448,8 @@ public final class HWPFDocument extends 
 
     // 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.

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java Sun Apr 25 17:35:56 2010
@@ -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();

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/PAPBinTable.java Sun Apr 25 17:35:56 2010
@@ -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();

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/TextPieceTable.java Sun Apr 25 17:35:56 2010
@@ -172,9 +172,9 @@ public final class TextPieceTable implem
 			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);
 			}

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java Sun Apr 25 17:35:56 2010
@@ -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 e
          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);

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/property/TestPropertyTable.java Sun Apr 25 17:35:56 2010
@@ -70,7 +70,7 @@ public final class TestPropertyTable ext
 	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 ext
 		};
 
 		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;

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java?rev=937834&r1=937833&r2=937834&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/storage/LocalRawDataBlockList.java Sun Apr 25 17:35:56 2010
@@ -38,7 +38,7 @@ public final class LocalRawDataBlockList
     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;
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org