#64004 - Replace clone() with copy constructor

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1871563 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2019-12-14 23:44:26 +00:00
parent 129b8215ce
commit 3fb5e79490
24 changed files with 499 additions and 183 deletions

View File

@ -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 AbstractEscherOptRecord extends EscherRecord
/**
* The list of properties stored by this record.
*
*
* @return the list of properties
*/
public List<EscherProperty> getEscherProperties()
@ -70,7 +77,7 @@ public abstract class AbstractEscherOptRecord extends EscherRecord
/**
* 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 AbstractEscherOptRecord extends EscherRecord
return properties.get( index );
}
private int getPropertiesSize()
{
int totalSize = 0;
@ -164,4 +171,7 @@ public abstract class AbstractEscherOptRecord extends EscherRecord
"properties", this::getEscherProperties
);
}
@Override
public abstract AbstractEscherOptRecord copy();
}

View File

@ -58,7 +58,25 @@ public final class EscherBSERecord extends EscherRecord {
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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* Set the expected win32 blip type
*
*
* @param blipTypeWin32 win32 blip type
*/
public void setBlipTypeWin32(byte blipTypeWin32) {
@ -172,7 +190,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* Set the expected MacOS blip type
*
*
* @param blipTypeMacOS MacOS blip type
*/
public void setBlipTypeMacOS(byte blipTypeMacOS) {
@ -194,7 +212,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* 16 byte MD4 checksum.
*
*
* @return 16 byte MD4 checksum
*/
public byte[] getUid() {
@ -203,7 +221,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* 16 byte MD4 checksum.
*
*
* @param uid 16 byte MD4 checksum
*/
public void setUid(byte[] uid) {
@ -215,7 +233,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* unused
*
*
* @return an unknown tag
*/
public short getTag() {
@ -224,7 +242,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* unused
*
*
* @param tag unknown tag
*/
public void setTag(short tag) {
@ -233,7 +251,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* Blip size in stream.
*
*
* @return the blip size
*/
public int getSize() {
@ -242,7 +260,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* Blip size in stream.
*
*
* @param size blip size
*/
public void setSize(int size) {
@ -251,7 +269,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* The reference count of this blip.
*
*
* @return the reference count
*/
public int getRef() {
@ -260,7 +278,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* The reference count of this blip.
*
*
* @param ref the reference count
*/
public void setRef(int ref) {
@ -269,7 +287,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* File offset in the delay stream.
*
*
* @return the file offset
*/
public int getOffset() {
@ -278,7 +296,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* File offset in the delay stream.
*
*
* @param offset the file offset
*/
public void setOffset(int offset) {
@ -287,7 +305,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* Defines the way this blip is used.
*
*
* @return the blip usage
*/
public byte getUsage() {
@ -296,7 +314,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* The length in characters of the blip name.
*
*
* @return the blip name length
*/
public byte getName() {
@ -314,7 +332,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* Any remaining data in this record.
*
*
* @return the remaining bytes
*/
public byte[] getRemainingData() {
@ -356,7 +374,7 @@ public final class EscherBSERecord extends EscherRecord {
/**
* Any remaining data in this record.
*
*
* @param remainingData the remaining bytes
*/
public void setRemainingData(byte[] remainingData) {
@ -388,4 +406,9 @@ public final class EscherBSERecord extends EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.BSE;
}
@Override
public EscherBSERecord copy() {
return new EscherBSERecord(this);
}
}

View File

@ -33,6 +33,14 @@ public class EscherBitmapBlip extends EscherBlipRecord {
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 EscherBlipRecord {
);
}
@Override
public EscherBitmapBlip copy() {
return new EscherBitmapBlip(this);
}
}

View File

@ -39,6 +39,11 @@ public class EscherBlipRecord extends EscherRecord {
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 EscherRecord {
EscherRecordTypes t = EscherRecordTypes.forTypeID(getRecordId());
return (t != EscherRecordTypes.UNKNOWN) ? t : EscherRecordTypes.BLIP_START;
}
@Override
public EscherBlipRecord copy() {
return new EscherBlipRecord(this);
}
}

View File

@ -38,6 +38,16 @@ public class EscherChildAnchorRecord extends EscherRecord {
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 extends EscherRecord {
default:
throw new RuntimeException("Invalid EscherChildAnchorRecord - neither 8 nor 16 bytes.");
}
return 8 + size;
}
@ -98,7 +108,7 @@ public class EscherChildAnchorRecord extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* 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 extends EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.CHILD_ANCHOR;
}
@Override
public EscherChildAnchorRecord copy() {
return new EscherChildAnchorRecord(this);
}
}

View File

@ -59,6 +59,23 @@ public class EscherClientAnchorRecord extends EscherRecord {
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 extends EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.CLIENT_ANCHOR;
}
@Override
public EscherClientAnchorRecord copy() {
return new EscherClientAnchorRecord(this);
}
}

View File

@ -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);
}
}

View File

@ -73,6 +73,14 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
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 extends EscherRecord implements Iterabl
public Enum getGenericRecordType() {
return EscherRecordTypes.forTypeID(getRecordId());
}
@Override
public EscherContainerRecord copy() {
return new EscherContainerRecord(this);
}
}

View File

@ -34,6 +34,15 @@ public class EscherDgRecord extends EscherRecord {
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 EscherRecord {
/**
* The number of shapes in this drawing group.
*
*
* @return the number of shapes
*/
public int getNumShapes()
@ -97,7 +106,7 @@ public class EscherDgRecord extends EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.DG;
}
@Override
public EscherDgRecord copy() {
return new EscherDgRecord(this);
}
}

View File

@ -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 extends EscherRecord {
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 extends EscherRecord {
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 extends EscherRecord {
}
}
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 extends EscherRecord {
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 extends EscherRecord {
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 extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* Number of id clusters + 1
*
*
* @return the number of id clusters + 1
*/
public int getNumIdClusters() {
@ -181,7 +202,7 @@ public final class EscherDggRecord extends EscherRecord {
/**
* 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 extends EscherRecord {
/**
* Gets the maximum drawing group ID
*
*
* @return The maximum drawing group ID
*/
public int getMaxDrawingGroupId() {
@ -234,13 +255,13 @@ public final class EscherDggRecord extends EscherRecord {
}
}
/**
* 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 extends EscherRecord {
* @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 extends EscherRecord {
}
return (short)bs.nextClearBit(0);
}
/**
* Allocates new shape id for the drawing group
*
@ -306,7 +321,7 @@ public final class EscherDggRecord extends EscherRecord {
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 extends EscherRecord {
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 extends EscherRecord {
"drawingsSaved", this::getDrawingsSaved
);
}
@Override
public EscherDggRecord copy() {
return new EscherDggRecord(this);
}
}

View File

@ -65,6 +65,26 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
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 extends EscherBlipRecord {
}
/**
* 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 extends EscherBlipRecord {
/**
* Gets the compressed size of the metafile (in bytes)
*
*
* @return the compressed size
*/
public int getCompressedSize() {
@ -325,7 +345,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
public byte getFilter() {
return field_7_fFilter;
}
/**
* Sets the filter byte - this is usually 0xFE
*
@ -335,8 +355,8 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
field_7_fFilter = filter;
}
/**
* Returns any remaining bytes
*
@ -345,7 +365,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
public byte[] getRemainingData() {
return remainingData;
}
/**
* Return the blip signature
*
@ -381,7 +401,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
} 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 extends EscherBlipRecord {
m.put("filter", this::getFilter);
return Collections.unmodifiableMap(m);
}
@Override
public EscherMetafileBlip copy() {
return new EscherMetafileBlip(this);
}
}

View File

@ -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 AbstractEscherOptRecord
public Enum getGenericRecordType() {
return EscherRecordTypes.OPT;
}
@Override
public EscherOptRecord copy() {
return new EscherOptRecord(this);
}
}

View File

@ -58,6 +58,24 @@ public final class EscherPictBlip extends EscherBlipRecord {
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 extends EscherBlipRecord {
}
/**
* 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 extends EscherBlipRecord {
/**
* Gets the compressed size of the metafile (in bytes)
*
*
* @return the compressed size
*/
public int getCompressedSize() {
@ -274,7 +292,7 @@ public final class EscherPictBlip extends EscherBlipRecord {
public byte getFilter() {
return field_7_fFilter;
}
/**
* Sets the filter byte - this is usually 0xFE
*
@ -296,4 +314,9 @@ public final class EscherPictBlip extends EscherBlipRecord {
m.put("filter", this::getFilter);
return Collections.unmodifiableMap(m);
}
@Override
public EscherPictBlip copy() {
return new EscherPictBlip(this);
}
}

View File

@ -51,6 +51,11 @@ public abstract class EscherRecord implements Cloneable, GenericRecord {
// 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 implements Cloneable, GenericRecord {
* 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 implements Cloneable, GenericRecord {
"recordSize", this::getRecordSize
);
}
public abstract EscherRecord copy();
}

View File

@ -78,6 +78,14 @@ public class EscherSpRecord extends EscherRecord {
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 EscherRecord {
/**
* 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 EscherRecord {
/**
* The flags that apply to this shape.
*
*
* @return the flags
*
* @see #FLAG_GROUP
@ -202,7 +210,7 @@ public class EscherSpRecord extends EscherRecord {
/**
* The flags that apply to this shape.
*
*
* @param field_2_flags the flags
*
* @see #FLAG_GROUP
@ -226,7 +234,7 @@ public class EscherSpRecord extends EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.SP;
}
@Override
public EscherSpRecord copy() {
return new EscherSpRecord(this);
}
}

View File

@ -36,6 +36,16 @@ public class EscherSpgrRecord extends EscherRecord {
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 EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
/**
* The top-left coordinate of child records.
*
*
* @return the top-left y coordinate
*/
public int getRectY1()
@ -120,7 +130,7 @@ public class EscherSpgrRecord extends EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
/**
* 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 EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.SPGR;
}
@Override
public EscherSpgrRecord copy() {
return new EscherSpgrRecord(this);
}
}

View File

@ -36,6 +36,16 @@ public class EscherSplitMenuColorsRecord extends EscherRecord {
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 extends EscherRecord {
}
/**
* Gets the fill color
* Gets the fill color
*
* @return the fill color
*/
@ -173,4 +183,9 @@ public class EscherSplitMenuColorsRecord extends EscherRecord {
public Enum getGenericRecordType() {
return EscherRecordTypes.SPLIT_MENU_COLORS;
}
@Override
public EscherSplitMenuColorsRecord copy() {
return new EscherSplitMenuColorsRecord(this);
}
}

View File

@ -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 extends AbstractEscherOptRecord
public Enum getGenericRecordType() {
return EscherRecordTypes.USER_DEFINED;
}
@Override
public EscherTertiaryOptRecord copy() {
return new EscherTertiaryOptRecord(this);
}
}

View File

@ -43,8 +43,11 @@ public final class EscherTextboxRecord extends EscherRecord implements Cloneable
/** 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 extends EscherRecord implements Cloneable
* 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 extends EscherRecord implements Cloneable
* 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 extends EscherRecord implements Cloneable
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) {
@ -123,15 +126,6 @@ public final class EscherTextboxRecord extends EscherRecord implements Cloneable
return 8 + thedata.length;
}
@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 extends EscherRecord implements Cloneable
"extraData", this::getData
);
}
@Override
public EscherTextboxRecord copy() {
return new EscherTextboxRecord(this);
}
}

View File

@ -40,17 +40,20 @@ public final class UnknownEscherRecord extends EscherRecord implements Cloneable
/** 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 extends EscherRecord implements Cloneable
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 extends EscherRecord implements Cloneable
@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 extends EscherRecord implements Cloneable
public Enum getGenericRecordType() {
return EscherRecordTypes.UNKNOWN;
}
@Override
public UnknownEscherRecord copy() {
return new UnknownEscherRecord(this);
}
}

View File

@ -42,6 +42,14 @@ public class EscherPlaceholder extends EscherRecord {
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 EscherRecord {
public Enum getGenericRecordType() {
return RecordTypes.OEPlaceholderAtom;
}
@Override
public EscherPlaceholder copy() {
return new EscherPlaceholder(this);
}
}

View File

@ -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 extends EscherClientDataRecord {
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 extends EscherClientDataRecord {
@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 extends EscherClientDataRecord {
public int getRecordSize() {
return 8 + getRemainingData().length;
}
@Override
public byte[] getRemainingData() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@ -111,10 +121,13 @@ public class HSLFEscherClientDataRecord extends EscherClientDataRecord {
offset += 8 + rlen;
}
}
public String getRecordName() {
return "HSLFClientData";
}
@Override
public HSLFEscherClientDataRecord copy() {
return new HSLFEscherClientDataRecord(this);
}
}

View File

@ -170,6 +170,8 @@ public final class TestEscherContainerRecord {
public String getRecordName() { return ""; }
@Override
public Enum getGenericRecordType() { return EscherRecordTypes.UNKNOWN; }
@Override
public DummyEscherRecord copy() { return null; }
}
@Test

View File

@ -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 =
"H4sIAAAAAAAAAL2UaVCSWxjHX0SBChABLRXM1FxSEzXTzHK7dpVIcMmwxXCP9KaGTaWlGYLrtGmGmYEmYmqF2qIt4ppmjNG+" +
"2dWulUtOUdq1NHjva8v90HT7eM+Z5znP/M9/zpk5v3mONgAoc5AANBDKeVDW0gQAjZkVCti3mKnpAExpB/m8AKTyEiTCNd2J" +
"Z+O0o6W+srDCyH3DhzkgUAD76v86QNA4mKTMg4QfnUew/5qA29CZz6ALqGcSgNzOICB05gD1rhODJR2AZu3Ox3YOKAfVUPhH" +
"ULtbpdVJ0ccdijw0pY1A56M3Jup7U15jp7X4PPTTecx92/MT9eZwtUICrLJvsB6z0fHG5qbw7mRpFRaOnPYJ6SqXd5AQMSKM" +
"jceyMD4NsULkj1OwHncz5cO3pPvCXXPTMNdNa+kDfwku4q0RnFL8YGBI6N+oXHlgzCkGWGRdONJPK1PbusJrhBltylPBMm3e" +
"G0kw6DGdLhoU3pmgJ6n1maC1fXrs0uUL6cWG/kGVm3MWHh3pALq4+PH55k7Uu3d+x85u9zxwIzfQuU+3TIG5SkOgrS1tCJb3" +
"3nqHrxcx3XlJA6vZJ6Oi1ctaXppQyBQLbLLrPJaKKq+zIexFLrVdZM+r34pJJpNN1hSrWbM/lIyRmKpYRIi7CybTTUzBWt49" +
"11HRM/VbCiZ6Gyt9TZmhGXPS75xYjpH366vhgLJu4ZoZfM+/4FvGaBZIE9aZ2SduMrUT4mJA4NpP8F2AhB+dT+D/jY/7DZ84" +
"ULbaK4C4crJvZ4qej2+em2+Vni4mPluh2e5xyoGUWYRaoFnWubHcaX+L09Ya0ta4KrP13C2ozMyicr4ovY0fNhT2wfMF7ip8" +
"/tD0u96myXcn92gtTnEuGfBJxY0lFG0mJxPWpknjNxmzWvzKj18rpjO4hhQXAtaRVSmJu+D8egI3RdQVXYxzRhs1+HE2iNvM" +
"fVe2DsSjqJQbBdUajcaECC3/58MP97Q0Eo+GNTdKbhk1r7UJadrVj0rLplmAqU/BlGeXDObGLtl69vITp9tD25vVY9vUT17u" +
"WTGW8idcxUDMMX2PHa8X6xzG0C5cGJcVth40m3ycwCpcfuP4OClu6IpysV/9QuvrdW/Yb3Qj6Ul7e3nybqemdkvLXsXG2N3v" +
"qeVE0woXb06pLduuFWUv7NxY8jq1k63fcD5jvG/w/IE8eUNh0Pohz0WRx6tdOlf4XhlbF5pgfYYzn8w6cjYx/8rBXvtWNz8L" +
"6uu+ig35t+dgOc4jOpLirmFPtjQdKHovGZ4Bff4LaIPLnx6cbnKFo8JHDoGpJ1+BwKGfgM6GhB+d+F/0acj3PiVEABoProzN" +
"1dcsVo9TPoPIF+r9EQI0qtveV4WEI1YhFjfmLxDsyFJptHvx/0BD3bfKJY/XqlFTReyIko4tQSzFFRyGRbkyg7MyuCqTmsiA" +
"mAgs3FGB0BOR7LzNuUYMC9QWaXyUTcxELLOFQvaRIQZ1HlgkJtE25Ohym/xzkqxqbFI1fWKsGgKq0m/q9kwkVDJAvdKM+7c8" +
"wj8GVPdneU0GVaeLVO6Kd3T2lMQFRNeCRwUyx5LSIxI5RmIFNc2RnuSIfYOeOZ+0CwzE7BFTJO+5cVeUz2nDN7mMYUSYOZyv" +
"SyyaRRydLKPYMmqFbS5K8RJ6vQNIGtiuI8AKCEgXsqV9Vz1tgvzovKiD2FPtpNgRlb0keoprdS+hnsP6ICwLBrE9dz26g2YP" +
"DszibWNE7zW5xndwlsoqFRh87XTFw8BXiFdv0SDsGBnfNcOu/Qu7y7SLppfzLJq714byzYQ590BA+BN2xyDhR+fZX7CL/s5u" +
"Q9f/8ccWX28U3BaGw9qTiSqDfOtHmXXZq8XiHXAYoz901c5V2lVulTXZEMqwnLq8+8ds95s0FFrdl73saRntr/UuUxFHY0WU" +
"z5b333qXTe/NagSRrmqkqypoNG12Oz3nE5Yzyt7d05eY66Ci2oTR+rNS3K4OiClGK+07HWtFFLvAqv6sNkpFsLs4Wp8XfRp/" +
"11oPk3uTQB0ftHg1C16KRTBl+AbCzVaYfx6VFlJ7GL7Jme8bVOku8FKZL0eGgMVk4qhEnpZogNrtFU5yEyswJ+LbHOKsOPCn" +
"cT19LR+PfTgjN4CKCS5Es4LS+7nLt9hQ7ejwGQnEyxebOgJzlHjotWUACpoZsFkAgGqBeUDZAzB6h4N2MFCNhmIuFJMAgPsH" +
"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());
}
}
}
}
}