📄 compoundfile.java
字号:
* @return the defragmented ole stream * @exception BiffException */ public byte[] getStream(String streamName) throws BiffException { PropertyStorage ps = findPropertyStorage(streamName, rootEntryPropertyStorage); // Property set can't be found from the direct hierarchy, so just // search on the name if (ps == null) { ps = getPropertyStorage(streamName); } if (ps.size >= SMALL_BLOCK_THRESHOLD || streamName.equalsIgnoreCase(ROOT_ENTRY_NAME)) { return getBigBlockStream(ps); } else { return getSmallBlockStream(ps); } } /** * Gets the defragmented stream from this ole compound file. Used when * copying workbooks with macros * * @param psIndex the property storage index * @return the defragmented ole stream * @exception BiffException */ public byte[] getStream(int psIndex) throws BiffException { PropertyStorage ps = getPropertyStorage(psIndex); if (ps.size >= SMALL_BLOCK_THRESHOLD || ps.name.equalsIgnoreCase(ROOT_ENTRY_NAME)) { return getBigBlockStream(ps); } else { return getSmallBlockStream(ps); } } /** * Recursively searches the property storages in hierarchy order * for the appropriate name. This is the public version which is * invoked from the writable version * when copying a sheet with addition property sets. */ public PropertyStorage findPropertyStorage(String name) { return findPropertyStorage(name, rootEntryPropertyStorage); } /** * Recursively searches the property storages in hierarchy order * for the appropriate name. */ private PropertyStorage findPropertyStorage(String name, PropertyStorage base) { if (base.child == -1) { return null; } // Get the child PropertyStorage child = getPropertyStorage(base.child); if (child.name.equalsIgnoreCase(name)) { return child; } // Find the previous property storages on the same level PropertyStorage prev = child; while (prev.previous != -1) { prev = getPropertyStorage(prev.previous); if (prev.name.equalsIgnoreCase(name)) { return prev; } } // Find the next property storages on the same level PropertyStorage next = child; while (next.next != -1) { next = getPropertyStorage(next.next); if (next.name.equalsIgnoreCase(name)) { return next; } } return findPropertyStorage(name, child); } /** * Gets the property set with the specified name * @param name the property storage name * @return the property storage record * @exception BiffException * @deprecated remove me */ private PropertyStorage getPropertyStorage(String name) throws BiffException { // Find the workbook property Iterator i = propertySets.iterator(); boolean found = false; boolean multiple = false; PropertyStorage ps = null; while (i.hasNext()) { PropertyStorage ps2 = (PropertyStorage) i.next(); if (ps2.name.equalsIgnoreCase(name)) { multiple = found == true ? true : false; found = true; ps = ps2; } } if (multiple) { logger.warn("found multiple copies of property set " + name); } if (!found) { throw new BiffException(BiffException.streamNotFound); } return ps; } /** * Gets the property set with the specified name * @param index the index of the property storage * @return the property storage record */ private PropertyStorage getPropertyStorage(int index) { return (PropertyStorage) propertySets.get(index); } /** * Build up the resultant stream using the big blocks * * @param ps the property storage * @return the big block stream */ private byte[] getBigBlockStream(PropertyStorage ps) { int numBlocks = ps.size / BIG_BLOCK_SIZE; if (ps.size % BIG_BLOCK_SIZE != 0) { numBlocks++; } byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE]; int block = ps.startBlock; int count = 0; int pos = 0; while (block != -2 && count < numBlocks) { pos = (block + 1) * BIG_BLOCK_SIZE; System.arraycopy(data, pos, streamData, count * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE); count++; block = bigBlockChain[block]; } if (block != -2 && count == numBlocks) { logger.warn("Property storage size inconsistent with block chain."); } return streamData; } /** * Build up the resultant stream using the small blocks * @param ps the property storage * @return the data * @exception BiffException */ private byte[] getSmallBlockStream(PropertyStorage ps) throws BiffException { /* PropertyStorage rootps = null; try { rootps = getPropertyStorage(ROOT_ENTRY_NAME); } catch (BiffException e) { rootps = (PropertyStorage) propertySets.get(0); } */ byte[] rootdata = readData(rootEntryPropertyStorage.startBlock); byte[] sbdata = new byte[0]; int block = ps.startBlock; int pos = 0; while (block != -2) { // grow the array byte[] olddata = sbdata; sbdata = new byte[olddata.length + SMALL_BLOCK_SIZE]; System.arraycopy(olddata, 0, sbdata, 0, olddata.length); // Copy in the new data pos = block * SMALL_BLOCK_SIZE; System.arraycopy(rootdata, pos, sbdata, olddata.length, SMALL_BLOCK_SIZE); block = smallBlockChain[block]; if (block == -1) { logger.warn("Incorrect terminator for small block stream " + ps.name); block = -2; // kludge to force the loop termination } } return sbdata; } /** * Reads the block chain from the specified block and returns the * data as a continuous stream of bytes * * @param bl the block number * @return the data */ private byte[] readData(int bl) throws BiffException { int block = bl; int pos = 0; byte[] entry = new byte[0]; while (block != -2) { // Grow the array byte[] oldEntry = entry; entry = new byte[oldEntry.length + BIG_BLOCK_SIZE]; System.arraycopy(oldEntry, 0, entry, 0, oldEntry.length); pos = (block + 1) * BIG_BLOCK_SIZE; System.arraycopy(data, pos, entry, oldEntry.length, BIG_BLOCK_SIZE); if (bigBlockChain[block] == block) { throw new BiffException(BiffException.corruptFileFormat); } block = bigBlockChain[block]; } return entry; } /** * Gets the number of property sets * @return the number of property sets */ public int getNumberOfPropertySets() { return propertySets.size(); } /** * Gets the property set. Invoked when copying worksheets with macros. * Simply calls the private counterpart * * @param ps the property set name * @return the property set with the given name */ public PropertyStorage getPropertySet(int index) { return getPropertyStorage(index); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -