diff options
author | Andrew C. Oliver <acoliver@apache.org> | 2002-09-16 18:14:31 +0000 |
---|---|---|
committer | Andrew C. Oliver <acoliver@apache.org> | 2002-09-16 18:14:31 +0000 |
commit | 7145ea60d2f5a25f6a8cb5cb67e3cd11ccc53985 (patch) | |
tree | face7f950b6af05399c7b20b146f661184c14da7 /src | |
parent | 5233b119e45be404bae97ca213d7f38ecd911de3 (diff) | |
download | poi-7145ea60d2f5a25f6a8cb5cb67e3cd11ccc53985.tar.gz poi-7145ea60d2f5a25f6a8cb5cb67e3cd11ccc53985.zip |
vba code no longer corrupted - http://nagoya.apache.org/bugzilla/show_bug.cgi?id=10213
PR:
Obtained from:
Submitted by:
Reviewed by:
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352845 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
7 files changed, 158 insertions, 32 deletions
diff --git a/src/documentation/xdocs/poifs/fileformat.xml b/src/documentation/xdocs/poifs/fileformat.xml index 7042b59599..5e17a0e4d1 100644 --- a/src/documentation/xdocs/poifs/fileformat.xml +++ b/src/documentation/xdocs/poifs/fileformat.xml @@ -465,8 +465,8 @@ public int getShort (byte[] rec) <td>-2</td> </tr> <tr> - <td>UK11</td> - <td>Unknown Constant</td> + <td>SBAT_Block_Count</td> + <td>Number of big blocks holding the SBAT</td> <td>0x0040</td> <td>Integer</td> <td>1</td> diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index a345c44336..99ee6fb388 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -64,6 +64,10 @@ import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.*; import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.poifs.filesystem.Entry; +import org.apache.poi.poifs.filesystem.DirectoryEntry; +import org.apache.poi.poifs.filesystem.DocumentEntry; +import org.apache.poi.poifs.filesystem.DocumentInputStream; import org.apache.poi.util.POILogger; import java.io.ByteArrayInputStream; @@ -72,6 +76,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; +import java.util.Iterator; /** * High level representation of a workbook. This is the first object most users @@ -117,6 +122,18 @@ public class HSSFWorkbook */ private ArrayList names; + + /** + * holds whether or not to preserve other nodes in the POIFS. Used + * for macros and embedded objects. + */ + private boolean preserveNodes; + + /** + * if you do preserve the nodes, you'll need to hold the whole POIFS in + * memory. + */ + private POIFSFileSystem poifs; private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class); @@ -132,18 +149,31 @@ public class HSSFWorkbook names = new ArrayList(INITIAL_CAPACITY); } + public HSSFWorkbook(POIFSFileSystem fs) throws IOException { + this(fs,true); + } + /** * given a POI POIFSFileSystem object, read in its Workbook and populate the high and * low level models. If you're reading in a workbook...start here. * * @param fs the POI filesystem that contains the Workbook stream. + * @param preserveNodes whether to preseve other nodes, such as + * macros. This takes more memory, so only say yes if you + * need to. * @see org.apache.poi.poifs.filesystem.POIFSFileSystem * @exception IOException if the stream cannot be read */ - public HSSFWorkbook(POIFSFileSystem fs) + public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes) throws IOException { + this.preserveNodes = preserveNodes; + + if (preserveNodes) { + this.poifs = fs; + } + sheets = new ArrayList(INITIAL_CAPACITY); names = new ArrayList(INITIAL_CAPACITY); @@ -175,20 +205,27 @@ public class HSSFWorkbook } } + public HSSFWorkbook(InputStream s) throws IOException { + this(s,true); + } + /** * Companion to HSSFWorkbook(POIFSFileSystem), this constructs the POI filesystem around your * inputstream. * * @param s the POI filesystem that contains the Workbook stream. + * @param preserveNodes whether to preseve other nodes, such as + * macros. This takes more memory, so only say yes if you + * need to. * @see org.apache.poi.poifs.filesystem.POIFSFileSystem * @see #HSSFWorkbook(POIFSFileSystem) * @exception IOException if the stream cannot be read */ - public HSSFWorkbook(InputStream s) + public HSSFWorkbook(InputStream s, boolean preserveNodes) throws IOException { - this((new POIFSFileSystem(s))); + this(new POIFSFileSystem(s), preserveNodes); } /** @@ -515,9 +552,16 @@ public class HSSFWorkbook { byte[] bytes = getBytes(); POIFSFileSystem fs = new POIFSFileSystem(); - + fs.createDocument(new ByteArrayInputStream(bytes), "Workbook"); + + if (preserveNodes) { + List excepts = new ArrayList(1); + excepts.add("Workbook"); + copyNodes(this.poifs,fs,excepts); + } fs.writeFilesystem(stream); + //poifs.writeFilesystem(stream); } /** @@ -548,12 +592,12 @@ public class HSSFWorkbook // sheetbytes.add((( HSSFSheet ) sheets.get(k)).getSheet().getSize()); totalsize += ((HSSFSheet) sheets.get(k)).getSheet().getSize(); } - if (totalsize < 4096) +/* if (totalsize < 4096) { totalsize = 4096; - } - byte[] data = new byte[totalsize]; - int pos = workbook.serialize(0, data); + }*/ + byte[] retval = new byte[totalsize]; + int pos = workbook.serialize(0, retval); // System.arraycopy(wb, 0, retval, 0, wb.length); for (int k = 0; k < sheets.size(); k++) @@ -562,13 +606,13 @@ public class HSSFWorkbook // byte[] sb = (byte[])sheetbytes.get(k); // System.arraycopy(sb, 0, retval, pos, sb.length); pos += ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos, - data); // sb.length; + retval); // sb.length; } - for (int k = pos; k < totalsize; k++) +/* for (int k = pos; k < totalsize; k++) { - data[k] = 0; - } - return data; + retval[k] = 0; + }*/ + return retval; } public int addSSTString(String string) @@ -677,5 +721,57 @@ public class HSSFWorkbook removeName(index); } - + + /** + * Copies nodes from one POIFS to the other minus the excepts + * @param source is the source POIFS to copy from + * @param target is the target POIFS to copy to + * @param excepts is a list of Strings specifying what nodes NOT to copy + */ + private void copyNodes(POIFSFileSystem source, POIFSFileSystem target, + List excepts) throws IOException { + //System.err.println("CopyNodes called"); + + DirectoryEntry root = source.getRoot(); + DirectoryEntry newRoot = target.getRoot(); + + Iterator entries = root.getEntries(); + + while (entries.hasNext()) { + Entry entry = (Entry)entries.next(); + if (!isInList(entry.getName(), excepts)) { + copyNodeRecursively(entry,newRoot); + } + } + } + + private boolean isInList(String entry, List list) { + for (int k = 0; k < list.size(); k++) { + if (((String)list.get(k)).equals(entry)) { + return true; + } + } + return false; + } + + private void copyNodeRecursively(Entry entry, DirectoryEntry target) + throws IOException { + //System.err.println("copyNodeRecursively called with "+entry.getName()+ + // ","+target.getName()); + DirectoryEntry newTarget = null; + if (entry.isDirectoryEntry()) { + newTarget = target.createDirectory(entry.getName()); + Iterator entries = ((DirectoryEntry)entry).getEntries(); + + while (entries.hasNext()) { + copyNodeRecursively((Entry)entries.next(),newTarget); + } + } else { + DocumentEntry dentry = (DocumentEntry)entry; + DocumentInputStream dstream = new DocumentInputStream(dentry); + target.createDocument(dentry.getName(),dstream); + dstream.close(); + } + } + } diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java index dbd473f23f..7652753f6a 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java @@ -269,6 +269,9 @@ public class POIFSFileSystem // set the small block allocation table start block header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock()); + // set the small block allocation table block count + header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount()); + // the header is now properly initialized. Make a list of // writers (the header block, followed by the documents, the // property table, the small block store, the small block diff --git a/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java b/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java index c2c440160c..cfe4729c43 100644 --- a/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java +++ b/src/java/org/apache/poi/poifs/storage/HeaderBlockConstants.java @@ -70,18 +70,19 @@ import org.apache.poi.util.ShortField; 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 = + 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; // useful offsets - public static final int _signature_offset = 0; - public static final int _bat_count_offset = 0x2C; - public static final int _property_start_offset = 0x30; - public static final int _sbat_start_offset = 0x3C; - public static final int _xbat_start_offset = 0x44; - public static final int _xbat_count_offset = 0x48; + public static final int _signature_offset = 0; + public static final int _bat_count_offset = 0x2C; + public static final int _property_start_offset = 0x30; + public static final int _sbat_start_offset = 0x3C; + public static final int _sbat_block_count_offset = 0x40; + public static final int _xbat_start_offset = 0x44; + public static final int _xbat_count_offset = 0x48; } // end public interface HeaderBlockConstants diff --git a/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java b/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java index 9253d1c61c..c0c7a512fc 100644 --- a/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java +++ b/src/java/org/apache/poi/poifs/storage/HeaderBlockWriter.java @@ -88,6 +88,9 @@ public class HeaderBlockWriter // 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; @@ -121,7 +124,8 @@ public class HeaderBlockWriter new IntegerField(0x38, 0x1000, _data); _sbat_start = new IntegerField(_sbat_start_offset, POIFSConstants.END_OF_CHAIN, _data); - new IntegerField(0x40, 1, _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); @@ -201,6 +205,17 @@ public class HeaderBlockWriter } /** + * Set count of SBAT blocks + * + * @param count the number of SBAT blocks + */ + + public void setSBATBlockCount(final int count) + { + _sbat_block_count.set(count, _data); + } + + /** * For a given number of BAT blocks, calculate how many XBAT * blocks will be needed * diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java index 76b77b54bd..80987d0692 100644 --- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java +++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableWriter.java @@ -113,6 +113,17 @@ public class SmallBlockTableWriter } /** + * Get the number of SBAT blocks + * + * @return number of SBAT big blocks + */ + + public int getSBATBlockCount() + { + return (_big_block_count + 15) / 16; + } + + /** * Get the SBAT * * @return the Small Block Allocation Table diff --git a/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java b/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java index 30a9f35c51..f521073940 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestHeaderBlockWriter.java @@ -117,7 +117,7 @@ public class TestHeaderBlockWriter ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, - ( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, + ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, @@ -281,7 +281,7 @@ public class TestHeaderBlockWriter ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01, - ( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, + ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, @@ -436,7 +436,7 @@ public class TestHeaderBlockWriter ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, - ( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, + ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, @@ -597,7 +597,7 @@ public class TestHeaderBlockWriter ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, - ( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, + ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01, @@ -744,7 +744,7 @@ public class TestHeaderBlockWriter ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, - ( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, + ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01, @@ -891,7 +891,7 @@ public class TestHeaderBlockWriter ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, - ( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, + ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x67, ( byte ) 0x46, ( byte ) 0x23, ( byte ) 0x01, ( byte ) 0x02, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01, |