📄 compoundfile.java
字号:
* Writes out all the data in the small block depot
*
* @exception
*/
private void writeSmallBlockDepot() throws IOException
{
if (additionalPropertySets == null)
{
return;
}
byte[] smallBlockDepot =
new byte[numSmallBlockDepotBlocks * BIG_BLOCK_SIZE];
int pos = 0;
/*
int smallBlocks2 = getSmallBlocksRequired(rootEntryPropertySet.data.length);
int length2 = smallBlocks2 * SMALL_BLOCK_SIZE;
System.arraycopy(rootEntryPropertySet.data, 0, smallBlockDepot, pos, rootEntryPropertySet.data.length);
pos += length2;
*/
for (Iterator i = additionalPropertySets.iterator() ; i.hasNext() ; )
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
if (rps.data.length <= SMALL_BLOCK_THRESHOLD)
{
int smallBlocks = getSmallBlocksRequired(rps.data.length);
int length = smallBlocks * SMALL_BLOCK_SIZE;
System.arraycopy(rps.data, 0, smallBlockDepot, pos, rps.data.length);
pos += length;
}
}
out.write(smallBlockDepot);
}
/**
* Writes out the Big Block Depot
*
* @exception IOException
*/
private void writeBigBlockDepot() throws IOException
{
// This is after the excel data, the summary information, the
// big block property sets and the small block depot
bigBlockDepot = new byte[BIG_BLOCK_SIZE];
bbdPos = 0;
// Write out the extension blocks, indicating them as special blocks
for (int i = 0 ; i < numExtensionBlocks; i++)
{
IntegerHelper.getFourBytes(-3, bigBlockDepot, bbdPos);
bbdPos += 4;
checkBbdPos();
}
writeBlockChain(excelDataStartBlock, excelDataBlocks);
// The excel data has been written. Now write out the rest of it
// Write the block chain for the summary information
int summaryInfoBlock = excelDataStartBlock +
excelDataBlocks +
additionalPropertyBlocks;
for (int i = summaryInfoBlock; i < summaryInfoBlock + 7; i++)
{
IntegerHelper.getFourBytes(i + 1, bigBlockDepot, bbdPos);
bbdPos +=4 ;
checkBbdPos();
}
// Write the end of the block chain for the summary info block
IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos);
bbdPos += 4;
checkBbdPos();
// Write the block chain for the document summary information
for (int i = summaryInfoBlock + 8; i < summaryInfoBlock + 15; i++)
{
IntegerHelper.getFourBytes(i + 1, bigBlockDepot, bbdPos);
bbdPos +=4 ;
checkBbdPos();
}
// Write the end of the block chain for the document summary
IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos);
bbdPos += 4;
checkBbdPos();
// Write out the block chain for the copied property sets, if present
writeAdditionalPropertySetBlockChains();
if (sbdStartBlock != -2)
{
// Write out the block chain for the small block depot
writeBlockChain(sbdStartBlock, numSmallBlockDepotBlocks);
// Write out the block chain for the small block depot chain
writeBlockChain(sbdStartBlockChain, numSmallBlockDepotChainBlocks);
}
// The Big Block Depot immediately follows the document summary. Denote
// these as a special block
for (int i = 0; i < numBigBlockDepotBlocks; i++)
{
IntegerHelper.getFourBytes(-3, bigBlockDepot, bbdPos);
bbdPos += 4;
checkBbdPos();
}
// Write the root entry
writeBlockChain(rootStartBlock, numRootEntryBlocks);
// Pad out the remainder of the block
if (bbdPos != 0)
{
for (int i = bbdPos; i < BIG_BLOCK_SIZE; i++)
{
bigBlockDepot[i] = (byte) 0xff;
}
out.write(bigBlockDepot);
}
}
/**
* Calculates the number of big blocks required to store data of the
* specified length
*
* @param length the length of the data
* @return the number of big blocks required to store the data
*/
private int getBigBlocksRequired(int length)
{
int blocks = length / BIG_BLOCK_SIZE;
return (length % BIG_BLOCK_SIZE > 0 )? blocks + 1 : blocks;
}
/**
* Calculates the number of small blocks required to store data of the
* specified length
*
* @param length the length of the data
* @return the number of small blocks required to store the data
*/
private int getSmallBlocksRequired(int length)
{
int blocks = length / SMALL_BLOCK_SIZE;
return (length % SMALL_BLOCK_SIZE > 0 )? blocks + 1 : blocks;
}
/**
* Writes out the property sets
*
* @exception IOException
*/
private void writePropertySets() throws IOException
{
byte[] propertySetStorage = new byte[BIG_BLOCK_SIZE * numRootEntryBlocks];
int pos = 0;
int[] mappings = null;
// Build up the mappings array
if (additionalPropertySets != null)
{
mappings = new int[numPropertySets];
// Map the standard ones to the first four
for (int i = 0 ; i < STANDARD_PROPERTY_SETS.length ; i++)
{
ReadPropertyStorage rps = (ReadPropertyStorage)
readPropertySets.get(STANDARD_PROPERTY_SETS[i]);
mappings[rps.number] = i;
}
// Now go through the original ones
int newMapping = STANDARD_PROPERTY_SETS.length;
for (Iterator i = additionalPropertySets.iterator(); i.hasNext(); )
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
mappings[rps.number] = newMapping;
newMapping++;
}
}
int child = 0;
int previous = 0;
int next = 0;
// Compute the size of the root property set
int size = 0;
if (additionalPropertySets != null)
{
// Workbook
size += getBigBlocksRequired(requiredSize) * BIG_BLOCK_SIZE;
// The two information blocks
size += getBigBlocksRequired(SMALL_BLOCK_THRESHOLD) * BIG_BLOCK_SIZE;
size += getBigBlocksRequired(SMALL_BLOCK_THRESHOLD) * BIG_BLOCK_SIZE;
// Additional property sets
for (Iterator i = additionalPropertySets.iterator(); i.hasNext(); )
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
if (rps.propertyStorage.type != 1)
{
if (rps.propertyStorage.size >= SMALL_BLOCK_THRESHOLD)
{
size += getBigBlocksRequired(rps.propertyStorage.size) *
BIG_BLOCK_SIZE;
}
else
{
size += getSmallBlocksRequired(rps.propertyStorage.size) *
SMALL_BLOCK_SIZE;
}
}
}
}
// Set the root entry property set
PropertyStorage ps = new PropertyStorage(ROOT_ENTRY_NAME);
ps.setType(5);
ps.setStartBlock(sbdStartBlock);
ps.setSize(size);
ps.setPrevious(-1);
ps.setNext(-1);
ps.setColour(0);
child = 1;
if (additionalPropertySets != null)
{
ReadPropertyStorage rps = (ReadPropertyStorage)
readPropertySets.get(ROOT_ENTRY_NAME);
child = mappings[rps.propertyStorage.child];
}
ps.setChild(child);
System.arraycopy(ps.data, 0,
propertySetStorage, pos,
PROPERTY_STORAGE_BLOCK_SIZE);
pos += PROPERTY_STORAGE_BLOCK_SIZE;
// Set the workbook property set
ps = new PropertyStorage(WORKBOOK_NAME);
ps.setType(2);
ps.setStartBlock(excelDataStartBlock);
// start the excel data after immediately after this block
ps.setSize(requiredSize);
// alway use a big block stream - none of that messing around
// with small blocks
previous = 3;
next = -1;
if (additionalPropertySets != null)
{
ReadPropertyStorage rps = (ReadPropertyStorage)
readPropertySets.get(WORKBOOK_NAME);
previous = rps.propertyStorage.previous != -1 ?
mappings[rps.propertyStorage.previous] : -1;
next = rps.propertyStorage.next != -1 ?
mappings[rps.propertyStorage.next] : -1 ;
}
ps.setPrevious(previous);
ps.setNext(next);
ps.setChild(-1);
System.arraycopy(ps.data, 0,
propertySetStorage, pos,
PROPERTY_STORAGE_BLOCK_SIZE);
pos += PROPERTY_STORAGE_BLOCK_SIZE;
// Set the summary information
ps = new PropertyStorage(SUMMARY_INFORMATION_NAME);
ps.setType(2);
ps.setStartBlock(excelDataStartBlock + excelDataBlocks);
ps.setSize(SMALL_BLOCK_THRESHOLD);
previous = 1;
next = 3;
if (additionalPropertySets != null)
{
ReadPropertyStorage rps = (ReadPropertyStorage)
readPropertySets.get(SUMMARY_INFORMATION_NAME);
previous = rps.propertyStorage.previous != - 1 ?
mappings[rps.propertyStorage.previous] : -1 ;
next = rps.propertyStorage.next != - 1 ?
mappings[rps.propertyStorage.next] : -1 ;
}
ps.setPrevious(previous);
ps.setNext(next);
ps.setChild(-1);
System.arraycopy(ps.data, 0,
propertySetStorage, pos,
PROPERTY_STORAGE_BLOCK_SIZE);
pos += PROPERTY_STORAGE_BLOCK_SIZE;
// Set the document summary information
ps = new PropertyStorage(DOCUMENT_SUMMARY_INFORMATION_NAME);
ps.setType(2);
ps.setStartBlock(excelDataStartBlock + excelDataBlocks + 8);
ps.setSize(SMALL_BLOCK_THRESHOLD);
ps.setPrevious(-1);
ps.setNext(-1);
ps.setChild(-1);
System.arraycopy(ps.data, 0,
propertySetStorage, pos,
PROPERTY_STORAGE_BLOCK_SIZE);
pos += PROPERTY_STORAGE_BLOCK_SIZE;
// Write out the additional property sets
if (additionalPropertySets == null)
{
out.write(propertySetStorage);
return;
}
int bigBlock = excelDataStartBlock + excelDataBlocks + 16;
int smallBlock = 0;
int sz = 0;
for (Iterator i = additionalPropertySets.iterator() ; i.hasNext(); )
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
int block = rps.data.length > SMALL_BLOCK_THRESHOLD ?
bigBlock : smallBlock;
ps = new PropertyStorage(rps.propertyStorage.name);
ps.setType(rps.propertyStorage.type);
ps.setStartBlock(block);
ps.setSize(rps.propertyStorage.size);
// ps.setColour(rps.propertyStorage.colour);
previous = rps.propertyStorage.previous != -1 ?
mappings[rps.propertyStorage.previous] : -1;
next = rps.propertyStorage.next != -1 ?
mappings[rps.propertyStorage.next] : -1;
child = rps.propertyStorage.child != -1 ?
mappings[rps.propertyStorage.child] : -1;
ps.setPrevious(previous);
ps.setNext(next);
ps.setChild(child);
System.arraycopy(ps.data, 0,
propertySetStorage, pos,
PROPERTY_STORAGE_BLOCK_SIZE);
pos += PROPERTY_STORAGE_BLOCK_SIZE;
if (rps.data.length > SMALL_BLOCK_THRESHOLD)
{
bigBlock += getBigBlocksRequired(rps.data.length);
}
else
{
smallBlock += getSmallBlocksRequired(rps.data.length);
}
}
out.write(propertySetStorage);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -