You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2021/05/14 00:37:53 UTC

svn commit: r1889871 [8/17] - in /poi: site/src/documentation/content/xdocs/ site/src/documentation/content/xdocs/components/ trunk/ trunk/maven/ trunk/osgi/ trunk/osgi/src/test/java/org/apache/poi/osgi/ trunk/poi-examples/src/main/java/org/apache/poi/...

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java Fri May 14 00:37:50 2021
@@ -23,7 +23,6 @@ import java.awt.Color;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -33,6 +32,7 @@ import java.util.function.Supplier;
 
 import javax.imageio.ImageIO;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emfplus.HemfPlusHeader.EmfPlusGraphicsVersion;
@@ -445,7 +445,7 @@ public class HemfPlusImage {
         }
 
         public byte[] getRawData(List<? extends EmfPlusObjectData> continuedObjectData) {
-            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
             try {
                 bos.write(getImageData());
                 if (continuedObjectData != null) {
@@ -607,6 +607,7 @@ public class HemfPlusImage {
             return size + 5*LittleEndianConsts.INT_SIZE;
         }
 
+        @Override
         public EmfPlusGraphicsVersion getGraphicsVersion() {
             return graphicsVersion;
         }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfEmbeddedIterator.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfEmbeddedIterator.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfEmbeddedIterator.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfEmbeddedIterator.java Fri May 14 00:37:50 2021
@@ -18,7 +18,6 @@
 package org.apache.poi.hemf.usermodel;
 
 import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Deque;
@@ -27,6 +26,7 @@ import java.util.NoSuchElementException;
 
 import javax.imageio.ImageIO;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hemf.record.emf.HemfComment;
 import org.apache.poi.hemf.record.emf.HemfComment.EmfComment;
 import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataFormat;
@@ -273,7 +273,7 @@ public class HemfEmbeddedIterator implem
     private void compressGDIBitmap(EmfPlusImage img, HwmfEmbedded emb, HwmfEmbeddedType et) {
         BufferedImage bi = img.readGDIImage(emb.getRawData());
         try {
-            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
             // use HwmfEmbeddedType literal for conversion
             ImageIO.write(bi, et.toString(), bos);
             emb.setData(bos.toByteArray());
@@ -298,7 +298,7 @@ public class HemfEmbeddedIterator implem
         int totalSize = epo.getTotalObjectSize();
         IOUtils.safelyAllocateCheck(totalSize, MAX_RECORD_LENGTH);
 
-        ByteArrayOutputStream bos = new ByteArrayOutputStream(epo.getTotalObjectSize());
+        UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream(epo.getTotalObjectSize());
         try {
             for (;;) {
                 bos.write(img.getImageData());
@@ -315,8 +315,8 @@ public class HemfEmbeddedIterator implem
                     return emb;
                 }
             }
-        } catch (IOException e) {
-            // ByteArrayOutputStream doesn't throw IOException
+        } catch (IOException ignored) {
+            // UnsynchronizedByteArrayOutputStream doesn't throw IOException
             return null;
         } finally {
             emb.setData(bos.toByteArray());

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hmef/CompressedRTF.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hmef/CompressedRTF.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hmef/CompressedRTF.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hmef/CompressedRTF.java Fri May 14 00:37:50 2021
@@ -70,6 +70,7 @@ public final class CompressedRTF extends
     *  if you need to know how much of the result is
     *  real. (Padding may be up to 7 bytes).
     */
+   @Override
    public void decompress(InputStream src, OutputStream res) throws IOException {
       // Validate the header on the front of the RTF
       compressedSize = LittleEndian.readInt(src);

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/EMF.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/EMF.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/EMF.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/EMF.java Fri May 14 00:37:50 2021
@@ -19,11 +19,11 @@ package org.apache.poi.hslf.blip;
 
 import java.awt.Dimension;
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.zip.InflaterInputStream;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.EscherBSERecord;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -41,7 +41,7 @@ public final class EMF extends Metafile
 
     /**
      * @deprecated Use {@link HSLFSlideShow#addPicture(byte[], PictureType)} or one of it's overloads to create new
-     *             {@link EMF}. This API led to detached {@link EMF} instances (See Bugzilla
+     *             EMF. This API led to detached EMF instances (See Bugzilla
      *             46122) and prevented adding additional functionality.
      */
     @Deprecated
@@ -64,23 +64,19 @@ public final class EMF extends Metafile
 
     @Override
     public byte[] getData(){
-        try {
-            byte[] rawdata = getRawData();
+        byte[] rawdata = getRawData();
+        Header header = new Header();
+        header.read(rawdata, CHECKSUM_SIZE);
+
+        try (UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
+             InputStream is = new ByteArrayInputStream(rawdata);
+             InflaterInputStream inflater = new InflaterInputStream(is)) {
 
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            InputStream is = new ByteArrayInputStream( rawdata );
-            Header header = new Header();
-            header.read(rawdata, CHECKSUM_SIZE);
             long len = IOUtils.skipFully(is,header.getSize() + (long)CHECKSUM_SIZE);
             assert(len == header.getSize() + CHECKSUM_SIZE);
 
-            InflaterInputStream inflater = new InflaterInputStream( is );
-            byte[] chunk = new byte[4096];
-            int count;
-            while ((count = inflater.read(chunk)) >=0 ) {
-                out.write(chunk,0,count);
-            }
-            inflater.close();
+            IOUtils.copy(inflater, out);
+
             return out.toByteArray();
         } catch (IOException e){
             throw new HSLFException(e);
@@ -129,13 +125,15 @@ public final class EMF extends Metafile
      *
      * @return EMF signature ({@code 0x3D40} or {@code 0x3D50})
      */
+    @Override
     public int getSignature(){
         return (getUIDInstanceCount() == 1 ? 0x3D40 : 0x3D50);
     }
-    
+
     /**
      * Sets the EMF signature - either {@code 0x3D40} or {@code 0x3D50}
      */
+    @Override
     public void setSignature(int signature) {
         switch (signature) {
             case 0x3D40:
@@ -146,6 +144,6 @@ public final class EMF extends Metafile
                 break;
             default:
                 throw new IllegalArgumentException(signature+" is not a valid instance/signature value for EMF");
-        }        
+        }
     }
 }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Metafile.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Metafile.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Metafile.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Metafile.java Fri May 14 00:37:50 2021
@@ -20,11 +20,11 @@ package org.apache.poi.hslf.blip;
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.zip.DeflaterOutputStream;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.EscherBSERecord;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.hslf.usermodel.HSLFPictureData;
@@ -44,7 +44,7 @@ public abstract class Metafile extends H
 
     /**
      * @deprecated Use {@link HSLFSlideShow#addPicture(byte[], PictureType)} or one of it's overloads to create new
-     *             {@link Metafile}. This API led to detached {@link Metafile} instances (See Bugzilla
+     *             Metafile. This API led to detached Metafile instances (See Bugzilla
      *             46122) and prevented adding additional functionality.
      */
     @Deprecated
@@ -70,7 +70,7 @@ public abstract class Metafile extends H
      */
     public static class Header{
         private static final int RECORD_LENGTH = 34;
-        
+
         /**
          * size of the original file
          */
@@ -105,7 +105,7 @@ public abstract class Metafile extends H
             @SuppressWarnings("resource")
             LittleEndianInputStream leis = new LittleEndianInputStream(
                 new ByteArrayInputStream(data, offset, RECORD_LENGTH));
-            
+
             wmfsize = leis.readInt();
 
             int left = leis.readInt();
@@ -126,7 +126,7 @@ public abstract class Metafile extends H
         public void write(OutputStream out) throws IOException {
             @SuppressWarnings("resource")
             LittleEndianOutputStream leos = new LittleEndianOutputStream(out);
-            
+
             //hmf
             leos.writeInt(wmfsize);
             //left
@@ -140,8 +140,8 @@ public abstract class Metafile extends H
             //inch
             leos.writeInt(size.width);
             //inch
-            leos.writeInt(size.height); 
-            leos.writeInt(zipsize); 
+            leos.writeInt(size.height);
+            leos.writeInt(zipsize);
             leos.writeByte(compression);
             leos.writeByte(filter);
         }
@@ -187,15 +187,15 @@ public abstract class Metafile extends H
         public int getSize(){
             return 34;
         }
-        
+
         public int getWmfSize() {
             return wmfsize;
         }
-        
+
         protected void setWmfSize(int wmfSize) {
             this.wmfsize = wmfSize;
         }
-        
+
         protected void setZipSize(int zipSize) {
             this.zipsize = zipSize;
         }
@@ -203,25 +203,25 @@ public abstract class Metafile extends H
         public Rectangle getBounds() {
             return (Rectangle)bounds.clone();
         }
-        
+
         protected void setBounds(Rectangle bounds) {
             this.bounds.setBounds(bounds);
         }
-        
+
         protected void setDimension(Dimension size) {
             this.size.setSize(size);
         }
     }
 
     protected static byte[] compress(byte[] bytes, int offset, int length) {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
         try (DeflaterOutputStream deflater = new DeflaterOutputStream(out)) {
             deflater.write(bytes, offset, length);
-        } catch (IOException e) {
+        } catch (IOException ignored) {
             // IOException won't get thrown by the DeflaterOutputStream in this configuration because:
-            //  1. ByteArrayOutputStream doesn't throw an IOException during writes.
+            //  1. UnsynchronizedByteArrayOutputStream doesn't throw an IOException during writes.
             //  2. The DeflaterOutputStream is not finished until we're done writing.
-            throw new AssertionError("Won't happen", e);
+            throw new AssertionError("Won't happen", ignored);
         }
         return out.toByteArray();
     }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java Fri May 14 00:37:50 2021
@@ -17,13 +17,15 @@
 
 package org.apache.poi.hslf.blip;
 
+import static org.apache.logging.log4j.util.Unbox.box;
+
 import java.awt.Dimension;
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
 import java.io.IOException;
 import java.util.zip.InflaterInputStream;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.ddf.EscherBSERecord;
@@ -36,8 +38,6 @@ import org.apache.poi.util.Internal;
 import org.apache.poi.util.Removal;
 import org.apache.poi.util.Units;
 
-import static org.apache.logging.log4j.util.Unbox.box;
-
 /**
  * Represents Macintosh PICT picture data.
  */
@@ -46,7 +46,7 @@ public final class PICT extends Metafile
 
     /**
      * @deprecated Use {@link HSLFSlideShow#addPicture(byte[], PictureType)} or one of it's overloads to create new
-     *             {@link PICT}. This API led to detached {@link PICT} instances (See Bugzilla
+     *             PICT. This API led to detached PICT instances (See Bugzilla
      *             46122) and prevented adding additional functionality.
      */
     @Deprecated
@@ -72,7 +72,7 @@ public final class PICT extends Metafile
         byte[] rawdata = getRawData();
         try {
             byte[] macheader = new byte[512];
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
             out.write(macheader);
             int pos = CHECKSUM_SIZE*getUIDInstanceCount();
             byte[] pict = read(rawdata, pos);
@@ -93,7 +93,7 @@ public final class PICT extends Metafile
             throw new EOFException();
         }
         byte[] chunk = new byte[4096];
-        ByteArrayOutputStream out = new ByteArrayOutputStream(header.getWmfSize());
+        UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream(header.getWmfSize());
         try (InflaterInputStream inflater = new InflaterInputStream(bis)) {
             int count;
             while ((count = inflater.read(chunk)) >= 0) {
@@ -163,6 +163,7 @@ public final class PICT extends Metafile
      *
      * @return PICT signature ({@code 0x5420} or {@code 0x5430})
      */
+    @Override
     public int getSignature(){
         return (getUIDInstanceCount() == 1 ? 0x5420 : 0x5430);
     }
@@ -170,6 +171,7 @@ public final class PICT extends Metafile
     /**
      * Sets the PICT signature - either {@code 0x5420} or {@code 0x5430}
      */
+    @Override
     public void setSignature(int signature) {
         switch (signature) {
             case 0x5420:

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/WMF.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/WMF.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/WMF.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/WMF.java Fri May 14 00:37:50 2021
@@ -19,11 +19,11 @@ package org.apache.poi.hslf.blip;
 
 import java.awt.Dimension;
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.zip.InflaterInputStream;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.EscherBSERecord;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -41,7 +41,7 @@ public final class WMF extends Metafile
 
     /**
      * @deprecated Use {@link HSLFSlideShow#addPicture(byte[], PictureType)} or one of it's overloads to create new
-     *             {@link WMF}. This API led to detached {@link WMF} instances (See Bugzilla
+     *             WMF. This API led to detached WMF instances (See Bugzilla
      *             46122) and prevented adding additional functionality.
      */
     @Deprecated
@@ -67,7 +67,6 @@ public final class WMF extends Metafile
         try {
             byte[] rawdata = getRawData();
 
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
             InputStream is = new ByteArrayInputStream( rawdata );
             Header header = new Header();
             header.read(rawdata, CHECKSUM_SIZE*getUIDInstanceCount());
@@ -76,15 +75,12 @@ public final class WMF extends Metafile
             assert(skipped == skipLen);
 
             ImageHeaderWMF aldus = new ImageHeaderWMF(header.getBounds());
+            UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
             aldus.write(out);
 
-            InflaterInputStream inflater = new InflaterInputStream( is );
-            byte[] chunk = new byte[4096];
-            int count;
-            while ((count = inflater.read(chunk)) >=0 ) {
-                out.write(chunk,0,count);
+            try (InflaterInputStream inflater = new InflaterInputStream( is )) {
+                IOUtils.copy(inflater, out);
             }
-            inflater.close();
             return out.toByteArray();
         } catch (IOException e){
             throw new HSLFException(e);
@@ -133,6 +129,7 @@ public final class WMF extends Metafile
     /**
      * WMF signature is either {@code 0x2160} or {@code 0x2170}
      */
+    @Override
     public int getSignature(){
         return (getUIDInstanceCount() == 1 ? 0x2160 : 0x2170);
     }
@@ -140,6 +137,7 @@ public final class WMF extends Metafile
     /**
      * Sets the WMF signature - either {@code 0x2160} or {@code 0x2170}
      */
+    @Override
     public void setSignature(int signature) {
         switch (signature) {
             case 0x2160:

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/PPTXMLDump.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/PPTXMLDump.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/PPTXMLDump.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/PPTXMLDump.java Fri May 14 00:37:50 2021
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hslf.dev;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -28,6 +27,7 @@ import java.io.Writer;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.record.RecordTypes;
 import org.apache.poi.hslf.usermodel.HSLFSlideShow;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
@@ -41,19 +41,15 @@ import org.apache.poi.util.LittleEndianC
  */
 
 public final class PPTXMLDump {
-
-    //arbitrarily selected; may need to increase
-    private static final int MAX_RECORD_LENGTH = 1_000_000;
-
     private static final int HEADER_SIZE = 8; //size of the record header
     private static final int PICT_HEADER_SIZE = 25; //size of the picture header
     private static final String PICTURES_ENTRY = "Pictures";
     private static final String CR = System.getProperty("line.separator");
 
     private Writer out;
-    private byte[] docstream;
-    private byte[] pictstream;
-    private boolean hexHeader = true;
+    private final byte[] docstream;
+    private final byte[] pictstream;
+    private final boolean hexHeader = true;
 
     public PPTXMLDump(File ppt) throws IOException {
         try (POIFSFileSystem fs = new POIFSFileSystem(ppt, true)) {
@@ -68,8 +64,8 @@ public final class PPTXMLDump {
         if (!dn.hasEntry(entry)) {
             return null;
         }
-        try (InputStream is = dn.createDocumentInputStream(entry)) {
-            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        try (InputStream is = dn.createDocumentInputStream(entry);
+            UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
             IOUtils.copy(is, bos);
             return bos.toByteArray();
         }
@@ -77,7 +73,7 @@ public final class PPTXMLDump {
 
     /**
      * Dump the structure of the supplied PPT file into XML
-     * @param outWriter <code>Writer</code> to write out
+     * @param outWriter {@code Writer} to write out
      * @throws java.io.IOException If writing to the writer fails
      */
     public void dump(Writer outWriter) throws IOException {
@@ -229,7 +225,7 @@ public final class PPTXMLDump {
 
 
     /**
-     *  write a string to <code>out</code> with the specified padding
+     *  write a string to {@code out} with the specified padding
      */
     private static void write(Writer out, String str, int padding) throws IOException {
         for (int i = 0; i < padding; i++) out.write("  ");
@@ -250,7 +246,7 @@ public final class PPTXMLDump {
     }
 
     /**
-     *  dump binary data to <code>out</code> with the specified padding
+     *  dump binary data to {@code out} with the specified padding
      */
     private static void dump(Writer out, byte[] data, int offset, int length, int padding, boolean nl) throws IOException {
         int linesize = 25;

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideIdListing.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideIdListing.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideIdListing.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideIdListing.java Fri May 14 00:37:50 2021
@@ -17,10 +17,10 @@
 
 package org.apache.poi.hslf.dev;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Map;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.record.Document;
 import org.apache.poi.hslf.record.Notes;
 import org.apache.poi.hslf.record.NotesAtom;
@@ -136,7 +136,7 @@ public final class SlideIdListing {
                         System.out.println("  Knows about sheet " + id);
                         System.out.println("    That sheet lives at " + offset);
 
-                        Record atPos = findRecordAtPos(offset.intValue());
+                        Record atPos = findRecordAtPos(offset);
                         System.out.println("    The record at that pos is of type " + atPos.getRecordType());
                         System.out.println("    The record at that pos has class " + atPos.getClass().getName());
 
@@ -147,7 +147,7 @@ public final class SlideIdListing {
                 }
 
                 // Increase the position by the on disk size
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
                 r.writeOut(baos);
                 pos += baos.size();
             }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideShowRecordDumper.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideShowRecordDumper.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideShowRecordDumper.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/SlideShowRecordDumper.java Fri May 14 00:37:50 2021
@@ -17,12 +17,11 @@
 
 package org.apache.poi.hslf.dev;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.util.List;
 import java.util.Locale;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.DefaultEscherRecordFactory;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherRecord;
@@ -44,9 +43,9 @@ import org.apache.poi.util.HexDump;
 public final class SlideShowRecordDumper {
     static final String tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
 
-    private boolean optVerbose;
-    private boolean optEscher;
-    private HSLFSlideShowImpl doc;
+    private final boolean optVerbose;
+    private final boolean optEscher;
+    private final HSLFSlideShowImpl doc;
     private final PrintStream ps;
 
     /**
@@ -59,7 +58,7 @@ public final class SlideShowRecordDumper
 
         int ndx = 0;
         for (; ndx < args.length; ndx++) {
-            if (!args[ndx].substring(0, 1).equals("-"))
+            if (args[ndx].charAt(0) != '-')
                 break;
 
             if (args[ndx].equals("-escher")) {
@@ -147,7 +146,7 @@ public final class SlideShowRecordDumper
     public int getDiskLen(org.apache.poi.hslf.record.Record r) throws IOException {
         int diskLen = 0;
         if (r != null) {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
             r.writeOut(baos);
             diskLen = baos.size();
         }
@@ -159,7 +158,7 @@ public final class SlideShowRecordDumper
             return "<<null>>";
         }
 
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
         r.writeOut(baos);
         byte[] b = baos.toByteArray();
         return HexDump.dump(b, 0, 0);
@@ -259,7 +258,7 @@ public final class SlideShowRecordDumper
             if (optEscher && cname.equals("PPDrawing")) {
                 DefaultEscherRecordFactory factory = new HSLFEscherRecordFactory();
 
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
                 r.writeOut(baos);
                 byte[] b = baos.toByteArray();
 

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/UserEditAndPersistListing.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/UserEditAndPersistListing.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/UserEditAndPersistListing.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/dev/UserEditAndPersistListing.java Fri May 14 00:37:50 2021
@@ -17,10 +17,10 @@
 
 package org.apache.poi.hslf.dev;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Map;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.record.CurrentUserAtom;
 import org.apache.poi.hslf.record.PersistPtrHolder;
 import org.apache.poi.hslf.record.PositionDependentRecord;
@@ -68,7 +68,7 @@ public final class UserEditAndPersistLis
 						System.out.println("  Knows about sheet " + id);
 						System.out.println("    That sheet lives at " + offset);
 
-						Record atPos = findRecordAtPos(offset.intValue());
+						Record atPos = findRecordAtPos(offset);
 						System.out.println("    The record at that pos is of type " + atPos.getRecordType());
 						System.out.println("    The record at that pos has class " + atPos.getClass().getName());
 
@@ -79,7 +79,7 @@ public final class UserEditAndPersistLis
 				}
 
 				// Increase the position by the on disk size
-				ByteArrayOutputStream baos = new ByteArrayOutputStream();
+				UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
 				r.writeOut(baos);
 				pos += baos.size();
 			}
@@ -99,7 +99,7 @@ public final class UserEditAndPersistLis
 				}
 
 				// Increase the position by the on disk size
-				ByteArrayOutputStream baos = new ByteArrayOutputStream();
+				UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
 				r.writeOut(baos);
 				pos += baos.size();
 			}

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/model/textproperties/TextPropCollection.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/model/textproperties/TextPropCollection.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/model/textproperties/TextPropCollection.java Fri May 14 00:37:50 2021
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hslf.model.textproperties;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -29,6 +28,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.common.Duplicatable;
@@ -355,10 +355,10 @@ public class TextPropCollection implemen
 
     public String toString() {
         StringBuilder out = new StringBuilder();
-        out.append("  chars covered: " + getCharactersCovered());
-        out.append("  special mask flags: 0x" + HexDump.toHex(getSpecialMask()) + "\n");
+        out.append("  chars covered: ").append(getCharactersCovered());
+        out.append("  special mask flags: 0x").append(HexDump.toHex(getSpecialMask())).append("\n");
         if (textPropType == TextPropType.paragraph) {
-            out.append("  indent level: "+getIndentLevel()+"\n");
+            out.append("  indent level: ").append(getIndentLevel()).append("\n");
         }
         for(TextProp p : getTextPropList()) {
             out.append("    ");
@@ -369,7 +369,7 @@ public class TextPropCollection implemen
                 int i = 0;
                 for (String s : bm.getSubPropNames()) {
                     if (bm.getSubPropMatches()[i]) {
-                        out.append("          " + s + " = " + bm.getSubValue(i) + "\n");
+                        out.append("          ").append(s).append(" = ").append(bm.getSubValue(i)).append("\n");
                     }
                     i++;
                 }
@@ -379,7 +379,7 @@ public class TextPropCollection implemen
         out.append("  bytes that would be written: \n");
 
         try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
             writeOut(baos);
             byte[] b = baos.toByteArray();
             out.append(HexDump.dump(b, 0, 0));

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ColorSchemeAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ColorSchemeAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ColorSchemeAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ColorSchemeAtom.java Fri May 14 00:37:50 2021
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Arrays;
@@ -26,6 +25,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.util.LittleEndian;
 
@@ -36,9 +36,9 @@ import org.apache.poi.util.LittleEndian;
  *  defines the colours to be used
  */
 public final class ColorSchemeAtom extends RecordAtom {
-	private byte[] _header;
-	private static long _type = 2032l;
+	private static final long _type = 2032L;
 
+	private final byte[] _header;
 	private int backgroundColourRGB;
 	private int textAndLinesColourRGB;
 	private int shadowsColourRGB;
@@ -99,8 +99,7 @@ public final class ColorSchemeAtom exten
 	 */
 	protected ColorSchemeAtom(byte[] source, int start, int len) {
 		// Sanity Checking - we're always 40 bytes long
-		if(len < 40) {
-			len = 40;
+		if (len < 40) {
 			if(source.length - start < 40) {
 				throw new HSLFException("Not enough data to form a ColorSchemeAtom (always 40 bytes long) - found " + (source.length - start));
 			}
@@ -155,7 +154,7 @@ public final class ColorSchemeAtom exten
 		byte[] ret = new byte[3];
 
 		// Serialise to bytes, then grab the right ones out
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
 		try {
 			writeLittleEndian(rgb,baos);
 		} catch(IOException ie) {

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/CurrentUserAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/CurrentUserAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/CurrentUserAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/CurrentUserAtom.java Fri May 14 00:37:50 2021
@@ -23,12 +23,11 @@ package org.apache.poi.hslf.record;
 import static org.apache.logging.log4j.util.Unbox.box;
 import static org.apache.poi.hslf.usermodel.HSLFSlideShow.PP95_DOCUMENT;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
@@ -267,12 +266,12 @@ public class CurrentUserAtom
 	 */
 	public void writeToFS(POIFSFileSystem fs) throws IOException {
 		// Grab contents
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		writeOut(baos);
-		ByteArrayInputStream bais =
-			new ByteArrayInputStream(baos.toByteArray());
-
-		// Write out
-		fs.createOrUpdateDocument(bais,"Current User");
+		try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
+			writeOut(baos);
+			try (InputStream is = baos.toInputStream()) {
+				// Write out
+				fs.createOrUpdateDocument(is, "Current User");
+			}
+		}
 	}
 }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/DocumentAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/DocumentAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/DocumentAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/DocumentAtom.java Fri May 14 00:37:50 2021
@@ -66,7 +66,7 @@ public final class DocumentAtom extends
 
 
 	private final byte[] _header = new byte[8];
-	private static long _type = RecordTypes.DocumentAtom.typeID;
+	private static final long _type = RecordTypes.DocumentAtom.typeID;
 
 	private long slideSizeX; // PointAtom, assume 1st 4 bytes = X
 	private long slideSizeY; // PointAtom, assume 2nd 4 bytes = Y
@@ -75,18 +75,18 @@ public final class DocumentAtom extends
 	private long serverZoomFrom; // RatioAtom, assume 1st 4 bytes = from
 	private long serverZoomTo;   // RatioAtom, assume 2nd 4 bytes = to
 
-	private long notesMasterPersist; // ref to NotesMaster, 0 if none
-	private long handoutMasterPersist; // ref to HandoutMaster, 0 if none
+	private final long notesMasterPersist; // ref to NotesMaster, 0 if none
+	private final long handoutMasterPersist; // ref to HandoutMaster, 0 if none
 
-	private int firstSlideNum;
+	private final int firstSlideNum;
 	private int slideSizeType; // see DocumentAtom.SlideSize
 
 	private byte saveWithFonts;
-	private byte omitTitlePlace;
-	private byte rightToLeft;
-	private byte showComments;
+	private final byte omitTitlePlace;
+	private final byte rightToLeft;
+	private final byte showComments;
 
-	private byte[] reserved;
+	private final byte[] reserved;
 
 
 	public long getSlideSizeX() { return slideSizeX; }
@@ -197,12 +197,14 @@ public final class DocumentAtom extends
 	/**
 	 * We are of type 1001
 	 */
+	@Override
 	public long getRecordType() { return _type; }
 
 	/**
 	 * Write the contents of the record back, so it can be written
 	 *  to disk
 	 */
+	@Override
 	public void writeOut(OutputStream out) throws IOException {
 		// Header
 		out.write(_header);

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/EscherTextboxWrapper.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/EscherTextboxWrapper.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/EscherTextboxWrapper.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/EscherTextboxWrapper.java Fri May 14 00:37:50 2021
@@ -17,12 +17,12 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.EscherTextboxRecord;
 import org.apache.poi.util.GenericRecordUtil;
 
@@ -34,7 +34,7 @@ import org.apache.poi.util.GenericRecord
  *  parent PPDrawing) will do the actual write out
  */
 public final class EscherTextboxWrapper extends RecordContainer {
-	private EscherTextboxRecord _escherRecord;
+	private final EscherTextboxRecord _escherRecord;
 	private long _type;
 	private int shapeId;
 	private StyleTextPropAtom styleTextPropAtom;
@@ -75,6 +75,7 @@ public final class EscherTextboxWrapper
 	/**
 	 * Return the type of the escher record (normally in the 0xFnnn range)
 	 */
+	@Override
 	public long getRecordType() { return _type; }
 
 	/**
@@ -83,11 +84,12 @@ public final class EscherTextboxWrapper
 	 *  layer to do. Must be called before writeOut/serialize is called
 	 *  on the underlying Escher object!
 	 */
+	@Override
 	public void writeOut(OutputStream out) throws IOException {
 		// Write out our children, and stuff them into the Escher layer
 
 		// Grab the children's data
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
 		for (org.apache.poi.hslf.record.Record r : _children) r.writeOut(baos);
 		byte[] data = baos.toByteArray();
 

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ExOleObjStg.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ExOleObjStg.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ExOleObjStg.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/ExOleObjStg.java Fri May 14 00:37:50 2021
@@ -18,7 +18,6 @@
 package org.apache.poi.hslf.record;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -28,7 +27,8 @@ import java.util.function.Supplier;
 import java.util.zip.DeflaterOutputStream;
 import java.util.zip.InflaterInputStream;
 
-import org.apache.poi.util.BoundedInputStream;
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
+import org.apache.commons.io.input.BoundedInputStream;
 import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
@@ -124,7 +124,7 @@ public class ExOleObjStg extends Positio
      * @param data the embedded data.
      */
      public void setData(byte[] data) throws IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream();
         //first four bytes is the length of the raw data
         byte[] b = new byte[4];
         LittleEndian.putInt(b, 0, data.length);
@@ -133,6 +133,7 @@ public class ExOleObjStg extends Positio
         DeflaterOutputStream def = new DeflaterOutputStream(out);
         def.write(data, 0, data.length);
         def.finish();
+        // TODO: CHECK if it's correct that DeflaterOutputStream is only finished and not closed?
         _data = out.toByteArray();
         LittleEndian.putInt(_header, 4, _data.length);
     }
@@ -142,6 +143,7 @@ public class ExOleObjStg extends Positio
      *
      * @return the record type.
      */
+    @Override
     public long getRecordType() {
         return RecordTypes.ExOleObjStg.typeID;
     }
@@ -162,6 +164,7 @@ public class ExOleObjStg extends Positio
      * @param out the output stream to write to.
      * @throws IOException if an error occurs.
      */
+    @Override
     public void writeOut(OutputStream out) throws IOException {
         out.write(_header);
         out.write(_data);
@@ -171,6 +174,7 @@ public class ExOleObjStg extends Positio
      * Fetch our sheet ID, as found from a PersistPtrHolder.
      * Should match the RefId of our matching SlidePersistAtom
      */
+    @Override
     public int getPersistId() {
         return _persistId;
     }
@@ -178,6 +182,7 @@ public class ExOleObjStg extends Positio
     /**
      * Set our sheet ID, as found from a PersistPtrHolder
      */
+    @Override
     public void setPersistId(int id) {
         _persistId = id;
     }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java Fri May 14 00:37:50 2021
@@ -17,11 +17,11 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.EscherClientDataRecord;
 import org.apache.poi.ddf.EscherRecordFactory;
 import org.apache.poi.ddf.EscherSerializationListener;
@@ -49,7 +49,7 @@ public class HSLFEscherClientDataRecord
         super(other);
         // TODO: for now only reference others children, later copy them when Record.copy is available
         // other._childRecords.stream().map(Record::copy).forEach(_childRecords::add);
-        other._childRecords.addAll(other._childRecords);
+        _childRecords.addAll(other._childRecords);
     }
 
 
@@ -96,15 +96,14 @@ public class HSLFEscherClientDataRecord
 
     @Override
     public byte[] getRemainingData() {
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        try {
+        try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) {
             for (org.apache.poi.hslf.record.Record r : _childRecords) {
                 r.writeOut(bos);
             }
+            return bos.toByteArray();
         } catch (IOException e) {
             throw new HSLFException(e);
         }
-        return bos.toByteArray();
     }
 
     @Override
@@ -121,6 +120,7 @@ public class HSLFEscherClientDataRecord
         }
     }
 
+    @Override
     public String getRecordName() {
         return "HSLFClientData";
     }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawingGroup.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawingGroup.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawingGroup.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PPDrawingGroup.java Fri May 14 00:37:50 2021
@@ -17,13 +17,13 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.ddf.DefaultEscherRecordFactory;
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherDggRecord;
@@ -44,8 +44,8 @@ public final class PPDrawingGroup extend
     private static final int MAX_RECORD_LENGTH = 10_485_760;
 
 
-    private byte[] _header;
-    private EscherContainerRecord dggContainer;
+    private final byte[] _header;
+    private final EscherContainerRecord dggContainer;
     //cached dgg
     private EscherDggRecord dgg;
 
@@ -65,6 +65,7 @@ public final class PPDrawingGroup extend
     /**
      * We are type 1035
      */
+    @Override
     public long getRecordType() {
         return RecordTypes.PPDrawingGroup.typeID;
     }
@@ -72,17 +73,19 @@ public final class PPDrawingGroup extend
     /**
      * We're pretending to be an atom, so return null
      */
+    @Override
     public org.apache.poi.hslf.record.Record[] getChildRecords() {
         return null;
     }
 
+    @Override
     public void writeOut(OutputStream out) throws IOException {
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream bout = new UnsynchronizedByteArrayOutputStream();
         for (EscherRecord r : dggContainer) {
             if (r.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER){
                 EscherContainerRecord bstore = (EscherContainerRecord)r;
 
-                ByteArrayOutputStream b2 = new ByteArrayOutputStream();
+                UnsynchronizedByteArrayOutputStream b2 = new UnsynchronizedByteArrayOutputStream();
                 for (EscherRecord br : bstore) {
                     byte[] b = new byte[36+8];
                     br.serialize(0, b);
@@ -114,8 +117,7 @@ public final class PPDrawingGroup extend
         out.write(dgghead);
 
         // Finally, write out the children
-        out.write(bout.toByteArray());
-
+        bout.writeTo(out);
     }
 
     public EscherContainerRecord getDggContainer(){

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PersistPtrHolder.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PersistPtrHolder.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PersistPtrHolder.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/PersistPtrHolder.java Fri May 14 00:37:50 2021
@@ -17,24 +17,23 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.TreeMap;
 import java.util.function.Supplier;
 
 import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
-import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
 
 /**
  * General holder for PersistPtrFullBlock and PersistPtrIncrementalBlock
@@ -54,14 +53,14 @@ public final class PersistPtrHolder exte
 
 	private final byte[] _header;
 	private byte[] _ptrData; // Will need to update this once we allow updates to _slideLocations
-	private long _type;
+	private final long _type;
 
 	/**
 	 * Holds the lookup for slides to their position on disk.
 	 * You always need to check the most recent PersistPtrHolder
 	 *  that knows about a given slide to find the right location
 	 */
-	private Map<Integer,Integer> _slideLocations;
+	private final Map<Integer,Integer> _slideLocations;
 
 	private static final BitField persistIdFld = BitFieldFactory.getInstance(0X000FFFFF);
 	private static final BitField cntPersistFld  = BitFieldFactory.getInstance(0XFFF00000);
@@ -185,51 +184,47 @@ public final class PersistPtrHolder exte
 	}
 
 	private void normalizePersistDirectory() {
-        TreeMap<Integer,Integer> orderedSlideLocations = new TreeMap<>(_slideLocations);
+		// Building the info block
+		// First 20 bits = offset number = slide ID (persistIdFld, i.e. first slide ID of a continuous group)
+		// Remaining 12 bits = offset count = 1 (cntPersistFld, i.e. continuous entries in a group)
+		//
+		// the info block is then followed by the slide offset (32 bits)
+
+		int[] infoBlocks = new int[_slideLocations.size()*2];
+		int lastSlideId = -1;
+		int lastPersistIdx = 0;
+		int lastIdx = -1;
+		int entryCnt = 0;
+		int baseSlideId = -1;
+
+		Iterable<Entry<Integer,Integer>> iter = _slideLocations.entrySet().stream()
+			.sorted(Comparator.comparingInt(Entry::getKey))::iterator;
+		for (Entry<Integer, Integer> me : iter) {
+			int nextSlideId = me.getKey();
+			if (lastSlideId + 1 < nextSlideId) {
+				// start new PersistDirectoryEntry
+				lastPersistIdx = ++lastIdx;
+				entryCnt = 0;
+				baseSlideId = nextSlideId;
+			}
 
-        @SuppressWarnings("resource")
-        BufAccessBAOS bos = new BufAccessBAOS(); // NOSONAR
-        byte[] intbuf = new byte[4];
-        int lastPersistEntry = -1;
-        int lastSlideId = -1;
-        for (Entry<Integer,Integer> me : orderedSlideLocations.entrySet()) {
-            int nextSlideId = me.getKey();
-            int offset = me.getValue();
-            try {
-                // Building the info block
-                // First 20 bits = offset number = slide ID (persistIdFld, i.e. first slide ID of a continuous group)
-                // Remaining 12 bits = offset count = 1 (cntPersistFld, i.e. continuous entries in a group)
-
-                if (lastSlideId+1 == nextSlideId) {
-                    // use existing PersistDirectoryEntry, need to increase entry count
-                    assert(lastPersistEntry != -1);
-                    int infoBlock = LittleEndian.getInt(bos.getBuf(), lastPersistEntry);
-                    int entryCnt = cntPersistFld.getValue(infoBlock);
-                    infoBlock = cntPersistFld.setValue(infoBlock, entryCnt+1);
-                    LittleEndian.putInt(bos.getBuf(), lastPersistEntry, infoBlock);
-                } else {
-                    // start new PersistDirectoryEntry
-                    lastPersistEntry = bos.size();
-                    int infoBlock = persistIdFld.setValue(0, nextSlideId);
-                    infoBlock = cntPersistFld.setValue(infoBlock, 1);
-                    LittleEndian.putInt(intbuf, 0, infoBlock);
-                    bos.write(intbuf);
-                }
-                // Add to the ptrData offset lookup hash
-                LittleEndian.putInt(intbuf, 0, offset);
-                bos.write(intbuf);
-                lastSlideId = nextSlideId;
-            } catch (IOException e) {
-                // ByteArrayOutputStream is very unlikely throwing a IO exception (maybe because of OOM ...)
-                throw new HSLFException(e);
-            }
-        }
+			int infoBlock = persistIdFld.setValue(0, baseSlideId);
+			infoBlock = cntPersistFld.setValue(infoBlock, ++entryCnt);
+			infoBlocks[lastPersistIdx] = infoBlock;
+			// add the offset
+			infoBlocks[++lastIdx] = me.getValue();
 
-        // Save the new ptr data
-        _ptrData = bos.toByteArray();
+			lastSlideId = nextSlideId;
+		}
 
-        // Update the atom header
-        LittleEndian.putInt(_header,4,bos.size());
+		// Save the new ptr data
+		_ptrData = new byte[(lastIdx+1)*LittleEndianConsts.INT_SIZE];
+		for (int idx = 0; idx<=lastIdx; idx++) {
+			LittleEndian.putInt(_ptrData, idx*LittleEndianConsts.INT_SIZE, infoBlocks[idx]);
+		}
+
+		// Update the atom header
+		LittleEndian.putInt(_header, 4, _ptrData.length);
 	}
 
 	/**
@@ -243,12 +238,6 @@ public final class PersistPtrHolder exte
 		out.write(_ptrData);
 	}
 
-    private static class BufAccessBAOS extends ByteArrayOutputStream {
-        public byte[] getBuf() {
-            return buf;
-        }
-    }
-
 	@Override
 	public Map<String, Supplier<?>> getGenericProperties() {
 		return GenericRecordUtil.getGenericProperties(

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/RecordContainer.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/RecordContainer.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/RecordContainer.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/RecordContainer.java Fri May 14 00:37:50 2021
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -25,6 +24,7 @@ import java.util.Arrays;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.util.ArrayUtil;
 import org.apache.poi.util.LittleEndian;
 
@@ -226,8 +226,8 @@ public abstract class RecordContainer ex
 	 * @param out the stream to write to
 	 */
 	public void writeOut(byte headerA, byte headerB, long type, Record[] children, OutputStream out) throws IOException {
-		// Create a ByteArrayOutputStream to hold everything in
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		// Create a UnsynchronizedByteArrayOutputStream to hold everything in
+		UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
 
 		// Write out our header, less the size
 		baos.write(new byte[] {headerA,headerB});

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/StyleTextPropAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/StyleTextPropAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/StyleTextPropAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/StyleTextPropAtom.java Fri May 14 00:37:50 2021
@@ -17,7 +17,8 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
+import static org.apache.logging.log4j.util.Unbox.box;
+
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -26,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
@@ -34,8 +36,6 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 
-import static org.apache.logging.log4j.util.Unbox.box;
-
 /**
  * A StyleTextPropAtom (type 4001). Holds basic character properties
  *  (bold, italic, underline, font size etc) and paragraph properties
@@ -55,7 +55,7 @@ public final class StyleTextPropAtom ext
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 1_000_000;
 
-    private byte[] _header;
+    private final byte[] _header;
     private byte[] reserved;
 
     private byte[] rawContents; // Holds the contents between write-outs
@@ -312,7 +312,7 @@ public final class StyleTextPropAtom ext
             // Only update the style bytes, if the styles have been potentially
             // changed
 
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
 
             // First up, we need to serialise the paragraph properties
             for(TextPropCollection tpc : paragraphStyles) {

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextRulerAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextRulerAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextRulerAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextRulerAtom.java Fri May 14 00:37:50 2021
@@ -19,7 +19,6 @@ package org.apache.poi.hslf.record;
 
 import static org.apache.poi.util.BitFieldFactory.getInstance;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -28,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.model.textproperties.HSLFTabStop;
 import org.apache.poi.hslf.model.textproperties.HSLFTabStopPropCollection;
 import org.apache.poi.util.BitField;
@@ -120,7 +120,7 @@ public final class TextRulerAtom extends
      */
     @Override
     public void writeOut(final OutputStream out) throws IOException {
-        final ByteArrayOutputStream bos = new ByteArrayOutputStream(200);
+        final UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream(200);
         final LittleEndianOutputStream lbos = new LittleEndianOutputStream(bos);
         int mask = 0;
         mask |= writeIf(lbos, numLevels, C_LEVELS);

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextSpecInfoAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextSpecInfoAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextSpecInfoAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TextSpecInfoAtom.java Fri May 14 00:37:50 2021
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -26,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
@@ -46,7 +46,7 @@ public final class TextSpecInfoAtom exte
     /**
      * Record header.
      */
-    private byte[] _header;
+    private final byte[] _header;
 
     /**
      * Record data.
@@ -112,7 +112,7 @@ public final class TextSpecInfoAtom exte
      */
     public void reset(int size){
         TextSpecInfoRun sir = new TextSpecInfoRun(size);
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
         try {
             sir.writeOut(bos);
         } catch (IOException e) {
@@ -127,13 +127,11 @@ public final class TextSpecInfoAtom exte
     /**
      * Adapts the size by enlarging the last {@link TextSpecInfoRun}
      * or chopping the runs to the given length
-     *
-     * @param size
      */
     public void setParentSize(int size) {
         assert(size > 0);
         int covered = 0;
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
         TextSpecInfoRun[] runs = getTextSpecInfoRuns();
         assert(runs.length > 0);
         for (int i=0; i<runs.length && covered < size; i++) {

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TxMasterStyleAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TxMasterStyleAtom.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TxMasterStyleAtom.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/record/TxMasterStyleAtom.java Fri May 14 00:37:50 2021
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -26,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -64,7 +64,7 @@ public final class TxMasterStyleAtom ext
 
     private static final long _type = RecordTypes.TxMasterStyleAtom.typeID;
 
-    private byte[] _header;
+    private final byte[] _header;
     private byte[] _data;
 
     private List<TextPropCollection> paragraphStyles;
@@ -89,6 +89,7 @@ public final class TxMasterStyleAtom ext
      * @return type of this record
      * @see RecordTypes#TxMasterStyleAtom
      */
+    @Override
     public long getRecordType() {
         return _type;
     }
@@ -97,6 +98,7 @@ public final class TxMasterStyleAtom ext
      * Write the contents of the record back, so it can be written
      *  to disk
      */
+    @Override
     public void writeOut(OutputStream out) throws IOException {
         // Write out the (new) header
         out.write(_header);
@@ -126,7 +128,7 @@ public final class TxMasterStyleAtom ext
 
     /**
      * Return type of the text.
-     * Must be a constant defined in <code>TextHeaderAtom</code>
+     * Must be a constant defined in {@code TextHeaderAtom}
      *
      * @return type of the text
      * @see TextHeaderAtom
@@ -187,7 +189,7 @@ public final class TxMasterStyleAtom ext
         int type = getTextType();
 
         try {
-            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
             LittleEndianOutputStream leos = new LittleEndianOutputStream(bos);
             int levels = paragraphStyles.size();
             leos.writeShort(levels);

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectData.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectData.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectData.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectData.java Fri May 14 00:37:50 2021
@@ -16,7 +16,6 @@
 ==================================================================== */
 package org.apache.poi.hslf.usermodel;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -25,8 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hslf.record.ExOleObjStg;
 import org.apache.poi.sl.usermodel.ObjectData;
@@ -35,12 +33,10 @@ import org.apache.poi.sl.usermodel.Objec
  * A class that represents object data embedded in a slide show.
  */
 public class HSLFObjectData implements ObjectData, GenericRecord {
-    private static final Logger LOG = LogManager.getLogger(HSLFObjectData.class);
-
     /**
      * The record that contains the object data.
      */
-    private ExOleObjStg storage;
+    private final ExOleObjStg storage;
 
     /**
      * Creates the object data wrapping the record that contains the object data.
@@ -55,10 +51,12 @@ public class HSLFObjectData implements O
     public InputStream getInputStream() {
         return storage.getData();
     }
-    
+
     @Override
-    public OutputStream getOutputStream() throws IOException {
-        return new ByteArrayOutputStream(100000) {
+    public OutputStream getOutputStream() {
+        // can't use UnsynchronizedByteArrayOutputStream here, because it's final
+        return new ByteArrayOutputStream() {
+            @Override
             public void close() throws IOException {
                 setData(getBytes());
             }
@@ -71,7 +69,7 @@ public class HSLFObjectData implements O
      * @param data the embedded data.
      */
      public void setData(byte[] data) throws IOException {
-        storage.setData(data);    
+        storage.setData(data);
     }
 
     /**

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectShape.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectShape.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFObjectShape.java Fri May 14 00:37:50 2021
@@ -17,11 +17,12 @@
 
 package org.apache.poi.hslf.usermodel;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.commons.io.output.AbstractByteArrayOutputStream;
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.ddf.EscherContainerRecord;
@@ -51,7 +52,7 @@ public final class HSLFObjectShape exten
     private ExEmbed _exEmbed;
 
     /**
-     * Create a new <code>OLEShape</code>
+     * Create a new {@code OLEShape}
      *
     * @param data the picture data
      */
@@ -60,7 +61,7 @@ public final class HSLFObjectShape exten
     }
 
     /**
-     * Create a new <code>OLEShape</code>
+     * Create a new {@code OLEShape}
      *
      * @param data the picture data
      * @param parent the parent shape
@@ -70,10 +71,10 @@ public final class HSLFObjectShape exten
     }
 
     /**
-      * Create a <code>OLEShape</code> object
+      * Create a {@code OLEShape} object
       *
-      * @param escherRecord the <code>EscherSpContainer</code> record which holds information about
-      *        this picture in the <code>Slide</code>
+      * @param escherRecord the {@code EscherSpContainer} record which holds information about
+      *        this picture in the {@code Slide}
       * @param parent the parent shape of this picture
       */
     public HSLFObjectShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
@@ -100,7 +101,11 @@ public final class HSLFObjectShape exten
 
     	EscherContainerRecord ecr = getSpContainer();
     	EscherSpRecord spRecord = ecr.getChildById(EscherSpRecord.RECORD_ID);
-        spRecord.setFlags(spRecord.getFlags()|EscherSpRecord.FLAG_OLESHAPE);
+    	if (spRecord != null) {
+            spRecord.setFlags(spRecord.getFlags() | EscherSpRecord.FLAG_OLESHAPE);
+        } else {
+    	    LOG.atWarn().log("Ole shape record not found.");
+        }
 
         HSLFEscherClientDataRecord cldata = getClientData(true);
         ExObjRefAtom uer = null;
@@ -123,6 +128,7 @@ public final class HSLFObjectShape exten
      *
      * @return the unique identifier for the OLE object
      */
+    @Override
     public HSLFObjectData getObjectData(){
         HSLFSlideShow ppt = getSheet().getSlideShow();
         HSLFObjectData[] ole = ppt.getEmbeddedObjects();
@@ -184,7 +190,7 @@ public final class HSLFObjectShape exten
                     }
                 }
             }
-            
+
             if (_exEmbed == null && create) {
                 _exEmbed = new ExEmbed();
                 _exEmbed.getExOleObjAtom().setObjID(id);
@@ -193,8 +199,8 @@ public final class HSLFObjectShape exten
         }
         return _exEmbed;
     }
-    
-    
+
+
     /**
      * Returns the instance name of the embedded object, e.g. "Document" or "Workbook".
      *
@@ -231,45 +237,51 @@ public final class HSLFObjectShape exten
         }
     }
 
-    public OutputStream updateObjectData(final Application application, final ObjectMetaData metaData) throws IOException {
+    @Override
+    public OutputStream updateObjectData(final Application application, final ObjectMetaData metaData) {
         final ObjectMetaData md = (application != null) ? application.getMetaData() : metaData;
         if (md == null) {
             throw new RuntimeException("either application or metaData needs to be set");
         }
 
-        return new ByteArrayOutputStream(100000) {
+        // can't use UnsynchronizedByteArrayOutputStream here, because it's final
+        return new ByteArrayOutputStream() {
+            @Override
             public void close() throws IOException {
-                final FileMagic fm = FileMagic.valueOf(this.buf);
-                final ByteArrayInputStream bis = new ByteArrayInputStream(this.buf, 0, this.count);
-                final HSLFSlideShow ppt = getSheet().getSlideShow();
-
-                try (POIFSFileSystem poifs = (fm == FileMagic.OLE2) ? new POIFSFileSystem(bis) : new POIFSFileSystem()) {
-                    if (fm != FileMagic.OLE2) {
-                        poifs.createDocument(bis, md.getOleEntry());
-                    }
+                addUpdatedData(md,this);
+            }
+        };
+    }
 
-                    Ole10Native.createOleMarkerEntry(poifs);
+    private void addUpdatedData(ObjectMetaData md, AbstractByteArrayOutputStream baos) throws IOException {
+        try (InputStream bis = FileMagic.prepareToCheckMagic(baos.toInputStream())) {
+            final FileMagic fm = FileMagic.valueOf(bis);
+            try (POIFSFileSystem poifs = (fm == FileMagic.OLE2) ? new POIFSFileSystem(bis) : new POIFSFileSystem()) {
+                if (fm != FileMagic.OLE2) {
+                    poifs.createDocument(bis, md.getOleEntry());
+                }
+                baos.reset();
 
-                    poifs.getRoot().setStorageClsid(md.getClassID());
+                Ole10Native.createOleMarkerEntry(poifs);
 
-                    int oid = getObjectID();
-                    if (oid == 0) {
-                        // assign new embedding
-                        oid = ppt.addEmbed(poifs);
-                        setObjectID(oid);
-                    } else {
-                        final HSLFObjectData od = getObjectData();
-                        if (od != null) {
-                            ByteArrayOutputStream bos = new ByteArrayOutputStream(this.size()+1000);
-                            poifs.writeFilesystem(bos);
-                            od.setData(bos.toByteArray());
-                        }
-                    }
+                poifs.getRoot().setStorageClsid(md.getClassID());
 
-                    setProgId(md.getProgId());
-                    setFullName(md.getObjectName());
+                int oid = getObjectID();
+                if (oid == 0) {
+                    // assign new embedding
+                    oid = getSheet().getSlideShow().addEmbed(poifs);
+                    setObjectID(oid);
+                } else {
+                    final HSLFObjectData od = getObjectData();
+                    if (od != null) {
+                        poifs.writeFilesystem(baos);
+                        od.setData(baos.toByteArray());
+                    }
                 }
+
+                setProgId(md.getProgId());
+                setFullName(md.getObjectName());
             }
-        };
+        }
     }
 }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShow.java Fri May 14 00:37:50 2021
@@ -17,8 +17,9 @@
 
 package org.apache.poi.hslf.usermodel;
 
+import static org.apache.logging.log4j.util.Unbox.box;
+
 import java.awt.Dimension;
-import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
@@ -33,6 +34,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.POIDocument;
@@ -66,8 +68,6 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.Units;
 
-import static org.apache.logging.log4j.util.Unbox.box;
-
 /**
  * This class is a friendly wrapper on top of the more scary HSLFSlideShow.
  *
@@ -708,9 +708,9 @@ public final class HSLFSlideShow extends
 	}
 
 	/**
-	 * Create a blank <code>Slide</code>.
+	 * Create a blank {@code Slide}.
 	 *
-	 * @return the created <code>Slide</code>
+	 * @return the created {@code Slide}
 	 */
 	@Override
 	public HSLFSlide createSlide() {
@@ -882,6 +882,7 @@ public final class HSLFSlideShow extends
 	 *
 	 * @since POI 4.1.0
 	 */
+	@Override
 	public HSLFFontInfo addFont(InputStream fontData) throws IOException {
 		Document doc = getDocumentRecord();
 		doc.getDocumentAtom().setSaveWithFonts(true);
@@ -893,7 +894,7 @@ public final class HSLFSlideShow extends
 	 *
 	 * @param idx
 	 *            0-based index of the font
-	 * @return of an instance of <code>PPFont</code> or <code>null</code> if not
+	 * @return of an instance of {@code PPFont} or {@code null} if not
 	 *         found
 	 */
 	public HSLFFontInfo getFont(int idx) {
@@ -1040,7 +1041,7 @@ public final class HSLFSlideShow extends
         ExOleObjStg exOleObjStg = new ExOleObjStg();
         try {
             Ole10Native.createOleMarkerEntry(poiData);
-	        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+	        UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream();
 	        poiData.writeFilesystem(bos);
 	        exOleObjStg.setData(bos.toByteArray());
         } catch (IOException e) {
@@ -1246,7 +1247,7 @@ public final class HSLFSlideShow extends
 	}
 
 	@Override
-	public EncryptionInfo getEncryptionInfo() throws IOException {
+	public EncryptionInfo getEncryptionInfo() {
 		return getSlideShowImpl().getEncryptionInfo();
 	}
 

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java Fri May 14 00:37:50 2021
@@ -23,17 +23,18 @@ import static org.apache.poi.hslf.usermo
 import static org.apache.poi.hslf.usermodel.HSLFSlideShow.PP97_DOCUMENT;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.SequenceInputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -44,6 +45,8 @@ import java.util.Objects;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.poi.POIDocument;
@@ -659,7 +662,7 @@ public final class HSLFSlideShowImpl ext
     /**
      * Writes out the slideshow to the currently open file.
      * <p>
-     * <p>This will fail (with an {@link IllegalStateException} if the
+     * This will fail (with an {@link IllegalStateException} if the
      * slideshow was opened read-only, opened from an {@link InputStream}
      * instead of a File, or if this is not the root document. For those cases,
      * you must use {@link #write(OutputStream)} or {@link #write(File)} to
@@ -686,7 +689,7 @@ public final class HSLFSlideShowImpl ext
      * of this class.
      * <p>This will write out only the common OLE2 streams. If you require all
      * streams to be written out, use {@link #write(File, boolean)}
-     * with <code>preserveNodes</code> set to <code>true</code>.
+     * with {@code preserveNodes} set to {@code true}.
      *
      * @param newFile The File to write to.
      * @throws IOException If there is an unexpected IOException from writing to the File
@@ -701,7 +704,7 @@ public final class HSLFSlideShowImpl ext
      * Writes out the slideshow file the is represented by an instance
      * of this class.
      * If you require all streams to be written out (eg Marcos, embeded
-     * documents), then set <code>preserveNodes</code> set to <code>true</code>
+     * documents), then set {@code preserveNodes} set to {@code true}
      *
      * @param newFile       The File to write to.
      * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones?
@@ -724,7 +727,7 @@ public final class HSLFSlideShowImpl ext
      * of this class.
      * <p>This will write out only the common OLE2 streams. If you require all
      * streams to be written out, use {@link #write(OutputStream, boolean)}
-     * with <code>preserveNodes</code> set to <code>true</code>.
+     * with {@code preserveNodes} set to {@code true}.
      *
      * @param out The OutputStream to write to.
      * @throws IOException If there is an unexpected IOException from
@@ -740,7 +743,7 @@ public final class HSLFSlideShowImpl ext
      * Writes out the slideshow file the is represented by an instance
      * of this class.
      * If you require all streams to be written out (eg Marcos, embeded
-     * documents), then set <code>preserveNodes</code> set to <code>true</code>
+     * documents), then set {@code preserveNodes} set to {@code true}
      *
      * @param out           The OutputStream to write to.
      * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones?
@@ -776,16 +779,16 @@ public final class HSLFSlideShowImpl ext
             // Write out the Property Streams
             writeProperties(outFS, writtenEntries);
 
-            BufAccessBAOS baos = new BufAccessBAOS();
+            try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
 
-            // For position dependent records, hold where they were and now are
-            // As we go along, update, and hand over, to any Position Dependent
-            // records we happen across
-            updateAndWriteDependantRecords(baos, null);
-
-            // Update our cached copy of the bytes that make up the PPT stream
-            _docstream = baos.toByteArray();
-            baos.close();
+                // For position dependent records, hold where they were and now are
+                // As we go along, update, and hand over, to any Position Dependent
+                // records we happen across
+                updateAndWriteDependantRecords(baos, null);
+
+                // Update our cached copy of the bytes that make up the PPT stream
+                _docstream = baos.toByteArray();
+            }
 
             // Write the PPT stream into the POIFS layer
             ByteArrayInputStream bais = new ByteArrayInputStream(_docstream);
@@ -796,20 +799,18 @@ public final class HSLFSlideShowImpl ext
             currentUser.writeToFS(outFS);
             writtenEntries.add("Current User");
 
-            if (_pictures.size() > 0) {
-                BufAccessBAOS pict = new BufAccessBAOS();
-                for (HSLFPictureData p : _pictures) {
-                    int offset = pict.size();
-                    p.write(pict);
-                    encryptedSS.encryptPicture(pict.getBuf(), offset);
-                }
-                outFS.createOrUpdateDocument(
-                    new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures"
+            if (!_pictures.isEmpty()) {
+                Enumeration<InputStream> pictEnum = IteratorUtils.asEnumeration(
+                    _pictures.stream().map(data -> encryptOnePicture(encryptedSS, data)).iterator()
                 );
-                writtenEntries.add("Pictures");
-                pict.close();
-            }
 
+                try (SequenceInputStream sis = new SequenceInputStream(pictEnum)) {
+                    outFS.createOrUpdateDocument(sis, "Pictures");
+                    writtenEntries.add("Pictures");
+                } catch (IllegalStateException e) {
+                    throw (IOException)e.getCause();
+                }
+            }
         }
 
         // If requested, copy over any other streams we spot, eg Macros
@@ -818,6 +819,17 @@ public final class HSLFSlideShowImpl ext
         }
     }
 
+    private static InputStream encryptOnePicture(HSLFSlideShowEncrypted encryptedSS, HSLFPictureData data) {
+        try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream()) {
+            data.write(baos);
+            byte[] pictBytes = baos.toByteArray();
+            encryptedSS.encryptPicture(pictBytes, 0);
+            return new ByteArrayInputStream(pictBytes);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
 
     @Override
     public EncryptionInfo getEncryptionInfo() {
@@ -1017,12 +1029,6 @@ public final class HSLFSlideShowImpl ext
         super.replaceDirectory(newDirectory);
     }
 
-    private static class BufAccessBAOS extends ByteArrayOutputStream {
-        public byte[] getBuf() {
-            return buf;
-        }
-    }
-
     private static class CountingOS extends OutputStream {
         int count;
 



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