Author: kiwiwings Date: Sat Dec 14 23:44:26 2019 New Revision: 1871563 URL: http://svn.apache.org/viewvc?rev=1871563&view=rev Log: #64004 - Replace clone() with copy constructor
Modified: poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java poi/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java poi/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDump.java Modified: poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java Sat Dec 14 23:44:26 2019 @@ -30,13 +30,20 @@ import org.apache.poi.util.Removal; * Common abstract class for {@link EscherOptRecord} and * {@link EscherTertiaryOptRecord} */ -public abstract class AbstractEscherOptRecord extends EscherRecord -{ +public abstract class AbstractEscherOptRecord extends EscherRecord { private final List<EscherProperty> properties = new ArrayList<>(); + protected AbstractEscherOptRecord() {} + + protected AbstractEscherOptRecord(AbstractEscherOptRecord other) { + super(other); + properties.addAll(other.properties); + } + + /** * Add a property to this record. - * + * * @param prop the escher property to add */ public void addEscherProperty( EscherProperty prop ) @@ -60,7 +67,7 @@ public abstract class AbstractEscherOptR /** * The list of properties stored by this record. - * + * * @return the list of properties */ public List<EscherProperty> getEscherProperties() @@ -70,7 +77,7 @@ public abstract class AbstractEscherOptR /** * The list of properties stored by this record. - * + * * @param index the ordinal index of the property * @return the escher property */ @@ -79,7 +86,7 @@ public abstract class AbstractEscherOptR return properties.get( index ); } - + private int getPropertiesSize() { int totalSize = 0; @@ -164,4 +171,7 @@ public abstract class AbstractEscherOptR "properties", this::getEscherProperties ); } + + @Override + public abstract AbstractEscherOptRecord copy(); } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java Sat Dec 14 23:44:26 2019 @@ -58,7 +58,25 @@ public final class EscherBSERecord exten public EscherBSERecord() { setRecordId(RECORD_ID); } - + + public EscherBSERecord(EscherBSERecord other) { + super(other); + + field_1_blipTypeWin32 = other.field_1_blipTypeWin32; + field_2_blipTypeMacOS = other.field_2_blipTypeMacOS; + System.arraycopy(other.field_3_uid, 0, field_3_uid, 0, field_3_uid.length); + field_4_tag = other.field_4_tag; + field_5_size = other.field_5_size; + field_6_ref = other.field_6_ref; + field_7_offset = other.field_7_offset; + field_8_usage = other.field_8_usage; + field_9_name = other.field_9_name; + field_10_unused2 = other.field_10_unused2; + field_11_unused3 = other.field_11_unused3; + field_12_blipRecord = other.field_12_blipRecord.copy(); + _remainingData = other._remainingData.clone(); + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -149,7 +167,7 @@ public final class EscherBSERecord exten /** * The expected blip type under windows (failure to match this blip type will result in * Excel converting to this format). - * + * * @return win32 blip type */ public byte getBlipTypeWin32() { @@ -162,7 +180,7 @@ public final class EscherBSERecord exten /** * Set the expected win32 blip type - * + * * @param blipTypeWin32 win32 blip type */ public void setBlipTypeWin32(byte blipTypeWin32) { @@ -172,7 +190,7 @@ public final class EscherBSERecord exten /** * The expected blip type under MacOS (failure to match this blip type will result in * Excel converting to this format). - * + * * @return MacOS blip type */ public byte getBlipTypeMacOS() { @@ -185,7 +203,7 @@ public final class EscherBSERecord exten /** * Set the expected MacOS blip type - * + * * @param blipTypeMacOS MacOS blip type */ public void setBlipTypeMacOS(byte blipTypeMacOS) { @@ -194,7 +212,7 @@ public final class EscherBSERecord exten /** * 16 byte MD4 checksum. - * + * * @return 16 byte MD4 checksum */ public byte[] getUid() { @@ -203,7 +221,7 @@ public final class EscherBSERecord exten /** * 16 byte MD4 checksum. - * + * * @param uid 16 byte MD4 checksum */ public void setUid(byte[] uid) { @@ -215,7 +233,7 @@ public final class EscherBSERecord exten /** * unused - * + * * @return an unknown tag */ public short getTag() { @@ -224,7 +242,7 @@ public final class EscherBSERecord exten /** * unused - * + * * @param tag unknown tag */ public void setTag(short tag) { @@ -233,7 +251,7 @@ public final class EscherBSERecord exten /** * Blip size in stream. - * + * * @return the blip size */ public int getSize() { @@ -242,7 +260,7 @@ public final class EscherBSERecord exten /** * Blip size in stream. - * + * * @param size blip size */ public void setSize(int size) { @@ -251,7 +269,7 @@ public final class EscherBSERecord exten /** * The reference count of this blip. - * + * * @return the reference count */ public int getRef() { @@ -260,7 +278,7 @@ public final class EscherBSERecord exten /** * The reference count of this blip. - * + * * @param ref the reference count */ public void setRef(int ref) { @@ -269,7 +287,7 @@ public final class EscherBSERecord exten /** * File offset in the delay stream. - * + * * @return the file offset */ public int getOffset() { @@ -278,7 +296,7 @@ public final class EscherBSERecord exten /** * File offset in the delay stream. - * + * * @param offset the file offset */ public void setOffset(int offset) { @@ -287,7 +305,7 @@ public final class EscherBSERecord exten /** * Defines the way this blip is used. - * + * * @return the blip usage */ public byte getUsage() { @@ -296,7 +314,7 @@ public final class EscherBSERecord exten /** * Defines the way this blip is used. - * + * * @param usage the blip usae */ public void setUsage(byte usage) { @@ -305,7 +323,7 @@ public final class EscherBSERecord exten /** * The length in characters of the blip name. - * + * * @return the blip name length */ public byte getName() { @@ -314,7 +332,7 @@ public final class EscherBSERecord exten /** * The length in characters of the blip name. - * + * * @param name the blip name length */ public void setName(byte name) { @@ -347,7 +365,7 @@ public final class EscherBSERecord exten /** * Any remaining data in this record. - * + * * @return the remaining bytes */ public byte[] getRemainingData() { @@ -356,7 +374,7 @@ public final class EscherBSERecord exten /** * Any remaining data in this record. - * + * * @param remainingData the remaining bytes */ public void setRemainingData(byte[] remainingData) { @@ -388,4 +406,9 @@ public final class EscherBSERecord exten public Enum getGenericRecordType() { return EscherRecordTypes.BSE; } + + @Override + public EscherBSERecord copy() { + return new EscherBSERecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java Sat Dec 14 23:44:26 2019 @@ -33,6 +33,14 @@ public class EscherBitmapBlip extends Es private final byte[] field_1_UID = new byte[16]; private byte field_2_marker = (byte) 0xFF; + public EscherBitmapBlip() {} + + public EscherBitmapBlip(EscherBitmapBlip other) { + super(other); + System.arraycopy(other.field_1_UID, 0, field_1_UID, 0, field_1_UID.length); + field_2_marker = other.field_2_marker; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesAfterHeader = readHeader( data, offset ); @@ -121,4 +129,8 @@ public class EscherBitmapBlip extends Es ); } + @Override + public EscherBitmapBlip copy() { + return new EscherBitmapBlip(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java Sat Dec 14 23:44:26 2019 @@ -39,6 +39,11 @@ public class EscherBlipRecord extends Es public EscherBlipRecord() { } + public EscherBlipRecord(EscherBlipRecord other) { + super(other); + field_pictureData = (other.field_pictureData == null) ? null : other.field_pictureData.clone(); + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesAfterHeader = readHeader( data, offset ); @@ -120,4 +125,10 @@ public class EscherBlipRecord extends Es EscherRecordTypes t = EscherRecordTypes.forTypeID(getRecordId()); return (t != EscherRecordTypes.UNKNOWN) ? t : EscherRecordTypes.BLIP_START; } + + + @Override + public EscherBlipRecord copy() { + return new EscherBlipRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java Sat Dec 14 23:44:26 2019 @@ -38,6 +38,16 @@ public class EscherChildAnchorRecord ext private int field_3_dx2; private int field_4_dy2; + public EscherChildAnchorRecord() {} + + public EscherChildAnchorRecord(EscherChildAnchorRecord other) { + super(other); + field_1_dx1 = other.field_1_dx1; + field_2_dy1 = other.field_2_dy1; + field_3_dx2 = other.field_3_dx2; + field_4_dy2 = other.field_4_dy2; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -59,7 +69,7 @@ public class EscherChildAnchorRecord ext default: throw new RuntimeException("Invalid EscherChildAnchorRecord - neither 8 nor 16 bytes."); } - + return 8 + size; } @@ -98,7 +108,7 @@ public class EscherChildAnchorRecord ext /** * Retrieves offset within the parent coordinate space for the top left point. - * + * * @return the x offset of the top left point */ public int getDx1() @@ -108,7 +118,7 @@ public class EscherChildAnchorRecord ext /** * Sets offset within the parent coordinate space for the top left point. - * + * * @param field_1_dx1 the x offset of the top left point */ public void setDx1( int field_1_dx1 ) @@ -118,7 +128,7 @@ public class EscherChildAnchorRecord ext /** * Gets offset within the parent coordinate space for the top left point. - * + * * @return the y offset of the top left point */ public int getDy1() @@ -128,8 +138,8 @@ public class EscherChildAnchorRecord ext /** * Sets offset within the parent coordinate space for the top left point. - * - * @param field_2_dy1 the y offset of the top left point + * + * @param field_2_dy1 the y offset of the top left point */ public void setDy1( int field_2_dy1 ) { @@ -138,7 +148,7 @@ public class EscherChildAnchorRecord ext /** * Retrieves offset within the parent coordinate space for the bottom right point. - * + * * @return the x offset of the bottom right point */ public int getDx2() @@ -148,7 +158,7 @@ public class EscherChildAnchorRecord ext /** * Sets offset within the parent coordinate space for the bottom right point. - * + * * @param field_3_dx2 the x offset of the bottom right point */ public void setDx2( int field_3_dx2 ) @@ -158,7 +168,7 @@ public class EscherChildAnchorRecord ext /** * Gets the offset within the parent coordinate space for the bottom right point. - * + * * @return the y offset of the bottom right point */ public int getDy2() @@ -168,7 +178,7 @@ public class EscherChildAnchorRecord ext /** * Sets the offset within the parent coordinate space for the bottom right point. - * + * * @param field_4_dy2 the y offset of the bottom right point */ public void setDy2( int field_4_dy2 ) @@ -191,4 +201,9 @@ public class EscherChildAnchorRecord ext public Enum getGenericRecordType() { return EscherRecordTypes.CHILD_ANCHOR; } + + @Override + public EscherChildAnchorRecord copy() { + return new EscherChildAnchorRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java Sat Dec 14 23:44:26 2019 @@ -59,6 +59,23 @@ public class EscherClientAnchorRecord ex private byte[] remainingData = new byte[0]; private boolean shortRecord; + public EscherClientAnchorRecord() {} + + public EscherClientAnchorRecord(EscherClientAnchorRecord other) { + super(other); + field_1_flag = other.field_1_flag; + field_2_col1 = other.field_2_col1; + field_3_dx1 = other.field_3_dx1; + field_4_row1 = other.field_4_row1; + field_5_dy1 = other.field_5_dy1; + field_6_col2 = other.field_6_col2; + field_7_dx2 = other.field_7_dx2; + field_8_row2 = other.field_8_row2; + field_9_dy2 = other.field_9_dy2; + remainingData = (other.remainingData == null) ? null : other.remainingData.clone(); + shortRecord = other.shortRecord; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -368,4 +385,9 @@ public class EscherClientAnchorRecord ex public Enum getGenericRecordType() { return EscherRecordTypes.CLIENT_ANCHOR; } + + @Override + public EscherClientAnchorRecord copy() { + return new EscherClientAnchorRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java Sat Dec 14 23:44:26 2019 @@ -29,9 +29,7 @@ import org.apache.poi.util.LittleEndian; * The EscherClientDataRecord is used to store client specific data about the position of a * shape within a container. */ -public class EscherClientDataRecord - extends EscherRecord -{ +public class EscherClientDataRecord extends EscherRecord { //arbitrarily selected; may need to increase private static final int MAX_RECORD_LENGTH = 100_000; @@ -39,6 +37,13 @@ public class EscherClientDataRecord private byte[] remainingData; + public EscherClientDataRecord() {} + + public EscherClientDataRecord(EscherClientDataRecord other) { + super(other); + remainingData = (other.remainingData == null) ? null : other.remainingData.clone(); + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -83,7 +88,7 @@ public class EscherClientDataRecord /** * Any data recording this record. - * + * * @return the remaining bytes */ public byte[] getRemainingData() @@ -93,7 +98,7 @@ public class EscherClientDataRecord /** * Any data recording this record. - * + * * @param remainingData the remaining bytes */ public void setRemainingData( byte[] remainingData ) { @@ -114,4 +119,9 @@ public class EscherClientDataRecord public Enum getGenericRecordType() { return EscherRecordTypes.CLIENT_DATA; } + + @Override + public EscherClientDataRecord copy() { + return new EscherClientDataRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java Sat Dec 14 23:44:26 2019 @@ -73,6 +73,14 @@ public final class EscherContainerRecord private final List<EscherRecord> _childRecords = new ArrayList<>(); + public EscherContainerRecord() {} + + public EscherContainerRecord(EscherContainerRecord other) { + super(other); + _remainingLength = other._remainingLength; + other._childRecords.stream().map(EscherRecord::copy).forEach(_childRecords::add); + } + @Override public int fillFields(byte[] data, int pOffset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader(data, pOffset); @@ -284,4 +292,9 @@ public final class EscherContainerRecord public Enum getGenericRecordType() { return EscherRecordTypes.forTypeID(getRecordId()); } + + @Override + public EscherContainerRecord copy() { + return new EscherContainerRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java Sat Dec 14 23:44:26 2019 @@ -34,6 +34,15 @@ public class EscherDgRecord extends Esch private int field_1_numShapes; private int field_2_lastMSOSPID; + public EscherDgRecord() {} + + public EscherDgRecord(EscherDgRecord other) { + super(other); + field_1_numShapes = other.field_1_numShapes; + field_2_lastMSOSPID = other.field_2_lastMSOSPID; + } + + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { /*int bytesRemaining =*/ readHeader( data, offset ); @@ -87,7 +96,7 @@ public class EscherDgRecord extends Esch /** * The number of shapes in this drawing group. - * + * * @return the number of shapes */ public int getNumShapes() @@ -97,7 +106,7 @@ public class EscherDgRecord extends Esch /** * The number of shapes in this drawing group. - * + * * @param field_1_numShapes the number of shapes */ public void setNumShapes( int field_1_numShapes ) @@ -107,7 +116,7 @@ public class EscherDgRecord extends Esch /** * The last shape id used in this drawing group. - * + * * @return the last shape id */ public int getLastMSOSPID() @@ -117,7 +126,7 @@ public class EscherDgRecord extends Esch /** * The last shape id used in this drawing group. - * + * * @param field_2_lastMSOSPID the last shape id */ public void setLastMSOSPID( int field_2_lastMSOSPID ) @@ -158,4 +167,9 @@ public class EscherDgRecord extends Esch public Enum getGenericRecordType() { return EscherRecordTypes.DG; } + + @Override + public EscherDgRecord copy() { + return new EscherDgRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java Sat Dec 14 23:44:26 2019 @@ -20,7 +20,6 @@ package org.apache.poi.ddf; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -48,6 +47,11 @@ public final class EscherDggRecord exten private int field_1_drawingGroupId; private int field_2_numShapeIdsUsed; + public FileIdCluster(FileIdCluster other) { + field_1_drawingGroupId = other.field_1_drawingGroupId; + field_2_numShapeIdsUsed = other.field_2_numShapeIdsUsed; + } + public FileIdCluster( int drawingGroupId, int numShapeIdsUsed ) { this.field_1_drawingGroupId = drawingGroupId; this.field_2_numShapeIdsUsed = numShapeIdsUsed; @@ -65,6 +69,12 @@ public final class EscherDggRecord exten field_2_numShapeIdsUsed++; } + private static int compareFileIdCluster(FileIdCluster f1, FileIdCluster f2) { + int dgDif = f1.getDrawingGroupId() - f2.getDrawingGroupId(); + int cntDif = f2.getNumShapeIdsUsed() - f1.getNumShapeIdsUsed(); + return (dgDif != 0) ? dgDif : cntDif; + } + @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( @@ -74,6 +84,17 @@ public final class EscherDggRecord exten } } + public EscherDggRecord() {} + + public EscherDggRecord(EscherDggRecord other) { + super(other); + field_1_shapeIdMax = other.field_1_shapeIdMax; + field_3_numShapesSaved = other.field_3_numShapesSaved; + field_4_drawingsSaved = other.field_4_drawingsSaved; + other.field_5_fileIdClusters.stream().map(FileIdCluster::new).forEach(field_5_fileIdClusters::add); + maxDgId = other.maxDgId; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -81,14 +102,14 @@ public final class EscherDggRecord exten int size = 0; field_1_shapeIdMax = LittleEndian.getInt( data, pos + size );size+=4; // field_2_numIdClusters = LittleEndian.getInt( data, pos + size ); - size+=4; + size+=4; field_3_numShapesSaved = LittleEndian.getInt( data, pos + size );size+=4; field_4_drawingsSaved = LittleEndian.getInt( data, pos + size );size+=4; - + field_5_fileIdClusters.clear(); // Can't rely on field_2_numIdClusters int numIdClusters = (bytesRemaining-size) / 8; - + for (int i = 0; i < numIdClusters; i++) { int drawingGroupId = LittleEndian.getInt( data, pos + size ); int numShapeIdsUsed = LittleEndian.getInt( data, pos + size + 4 ); @@ -118,7 +139,7 @@ public final class EscherDggRecord exten LittleEndian.putInt( data, pos, getNumIdClusters() ); pos += 4; LittleEndian.putInt( data, pos, field_3_numShapesSaved ); pos += 4; LittleEndian.putInt( data, pos, field_4_drawingsSaved ); pos += 4; - + for (FileIdCluster fic : field_5_fileIdClusters) { LittleEndian.putInt( data, pos, fic.getDrawingGroupId() ); pos += 4; LittleEndian.putInt( data, pos, fic.getNumShapeIdsUsed() ); pos += 4; @@ -154,7 +175,7 @@ public final class EscherDggRecord exten /** * The maximum is actually the next available shape id. - * + * * @param shapeIdMax the next available shape id */ public void setShapeIdMax(int shapeIdMax) { @@ -163,7 +184,7 @@ public final class EscherDggRecord exten /** * Number of id clusters + 1 - * + * * @return the number of id clusters + 1 */ public int getNumIdClusters() { @@ -181,7 +202,7 @@ public final class EscherDggRecord exten /** * Sets the number of shapes saved - * + * * @param numShapesSaved the number of shapes saved */ public void setNumShapesSaved(int numShapesSaved) { @@ -208,7 +229,7 @@ public final class EscherDggRecord exten /** * Gets the maximum drawing group ID - * + * * @return The maximum drawing group ID */ public int getMaxDrawingGroupId() { @@ -234,13 +255,13 @@ public final class EscherDggRecord exten } } - + /** * Add a new cluster * * @param dgId id of the drawing group (stored in the record options) * @param numShapedUsed initial value of the numShapedUsed field - * + * * @return the new {@link FileIdCluster} */ public FileIdCluster addCluster(int dgId, int numShapedUsed) { @@ -254,35 +275,29 @@ public final class EscherDggRecord exten * @param numShapedUsed initial value of the numShapedUsed field * @param sort if true then sort clusters by drawing group id.( * In Excel the clusters are sorted but in PPT they are not) - * + * * @return the new {@link FileIdCluster} */ public FileIdCluster addCluster( int dgId, int numShapedUsed, boolean sort ) { FileIdCluster ficNew = new FileIdCluster(dgId, numShapedUsed); field_5_fileIdClusters.add(ficNew); maxDgId = Math.min(maxDgId, dgId); - + if (sort) { sortCluster(); } - + return ficNew; } private void sortCluster() { - field_5_fileIdClusters.sort(new Comparator<FileIdCluster>() { - @Override - public int compare(FileIdCluster f1, FileIdCluster f2) { - int dgDif = f1.getDrawingGroupId() - f2.getDrawingGroupId(); - int cntDif = f2.getNumShapeIdsUsed() - f1.getNumShapeIdsUsed(); - return (dgDif != 0) ? dgDif : cntDif; - } - }); + field_5_fileIdClusters.sort(FileIdCluster::compareFileIdCluster); } - + + /** * Finds the next available (1 based) drawing group id - * + * * @return the next available drawing group id */ public short findNewDrawingGroupId() { @@ -293,7 +308,7 @@ public final class EscherDggRecord exten } return (short)bs.nextClearBit(0); } - + /** * Allocates new shape id for the drawing group * @@ -306,7 +321,7 @@ public final class EscherDggRecord exten public int allocateShapeId(EscherDgRecord dg, boolean sort) { final short drawingGroupId = dg.getDrawingGroupId(); field_3_numShapesSaved++; - + // check for an existing cluster, which has space available // see 2.2.46 OfficeArtIDCL (cspidCur) for the 1024 limitation // multiple clusters can belong to the same drawing group @@ -325,16 +340,16 @@ public final class EscherDggRecord exten ficAdd = addCluster( drawingGroupId, 0, sort ); maxDgId = Math.max(maxDgId, drawingGroupId); } - + int shapeId = index*1024 + ficAdd.getNumShapeIdsUsed(); ficAdd.incrementUsedShapeId(); - + dg.setNumShapes( dg.getNumShapes() + 1 ); dg.setLastMSOSPID( shapeId ); field_1_shapeIdMax = Math.max(field_1_shapeIdMax, shapeId + 1); - + return shapeId; - } + } @Override public Enum getGenericRecordType() { @@ -352,4 +367,9 @@ public final class EscherDggRecord exten "drawingsSaved", this::getDrawingsSaved ); } + + @Override + public EscherDggRecord copy() { + return new EscherDggRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java Sat Dec 14 23:44:26 2019 @@ -65,6 +65,26 @@ public final class EscherMetafileBlip ex private byte[] raw_pictureData; private byte[] remainingData; + public EscherMetafileBlip() {} + + public EscherMetafileBlip(EscherMetafileBlip other) { + super(other); + System.arraycopy(other.field_1_UID, 0, field_1_UID, 0, field_1_UID.length); + System.arraycopy(other.field_2_UID, 0, field_2_UID, 0, field_2_UID.length); + field_2_cb = other.field_2_cb; + field_3_rcBounds_x1 = other.field_3_rcBounds_x1; + field_3_rcBounds_y1 = other.field_3_rcBounds_y1; + field_3_rcBounds_x2 = other.field_3_rcBounds_x2; + field_3_rcBounds_y2 = other.field_3_rcBounds_y2; + field_4_ptSize_h = other.field_4_ptSize_h; + field_4_ptSize_w = other.field_4_ptSize_w; + field_5_cbSave = other.field_5_cbSave; + field_6_fCompression = other.field_6_fCompression; + field_7_fFilter = other.field_7_fFilter; + raw_pictureData = (other.raw_pictureData == null) ? null : other.raw_pictureData.clone(); + remainingData = (other.remainingData == null) ? null : other.remainingData.clone(); + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesAfterHeader = readHeader( data, offset ); @@ -263,7 +283,7 @@ public final class EscherMetafileBlip ex } /** - * Gets the dimensions of the metafile + * Gets the dimensions of the metafile * * @return the dimensions of the metafile */ @@ -283,7 +303,7 @@ public final class EscherMetafileBlip ex /** * Gets the compressed size of the metafile (in bytes) - * + * * @return the compressed size */ public int getCompressedSize() { @@ -325,7 +345,7 @@ public final class EscherMetafileBlip ex public byte getFilter() { return field_7_fFilter; } - + /** * Sets the filter byte - this is usually 0xFE * @@ -335,8 +355,8 @@ public final class EscherMetafileBlip ex field_7_fFilter = filter; } - - + + /** * Returns any remaining bytes * @@ -345,7 +365,7 @@ public final class EscherMetafileBlip ex public byte[] getRemainingData() { return remainingData; } - + /** * Return the blip signature * @@ -381,7 +401,7 @@ public final class EscherMetafileBlip ex } catch (IOException e) { throw new RuntimeException("Can't compress metafile picture data", e); } - + setCompressedSize(raw_pictureData.length); setCompressed(true); } @@ -398,4 +418,9 @@ public final class EscherMetafileBlip ex m.put("filter", this::getFilter); return Collections.unmodifiableMap(m); } + + @Override + public EscherMetafileBlip copy() { + return new EscherMetafileBlip(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java Sat Dec 14 23:44:26 2019 @@ -24,11 +24,17 @@ import org.apache.poi.util.Internal; * or complex. Simple types are fixed length. Complex properties are variable * length. */ -public class EscherOptRecord extends AbstractEscherOptRecord -{ +public class EscherOptRecord extends AbstractEscherOptRecord { public static final short RECORD_ID = EscherRecordTypes.OPT.typeID; public static final String RECORD_DESCRIPTION = EscherRecordTypes.OPT.description; + public EscherOptRecord() {} + + public EscherOptRecord(EscherOptRecord other) { + super(other); + } + + @Override public short getInstance() { @@ -76,4 +82,9 @@ public class EscherOptRecord extends Abs public Enum getGenericRecordType() { return EscherRecordTypes.OPT; } + + @Override + public EscherOptRecord copy() { + return new EscherOptRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java Sat Dec 14 23:44:26 2019 @@ -58,6 +58,24 @@ public final class EscherPictBlip extend private byte[] raw_pictureData; + public EscherPictBlip() {} + + public EscherPictBlip(EscherPictBlip other) { + super(other); + System.arraycopy(other.field_1_UID, 0, field_1_UID, 0, field_1_UID.length); + field_2_cb = other.field_2_cb; + field_3_rcBounds_x1 = other.field_3_rcBounds_x1; + field_3_rcBounds_y1 = other.field_3_rcBounds_y1; + field_3_rcBounds_x2 = other.field_3_rcBounds_x2; + field_3_rcBounds_y2 = other.field_3_rcBounds_y2; + field_4_ptSize_w = other.field_4_ptSize_w; + field_4_ptSize_h = other.field_4_ptSize_h; + field_5_cbSave = other.field_5_cbSave; + field_6_fCompression = other.field_6_fCompression; + field_7_fFilter = other.field_7_fFilter; + raw_pictureData = (other.raw_pictureData == null) ? null : other.raw_pictureData.clone(); + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesAfterHeader = readHeader(data, offset); @@ -212,7 +230,7 @@ public final class EscherPictBlip extend } /** - * Gets the dimensions of the metafile + * Gets the dimensions of the metafile * * @return the dimensions of the metafile */ @@ -232,7 +250,7 @@ public final class EscherPictBlip extend /** * Gets the compressed size of the metafile (in bytes) - * + * * @return the compressed size */ public int getCompressedSize() { @@ -274,7 +292,7 @@ public final class EscherPictBlip extend public byte getFilter() { return field_7_fFilter; } - + /** * Sets the filter byte - this is usually 0xFE * @@ -296,4 +314,9 @@ public final class EscherPictBlip extend m.put("filter", this::getFilter); return Collections.unmodifiableMap(m); } + + @Override + public EscherPictBlip copy() { + return new EscherPictBlip(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java Sat Dec 14 23:44:26 2019 @@ -51,6 +51,11 @@ public abstract class EscherRecord imple // fields uninitialised } + protected EscherRecord(EscherRecord other) { + _options = other._options; + _recordId = other._recordId; + } + /** * Delegates to fillFields(byte[], int, EscherRecordFactory) * @@ -233,12 +238,11 @@ public abstract class EscherRecord imple * Escher records may need to be clonable in the future. * * @return the cloned object - * - * @throws CloneNotSupportedException if the subclass hasn't implemented {@link Cloneable} */ @Override - public EscherRecord clone() throws CloneNotSupportedException { - return (EscherRecord)super.clone(); + @SuppressWarnings("squid:S2975") + public final EscherRecord clone() { + return copy(); } /** @@ -345,4 +349,6 @@ public abstract class EscherRecord imple "recordSize", this::getRecordSize ); } + + public abstract EscherRecord copy(); } \ No newline at end of file Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java Sat Dec 14 23:44:26 2019 @@ -78,6 +78,14 @@ public class EscherSpRecord extends Esch private int field_1_shapeId; private int field_2_flags; + public EscherSpRecord() {} + + public EscherSpRecord(EscherSpRecord other) { + super(other); + field_1_shapeId = other.field_1_shapeId; + field_2_flags = other.field_2_flags; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { /*int bytesRemaining =*/ readHeader( data, offset ); @@ -169,7 +177,7 @@ public class EscherSpRecord extends Esch /** * Sets a number that identifies this shape. - * + * * @param field_1_shapeId the shape id */ public void setShapeId( int field_1_shapeId ) @@ -179,7 +187,7 @@ public class EscherSpRecord extends Esch /** * The flags that apply to this shape. - * + * * @return the flags * * @see #FLAG_GROUP @@ -202,7 +210,7 @@ public class EscherSpRecord extends Esch /** * The flags that apply to this shape. - * + * * @param field_2_flags the flags * * @see #FLAG_GROUP @@ -226,7 +234,7 @@ public class EscherSpRecord extends Esch /** * Returns shape type. Must be one of MSOSPT values (see [MS-ODRAW] for * details). - * + * * @return shape type */ public short getShapeType() @@ -237,7 +245,7 @@ public class EscherSpRecord extends Esch /** * Sets shape type. Must be one of MSOSPT values (see [MS-ODRAW] for * details). - * + * * @param value * new shape type */ @@ -260,4 +268,9 @@ public class EscherSpRecord extends Esch public Enum getGenericRecordType() { return EscherRecordTypes.SP; } + + @Override + public EscherSpRecord copy() { + return new EscherSpRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java Sat Dec 14 23:44:26 2019 @@ -36,6 +36,16 @@ public class EscherSpgrRecord extends Es private int field_3_rectX2; private int field_4_rectY2; + public EscherSpgrRecord() {} + + public EscherSpgrRecord(EscherSpgrRecord other) { + super(other); + field_1_rectX1 = other.field_1_rectX1; + field_2_rectY1 = other.field_2_rectY1; + field_3_rectX2 = other.field_3_rectX2; + field_4_rectY2 = other.field_4_rectY2; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -90,7 +100,7 @@ public class EscherSpgrRecord extends Es /** * The starting top-left coordinate of child records. - * + * * @return the top-left x coordinate */ public int getRectX1() @@ -100,7 +110,7 @@ public class EscherSpgrRecord extends Es /** * The top-left coordinate of child records. - * + * * @param x1 the top-left x coordinate */ public void setRectX1( int x1 ) @@ -110,7 +120,7 @@ public class EscherSpgrRecord extends Es /** * The top-left coordinate of child records. - * + * * @return the top-left y coordinate */ public int getRectY1() @@ -120,7 +130,7 @@ public class EscherSpgrRecord extends Es /** * The top-left y coordinate of child records. - * + * * @param y1 the top-left y coordinate */ public void setRectY1( int y1 ) @@ -130,7 +140,7 @@ public class EscherSpgrRecord extends Es /** * The bottom-right x coordinate of child records. - * + * * @return the bottom-right x coordinate */ public int getRectX2() @@ -140,7 +150,7 @@ public class EscherSpgrRecord extends Es /** * The bottom-right x coordinate of child records. - * + * * @param x2 the bottom-right x coordinate */ public void setRectX2( int x2 ) @@ -150,7 +160,7 @@ public class EscherSpgrRecord extends Es /** * The bottom-right y coordinate of child records. - * + * * @return the bottom-right y coordinate */ public int getRectY2() @@ -160,7 +170,7 @@ public class EscherSpgrRecord extends Es /** * The bottom-right y coordinate of child records. - * + * * @param rectY2 the bottom-right y coordinate */ public void setRectY2(int rectY2) { @@ -182,4 +192,9 @@ public class EscherSpgrRecord extends Es public Enum getGenericRecordType() { return EscherRecordTypes.SPGR; } + + @Override + public EscherSpgrRecord copy() { + return new EscherSpgrRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java Sat Dec 14 23:44:26 2019 @@ -36,6 +36,16 @@ public class EscherSplitMenuColorsRecord private int field_3_color3; private int field_4_color4; + public EscherSplitMenuColorsRecord() {} + + public EscherSplitMenuColorsRecord(EscherSplitMenuColorsRecord other) { + super(other); + field_1_color1 = other.field_1_color1; + field_2_color2 = other.field_2_color2; + field_3_color3 = other.field_3_color3; + field_4_color4 = other.field_4_color4; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -87,7 +97,7 @@ public class EscherSplitMenuColorsRecord } /** - * Gets the fill color + * Gets the fill color * * @return the fill color */ @@ -173,4 +183,9 @@ public class EscherSplitMenuColorsRecord public Enum getGenericRecordType() { return EscherRecordTypes.SPLIT_MENU_COLORS; } + + @Override + public EscherSplitMenuColorsRecord copy() { + return new EscherSplitMenuColorsRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherTertiaryOptRecord.java Sat Dec 14 23:44:26 2019 @@ -20,10 +20,15 @@ package org.apache.poi.ddf; * "The OfficeArtTertiaryFOPT record specifies a table of OfficeArtRGFOPTE properties, as defined in section 2.3.1." * -- [MS-ODRAW] -- v20110608; Office Drawing Binary File Format */ -public class EscherTertiaryOptRecord extends AbstractEscherOptRecord -{ +public class EscherTertiaryOptRecord extends AbstractEscherOptRecord { public static final short RECORD_ID = EscherRecordTypes.USER_DEFINED.typeID; + public EscherTertiaryOptRecord() {} + + public EscherTertiaryOptRecord(EscherTertiaryOptRecord other) { + super(other); + } + @Override public String getRecordName() { return EscherRecordTypes.USER_DEFINED.recordName; @@ -33,4 +38,9 @@ public class EscherTertiaryOptRecord ext public Enum getGenericRecordType() { return EscherRecordTypes.USER_DEFINED; } + + @Override + public EscherTertiaryOptRecord copy() { + return new EscherTertiaryOptRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java Sat Dec 14 23:44:26 2019 @@ -43,8 +43,11 @@ public final class EscherTextboxRecord e /** The data for this record not including the the 8 byte header */ private byte[] thedata = NO_BYTES; - public EscherTextboxRecord() - { + public EscherTextboxRecord() {} + + public EscherTextboxRecord(EscherTextboxRecord other) { + super(other); + thedata = (other.thedata == null) ? NO_BYTES : other.thedata.clone(); } @Override @@ -83,7 +86,7 @@ public final class EscherTextboxRecord e * does not seem to put anything here, but with PowerPoint this will * contain the bytes that make up a TextHeaderAtom followed by a * TextBytesAtom/TextCharsAtom - * + * * @return the extra data */ public byte[] getData() @@ -95,7 +98,7 @@ public final class EscherTextboxRecord e * Sets the extra data (in the parent application's format) to be * contained by the record. Used when the parent application changes * the contents. - * + * * @param b the buffer which contains the data * @param start the start position in the buffer * @param length the length of the block @@ -105,12 +108,12 @@ public final class EscherTextboxRecord e thedata = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH); System.arraycopy(b,start,thedata,0,length); } - + /** * Sets the extra data (in the parent application's format) to be * contained by the record. Used when the parent application changes * the contents. - * + * * @param b the data */ public void setData(byte[] b) { @@ -124,15 +127,6 @@ public final class EscherTextboxRecord e } @Override - public EscherTextboxRecord clone() { - EscherTextboxRecord etr = new EscherTextboxRecord(); - etr.setOptions(this.getOptions()); - etr.setRecordId(this.getRecordId()); - etr.thedata = this.thedata.clone(); - return etr; - } - - @Override public String getRecordName() { return EscherRecordTypes.CLIENT_TEXTBOX.recordName; } @@ -150,4 +144,9 @@ public final class EscherTextboxRecord e "extraData", this::getData ); } + + @Override + public EscherTextboxRecord copy() { + return new EscherTextboxRecord(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java (original) +++ poi/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java Sat Dec 14 23:44:26 2019 @@ -40,17 +40,20 @@ public final class UnknownEscherRecord e /** The data for this record not including the the 8 byte header */ private byte[] thedata = NO_BYTES; - private List<EscherRecord> _childRecords; + private final List<EscherRecord> _childRecords = new ArrayList<>(); - public UnknownEscherRecord() { - _childRecords = new ArrayList<>(); + public UnknownEscherRecord() {} + + public UnknownEscherRecord(UnknownEscherRecord other) { + super(other); + other._childRecords.stream().map(EscherRecord::copy).forEach(_childRecords::add); } @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); /* - * Have a check between available bytes and bytesRemaining, + * Have a check between available bytes and bytesRemaining, * take the available length if the bytesRemaining out of range. */ int available = data.length - (offset + 8); @@ -77,7 +80,7 @@ public final class UnknownEscherRecord e if (bytesRemaining < 0) { bytesRemaining = 0; } - + thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH); System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining ); return bytesRemaining + 8; @@ -123,16 +126,11 @@ public final class UnknownEscherRecord e @Override public void setChildRecords(List<EscherRecord> childRecords) { - _childRecords = childRecords; - } - - @Override - public UnknownEscherRecord clone() { - UnknownEscherRecord uer = new UnknownEscherRecord(); - uer.thedata = this.thedata.clone(); - uer.setOptions(this.getOptions()); - uer.setRecordId(this.getRecordId()); - return uer; + if (childRecords == _childRecords) { + return; + } + _childRecords.clear(); + _childRecords.addAll(childRecords); } @Override @@ -156,4 +154,9 @@ public final class UnknownEscherRecord e public Enum getGenericRecordType() { return EscherRecordTypes.UNKNOWN; } + + @Override + public UnknownEscherRecord copy() { + return new UnknownEscherRecord(this); + } } Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java (original) +++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java Sat Dec 14 23:44:26 2019 @@ -42,6 +42,14 @@ public class EscherPlaceholder extends E public EscherPlaceholder() {} + public EscherPlaceholder(EscherPlaceholder other) { + super(other); + position = other.position; + placementId = other.placementId; + size = other.size; + unused = other.unused; + } + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -107,4 +115,9 @@ public class EscherPlaceholder extends E public Enum getGenericRecordType() { return RecordTypes.OEPlaceholderAtom; } + + @Override + public EscherPlaceholder copy() { + return new EscherPlaceholder(this); + } } Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java (original) +++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/HSLFEscherClientDataRecord.java Sat Dec 14 23:44:26 2019 @@ -33,7 +33,7 @@ import org.apache.poi.util.LittleEndian; * An atom record that specifies whether a shape is a placeholder shape. * The number, position, and type of placeholder shapes are determined by * the slide layout as specified in the SlideAtom record. - * + * * @since POI 3.14-Beta2 */ public class HSLFEscherClientDataRecord extends EscherClientDataRecord { @@ -42,19 +42,29 @@ public class HSLFEscherClientDataRecord private static final int MAX_RECORD_LENGTH = 1_000_000; private final List<Record> _childRecords = new ArrayList<>(); - - public List<? extends Record> getHSLFChildRecords() { + + public HSLFEscherClientDataRecord() {} + + public HSLFEscherClientDataRecord(HSLFEscherClientDataRecord other) { + 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); + } + + + public List<? extends Record> getHSLFChildRecords() { return _childRecords; } - + public void removeChild(Class<? extends Record> childClass) { _childRecords.removeIf(childClass::isInstance); } - + public void addChild(Record childRecord) { _childRecords.add(childRecord); } - + @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { int bytesRemaining = readHeader( data, offset ); @@ -67,12 +77,12 @@ public class HSLFEscherClientDataRecord @Override public int serialize(int offset, byte[] data, EscherSerializationListener listener) { listener.beforeRecordSerialize( offset, getRecordId(), this ); - + LittleEndian.putShort(data, offset, getOptions()); LittleEndian.putShort(data, offset+2, getRecordId()); byte[] childBytes = getRemainingData(); - + LittleEndian.putInt(data, offset+4, childBytes.length); System.arraycopy(childBytes, 0, data, offset+8, childBytes.length); int recordSize = 8+childBytes.length; @@ -84,7 +94,7 @@ public class HSLFEscherClientDataRecord public int getRecordSize() { return 8 + getRemainingData().length; } - + @Override public byte[] getRemainingData() { ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -111,10 +121,13 @@ public class HSLFEscherClientDataRecord offset += 8 + rlen; } } - + public String getRecordName() { return "HSLFClientData"; } - + @Override + public HSLFEscherClientDataRecord copy() { + return new HSLFEscherClientDataRecord(this); + } } Modified: poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java (original) +++ poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java Sat Dec 14 23:44:26 2019 @@ -170,6 +170,8 @@ public final class TestEscherContainerRe public String getRecordName() { return ""; } @Override public Enum getGenericRecordType() { return EscherRecordTypes.UNKNOWN; } + @Override + public DummyEscherRecord copy() { return null; } } @Test Modified: poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDump.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDump.java?rev=1871563&r1=1871562&r2=1871563&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDump.java (original) +++ poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDump.java Sat Dec 14 23:44:26 2019 @@ -17,11 +17,14 @@ package org.apache.poi.ddf; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; import java.io.InputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -33,8 +36,35 @@ import org.junit.BeforeClass; import org.junit.Test; public class TestEscherDump { - static NullPrinterStream nullPS; - + private static NullPrinterStream nullPS; + + private static final String recordData = + "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" + + "eJr+iZEHAAA="; + + @BeforeClass public static void init() throws UnsupportedEncodingException { nullPS = new NullPrinterStream(); @@ -43,32 +73,6 @@ public class TestEscherDump { // simple test to at least cover some parts of the class @Test public void testSimple() throws Exception { - final String recordData = - "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" + - "eJr+iZEHAAA="; - // Create a new instance of the escher dumper EscherDump dumper = new EscherDump(); @@ -82,17 +86,17 @@ public class TestEscherDump { } @Test - public void testWithData() throws Exception { + public void testWithData() { new EscherDump().dump(8, new byte[] {0, 0, 0, 0, 0, 0, 0, 0}, nullPS); } @Test - public void testWithSamplefile() throws Exception { + public void testWithSamplefile() throws Exception { //InputStream stream = HSSFTestDataSamples.openSampleFileStream(") byte[] data = POIDataSamples.getDDFInstance().readFile("Container.dat"); new EscherDump().dump(data.length, data, nullPS); //new EscherDump().dumpOld(data.length, new ByteArrayInputStream(data), System.out); - + data = new byte[2586114]; try (InputStream stream = HSSFTestDataSamples.openSampleFileStream("44593.xls")) { int bytes = IOUtils.readFully(stream, data); @@ -101,7 +105,21 @@ public class TestEscherDump { //new EscherDump().dumpOld(bytes, new ByteArrayInputStream(data), System.out); } } - + + @Test + public void testCopy() throws Exception { + byte[] data1 = RawDataUtil.decompress(recordData); + + List<EscherRecord> records = new ArrayList<>(); + EscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); + EscherRecord r = recordFactory.createRecord(data1, 0); + r.fillFields(data1, recordFactory); + EscherRecord r2 = r.copy(); + byte[] data2 = r2.serialize(); + + assertArrayEquals(data1, data2); + } + /** * Implementation of an OutputStream which does nothing, used * to redirect stdout to avoid spamming the console with output @@ -110,6 +128,6 @@ public class TestEscherDump { @SuppressWarnings("resource") private NullPrinterStream() throws UnsupportedEncodingException { super(new NullOutputStream(),true,LocaleUtil.CHARSET_1252.name()); - } - } + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org