mirror of https://github.com/apache/poi.git
Move more of the logic from HeaderBlockWriter to HeaderBlock
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1050767 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6703ad1c93
commit
626e01a4e3
|
@ -17,17 +17,6 @@
|
||||||
|
|
||||||
package org.apache.poi.poifs.storage;
|
package org.apache.poi.poifs.storage;
|
||||||
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._bat_array_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._bat_count_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._max_bats_in_header;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._property_start_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._sbat_start_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._sbat_block_count_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._signature;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._signature_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._xbat_count_offset;
|
|
||||||
import static org.apache.poi.poifs.storage.HeaderBlockConstants._xbat_start_offset;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -37,7 +26,6 @@ import java.util.Arrays;
|
||||||
import org.apache.poi.poifs.common.POIFSBigBlockSize;
|
import org.apache.poi.poifs.common.POIFSBigBlockSize;
|
||||||
import org.apache.poi.poifs.common.POIFSConstants;
|
import org.apache.poi.poifs.common.POIFSConstants;
|
||||||
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
|
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.util.HexDump;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
import org.apache.poi.util.IntegerField;
|
import org.apache.poi.util.IntegerField;
|
||||||
|
@ -51,7 +39,7 @@ import org.apache.poi.util.ShortField;
|
||||||
/**
|
/**
|
||||||
* The block containing the archive header
|
* The block containing the archive header
|
||||||
*/
|
*/
|
||||||
public final class HeaderBlock {
|
public final class HeaderBlock implements HeaderBlockConstants {
|
||||||
private static final POILogger _logger =
|
private static final POILogger _logger =
|
||||||
POILogFactory.getLogger(HeaderBlock.class);
|
POILogFactory.getLogger(HeaderBlock.class);
|
||||||
|
|
||||||
|
@ -183,7 +171,7 @@ public final class HeaderBlock {
|
||||||
/**
|
/**
|
||||||
* Create a single instance initialized with default values
|
* Create a single instance initialized with default values
|
||||||
*/
|
*/
|
||||||
public HeaderBlock(POIFSBigBlockSize bigBlockSize) throws IOException
|
public HeaderBlock(POIFSBigBlockSize bigBlockSize)
|
||||||
{
|
{
|
||||||
this.bigBlockSize = bigBlockSize;
|
this.bigBlockSize = bigBlockSize;
|
||||||
|
|
||||||
|
@ -255,6 +243,14 @@ public final class HeaderBlock {
|
||||||
public int getPropertyStart() {
|
public int getPropertyStart() {
|
||||||
return _property_start;
|
return _property_start;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Set start of Property Table
|
||||||
|
*
|
||||||
|
* @param startBlock the index of the first block of the Property Table
|
||||||
|
*/
|
||||||
|
public void setPropertyStart(final int startBlock) {
|
||||||
|
_property_start = startBlock;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return start of small block (MiniFAT) allocation table
|
* @return start of small block (MiniFAT) allocation table
|
||||||
|
@ -266,12 +262,38 @@ public final class HeaderBlock {
|
||||||
return _sbat_count;
|
return _sbat_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set start of small block allocation table
|
||||||
|
*
|
||||||
|
* @param startBlock the index of the first big block of the small
|
||||||
|
* block allocation table
|
||||||
|
*/
|
||||||
|
public void setSBATStart(final int startBlock) {
|
||||||
|
_sbat_start = startBlock;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set count of SBAT blocks
|
||||||
|
*
|
||||||
|
* @param count the number of SBAT blocks
|
||||||
|
*/
|
||||||
|
public void setSBATBlockCount(final int count)
|
||||||
|
{
|
||||||
|
_sbat_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return number of BAT blocks
|
* @return number of BAT blocks
|
||||||
*/
|
*/
|
||||||
public int getBATCount() {
|
public int getBATCount() {
|
||||||
return _bat_count;
|
return _bat_count;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of BAT blocks that are used.
|
||||||
|
* This is the number used in both the BAT and XBAT.
|
||||||
|
*/
|
||||||
|
public void setBATCount(final int count) {
|
||||||
|
_bat_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the offsets to the first (up to) 109
|
* Returns the offsets to the first (up to) 109
|
||||||
|
@ -282,7 +304,7 @@ public final class HeaderBlock {
|
||||||
*/
|
*/
|
||||||
public int[] getBATArray() {
|
public int[] getBATArray() {
|
||||||
// Read them in
|
// Read them in
|
||||||
int[] result = new int[ _bat_count ];
|
int[] result = new int[ Math.min(_bat_count,_max_bats_in_header) ];
|
||||||
int offset = _bat_array_offset;
|
int offset = _bat_array_offset;
|
||||||
for (int j = 0; j < _bat_count; j++) {
|
for (int j = 0; j < _bat_count; j++) {
|
||||||
result[ j ] = LittleEndian.getInt(_data, offset);
|
result[ j ] = LittleEndian.getInt(_data, offset);
|
||||||
|
@ -290,6 +312,24 @@ public final class HeaderBlock {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Sets the offsets of the first (up to) 109
|
||||||
|
* BAT sectors.
|
||||||
|
*/
|
||||||
|
public void setBATArray(int[] bat_array) {
|
||||||
|
int count = Math.min(bat_array.length, _max_bats_in_header);
|
||||||
|
int blank = _max_bats_in_header - count;
|
||||||
|
|
||||||
|
int offset = _bat_array_offset;
|
||||||
|
for(int i=0; i<count; i++) {
|
||||||
|
LittleEndian.putInt(_data, offset, bat_array[i]);
|
||||||
|
offset += LittleEndianConsts.INT_SIZE;
|
||||||
|
}
|
||||||
|
for(int i=0; i<blank; i++) {
|
||||||
|
LittleEndian.putInt(_data, offset, POIFSConstants.UNUSED_BLOCK);
|
||||||
|
offset += LittleEndianConsts.INT_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return XBAT (DIFAT) count
|
* @return XBAT (DIFAT) count
|
||||||
|
@ -297,6 +337,12 @@ public final class HeaderBlock {
|
||||||
public int getXBATCount() {
|
public int getXBATCount() {
|
||||||
return _xbat_count;
|
return _xbat_count;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Sets the number of XBAT (DIFAT) blocks used
|
||||||
|
*/
|
||||||
|
public void setXBATCount(final int count) {
|
||||||
|
_xbat_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return XBAT (DIFAT) index
|
* @return XBAT (DIFAT) index
|
||||||
|
@ -304,6 +350,12 @@ public final class HeaderBlock {
|
||||||
public int getXBATIndex() {
|
public int getXBATIndex() {
|
||||||
return _xbat_start;
|
return _xbat_start;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Sets the first XBAT (DIFAT) block location
|
||||||
|
*/
|
||||||
|
public void setXBATStart(final int startBlock) {
|
||||||
|
_xbat_start = startBlock;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
|
* @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
|
||||||
|
@ -336,7 +388,7 @@ public final class HeaderBlock {
|
||||||
stream.write(_data, 0, 512);
|
stream.write(_data, 0, 512);
|
||||||
|
|
||||||
// Now do the padding if needed
|
// Now do the padding if needed
|
||||||
for(int i=POIFSConstants.SMALLER_BIG_BLOCK_SIZE; i<POIFSConstants.LARGER_BIG_BLOCK_SIZE; i++) {
|
for(int i=POIFSConstants.SMALLER_BIG_BLOCK_SIZE; i<bigBlockSize.getBigBlockSize(); i++) {
|
||||||
stream.write(0);
|
stream.write(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,47 +19,20 @@
|
||||||
|
|
||||||
package org.apache.poi.poifs.storage;
|
package org.apache.poi.poifs.storage;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.apache.poi.poifs.common.POIFSBigBlockSize;
|
import org.apache.poi.poifs.common.POIFSBigBlockSize;
|
||||||
import org.apache.poi.poifs.common.POIFSConstants;
|
import org.apache.poi.poifs.common.POIFSConstants;
|
||||||
import org.apache.poi.util.IntegerField;
|
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
|
||||||
import org.apache.poi.util.LongField;
|
|
||||||
import org.apache.poi.util.ShortField;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The block containing the archive header
|
* The block containing the archive header
|
||||||
*
|
*
|
||||||
* @author Marc Johnson (mjohnson at apache dot org)
|
* @author Marc Johnson (mjohnson at apache dot org)
|
||||||
*/
|
*/
|
||||||
|
public class HeaderBlockWriter implements HeaderBlockConstants, BlockWritable
|
||||||
public class HeaderBlockWriter
|
|
||||||
extends BigBlock
|
|
||||||
implements HeaderBlockConstants
|
|
||||||
{
|
{
|
||||||
private static final byte _default_value = ( byte ) 0xFF;
|
private final HeaderBlock _header_block;
|
||||||
|
|
||||||
// number of big block allocation table blocks (int)
|
|
||||||
private IntegerField _bat_count;
|
|
||||||
|
|
||||||
// start of the property set block (int index of the property set
|
|
||||||
// chain's first big block)
|
|
||||||
private IntegerField _property_start;
|
|
||||||
|
|
||||||
// start of the small block allocation table (int index of small
|
|
||||||
// block allocation table's first big block)
|
|
||||||
private IntegerField _sbat_start;
|
|
||||||
|
|
||||||
// number of big blocks holding the small block allocation table
|
|
||||||
private IntegerField _sbat_block_count;
|
|
||||||
|
|
||||||
// big block index for extension to the big block allocation table
|
|
||||||
private IntegerField _xbat_start;
|
|
||||||
private IntegerField _xbat_count;
|
|
||||||
private byte[] _data;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a single instance initialized with default values
|
* Create a single instance initialized with default values
|
||||||
|
@ -67,43 +40,7 @@ public class HeaderBlockWriter
|
||||||
|
|
||||||
public HeaderBlockWriter(POIFSBigBlockSize bigBlockSize)
|
public HeaderBlockWriter(POIFSBigBlockSize bigBlockSize)
|
||||||
{
|
{
|
||||||
super(bigBlockSize);
|
_header_block = new HeaderBlock(bigBlockSize);
|
||||||
|
|
||||||
_data = new byte[ bigBlockSize.getBigBlockSize() ];
|
|
||||||
Arrays.fill(_data, _default_value);
|
|
||||||
new LongField(_signature_offset, _signature, _data);
|
|
||||||
new IntegerField(0x08, 0, _data);
|
|
||||||
new IntegerField(0x0c, 0, _data);
|
|
||||||
new IntegerField(0x10, 0, _data);
|
|
||||||
new IntegerField(0x14, 0, _data);
|
|
||||||
new ShortField(0x18, ( short ) 0x3b, _data);
|
|
||||||
new ShortField(0x1a, ( short ) 0x3, _data);
|
|
||||||
new ShortField(0x1c, ( short ) -2, _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);
|
|
||||||
_bat_count = new IntegerField(_bat_count_offset, 0, _data);
|
|
||||||
_property_start = new IntegerField(_property_start_offset,
|
|
||||||
POIFSConstants.END_OF_CHAIN,
|
|
||||||
_data);
|
|
||||||
new IntegerField(0x34, 0, _data);
|
|
||||||
new IntegerField(0x38, 0x1000, _data);
|
|
||||||
_sbat_start = new IntegerField(_sbat_start_offset,
|
|
||||||
POIFSConstants.END_OF_CHAIN, _data);
|
|
||||||
_sbat_block_count = new IntegerField(_sbat_block_count_offset, 0,
|
|
||||||
_data);
|
|
||||||
_xbat_start = new IntegerField(_xbat_start_offset,
|
|
||||||
POIFSConstants.END_OF_CHAIN, _data);
|
|
||||||
_xbat_count = new IntegerField(_xbat_count_offset, 0, _data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,16 +59,19 @@ public class HeaderBlockWriter
|
||||||
final int startBlock)
|
final int startBlock)
|
||||||
{
|
{
|
||||||
BATBlock[] rvalue;
|
BATBlock[] rvalue;
|
||||||
|
POIFSBigBlockSize bigBlockSize = _header_block.getBigBlockSize();
|
||||||
|
|
||||||
_bat_count.set(blockCount, _data);
|
_header_block.setBATCount(blockCount);
|
||||||
|
|
||||||
|
// Set the BAT locations
|
||||||
int limit = Math.min(blockCount, _max_bats_in_header);
|
int limit = Math.min(blockCount, _max_bats_in_header);
|
||||||
int offset = _bat_array_offset;
|
int[] bat_blocks = new int[limit];
|
||||||
|
for (int j = 0; j < limit; j++) {
|
||||||
for (int j = 0; j < limit; j++)
|
bat_blocks[j] = startBlock + j;
|
||||||
{
|
|
||||||
new IntegerField(offset, startBlock + j, _data);
|
|
||||||
offset += LittleEndianConsts.INT_SIZE;
|
|
||||||
}
|
}
|
||||||
|
_header_block.setBATArray(bat_blocks);
|
||||||
|
|
||||||
|
// Now do the XBATs
|
||||||
if (blockCount > _max_bats_in_header)
|
if (blockCount > _max_bats_in_header)
|
||||||
{
|
{
|
||||||
int excess_blocks = blockCount - _max_bats_in_header;
|
int excess_blocks = blockCount - _max_bats_in_header;
|
||||||
|
@ -144,14 +84,14 @@ public class HeaderBlockWriter
|
||||||
}
|
}
|
||||||
rvalue = BATBlock.createXBATBlocks(bigBlockSize, excess_block_array,
|
rvalue = BATBlock.createXBATBlocks(bigBlockSize, excess_block_array,
|
||||||
startBlock + blockCount);
|
startBlock + blockCount);
|
||||||
_xbat_start.set(startBlock + blockCount, _data);
|
_header_block.setXBATStart(startBlock + blockCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rvalue = BATBlock.createXBATBlocks(bigBlockSize, new int[ 0 ], 0);
|
rvalue = BATBlock.createXBATBlocks(bigBlockSize, new int[ 0 ], 0);
|
||||||
_xbat_start.set(POIFSConstants.END_OF_CHAIN, _data);
|
_header_block.setXBATStart(POIFSConstants.END_OF_CHAIN);
|
||||||
}
|
}
|
||||||
_xbat_count.set(rvalue.length, _data);
|
_header_block.setXBATCount(rvalue.length);
|
||||||
return rvalue;
|
return rvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,10 +101,9 @@ public class HeaderBlockWriter
|
||||||
* @param startBlock the index of the first block of the Property
|
* @param startBlock the index of the first block of the Property
|
||||||
* Table
|
* Table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setPropertyStart(final int startBlock)
|
public void setPropertyStart(final int startBlock)
|
||||||
{
|
{
|
||||||
_property_start.set(startBlock, _data);
|
_header_block.setPropertyStart(startBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,10 +112,9 @@ public class HeaderBlockWriter
|
||||||
* @param startBlock the index of the first big block of the small
|
* @param startBlock the index of the first big block of the small
|
||||||
* block allocation table
|
* block allocation table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setSBATStart(final int startBlock)
|
public void setSBATStart(final int startBlock)
|
||||||
{
|
{
|
||||||
_sbat_start.set(startBlock, _data);
|
_header_block.setSBATStart(startBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,10 +122,9 @@ public class HeaderBlockWriter
|
||||||
*
|
*
|
||||||
* @param count the number of SBAT blocks
|
* @param count the number of SBAT blocks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setSBATBlockCount(final int count)
|
public void setSBATBlockCount(final int count)
|
||||||
{
|
{
|
||||||
_sbat_block_count.set(count, _data);
|
_header_block.setSBATBlockCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,10 +156,10 @@ public class HeaderBlockWriter
|
||||||
* stream
|
* stream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void writeData(final OutputStream stream)
|
public void writeBlocks(final OutputStream stream)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
doWriteData(stream, _data);
|
_header_block.writeData(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********** END extension of BigBlock ********** */
|
/* ********** END extension of BigBlock ********** */
|
||||||
|
|
Loading…
Reference in New Issue