mirror of https://github.com/apache/poi.git
Replace Allocate+System.arraycopy with Array.copyOf/Range and IOUtils.safelyClone
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1876640 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
cdefe69aab
commit
7daeb4278c
|
@ -96,7 +96,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||
* @param propertyNumber the property number part of the property id
|
||||
* @param isBlipId {@code true}, if it references a blip
|
||||
* @param complexData the data
|
||||
*
|
||||
*
|
||||
* @deprecated use {@link #EscherArrayProperty(EscherPropertyTypes, boolean, int)} and {@link #setComplexData(byte[])}
|
||||
*/
|
||||
@Deprecated
|
||||
|
@ -124,7 +124,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||
// when called by user code, fix the size to be valid for the header
|
||||
return complexSize == 0 ? 6 : complexSize;
|
||||
}
|
||||
|
||||
|
||||
public int getNumberOfElementsInArray() {
|
||||
return (emptyComplexPart) ? 0 : LittleEndian.getUShort(getComplexData(), 0);
|
||||
}
|
||||
|
@ -171,9 +171,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||
|
||||
public byte[] getElement(int index) {
|
||||
int actualSize = getActualSizeOfElements(getSizeOfElements());
|
||||
byte[] result = IOUtils.safelyAllocate(actualSize, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(getComplexData(), FIXED_SIZE + index * actualSize, result, 0, result.length );
|
||||
return result;
|
||||
return IOUtils.safelyClone(getComplexData(), FIXED_SIZE + index * actualSize, actualSize, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
public void setElement(int index, byte[] element) {
|
||||
|
@ -252,7 +250,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||
public boolean hasNext() {
|
||||
return (idx < getNumberOfElementsInArray());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] next() {
|
||||
if (!hasNext()) {
|
||||
|
@ -260,7 +258,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||
}
|
||||
return getElement(idx++);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("not yet implemented");
|
||||
|
|
|
@ -103,8 +103,8 @@ public final class EscherBSERecord extends EscherRecord {
|
|||
pos += 36 + bytesRead;
|
||||
bytesRemaining -= bytesRead;
|
||||
|
||||
_remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, pos, _remainingData, 0, bytesRemaining );
|
||||
_remainingData = IOUtils.safelyClone(data, pos, bytesRemaining, MAX_RECORD_LENGTH);
|
||||
|
||||
return bytesRemaining + 8 + 36 + (field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize()) ;
|
||||
|
||||
}
|
||||
|
|
|
@ -49,9 +49,7 @@ public class EscherBlipRecord extends EscherRecord {
|
|||
int bytesAfterHeader = readHeader( data, offset );
|
||||
int pos = offset + HEADER_SIZE;
|
||||
|
||||
field_pictureData = IOUtils.safelyAllocate(bytesAfterHeader, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, pos, field_pictureData, 0, bytesAfterHeader);
|
||||
|
||||
field_pictureData = IOUtils.safelyClone(data, pos, bytesAfterHeader, MAX_RECORD_LENGTH);
|
||||
return bytesAfterHeader + 8;
|
||||
}
|
||||
|
||||
|
@ -108,8 +106,7 @@ public class EscherBlipRecord extends EscherRecord {
|
|||
if (pictureData == null || offset < 0 || length < 0 || pictureData.length < offset+length) {
|
||||
throw new IllegalArgumentException("picture data can't be null");
|
||||
}
|
||||
field_pictureData = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(pictureData, offset, field_pictureData, 0, length);
|
||||
field_pictureData = IOUtils.safelyClone(pictureData, offset, length, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -106,8 +106,8 @@ public class EscherClientAnchorRecord extends EscherRecord {
|
|||
}
|
||||
}
|
||||
bytesRemaining -= size;
|
||||
remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
|
||||
remainingData = IOUtils.safelyClone(data, pos + size, bytesRemaining, MAX_RECORD_LENGTH);
|
||||
|
||||
return 8 + size + bytesRemaining;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,8 +50,9 @@ public class EscherClientDataRecord extends EscherRecord {
|
|||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
||||
int bytesRemaining = readHeader( data, offset );
|
||||
int pos = offset + 8;
|
||||
remainingData = (bytesRemaining == 0) ? EMPTY : IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, pos, remainingData, 0, bytesRemaining );
|
||||
|
||||
remainingData = (bytesRemaining == 0) ? EMPTY : IOUtils.safelyClone(data, pos, bytesRemaining, MAX_RECORD_LENGTH);
|
||||
|
||||
return 8 + bytesRemaining;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,14 +45,11 @@ public class EscherDgRecord extends EscherRecord {
|
|||
|
||||
@Override
|
||||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
||||
/*int bytesRemaining =*/ readHeader( data, offset );
|
||||
readHeader( data, offset );
|
||||
int pos = offset + 8;
|
||||
int size = 0;
|
||||
field_1_numShapes = LittleEndian.getInt( data, pos + size ); size += 4;
|
||||
field_2_lastMSOSPID = LittleEndian.getInt( data, pos + size ); size += 4;
|
||||
// bytesRemaining -= size;
|
||||
// remainingData = new byte[bytesRemaining];
|
||||
// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
|
@ -66,8 +63,6 @@ public class EscherDgRecord extends EscherRecord {
|
|||
LittleEndian.putInt( data, offset + 4, 8 );
|
||||
LittleEndian.putInt( data, offset + 8, field_1_numShapes );
|
||||
LittleEndian.putInt( data, offset + 12, field_2_lastMSOSPID );
|
||||
// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
|
||||
// int pos = offset + 8 + 18 + remainingData.length;
|
||||
|
||||
listener.afterRecordSerialize( offset + 16, getRecordId(), getRecordSize(), this );
|
||||
return getRecordSize();
|
||||
|
|
|
@ -106,8 +106,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
|
|||
field_6_fCompression = data[pos]; pos++;
|
||||
field_7_fFilter = data[pos]; pos++;
|
||||
|
||||
raw_pictureData = IOUtils.safelyAllocate(field_5_cbSave, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave );
|
||||
raw_pictureData = IOUtils.safelyClone(data, pos, field_5_cbSave, MAX_RECORD_LENGTH);
|
||||
pos += field_5_cbSave;
|
||||
|
||||
// 0 means DEFLATE compression
|
||||
|
@ -120,8 +119,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
|
|||
|
||||
int remaining = bytesAfterHeader - pos + offset + HEADER_SIZE;
|
||||
if(remaining > 0) {
|
||||
remainingData = IOUtils.safelyAllocate(remaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, pos, remainingData, 0, remaining );
|
||||
remainingData = IOUtils.safelyClone(data, pos, remaining, MAX_RECORD_LENGTH);
|
||||
}
|
||||
return bytesAfterHeader + HEADER_SIZE;
|
||||
}
|
||||
|
|
|
@ -88,14 +88,11 @@ public class EscherSpRecord extends EscherRecord {
|
|||
|
||||
@Override
|
||||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
||||
/*int bytesRemaining =*/ readHeader( data, offset );
|
||||
readHeader( data, offset );
|
||||
int pos = offset + 8;
|
||||
int size = 0;
|
||||
field_1_shapeId = LittleEndian.getInt( data, pos + size ); size += 4;
|
||||
field_2_flags = LittleEndian.getInt( data, pos + size ); size += 4;
|
||||
// bytesRemaining -= size;
|
||||
// remainingData = new byte[bytesRemaining];
|
||||
// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
|
@ -119,8 +116,6 @@ public class EscherSpRecord extends EscherRecord {
|
|||
LittleEndian.putInt( data, offset + 4, remainingBytes );
|
||||
LittleEndian.putInt( data, offset + 8, field_1_shapeId );
|
||||
LittleEndian.putInt( data, offset + 12, field_2_flags );
|
||||
// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
|
||||
// int pos = offset + 8 + 18 + remainingData.length;
|
||||
listener.afterRecordSerialize( offset + getRecordSize(), getRecordId(), getRecordSize(), this );
|
||||
return 8 + 8;
|
||||
}
|
||||
|
|
|
@ -59,8 +59,6 @@ public class EscherSpgrRecord extends EscherRecord {
|
|||
if (bytesRemaining != 0) {
|
||||
throw new RecordFormatException("Expected no remaining bytes but got " + bytesRemaining);
|
||||
}
|
||||
// remainingData = new byte[bytesRemaining];
|
||||
// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
|
||||
return 8 + size + bytesRemaining;
|
||||
}
|
||||
|
||||
|
@ -76,8 +74,6 @@ public class EscherSpgrRecord extends EscherRecord {
|
|||
LittleEndian.putInt( data, offset + 12, field_2_rectY1 );
|
||||
LittleEndian.putInt( data, offset + 16, field_3_rectX2 );
|
||||
LittleEndian.putInt( data, offset + 20, field_4_rectY2 );
|
||||
// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
|
||||
// int pos = offset + 8 + 18 + remainingData.length;
|
||||
listener.afterRecordSerialize( offset + getRecordSize(), getRecordId(), offset + getRecordSize(), this );
|
||||
return 8 + 16;
|
||||
}
|
||||
|
|
|
@ -54,10 +54,8 @@ public final class EscherTextboxRecord extends EscherRecord {
|
|||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
||||
int bytesRemaining = readHeader( data, offset );
|
||||
|
||||
// Save the data, ready for the calling code to do something
|
||||
// useful with it
|
||||
thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining );
|
||||
// Save the data, ready for the calling code to do something useful with it
|
||||
thedata = IOUtils.safelyClone(data, offset + 8, bytesRemaining, MAX_RECORD_LENGTH);
|
||||
return bytesRemaining + 8;
|
||||
}
|
||||
|
||||
|
@ -103,10 +101,8 @@ public final class EscherTextboxRecord extends EscherRecord {
|
|||
* @param start the start position in the buffer
|
||||
* @param length the length of the block
|
||||
*/
|
||||
public void setData(byte[] b, int start, int length)
|
||||
{
|
||||
thedata = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(b,start,thedata,0,length);
|
||||
public void setData(byte[] b, int start, int length) {
|
||||
thedata = IOUtils.safelyClone(b, start, length, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,8 +81,8 @@ public final class UnknownEscherRecord extends EscherRecord {
|
|||
bytesRemaining = 0;
|
||||
}
|
||||
|
||||
thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining );
|
||||
thedata = IOUtils.safelyClone(data, offset + 8, bytesRemaining, MAX_RECORD_LENGTH);
|
||||
|
||||
return bytesRemaining + 8;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.poi.hpsf;
|
||||
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
/**
|
||||
* <p>Class to manipulate data in the Clipboard Variant ({@link
|
||||
|
@ -119,6 +120,9 @@ public final class Thumbnail {
|
|||
*/
|
||||
public static final int CF_BITMAP = 2;
|
||||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 1_000_000;
|
||||
|
||||
/**
|
||||
* <p>A <code>byte[]</code> to hold a thumbnail image in ({@link
|
||||
* Variant#VT_CF VT_CF}) format.</p>
|
||||
|
@ -260,13 +264,6 @@ public final class Thumbnail {
|
|||
"be CF_METAFILEPICT.");
|
||||
}
|
||||
byte[] thumbnail = getThumbnail();
|
||||
int wmfImageLength = thumbnail.length - OFFSET_WMFDATA;
|
||||
byte[] wmfImage = new byte[wmfImageLength];
|
||||
System.arraycopy(thumbnail,
|
||||
OFFSET_WMFDATA,
|
||||
wmfImage,
|
||||
0,
|
||||
wmfImageLength);
|
||||
return wmfImage;
|
||||
return IOUtils.safelyClone(thumbnail, OFFSET_WMFDATA, thumbnail.length - OFFSET_WMFDATA, MAX_RECORD_LENGTH);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,17 +87,17 @@ public abstract class AbstractEscherHolderRecord extends Record {
|
|||
@Override
|
||||
public int serialize(int offset, byte[] data)
|
||||
{
|
||||
LittleEndian.putShort( data, 0 + offset, getSid() );
|
||||
LittleEndian.putShort(data, offset, getSid() );
|
||||
LittleEndian.putShort( data, 2 + offset, (short) ( getRecordSize() - 4 ) );
|
||||
byte[] rawData = getRawData();
|
||||
if ( escherRecords.size() == 0 && rawData != null )
|
||||
{
|
||||
LittleEndian.putShort(data, 0 + offset, getSid());
|
||||
LittleEndian.putShort(data, offset, getSid());
|
||||
LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
|
||||
System.arraycopy( rawData, 0, data, 4 + offset, rawData.length);
|
||||
return rawData.length + 4;
|
||||
}
|
||||
LittleEndian.putShort(data, 0 + offset, getSid());
|
||||
LittleEndian.putShort(data, offset, getSid());
|
||||
LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
|
||||
|
||||
int pos = offset + 4;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -151,8 +152,7 @@ public final class FormatRecord extends StandardRecord {
|
|||
//there can be a remaining byte (without proper final '00')
|
||||
//that should be read as a byte
|
||||
if (ris.available() == 1) {
|
||||
char[] tmp = new char[buf.length+1];
|
||||
System.arraycopy(buf, 0, tmp, 0, buf.length);
|
||||
char[] tmp = Arrays.copyOf(buf, buf.length+1);
|
||||
tmp[buf.length] = (char)ris.readUByte();
|
||||
buf = tmp;
|
||||
}
|
||||
|
|
|
@ -78,9 +78,7 @@ public final class HeaderFooterRecord extends StandardRecord {
|
|||
* @return the sheet view?s GUID
|
||||
*/
|
||||
public byte[] getGuid(){
|
||||
byte[] guid = new byte[16];
|
||||
System.arraycopy(_rawData, 12, guid, 0, guid.length);
|
||||
return guid;
|
||||
return Arrays.copyOfRange(_rawData, 12, 12+16);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -74,9 +75,7 @@ public final class UserSViewBegin extends StandardRecord {
|
|||
* @return Globally unique identifier for the custom view
|
||||
*/
|
||||
public byte[] getGuid(){
|
||||
byte[] guid = new byte[16];
|
||||
System.arraycopy(_rawData, 0, guid, 0, guid.length);
|
||||
return guid;
|
||||
return Arrays.copyOf(_rawData, 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
package org.apache.poi.hssf.record.cont;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.record.ContinueRecord;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
|
||||
/**
|
||||
|
@ -44,7 +44,7 @@ import org.apache.poi.util.LittleEndianInput;
|
|||
*
|
||||
* <p>
|
||||
* YK: For now (March 2011) this class is only used to read
|
||||
* @see org.apache.poi.hssf.record.common.UnicodeString.ExtRst blocks of a UnicodeString.
|
||||
* @see org.apache.poi.hssf.record.common.ExtRst blocks of a UnicodeString.
|
||||
*
|
||||
* </p>
|
||||
*/
|
||||
|
@ -78,7 +78,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
|
|||
public int readUShort(){
|
||||
int ch1 = readUByte();
|
||||
int ch2 = readUByte();
|
||||
return (ch2 << 8) + (ch1 << 0);
|
||||
return (ch2 << 8) + (ch1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,7 +87,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
|
|||
int ch2 = _in.readUByte();
|
||||
int ch3 = _in.readUByte();
|
||||
int ch4 = _in.readUByte();
|
||||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,7 +107,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
|
|||
((long)b3 << 24) +
|
||||
(b2 << 16) +
|
||||
(b1 << 8) +
|
||||
(b0 << 0));
|
||||
(b0));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -124,7 +124,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
|
|||
public void readFully(byte[] buf, int off, int len){
|
||||
_in.readFully(buf, off, len);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void readPlain(byte[] buf, int off, int len) {
|
||||
readFully(buf, off, len);
|
||||
|
|
|
@ -96,7 +96,7 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
|
|||
* A factory method allowing the creation of conditional formatting
|
||||
* rules using an Icon Set / Multi-State formatting.
|
||||
* The thresholds for it will be created, but will be empty
|
||||
* and require configuring with
|
||||
* and require configuring with
|
||||
* {@link HSSFConditionalFormattingRule#getMultiStateFormatting()}
|
||||
* then
|
||||
* {@link HSSFIconMultiStateFormatting#getThresholds()}
|
||||
|
@ -109,12 +109,12 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
|
|||
|
||||
/**
|
||||
* Create a Databar conditional formatting rule.
|
||||
* <p>The thresholds and colour for it will be created, but will be
|
||||
* empty and require configuring with
|
||||
* <p>The thresholds and colour for it will be created, but will be
|
||||
* empty and require configuring with
|
||||
* {@link HSSFConditionalFormattingRule#getDataBarFormatting()}
|
||||
* then
|
||||
* {@link HSSFDataBarFormatting#getMinThreshold()}
|
||||
* and
|
||||
* and
|
||||
* {@link HSSFDataBarFormatting#getMaxThreshold()}
|
||||
*/
|
||||
public HSSFConditionalFormattingRule createConditionalFormattingRule(HSSFExtendedColor color) {
|
||||
|
@ -127,8 +127,8 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
|
|||
|
||||
/**
|
||||
* Create a Color Scale / Color Gradient conditional formatting rule.
|
||||
* <p>The thresholds and colours for it will be created, but will be
|
||||
* empty and require configuring with
|
||||
* <p>The thresholds and colours for it will be created, but will be
|
||||
* empty and require configuring with
|
||||
* {@link HSSFConditionalFormattingRule#getColorScaleFormatting()}
|
||||
* then
|
||||
* {@link HSSFColorScaleFormatting#getThresholds()}
|
||||
|
@ -139,7 +139,7 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
|
|||
CFRule12Record rr = CFRule12Record.createColorScale(_sheet);
|
||||
return new HSSFConditionalFormattingRule(_sheet, rr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a copy of HSSFConditionalFormatting object to the sheet
|
||||
* <p>This method could be used to copy HSSFConditionalFormatting object
|
||||
|
@ -196,8 +196,9 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
|
|||
|
||||
public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {
|
||||
HSSFConditionalFormattingRule[] hfRules;
|
||||
if(cfRules instanceof HSSFConditionalFormattingRule[]) hfRules = (HSSFConditionalFormattingRule[])cfRules;
|
||||
else {
|
||||
if(cfRules instanceof HSSFConditionalFormattingRule[]) {
|
||||
hfRules = (HSSFConditionalFormattingRule[])cfRules;
|
||||
} else {
|
||||
hfRules = new HSSFConditionalFormattingRule[cfRules.length];
|
||||
System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);
|
||||
}
|
||||
|
@ -206,7 +207,7 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
|
|||
|
||||
public int addConditionalFormatting(CellRangeAddress[] regions,
|
||||
HSSFConditionalFormattingRule rule1) {
|
||||
return addConditionalFormatting(regions, rule1 == null ?
|
||||
return addConditionalFormatting(regions, rule1 == null ?
|
||||
null : new HSSFConditionalFormattingRule[] { rule1 }
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import static org.apache.poi.hssf.model.InternalWorkbook.WORKBOOK_DIR_ENTRY_NAME
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -93,10 +92,11 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
|||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||
import org.apache.poi.poifs.filesystem.DocumentNode;
|
||||
import org.apache.poi.poifs.filesystem.EntryUtils;
|
||||
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||
import org.apache.poi.poifs.filesystem.FilteringDirectoryNode;
|
||||
import org.apache.poi.poifs.filesystem.Ole10Native;
|
||||
import org.apache.poi.poifs.filesystem.POIFSDocument;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.poifs.filesystem.Ole10Native;
|
||||
import org.apache.poi.ss.SpreadsheetVersion;
|
||||
import org.apache.poi.ss.formula.FormulaShifter;
|
||||
import org.apache.poi.ss.formula.FormulaType;
|
||||
|
@ -133,6 +133,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
private static final int MAX_IMAGE_LENGTH = 50_000_000;
|
||||
|
||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
||||
|
||||
|
@ -504,13 +505,13 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
|
||||
workbook.updateNamesAfterCellShift(shifter);
|
||||
updateNamedRangesAfterSheetReorder(oldSheetIndex, pos);
|
||||
|
||||
|
||||
updateActiveSheetAfterSheetReorder(oldSheetIndex, pos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy-pasted from XSSFWorkbook#updateNamedRangesAfterSheetReorder(int, int)
|
||||
*
|
||||
*
|
||||
* update sheet-scoped named ranges in this workbook after changing the sheet order
|
||||
* of a sheet at oldIndex to newIndex.
|
||||
* Sheets between these indices will move left or right by 1.
|
||||
|
@ -540,7 +541,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void updateActiveSheetAfterSheetReorder(int oldIndex, int newIndex) {
|
||||
// adjust active sheet if necessary
|
||||
int active = getActiveSheetIndex();
|
||||
|
@ -600,7 +601,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
}
|
||||
setSelectedTabs(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Selects multiple sheets as a group. This is distinct from
|
||||
* the 'active' sheet (which is the sheet with focus).
|
||||
|
@ -624,9 +625,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
short nSelected = (short) set.size();
|
||||
workbook.getWindowOne().setNumSelectedTabs(nSelected);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the selected sheets (if more than one, Excel calls these a [Group]).
|
||||
* Gets the selected sheets (if more than one, Excel calls these a [Group]).
|
||||
*
|
||||
* @return indices of selected sheets
|
||||
*/
|
||||
|
@ -641,7 +642,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
}
|
||||
return Collections.unmodifiableCollection(indexes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to set the active sheet. The active sheet is is the sheet
|
||||
* which is currently displayed when the workbook is viewed in Excel.
|
||||
|
@ -743,7 +744,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
validateSheetIndex(sheetIx);
|
||||
return workbook.isSheetVeryHidden(sheetIx);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SheetVisibility getSheetVisibility(int sheetIx) {
|
||||
return workbook.getSheetVisibility(sheetIx);
|
||||
|
@ -945,7 +946,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
public Iterator<Sheet> iterator() {
|
||||
return sheetIterator();
|
||||
}
|
||||
|
||||
|
||||
private final class SheetIterator<T extends Sheet> implements Iterator<T> {
|
||||
final private Iterator<T> it;
|
||||
private T cursor;
|
||||
|
@ -1294,7 +1295,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
* the Workbook was read, if any.
|
||||
*
|
||||
* <p>Once this has been called, no further
|
||||
* operations, updates or reads should be performed on the
|
||||
* operations, updates or reads should be performed on the
|
||||
* Workbook.
|
||||
*/
|
||||
@Override
|
||||
|
@ -1304,42 +1305,42 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
|
||||
/**
|
||||
* Write out this workbook to the currently open {@link File} via the
|
||||
* writeable {@link POIFSFileSystem} it was opened as.
|
||||
*
|
||||
* writeable {@link POIFSFileSystem} it was opened as.
|
||||
*
|
||||
* <p>This will fail (with an {@link IllegalStateException} if the
|
||||
* Workbook was opened read-only, opened from an {@link InputStream}
|
||||
* instead of a File, or if this is not the root document. For those cases,
|
||||
* you must use {@link #write(OutputStream)} or {@link #write(File)} to
|
||||
* instead of a File, or if this is not the root document. For those cases,
|
||||
* you must use {@link #write(OutputStream)} or {@link #write(File)} to
|
||||
* write to a brand new document.
|
||||
*/
|
||||
@Override
|
||||
public void write() throws IOException {
|
||||
validateInPlaceWritePossible();
|
||||
final DirectoryNode dir = getDirectory();
|
||||
|
||||
|
||||
// Update the Workbook stream in the file
|
||||
DocumentNode workbookNode = (DocumentNode)dir.getEntry(
|
||||
getWorkbookDirEntryName(dir));
|
||||
POIFSDocument workbookDoc = new POIFSDocument(workbookNode);
|
||||
workbookDoc.replaceContents(new ByteArrayInputStream(getBytes()));
|
||||
|
||||
|
||||
// Update the properties streams in the file
|
||||
writeProperties();
|
||||
|
||||
|
||||
// Sync with the File on disk
|
||||
dir.getFileSystem().writeFilesystem();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method write - write out this workbook to a new {@link File}. Constructs
|
||||
* a new POI POIFSFileSystem, passes in the workbook binary representation and
|
||||
* writes it out. If the file exists, it will be replaced, otherwise a new one
|
||||
* will be created.
|
||||
*
|
||||
*
|
||||
* Note that you cannot write to the currently open File using this method.
|
||||
* If you opened your Workbook from a File, you <i>must</i> use the {@link #write()}
|
||||
* method instead!
|
||||
*
|
||||
*
|
||||
* @param newFile The new File you wish to write the XLS to
|
||||
*
|
||||
* @exception IOException if anything can't be written.
|
||||
|
@ -1352,12 +1353,12 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
fs.writeFilesystem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method write - write out this workbook to an {@link OutputStream}. Constructs
|
||||
* a new POI POIFSFileSystem, passes in the workbook binary representation and
|
||||
* writes it out.
|
||||
*
|
||||
*
|
||||
* If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive
|
||||
* or has a high cost/latency associated with each written byte,
|
||||
* consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream}
|
||||
|
@ -1375,7 +1376,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
fs.writeFilesystem(stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Writes the workbook out to a brand new, empty POIFS */
|
||||
private void write(POIFSFileSystem fs) throws IOException {
|
||||
// For tracking what we've written out, used if we're
|
||||
|
@ -1387,7 +1388,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
|
||||
// Write out our HPFS properties, if we have them
|
||||
writeProperties(fs, excepts);
|
||||
|
||||
|
||||
if (preserveNodes) {
|
||||
// Don't write out the old Workbook, we'll be doing our new one
|
||||
// If the file had an "incorrect" name for the workbook stream,
|
||||
|
@ -1457,7 +1458,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
if (log.check( POILogger.DEBUG )) {
|
||||
log.log(DEBUG, "HSSFWorkbook.getBytes()");
|
||||
}
|
||||
|
||||
|
||||
HSSFSheet[] sheets = getSheets();
|
||||
int nSheets = sheets.length;
|
||||
|
||||
|
@ -1502,7 +1503,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
}
|
||||
|
||||
encryptBytes(retval);
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1555,7 +1556,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
throw new EncryptedDocumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*package*/ InternalWorkbook getWorkbook() {
|
||||
return workbook;
|
||||
}
|
||||
|
@ -1873,12 +1874,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
short escherTag;
|
||||
switch (format) {
|
||||
case PICTURE_TYPE_WMF:
|
||||
// remove first 22 bytes if file starts with magic bytes D7-CD-C6-9A
|
||||
// see also http://de.wikipedia.org/wiki/Windows_Metafile#Hinweise_zur_WMF-Spezifikation
|
||||
if (LittleEndian.getInt(pictureData) == 0x9AC6CDD7) {
|
||||
byte[] picDataNoHeader = new byte[pictureData.length - 22];
|
||||
System.arraycopy(pictureData, 22, picDataNoHeader, 0, pictureData.length-22);
|
||||
pictureData = picDataNoHeader;
|
||||
// remove first 22 bytes if file starts with the WMF placeable header
|
||||
if (FileMagic.valueOf(pictureData) == FileMagic.WMF) {
|
||||
pictureData = IOUtils.safelyClone(pictureData, 22, pictureData.length - 22, MAX_IMAGE_LENGTH);
|
||||
}
|
||||
// fall through
|
||||
case PICTURE_TYPE_EMF:
|
||||
|
@ -2047,7 +2045,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
} while (oleDir == null);
|
||||
|
||||
Ole10Native.createOleMarkerEntry(oleDir);
|
||||
|
||||
|
||||
Ole10Native oleNative = new Ole10Native(label, fileName, command, oleData);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
oleNative.writeOut(bos);
|
||||
|
@ -2213,15 +2211,15 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||
public boolean changeExternalReference(String oldUrl, String newUrl) {
|
||||
return workbook.changeExternalReference(oldUrl, newUrl);
|
||||
}
|
||||
|
||||
|
||||
@Internal
|
||||
public InternalWorkbook getInternalWorkbook() {
|
||||
return workbook;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the spreadsheet version (EXCLE97) of this workbook
|
||||
*
|
||||
*
|
||||
* @return EXCEL97 SpreadsheetVersion enum
|
||||
* @since 3.14 beta 2
|
||||
*/
|
||||
|
|
|
@ -135,8 +135,7 @@ public class BinaryRC4Decryptor extends Decryptor {
|
|||
hashAlg.update(salt);
|
||||
}
|
||||
|
||||
hash = new byte[5];
|
||||
System.arraycopy(hashAlg.digest(), 0, hash, 0, 5);
|
||||
hash = Arrays.copyOf(hashAlg.digest(), 5);
|
||||
return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,12 +43,12 @@ public class Ole10Native {
|
|||
/**
|
||||
* Default content of the \u0001Ole entry
|
||||
*/
|
||||
private static final byte[] OLE_MARKER_BYTES =
|
||||
private static final byte[] OLE_MARKER_BYTES =
|
||||
{ 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
private static final String OLE_MARKER_NAME = "\u0001Ole";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// (the fields as they appear in the raw record:)
|
||||
private int totalSize; // 4 bytes, total size of record not including this field
|
||||
private short flags1 = 2; // 2 bytes, unknown, mostly [02 00]
|
||||
|
@ -59,10 +59,10 @@ public class Ole10Native {
|
|||
private String command; // ASCIIZ, stored in this field without the terminating zero
|
||||
private byte[] dataBuffer; // varying size, the actual native data
|
||||
private short flags3; // some final flags? or zero terminators?, sometimes not there
|
||||
|
||||
|
||||
/**
|
||||
* the field encoding mode - merely a try-and-error guess ...
|
||||
**/
|
||||
**/
|
||||
private enum EncodingMode {
|
||||
/**
|
||||
* the data is stored in parsed format - including label, command, etc.
|
||||
|
@ -77,11 +77,11 @@ public class Ole10Native {
|
|||
*/
|
||||
compact
|
||||
}
|
||||
|
||||
|
||||
private EncodingMode mode;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an instance of this class from an embedded OLE Object. The OLE Object is expected
|
||||
* to include a stream "{01}Ole10Native" which contains the actual
|
||||
|
@ -95,7 +95,7 @@ public class Ole10Native {
|
|||
public static Ole10Native createFromEmbeddedOleObject(POIFSFileSystem poifs) throws IOException, Ole10NativeException {
|
||||
return createFromEmbeddedOleObject(poifs.getRoot());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an instance of this class from an embedded OLE Object. The OLE Object is expected
|
||||
* to include a stream "{01}Ole10Native" which contains the actual
|
||||
|
@ -113,7 +113,7 @@ public class Ole10Native {
|
|||
return new Ole10Native(data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an instance and fills the fields based on ... the fields
|
||||
*/
|
||||
|
@ -124,7 +124,7 @@ public class Ole10Native {
|
|||
setDataBuffer(data);
|
||||
mode = EncodingMode.parsed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an instance and fills the fields based on the data in the given buffer.
|
||||
*
|
||||
|
@ -134,14 +134,14 @@ public class Ole10Native {
|
|||
*/
|
||||
public Ole10Native(byte[] data, int offset) throws Ole10NativeException {
|
||||
int ofs = offset; // current offset, initialized to start
|
||||
|
||||
|
||||
if (data.length < offset + 2) {
|
||||
throw new Ole10NativeException("data is too small");
|
||||
}
|
||||
|
||||
|
||||
totalSize = LittleEndian.getInt(data, ofs);
|
||||
ofs += LittleEndianConsts.INT_SIZE;
|
||||
|
||||
|
||||
mode = EncodingMode.unparsed;
|
||||
if (LittleEndian.getShort(data, ofs) == 2) {
|
||||
// some files like equations don't have a valid filename,
|
||||
|
@ -157,36 +157,36 @@ public class Ole10Native {
|
|||
switch (mode) {
|
||||
case parsed: {
|
||||
flags1 = LittleEndian.getShort(data, ofs);
|
||||
|
||||
|
||||
// structured format
|
||||
ofs += LittleEndianConsts.SHORT_SIZE;
|
||||
|
||||
|
||||
int len = getStringLength(data, ofs);
|
||||
label = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
|
||||
ofs += len;
|
||||
|
||||
|
||||
len = getStringLength(data, ofs);
|
||||
fileName = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
|
||||
ofs += len;
|
||||
|
||||
|
||||
flags2 = LittleEndian.getShort(data, ofs);
|
||||
ofs += LittleEndianConsts.SHORT_SIZE;
|
||||
|
||||
|
||||
unknown1 = LittleEndian.getShort(data, ofs);
|
||||
ofs += LittleEndianConsts.SHORT_SIZE;
|
||||
|
||||
|
||||
len = LittleEndian.getInt(data, ofs);
|
||||
ofs += LittleEndianConsts.INT_SIZE;
|
||||
command = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
|
||||
ofs += len;
|
||||
|
||||
|
||||
if (totalSize < ofs) {
|
||||
throw new Ole10NativeException("Invalid Ole10Native");
|
||||
}
|
||||
|
||||
|
||||
dataSize = LittleEndian.getInt(data, ofs);
|
||||
ofs += LittleEndianConsts.INT_SIZE;
|
||||
|
||||
|
||||
if (dataSize < 0 || totalSize - (ofs - LittleEndianConsts.INT_SIZE) < dataSize) {
|
||||
throw new Ole10NativeException("Invalid Ole10Native");
|
||||
}
|
||||
|
@ -206,14 +206,12 @@ public class Ole10Native {
|
|||
if ((long)dataSize + (long)ofs > (long)data.length) { //cast to avoid overflow
|
||||
throw new Ole10NativeException("Invalid Ole10Native: declared data length > available data");
|
||||
}
|
||||
dataBuffer = IOUtils.safelyAllocate(dataSize, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, ofs, dataBuffer, 0, dataSize);
|
||||
ofs += dataSize;
|
||||
dataBuffer = IOUtils.safelyClone(data, ofs, dataSize, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the \1OLE marker entry, which is not the Ole10Native entry.
|
||||
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
|
||||
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
|
||||
* OlePresXXX, but it seems, that they aren't necessary
|
||||
*/
|
||||
public static void createOleMarkerEntry(final DirectoryEntry parent) throws IOException {
|
||||
|
@ -224,14 +222,14 @@ public class Ole10Native {
|
|||
|
||||
/**
|
||||
* Add the \1OLE marker entry, which is not the Ole10Native entry.
|
||||
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
|
||||
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
|
||||
* OlePresXXX, but it seems, that they aren't necessary
|
||||
*/
|
||||
public static void createOleMarkerEntry(final POIFSFileSystem poifs) throws IOException {
|
||||
createOleMarkerEntry(poifs.getRoot());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Helper - determine length of zero terminated string (ASCIIZ).
|
||||
*/
|
||||
|
@ -247,7 +245,7 @@ public class Ole10Native {
|
|||
/**
|
||||
* Returns the value of the totalSize field - the total length of the
|
||||
* structure is totalSize + 4 (value of this field + size of this field).
|
||||
*
|
||||
*
|
||||
* @return the totalSize
|
||||
*/
|
||||
public int getTotalSize() {
|
||||
|
@ -256,7 +254,7 @@ public class Ole10Native {
|
|||
|
||||
/**
|
||||
* Returns flags1 - currently unknown - usually 0x0002.
|
||||
*
|
||||
*
|
||||
* @return the flags1
|
||||
*/
|
||||
public short getFlags1() {
|
||||
|
@ -267,7 +265,7 @@ public class Ole10Native {
|
|||
* Returns the label field - usually the name of the file (without
|
||||
* directory) but probably may be any name specified during
|
||||
* packaging/embedding the data.
|
||||
*
|
||||
*
|
||||
* @return the label
|
||||
*/
|
||||
public String getLabel() {
|
||||
|
@ -277,7 +275,7 @@ public class Ole10Native {
|
|||
/**
|
||||
* Returns the fileName field - usually the name of the file being embedded
|
||||
* including the full path.
|
||||
*
|
||||
*
|
||||
* @return the fileName
|
||||
*/
|
||||
public String getFileName() {
|
||||
|
@ -286,7 +284,7 @@ public class Ole10Native {
|
|||
|
||||
/**
|
||||
* Returns flags2 - currently unknown - mostly 0x0000.
|
||||
*
|
||||
*
|
||||
* @return the flags2
|
||||
*/
|
||||
public short getFlags2() {
|
||||
|
@ -295,7 +293,7 @@ public class Ole10Native {
|
|||
|
||||
/**
|
||||
* Returns unknown1 field - currently unknown.
|
||||
*
|
||||
*
|
||||
* @return the unknown1
|
||||
*/
|
||||
public short getUnknown1() {
|
||||
|
@ -306,7 +304,7 @@ public class Ole10Native {
|
|||
* Returns the command field - usually the name of the file being embedded
|
||||
* including the full path, may be a command specified during embedding the
|
||||
* file.
|
||||
*
|
||||
*
|
||||
* @return the command
|
||||
*/
|
||||
public String getCommand() {
|
||||
|
@ -317,7 +315,7 @@ public class Ole10Native {
|
|||
* Returns the size of the embedded file. If the size is 0 (zero), no data
|
||||
* has been embedded. To be sure, that no data has been embedded, check
|
||||
* whether {@link #getDataBuffer()} returns <code>null</code>.
|
||||
*
|
||||
*
|
||||
* @return the dataSize
|
||||
*/
|
||||
public int getDataSize() {
|
||||
|
@ -330,7 +328,7 @@ public class Ole10Native {
|
|||
* provide information about the data, but the actual data is not included.
|
||||
* (So label, filename etc. are available, but this method returns
|
||||
* <code>null</code>.)
|
||||
*
|
||||
*
|
||||
* @return the dataBuffer
|
||||
*/
|
||||
public byte[] getDataBuffer() {
|
||||
|
@ -339,7 +337,7 @@ public class Ole10Native {
|
|||
|
||||
/**
|
||||
* Returns the flags3 - currently unknown.
|
||||
*
|
||||
*
|
||||
* @return the flags3
|
||||
*/
|
||||
public short getFlags3() {
|
||||
|
@ -358,7 +356,7 @@ public class Ole10Native {
|
|||
|
||||
@SuppressWarnings("resource")
|
||||
LittleEndianOutputStream leosOut = new LittleEndianOutputStream(out);
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case parsed: {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
@ -379,7 +377,7 @@ public class Ole10Native {
|
|||
leos.write(getDataBuffer());
|
||||
leos.writeShort(getFlags3());
|
||||
leos.close(); // satisfy compiler ...
|
||||
|
||||
|
||||
leosOut.writeInt(bos.size()); // total size
|
||||
bos.writeTo(out);
|
||||
break;
|
||||
|
|
|
@ -124,19 +124,13 @@ public abstract class Property implements Child, POIFSViewable {
|
|||
*/
|
||||
protected Property(int index, byte [] array, int offset)
|
||||
{
|
||||
_raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ];
|
||||
System.arraycopy(array, offset, _raw_data, 0,
|
||||
POIFSConstants.PROPERTY_SIZE);
|
||||
_raw_data = Arrays.copyOfRange(array, offset, offset + POIFSConstants.PROPERTY_SIZE);
|
||||
_name_size = new ShortField(_name_size_offset, _raw_data);
|
||||
_property_type =
|
||||
new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data);
|
||||
_property_type = new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data);
|
||||
_node_color = new ByteField(_node_color_offset, _raw_data);
|
||||
_previous_property = new IntegerField(_previous_property_offset,
|
||||
_raw_data);
|
||||
_next_property = new IntegerField(_next_property_offset,
|
||||
_raw_data);
|
||||
_child_property = new IntegerField(_child_property_offset,
|
||||
_raw_data);
|
||||
_previous_property = new IntegerField(_previous_property_offset, _raw_data);
|
||||
_next_property = new IntegerField(_next_property_offset, _raw_data);
|
||||
_child_property = new IntegerField(_child_property_offset, _raw_data);
|
||||
_storage_clsid = new ClassID(_raw_data,_storage_clsid_offset);
|
||||
_user_flags = new IntegerField(_user_flags_offset, 0, _raw_data);
|
||||
_seconds_1 = new IntegerField(_seconds_1_offset, _raw_data);
|
||||
|
@ -146,8 +140,7 @@ public abstract class Property implements Child, POIFSViewable {
|
|||
_start_block = new IntegerField(_start_block_offset, _raw_data);
|
||||
_size = new IntegerField(_size_offset, _raw_data);
|
||||
_index = index;
|
||||
int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE)
|
||||
- 1;
|
||||
int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE) - 1;
|
||||
|
||||
if (name_length < 1)
|
||||
{
|
||||
|
|
|
@ -245,8 +245,7 @@ public class EmbeddedExtractor implements Iterable<EmbeddedExtractor> {
|
|||
}
|
||||
|
||||
int pictureBytesLen = idxEnd-idxStart+6;
|
||||
byte[] pdfBytes = IOUtils.safelyAllocate(pictureBytesLen, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(pictureBytes, idxStart, pdfBytes, 0, pictureBytesLen);
|
||||
byte[] pdfBytes = IOUtils.safelyClone(pictureBytes, idxStart, pictureBytesLen, MAX_RECORD_LENGTH);
|
||||
String filename = source.getShapeName().trim();
|
||||
if (!endsWithIgnoreCase(filename, ".pdf")) {
|
||||
filename += ".pdf";
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.apache.poi.ss.formula.functions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.formula.eval.EvaluationException;
|
||||
|
||||
|
@ -60,8 +62,7 @@ public class Mirr extends MultiOperandNumericFunction {
|
|||
double financeRate = values[values.length-1];
|
||||
double reinvestRate = values[values.length-2];
|
||||
|
||||
double[] mirrValues = new double[values.length - 2];
|
||||
System.arraycopy(values, 0, mirrValues, 0, mirrValues.length);
|
||||
double[] mirrValues = Arrays.copyOf(values, values.length - 2);
|
||||
|
||||
boolean mirrValuesAreAllNegatives = true;
|
||||
for (double mirrValue : mirrValues) {
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.poi.ss.formula.functions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.ss.SpreadsheetVersion;
|
||||
import org.apache.poi.ss.formula.ThreeDEval;
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
|
@ -67,20 +69,13 @@ public abstract class MultiOperandNumericFunction implements Function {
|
|||
}
|
||||
|
||||
public double[] toArray() {
|
||||
if (_count < 1) {
|
||||
return EMPTY_DOUBLE_ARRAY;
|
||||
}
|
||||
double[] result = new double[_count];
|
||||
System.arraycopy(_array, 0, result, 0, _count);
|
||||
return result;
|
||||
return _count < 1 ? EMPTY_DOUBLE_ARRAY : Arrays.copyOf(_array, _count);
|
||||
}
|
||||
|
||||
private void ensureCapacity(int reqSize) {
|
||||
if (reqSize > _array.length) {
|
||||
int newSize = reqSize * 3 / 2; // grow with 50% extra
|
||||
double[] newArr = new double[newSize];
|
||||
System.arraycopy(_array, 0, newArr, 0, _count);
|
||||
_array = newArr;
|
||||
_array = Arrays.copyOf(_array, newSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +154,7 @@ public abstract class MultiOperandNumericFunction implements Function {
|
|||
public boolean isHiddenRowCounted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects values from a single argument
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.poi.ss.formula.functions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.formula.eval.EvaluationException;
|
||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||
|
@ -43,8 +45,7 @@ public final class Npv implements Function {
|
|||
try {
|
||||
double rate = NumericFunction.singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
|
||||
// convert tail arguments into an array of doubles
|
||||
ValueEval[] vargs = new ValueEval[args.length-1];
|
||||
System.arraycopy(args, 1, vargs, 0, vargs.length);
|
||||
ValueEval[] vargs = Arrays.copyOfRange(args, 1, args.length, ValueEval[].class);
|
||||
double[] values = AggregateFunction.ValueCollector.collectValues(vargs);
|
||||
|
||||
double result = FinanceLib.npv(rate, values);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.poi.ss.formula.functions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.ss.formula.TwoDEval;
|
||||
import org.apache.poi.ss.formula.eval.AreaEval;
|
||||
import org.apache.poi.ss.formula.eval.BlankEval;
|
||||
|
@ -124,9 +126,9 @@ public final class Sumproduct implements Function {
|
|||
|
||||
private static ValueEval evaluateAreaSumProduct(ValueEval[] evalArgs) throws EvaluationException {
|
||||
int maxN = evalArgs.length;
|
||||
TwoDEval[] args = new TwoDEval[maxN];
|
||||
TwoDEval[] args;
|
||||
try {
|
||||
System.arraycopy(evalArgs, 0, args, 0, maxN);
|
||||
args = Arrays.copyOf(evalArgs, maxN, TwoDEval[].class);
|
||||
} catch (ArrayStoreException e) {
|
||||
// one of the other args was not an AreaRef
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
package org.apache.poi.util;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Utility classes for dealing with arrays.
|
||||
*/
|
||||
|
@ -54,8 +56,7 @@ public final class ArrayUtil {
|
|||
}
|
||||
|
||||
// Grab the bit to move
|
||||
Object[] toMove = new Object[numToMove];
|
||||
System.arraycopy(array, moveFrom, toMove, 0, numToMove);
|
||||
Object[] toMove = Arrays.copyOfRange(array, moveFrom, moveFrom+numToMove);
|
||||
|
||||
// Grab the bit to be shifted
|
||||
Object[] toShift;
|
||||
|
@ -63,14 +64,12 @@ public final class ArrayUtil {
|
|||
if(moveFrom > moveTo) {
|
||||
// Moving to an earlier point in the array
|
||||
// Grab everything between the two points
|
||||
toShift = new Object[(moveFrom-moveTo)];
|
||||
System.arraycopy(array, moveTo, toShift, 0, toShift.length);
|
||||
toShift = Arrays.copyOfRange(array, moveTo, moveFrom);
|
||||
shiftTo = moveTo + numToMove;
|
||||
} else {
|
||||
// Moving to a later point in the array
|
||||
// Grab everything from after the toMove block, to the new point
|
||||
toShift = new Object[(moveTo-moveFrom)];
|
||||
System.arraycopy(array, moveFrom+numToMove, toShift, 0, toShift.length);
|
||||
toShift = Arrays.copyOfRange(array, moveFrom+numToMove, moveTo+numToMove);
|
||||
shiftTo = moveFrom;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.io.OutputStream;
|
|||
import java.io.PushbackInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
|
@ -35,6 +36,8 @@ import org.apache.poi.EmptyFileException;
|
|||
import org.apache.poi.POIDocument;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
|
||||
@Internal
|
||||
public final class IOUtils {
|
||||
private static final POILogger logger = POILogFactory.getLogger( IOUtils.class );
|
||||
|
||||
|
@ -610,6 +613,18 @@ public final class IOUtils {
|
|||
checkLength(length, maxLength);
|
||||
}
|
||||
|
||||
public static byte[] safelyClone(byte[] src, int offset, int length, int maxLength) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
assert(offset >= 0 && length >= 0 && maxLength >= 0);
|
||||
safelyAllocateCheck(Math.min(src.length-offset,length), maxLength);
|
||||
return Arrays.copyOfRange(src, offset, offset+length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Simple utility function to check that you haven't hit EOF
|
||||
* when reading a byte.
|
||||
|
|
|
@ -26,93 +26,38 @@ import java.io.Serializable;
|
|||
* a utility class for handling little-endian numbers, which the 80x86 world is
|
||||
* replete with. The methods are all static, and input/output is from/to byte
|
||||
* arrays, or from InputStreams.
|
||||
*
|
||||
* @author Marc Johnson (mjohnson at apache dot org)
|
||||
* @author Andrew Oliver (acoliver at apache dot org)
|
||||
*/
|
||||
public class LittleEndian implements LittleEndianConsts
|
||||
{
|
||||
@Internal
|
||||
public final class LittleEndian implements LittleEndianConsts {
|
||||
|
||||
/**
|
||||
* Exception to handle buffer underruns
|
||||
*
|
||||
*
|
||||
* @author Marc Johnson (mjohnson at apache dot org)
|
||||
*/
|
||||
public static final class BufferUnderrunException extends IOException
|
||||
{
|
||||
public static final class BufferUnderrunException extends IOException {
|
||||
/**
|
||||
* Serial version UID
|
||||
*
|
||||
*
|
||||
* @see Serializable
|
||||
*/
|
||||
private static final long serialVersionUID = 8736973884877006145L;
|
||||
|
||||
BufferUnderrunException()
|
||||
{
|
||||
BufferUnderrunException() {
|
||||
super( "buffer underrun" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a portion of a byte array
|
||||
*
|
||||
* @param data
|
||||
* the original byte array
|
||||
* @param offset
|
||||
* Where to start copying from.
|
||||
* @param size
|
||||
* Number of bytes to copy.
|
||||
* @return The byteArray value
|
||||
*
|
||||
* @see #getByteArray(byte[], int, int, int) if size is not a constant
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* - if copying would cause access of data outside array bounds.
|
||||
*/
|
||||
public static byte[] getByteArray( byte[] data, int offset, int size )
|
||||
{
|
||||
byte[] copy = new byte[size];
|
||||
System.arraycopy( data, offset, copy, 0, size );
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a portion of a byte array
|
||||
*
|
||||
* @param data
|
||||
* the original byte array
|
||||
* @param offset
|
||||
* Where to start copying from.
|
||||
* @param size
|
||||
* Number of bytes to copy.
|
||||
* @param maxSize
|
||||
* Size must be <= maxSize or an exception is thrown.
|
||||
* Use this to avoid potential OOMs on corrupt data.
|
||||
* @return The byteArray value
|
||||
* @throws IndexOutOfBoundsException
|
||||
* - if copying would cause access of data outside array bounds.
|
||||
*/
|
||||
public static byte[] getByteArray( byte[] data, int offset, int size, int maxSize)
|
||||
{
|
||||
byte[] copy = IOUtils.safelyAllocate(size, maxSize);
|
||||
System.arraycopy( data, offset, copy, 0, size );
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get a double value from a byte array, reads it in little endian format
|
||||
* then converts the resulting revolting IEEE 754 (curse them) floating
|
||||
* point number to a happy java double
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the double (64-bit) value
|
||||
*/
|
||||
public static double getDouble( byte[] data )
|
||||
{
|
||||
public static double getDouble( byte[] data ) {
|
||||
return Double.longBitsToDouble( getLong( data, 0 ) );
|
||||
}
|
||||
|
||||
|
@ -120,15 +65,14 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* get a double value from a byte array, reads it in little endian format
|
||||
* then converts the resulting revolting IEEE 754 (curse them) floating
|
||||
* point number to a happy java double
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the double (64-bit) value
|
||||
*/
|
||||
public static double getDouble( byte[] data, int offset )
|
||||
{
|
||||
public static double getDouble( byte[] data, int offset ) {
|
||||
return Double.longBitsToDouble( getLong( data, offset ) );
|
||||
}
|
||||
|
||||
|
@ -136,13 +80,12 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* get a float value from a byte array, reads it in little endian format
|
||||
* then converts the resulting revolting IEEE 754 (curse them) floating
|
||||
* point number to a happy java float
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the double (64-bit) value
|
||||
*/
|
||||
public static float getFloat( byte[] data )
|
||||
{
|
||||
public static float getFloat( byte[] data ) {
|
||||
return getFloat( data, 0 );
|
||||
}
|
||||
|
||||
|
@ -150,72 +93,67 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* get a float value from a byte array, reads it in little endian format
|
||||
* then converts the resulting revolting IEEE 754 (curse them) floating
|
||||
* point number to a happy java float
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the double (64-bit) value
|
||||
*/
|
||||
public static float getFloat( byte[] data, int offset )
|
||||
{
|
||||
public static float getFloat( byte[] data, int offset ) {
|
||||
return Float.intBitsToFloat( getInt( data, offset ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* get an int value from the beginning of a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the int (32-bit) value
|
||||
*/
|
||||
public static int getInt( byte[] data )
|
||||
{
|
||||
public static int getInt( byte[] data ) {
|
||||
return getInt( data, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* get an int value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the int (32-bit) value
|
||||
*/
|
||||
public static int getInt( byte[] data, int offset )
|
||||
{
|
||||
public static int getInt( byte[] data, int offset ) {
|
||||
int i = offset;
|
||||
int b0 = data[i++] & 0xFF;
|
||||
int b1 = data[i++] & 0xFF;
|
||||
int b2 = data[i++] & 0xFF;
|
||||
int b3 = data[i++] & 0xFF;
|
||||
return ( b3 << 24 ) + ( b2 << 16 ) + ( b1 << 8 ) + ( b0 << 0 );
|
||||
int b3 = data[i ] & 0xFF;
|
||||
return ( b3 << 24 ) + ( b2 << 16 ) + ( b1 << 8 ) + (b0);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a long value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the long (64-bit) value
|
||||
*/
|
||||
public static long getLong( byte[] data )
|
||||
{
|
||||
public static long getLong( byte[] data ) {
|
||||
return getLong( data, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* get a long value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the long (64-bit) value
|
||||
*/
|
||||
public static long getLong( byte[] data, int offset )
|
||||
{
|
||||
public static long getLong( byte[] data, int offset ) {
|
||||
long result = 0xff & data[offset + 7];
|
||||
|
||||
for ( int j = offset + LONG_SIZE - 1; j >= offset; j-- )
|
||||
|
@ -228,35 +166,33 @@ public class LittleEndian implements LittleEndianConsts
|
|||
|
||||
/**
|
||||
* get a short value from the beginning of a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the short (16-bit) value
|
||||
*/
|
||||
public static short getShort( byte[] data )
|
||||
{
|
||||
public static short getShort( byte[] data ) {
|
||||
return getShort( data, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* get a short value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the short (16-bit) value
|
||||
*/
|
||||
public static short getShort( byte[] data, int offset )
|
||||
{
|
||||
public static short getShort( byte[] data, int offset ) {
|
||||
int b0 = data[offset] & 0xFF;
|
||||
int b1 = data[offset + 1] & 0xFF;
|
||||
return (short) ( ( b1 << 8 ) + ( b0 << 0 ) );
|
||||
return (short) ( ( b1 << 8 ) + (b0) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read short array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the original byte array
|
||||
* @param offset
|
||||
|
@ -266,8 +202,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IndexOutOfBoundsException
|
||||
* - if read would cause access of data outside array bounds.
|
||||
*/
|
||||
public static short[] getShortArray( byte[] data, int offset, int size )
|
||||
{
|
||||
public static short[] getShortArray( byte[] data, int offset, int size ) {
|
||||
short[] result = new short[size / SHORT_SIZE];
|
||||
for ( int i = 0; i < result.length; i++ )
|
||||
{
|
||||
|
@ -278,83 +213,77 @@ public class LittleEndian implements LittleEndianConsts
|
|||
|
||||
/**
|
||||
* get the unsigned value of a byte.
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array.
|
||||
* @return the unsigned value of the byte as a 16 bit short
|
||||
*/
|
||||
public static short getUByte( byte[] data )
|
||||
{
|
||||
public static short getUByte( byte[] data ) {
|
||||
return (short) ( data[0] & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* get the unsigned value of a byte.
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array.
|
||||
* @param offset
|
||||
* a starting offset into the byte array.
|
||||
* @return the unsigned value of the byte as a 16 bit short
|
||||
*/
|
||||
public static short getUByte( byte[] data, int offset )
|
||||
{
|
||||
public static short getUByte( byte[] data, int offset ) {
|
||||
return (short) ( data[offset] & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* get an unsigned int value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the unsigned int (32-bit) value in a long
|
||||
*/
|
||||
public static long getUInt( byte[] data )
|
||||
{
|
||||
public static long getUInt( byte[] data ) {
|
||||
return getUInt( data, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* get an unsigned int value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the unsigned int (32-bit) value in a long
|
||||
*/
|
||||
public static long getUInt( byte[] data, int offset )
|
||||
{
|
||||
public static long getUInt( byte[] data, int offset ) {
|
||||
long retNum = getInt( data, offset );
|
||||
return retNum & 0x00FFFFFFFFl;
|
||||
return retNum & 0x00FFFFFFFFL;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an unsigned short value from the beginning of a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @return the unsigned short (16-bit) value in an int
|
||||
*/
|
||||
public static int getUShort( byte[] data )
|
||||
{
|
||||
public static int getUShort( byte[] data ) {
|
||||
return getUShort( data, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* get an unsigned short value from a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @return the unsigned short (16-bit) value in an integer
|
||||
*/
|
||||
public static int getUShort( byte[] data, int offset )
|
||||
{
|
||||
public static int getUShort( byte[] data, int offset ) {
|
||||
int b0 = data[offset] & 0xFF;
|
||||
int b1 = data[offset + 1] & 0xFF;
|
||||
return ( b1 << 8 ) + ( b0 << 0 );
|
||||
return ( b1 << 8 ) + (b0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -366,14 +295,13 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* </p>
|
||||
* Added for consistency with other put~() methods
|
||||
*/
|
||||
public static void putByte( byte[] data, int offset, int value )
|
||||
{
|
||||
public static void putByte( byte[] data, int offset, int value ) {
|
||||
data[offset] = (byte) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* put a double value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
|
@ -381,14 +309,13 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @param value
|
||||
* the double (64-bit) value
|
||||
*/
|
||||
public static void putDouble( byte[] data, int offset, double value )
|
||||
{
|
||||
public static void putDouble( byte[] data, int offset, double value ) {
|
||||
putLong( data, offset, Double.doubleToLongBits( value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* put a double value into a byte array
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the double (64-bit) value
|
||||
* @param outputStream
|
||||
|
@ -396,15 +323,13 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putDouble( double value, OutputStream outputStream )
|
||||
throws IOException
|
||||
{
|
||||
public static void putDouble( double value, OutputStream outputStream ) throws IOException {
|
||||
putLong( Double.doubleToLongBits( value ), outputStream );
|
||||
}
|
||||
|
||||
/**
|
||||
* put a float value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
|
@ -412,14 +337,13 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @param value
|
||||
* the float (32-bit) value
|
||||
*/
|
||||
public static void putFloat( byte[] data, int offset, float value )
|
||||
{
|
||||
public static void putFloat( byte[] data, int offset, float value ) {
|
||||
putInt( data, offset, Float.floatToIntBits( value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* put a float value into a byte array
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the float (32-bit) value
|
||||
* @param outputStream
|
||||
|
@ -427,15 +351,14 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putFloat( float value, OutputStream outputStream )
|
||||
throws IOException
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
public static void putFloat(float value, OutputStream outputStream ) throws IOException {
|
||||
putInt( Float.floatToIntBits( value ), outputStream );
|
||||
}
|
||||
|
||||
/**
|
||||
* put an int value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
|
@ -443,18 +366,17 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @param value
|
||||
* the int (32-bit) value
|
||||
*/
|
||||
public static void putInt( byte[] data, int offset, int value )
|
||||
{
|
||||
public static void putInt( byte[] data, int offset, int value ) {
|
||||
int i = offset;
|
||||
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 16 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 24 ) & 0xFF );
|
||||
data[i] = (byte) ( ( value >>> 24 ) & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* Put int into output stream
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the int (32-bit) value
|
||||
* @param outputStream
|
||||
|
@ -462,18 +384,16 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putInt( int value, OutputStream outputStream )
|
||||
throws IOException
|
||||
{
|
||||
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
public static void putInt( int value, OutputStream outputStream ) throws IOException {
|
||||
outputStream.write( (byte) ( ( value ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* put a long value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
|
@ -481,10 +401,9 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @param value
|
||||
* the long (64-bit) value
|
||||
*/
|
||||
public static void putLong( byte[] data, int offset, long value )
|
||||
{
|
||||
data[offset + 0] = (byte) ( ( value >>> 0 ) & 0xFF );
|
||||
data[offset + 1] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
public static void putLong( byte[] data, int offset, long value ) {
|
||||
data[offset ] = (byte) ( ( value ) & 0xFF );
|
||||
data[offset + 1] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[offset + 2] = (byte) ( ( value >>> 16 ) & 0xFF );
|
||||
data[offset + 3] = (byte) ( ( value >>> 24 ) & 0xFF );
|
||||
data[offset + 4] = (byte) ( ( value >>> 32 ) & 0xFF );
|
||||
|
@ -495,7 +414,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
|
||||
/**
|
||||
* Put long into output stream
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the long (64-bit) value
|
||||
* @param outputStream
|
||||
|
@ -503,11 +422,9 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putLong( long value, OutputStream outputStream )
|
||||
throws IOException
|
||||
{
|
||||
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
public static void putLong( long value, OutputStream outputStream ) throws IOException {
|
||||
outputStream.write( (byte) ( ( value ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 32 ) & 0xFF ) );
|
||||
|
@ -518,7 +435,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
|
||||
/**
|
||||
* put a short value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
|
@ -526,16 +443,15 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @param value
|
||||
* the short (16-bit) value
|
||||
*/
|
||||
public static void putShort( byte[] data, int offset, short value )
|
||||
{
|
||||
public static void putShort( byte[] data, int offset, short value ) {
|
||||
int i = offset;
|
||||
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value ) & 0xFF );
|
||||
data[i ] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* Put signed short into output stream
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the short (16-bit) value
|
||||
* @param outputStream
|
||||
|
@ -543,16 +459,14 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putShort( OutputStream outputStream, short value )
|
||||
throws IOException
|
||||
{
|
||||
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||
public static void putShort( OutputStream outputStream, short value ) throws IOException {
|
||||
outputStream.write( (byte) ( ( value ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores short array in buffer
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param startOffset
|
||||
|
@ -560,9 +474,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @param value
|
||||
* the short (16-bit) values
|
||||
*/
|
||||
public static void putShortArray( byte[] data, int startOffset,
|
||||
short[] value )
|
||||
{
|
||||
public static void putShortArray( byte[] data, int startOffset, short[] value ) {
|
||||
int offset = startOffset;
|
||||
for ( short s : value )
|
||||
{
|
||||
|
@ -573,47 +485,45 @@ public class LittleEndian implements LittleEndianConsts
|
|||
|
||||
/**
|
||||
* put an unsigned byte value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @param value
|
||||
* the short (16-bit) value
|
||||
*
|
||||
*
|
||||
* @exception ArrayIndexOutOfBoundsException
|
||||
* may be thrown
|
||||
*/
|
||||
public static void putUByte( byte[] data, int offset, short value )
|
||||
{
|
||||
public static void putUByte( byte[] data, int offset, short value ) {
|
||||
data[offset] = (byte) ( value & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* put an unsigned int value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @param value
|
||||
* the int (32-bit) value
|
||||
*
|
||||
*
|
||||
* @exception ArrayIndexOutOfBoundsException
|
||||
* may be thrown
|
||||
*/
|
||||
public static void putUInt( byte[] data, int offset, long value )
|
||||
{
|
||||
public static void putUInt( byte[] data, int offset, long value ) {
|
||||
int i = offset;
|
||||
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 16 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 24 ) & 0xFF );
|
||||
data[i ] = (byte) ( ( value >>> 24 ) & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* Put unsigned int into output stream
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the int (32-bit) value
|
||||
* @param outputStream
|
||||
|
@ -621,38 +531,35 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putUInt( long value, OutputStream outputStream )
|
||||
throws IOException
|
||||
{
|
||||
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
public static void putUInt( long value, OutputStream outputStream ) throws IOException {
|
||||
outputStream.write( (byte) ( ( value ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* put an unsigned short value into a byte array
|
||||
*
|
||||
*
|
||||
* @param data
|
||||
* the byte array
|
||||
* @param offset
|
||||
* a starting offset into the byte array
|
||||
* @param value
|
||||
* the short (16-bit) value
|
||||
*
|
||||
*
|
||||
* @exception ArrayIndexOutOfBoundsException
|
||||
* may be thrown
|
||||
*/
|
||||
public static void putUShort( byte[] data, int offset, int value )
|
||||
{
|
||||
public static void putUShort( byte[] data, int offset, int value ) {
|
||||
int i = offset;
|
||||
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
data[i++] = (byte) ( ( value ) & 0xFF );
|
||||
data[i ] = (byte) ( ( value >>> 8 ) & 0xFF );
|
||||
}
|
||||
|
||||
/**
|
||||
* Put unsigned short into output stream
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* the unsigned short (16-bit) value
|
||||
* @param outputStream
|
||||
|
@ -660,16 +567,14 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
public static void putUShort( int value, OutputStream outputStream )
|
||||
throws IOException
|
||||
{
|
||||
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
|
||||
public static void putUShort( int value, OutputStream outputStream ) throws IOException {
|
||||
outputStream.write( (byte) ( ( value ) & 0xFF ) );
|
||||
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* get an int value from an InputStream
|
||||
*
|
||||
*
|
||||
* @param stream
|
||||
* the InputStream from which the int is to be read
|
||||
* @return the int (32-bit) value
|
||||
|
@ -678,9 +583,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @exception BufferUnderrunException
|
||||
* if the stream cannot provide enough bytes
|
||||
*/
|
||||
public static int readInt( InputStream stream ) throws IOException,
|
||||
BufferUnderrunException
|
||||
{
|
||||
public static int readInt( InputStream stream ) throws IOException {
|
||||
int ch1 = stream.read();
|
||||
int ch2 = stream.read();
|
||||
int ch3 = stream.read();
|
||||
|
@ -689,12 +592,12 @@ public class LittleEndian implements LittleEndianConsts
|
|||
{
|
||||
throw new BufferUnderrunException();
|
||||
}
|
||||
return ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 );
|
||||
return ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get an unsigned int value from an InputStream
|
||||
*
|
||||
*
|
||||
* @param stream
|
||||
* the InputStream from which the int is to be read
|
||||
* @return the unsigned int (32-bit) value
|
||||
|
@ -703,16 +606,14 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @exception BufferUnderrunException
|
||||
* if the stream cannot provide enough bytes
|
||||
*/
|
||||
public static long readUInt( InputStream stream ) throws IOException,
|
||||
BufferUnderrunException
|
||||
{
|
||||
public static long readUInt( InputStream stream ) throws IOException {
|
||||
long retNum = readInt(stream);
|
||||
return retNum & 0x00FFFFFFFFl;
|
||||
return retNum & 0x00FFFFFFFFL;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a long value from an InputStream
|
||||
*
|
||||
*
|
||||
* @param stream
|
||||
* the InputStream from which the long is to be read
|
||||
* @return the long (64-bit) value
|
||||
|
@ -721,9 +622,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @exception BufferUnderrunException
|
||||
* if the stream cannot provide enough bytes
|
||||
*/
|
||||
public static long readLong( InputStream stream ) throws IOException,
|
||||
BufferUnderrunException
|
||||
{
|
||||
public static long readLong( InputStream stream ) throws IOException {
|
||||
int ch1 = stream.read();
|
||||
int ch2 = stream.read();
|
||||
int ch3 = stream.read();
|
||||
|
@ -732,8 +631,7 @@ public class LittleEndian implements LittleEndianConsts
|
|||
int ch6 = stream.read();
|
||||
int ch7 = stream.read();
|
||||
int ch8 = stream.read();
|
||||
if ( ( ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8 ) < 0 )
|
||||
{
|
||||
if ( ( ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8 ) < 0 ) {
|
||||
throw new BufferUnderrunException();
|
||||
}
|
||||
|
||||
|
@ -741,12 +639,12 @@ public class LittleEndian implements LittleEndianConsts
|
|||
+ ( (long) ch6 << 40 ) + ( (long) ch5 << 32 )
|
||||
+ ( (long) ch4 << 24 ) + // cast to long to preserve bit 31
|
||||
// (sign bit for ints)
|
||||
( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 );
|
||||
( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* get a short value from an InputStream
|
||||
*
|
||||
*
|
||||
* @param stream
|
||||
* the InputStream from which the short is to be read
|
||||
* @return the short (16-bit) value
|
||||
|
@ -755,39 +653,32 @@ public class LittleEndian implements LittleEndianConsts
|
|||
* @exception BufferUnderrunException
|
||||
* if the stream cannot provide enough bytes
|
||||
*/
|
||||
public static short readShort( InputStream stream ) throws IOException,
|
||||
BufferUnderrunException
|
||||
{
|
||||
public static short readShort( InputStream stream ) throws IOException {
|
||||
return (short) readUShort( stream );
|
||||
}
|
||||
|
||||
public static int readUShort( InputStream stream ) throws IOException,
|
||||
BufferUnderrunException
|
||||
{
|
||||
public static int readUShort( InputStream stream ) throws IOException {
|
||||
int ch1 = stream.read();
|
||||
int ch2 = stream.read();
|
||||
if ( ( ch1 | ch2 ) < 0 )
|
||||
{
|
||||
if ( ( ch1 | ch2 ) < 0 ) {
|
||||
throw new BufferUnderrunException();
|
||||
}
|
||||
return ( ch2 << 8 ) + ( ch1 << 0 );
|
||||
return ( ch2 << 8 ) + ( ch1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an 'unsigned' byte to an integer. ie, don't carry across the
|
||||
* sign.
|
||||
*
|
||||
*
|
||||
* @param b
|
||||
* Description of the Parameter
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
public static int ubyteToInt( byte b )
|
||||
{
|
||||
public static int ubyteToInt( byte b ) {
|
||||
return b & 0xFF;
|
||||
}
|
||||
|
||||
private LittleEndian()
|
||||
{
|
||||
private LittleEndian() {
|
||||
// no instances of this class
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,9 @@ public final class StringUtil {
|
|||
final int offset,
|
||||
final int len)
|
||||
throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
|
||||
if (len == 0) {
|
||||
return "";
|
||||
}
|
||||
if ((offset < 0) || (offset >= string.length)) {
|
||||
throw new ArrayIndexOutOfBoundsException("Illegal offset " + offset + " (String data is of length " + string.length + ")");
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
//noinspection deprecation
|
||||
return color == null ? null : new XSSFColor(color, map);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance of XSSFColor from the supplied XML bean, with default color indexes
|
||||
* @param color The {@link CTColor} to use as color-value.
|
||||
|
@ -52,7 +52,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
public XSSFColor(CTColor color) {
|
||||
this(color, new DefaultIndexedColorMap());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance of XSSFColor from the supplied XML bean, with the given color indexes
|
||||
* @param color The {@link CTColor} to use as color-value.
|
||||
|
@ -119,7 +119,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
this(CTColor.Factory.newInstance(), colorMap);
|
||||
ctColor.setRgb(rgb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param indexedColor color index (Enum named for default colors)
|
||||
* @param colorMap The IndexedColorMap to use instead of the default one
|
||||
|
@ -167,7 +167,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
public boolean isThemed() {
|
||||
return ctColor.isSetTheme();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the ctColor has a alpha
|
||||
*/
|
||||
|
@ -215,14 +215,8 @@ public class XSSFColor extends ExtendedColor {
|
|||
return null;
|
||||
}
|
||||
|
||||
if(rgb.length == 4) {
|
||||
// Need to trim off the alpha
|
||||
byte[] tmp = new byte[3];
|
||||
System.arraycopy(rgb, 1, tmp, 0, 3);
|
||||
return tmp;
|
||||
} else {
|
||||
return rgb;
|
||||
}
|
||||
// Need to trim off the alpha
|
||||
return rgb.length == 4 ? Arrays.copyOfRange(rgb, 1, 4) : rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,7 +252,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Standard Alpha Red Green Blue ctColor value (ARGB).
|
||||
*/
|
||||
|
@ -403,7 +397,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
}
|
||||
return (XSSFColor)color;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return ctColor.toString().hashCode();
|
||||
|
@ -437,7 +431,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
private boolean sameAuto(XSSFColor other) {
|
||||
return isAuto() == other.isAuto();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(!(o instanceof XSSFColor)) {
|
||||
|
@ -445,7 +439,7 @@ public class XSSFColor extends ExtendedColor {
|
|||
}
|
||||
|
||||
XSSFColor other = (XSSFColor)o;
|
||||
|
||||
|
||||
// Compare each field in ctColor.
|
||||
// Cannot compare ctColor's XML string representation because equivalent
|
||||
// colors may have different relation namespace URI's
|
||||
|
|
|
@ -188,8 +188,7 @@ public final class ChunkFactory {
|
|||
}
|
||||
|
||||
// Now, create the chunk
|
||||
byte[] contents = IOUtils.safelyAllocate(header.getLength(), MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, offset+header.getSizeInBytes(), contents, 0, contents.length);
|
||||
byte[] contents = IOUtils.safelyClone(data, offset+header.getSizeInBytes(), header.getLength(), MAX_RECORD_LENGTH);
|
||||
Chunk chunk = new Chunk(header, trailer, separator, contents);
|
||||
|
||||
// Feed in the stuff from chunks_parse_cmds.tbl
|
||||
|
|
|
@ -17,16 +17,17 @@
|
|||
|
||||
package org.apache.poi.hdgf.chunks;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A separator between the trailer of one chunk, and the
|
||||
* header of the next one
|
||||
*/
|
||||
public final class ChunkSeparator {
|
||||
protected byte[] separatorData;
|
||||
final byte[] separatorData;
|
||||
|
||||
public ChunkSeparator(byte[] data, int offset) {
|
||||
separatorData = new byte[4];
|
||||
System.arraycopy(data, offset, separatorData, 0, 4);
|
||||
separatorData = Arrays.copyOfRange(data, offset, offset+4);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -17,15 +17,16 @@
|
|||
|
||||
package org.apache.poi.hdgf.chunks;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A trailer that follows a chunk
|
||||
*/
|
||||
public final class ChunkTrailer {
|
||||
private byte[] trailerData;
|
||||
private final byte[] trailerData;
|
||||
|
||||
public ChunkTrailer(byte[] data, int offset) {
|
||||
trailerData = new byte[8];
|
||||
System.arraycopy(data, offset, trailerData, 0, 8);
|
||||
trailerData = Arrays.copyOfRange(data, offset, offset+8);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -38,21 +38,19 @@ public final class CompressedStreamStore extends StreamStore {
|
|||
* We're not sure what this is, but it comes before the
|
||||
* real contents in the de-compressed data
|
||||
*/
|
||||
private byte[] blockHeader = new byte[4];
|
||||
private final byte[] blockHeader;
|
||||
private boolean blockHeaderInContents;
|
||||
|
||||
protected byte[] _getCompressedContents() { return compressedContents; }
|
||||
protected byte[] _getBlockHeader() { return blockHeader; }
|
||||
byte[] _getCompressedContents() { return compressedContents; }
|
||||
byte[] _getBlockHeader() { return blockHeader; }
|
||||
|
||||
/**
|
||||
* Creates a new compressed StreamStore, which will handle
|
||||
* the decompression.
|
||||
*/
|
||||
protected CompressedStreamStore(byte[] data, int offset, int length) throws IOException {
|
||||
CompressedStreamStore(byte[] data, int offset, int length) throws IOException {
|
||||
this(decompress(data,offset,length));
|
||||
|
||||
compressedContents = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, offset, compressedContents, 0, length);
|
||||
compressedContents = IOUtils.safelyClone(data, offset, length, MAX_RECORD_LENGTH);
|
||||
}
|
||||
/**
|
||||
* Handles passing the de-compressed data onto our superclass.
|
||||
|
|
|
@ -34,8 +34,7 @@ public class StreamStore { // TODO - instantiable superclass
|
|||
* Creates a new, non compressed Stream Store
|
||||
*/
|
||||
protected StreamStore(byte[] data, int offset, int length) {
|
||||
contents = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, offset, contents, 0, length);
|
||||
contents = IOUtils.safelyClone(data, offset, length, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
protected void prependContentsWith(byte[] b) {
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.apache.poi.hmef;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.LZWDecompresser;
|
||||
|
@ -43,18 +43,18 @@ public final class CompressedRTF extends LZWDecompresser {
|
|||
LittleEndian.getInt(COMPRESSED_SIGNATURE);
|
||||
public static final int UNCOMPRESSED_SIGNATURE_INT =
|
||||
LittleEndian.getInt(UNCOMPRESSED_SIGNATURE);
|
||||
|
||||
|
||||
// The 4096 byte LZW dictionary is pre-loaded with some common
|
||||
// RTF fragments. These come from RTFLIB32.LIB, which ships
|
||||
// with older versions of Visual Studio or the EDK
|
||||
public static final String LZW_RTF_PRELOAD =
|
||||
public static final String LZW_RTF_PRELOAD =
|
||||
"{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss " +
|
||||
"\\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier" +
|
||||
"{\\colortbl\\red0\\green0\\blue0\n\r\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx";
|
||||
|
||||
private int compressedSize;
|
||||
private int decompressedSize;
|
||||
|
||||
|
||||
public CompressedRTF() {
|
||||
// Out flag has the normal meaning
|
||||
// Length wise, we're 2 longer than we say, so the max len is 18
|
||||
|
@ -76,9 +76,9 @@ public final class CompressedRTF extends LZWDecompresser {
|
|||
decompressedSize = LittleEndian.readInt(src);
|
||||
int compressionType = LittleEndian.readInt(src);
|
||||
/* int dataCRC = */ LittleEndian.readInt(src);
|
||||
|
||||
|
||||
// TODO - Handle CRC checking on the output side
|
||||
|
||||
|
||||
// Do we need to do anything?
|
||||
if(compressionType == UNCOMPRESSED_SIGNATURE_INT) {
|
||||
// Nope, nothing fancy to do
|
||||
|
@ -92,7 +92,7 @@ public final class CompressedRTF extends LZWDecompresser {
|
|||
// Have it processed
|
||||
super.decompress(src, res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns how big the compressed version was.
|
||||
*/
|
||||
|
@ -100,7 +100,7 @@ public final class CompressedRTF extends LZWDecompresser {
|
|||
// Return the size less the header
|
||||
return compressedSize - 12;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns how big the decompressed version was.
|
||||
*/
|
||||
|
@ -119,10 +119,10 @@ public final class CompressedRTF extends LZWDecompresser {
|
|||
|
||||
@Override
|
||||
protected int populateDictionary(byte[] dict) {
|
||||
// Copy in the RTF constants
|
||||
byte[] preload = LZW_RTF_PRELOAD.getBytes(Charset.forName("US-ASCII"));
|
||||
// Copy in the RTF constants
|
||||
byte[] preload = LZW_RTF_PRELOAD.getBytes(StandardCharsets.US_ASCII);
|
||||
System.arraycopy(preload, 0, dict, 0, preload.length);
|
||||
|
||||
|
||||
// Start adding new codes after the constants
|
||||
return preload.length;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hmef.Attachment;
|
||||
|
@ -45,7 +46,7 @@ public class MAPIAttribute {
|
|||
private final MAPIProperty property;
|
||||
private final int type;
|
||||
private final byte[] data;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a single new attribute from
|
||||
* the contents of the stream
|
||||
|
@ -67,21 +68,20 @@ public class MAPIAttribute {
|
|||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
String hex;
|
||||
if(data.length <= 16) {
|
||||
hex = HexDump.toHex(data);
|
||||
} else {
|
||||
byte[] d = new byte[16];
|
||||
System.arraycopy(data, 0, d, 0, 16);
|
||||
byte[] d = Arrays.copyOf(data, 16);
|
||||
hex = HexDump.toHex(d);
|
||||
hex = hex.substring(0, hex.length()-1) + ", ....]";
|
||||
}
|
||||
|
||||
|
||||
return property + " " + hex;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a MAPI Properties TNEF Attribute, and returns
|
||||
* the list of MAPI Attributes contained within it
|
||||
|
@ -101,16 +101,16 @@ public class MAPIAttribute {
|
|||
);
|
||||
}
|
||||
ByteArrayInputStream inp = new ByteArrayInputStream(parent.getData());
|
||||
|
||||
|
||||
// First up, get the number of attributes
|
||||
int count = LittleEndian.readInt(inp);
|
||||
List<MAPIAttribute> attrs = new ArrayList<>();
|
||||
|
||||
|
||||
// Now, read each one in in turn
|
||||
for(int i=0; i<count; i++) {
|
||||
int typeAndMV = LittleEndian.readUShort(inp);
|
||||
int id = LittleEndian.readUShort(inp);
|
||||
|
||||
|
||||
// Is it either Multi-Valued or Variable-Length?
|
||||
boolean isMV = false;
|
||||
boolean isVL = false;
|
||||
|
@ -123,13 +123,13 @@ public class MAPIAttribute {
|
|||
typeId == Types.BINARY.getId() || typeId == Types.DIRECTORY.getId()) {
|
||||
isVL = true;
|
||||
}
|
||||
|
||||
|
||||
// Turn the type ID into a strongly typed thing
|
||||
MAPIType type = Types.getById(typeId);
|
||||
if (type == null) {
|
||||
type = Types.createCustom(typeId);
|
||||
}
|
||||
|
||||
|
||||
// If it's a named property, rather than a standard
|
||||
// MAPI property, grab the details of it
|
||||
MAPIProperty prop = MAPIProperty.get(id);
|
||||
|
@ -137,7 +137,7 @@ public class MAPIAttribute {
|
|||
byte[] guid = new byte[16];
|
||||
IOUtils.readFully(inp, guid);
|
||||
int mptype = LittleEndian.readInt(inp);
|
||||
|
||||
|
||||
// Get the name of it
|
||||
String name;
|
||||
if(mptype == 0) {
|
||||
|
@ -153,14 +153,14 @@ public class MAPIAttribute {
|
|||
name = StringUtil.getFromUnicodeLE(mpdata, 0, (mplen/2)-1);
|
||||
skipToBoundary(mplen, inp);
|
||||
}
|
||||
|
||||
|
||||
// Now create
|
||||
prop = MAPIProperty.createCustom(id, type, name);
|
||||
}
|
||||
if(prop == MAPIProperty.UNKNOWN) {
|
||||
prop = MAPIProperty.createCustom(id, type, "(unknown " + Integer.toHexString(id) + ")");
|
||||
}
|
||||
|
||||
|
||||
// Now read in the value(s)
|
||||
int values = 1;
|
||||
if(isMV || isVL) {
|
||||
|
@ -171,7 +171,7 @@ public class MAPIAttribute {
|
|||
byte[] data = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
|
||||
IOUtils.readFully(inp, data);
|
||||
skipToBoundary(len, inp);
|
||||
|
||||
|
||||
// Create
|
||||
MAPIAttribute attr;
|
||||
if(type == Types.UNICODE_STRING || type == Types.ASCII_STRING) {
|
||||
|
@ -186,7 +186,7 @@ public class MAPIAttribute {
|
|||
attrs.add(attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// All done
|
||||
return attrs;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.apache.poi.util.IOUtils;
|
|||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A pure-MAPI attribute holding RTF (compressed or not), which applies
|
||||
* A pure-MAPI attribute holding RTF (compressed or not), which applies
|
||||
* to a {@link HMEFMessage} or one of its {@link Attachment}s.
|
||||
*/
|
||||
public final class MAPIRtfAttribute extends MAPIAttribute {
|
||||
|
@ -38,45 +38,44 @@ public final class MAPIRtfAttribute extends MAPIAttribute {
|
|||
|
||||
private final byte[] decompressed;
|
||||
private final String data;
|
||||
|
||||
|
||||
public MAPIRtfAttribute(MAPIProperty property, int type, byte[] data) throws IOException {
|
||||
super(property, type, data);
|
||||
|
||||
|
||||
// Decompress it, removing any trailing padding as needed
|
||||
CompressedRTF rtf = new CompressedRTF();
|
||||
byte[] tmp = rtf.decompress(new ByteArrayInputStream(data));
|
||||
if(tmp.length > rtf.getDeCompressedSize()) {
|
||||
this.decompressed = IOUtils.safelyAllocate(rtf.getDeCompressedSize(), MAX_RECORD_LENGTH);
|
||||
System.arraycopy(tmp, 0, decompressed, 0, decompressed.length);
|
||||
this.decompressed = IOUtils.safelyClone(tmp, 0, rtf.getDeCompressedSize(), MAX_RECORD_LENGTH);
|
||||
} else {
|
||||
this.decompressed = tmp;
|
||||
}
|
||||
|
||||
|
||||
// Turn the RTF data into a more useful string
|
||||
this.data = StringUtil.getFromCompressedUnicode(decompressed, 0, decompressed.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the original, compressed RTF
|
||||
*/
|
||||
public byte[] getRawData() {
|
||||
return super.getData();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the raw uncompressed RTF data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return decompressed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the uncompressed RTF as a string
|
||||
*/
|
||||
public String getDataString() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return getProperty() + " " + data;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public final class HMEFDumper {
|
|||
if(args.length < 1) {
|
||||
throw new IllegalArgumentException("Filename must be given");
|
||||
}
|
||||
|
||||
|
||||
boolean truncatePropData = true;
|
||||
for (String arg : args) {
|
||||
if (arg.equalsIgnoreCase("--full")) {
|
||||
|
@ -62,77 +62,77 @@ public final class HMEFDumper {
|
|||
|
||||
private InputStream inp;
|
||||
private boolean truncatePropertyData;
|
||||
|
||||
|
||||
public HMEFDumper(InputStream inp) throws IOException {
|
||||
this.inp = inp;
|
||||
|
||||
|
||||
// Check the signature matches
|
||||
int sig = LittleEndian.readInt(inp);
|
||||
if(sig != HMEFMessage.HEADER_SIGNATURE) {
|
||||
throw new IllegalArgumentException(
|
||||
"TNEF signature not detected in file, " +
|
||||
"expected " + HMEFMessage.HEADER_SIGNATURE +
|
||||
"expected " + HMEFMessage.HEADER_SIGNATURE +
|
||||
" but got " + sig
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Skip over the File ID
|
||||
LittleEndian.readUShort(inp);
|
||||
}
|
||||
|
||||
|
||||
public void setTruncatePropertyData(boolean truncate) {
|
||||
truncatePropertyData = truncate;
|
||||
}
|
||||
|
||||
|
||||
private void dump() throws IOException {
|
||||
int level;
|
||||
int attachments = 0;
|
||||
|
||||
|
||||
while(true) {
|
||||
// Fetch the level
|
||||
level = inp.read();
|
||||
if(level == TNEFProperty.LEVEL_END_OF_FILE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Build the attribute
|
||||
TNEFAttribute attr = TNEFAttribute.create(inp);
|
||||
|
||||
|
||||
// Is it a new attachment?
|
||||
if(level == TNEFProperty.LEVEL_ATTACHMENT &&
|
||||
if(level == TNEFProperty.LEVEL_ATTACHMENT &&
|
||||
attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
|
||||
attachments++;
|
||||
System.out.println();
|
||||
System.out.println("Attachment # " + attachments);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
|
||||
// Print the attribute into
|
||||
System.out.println(
|
||||
"Level " + level + " : Type " + attr.getType() +
|
||||
" : ID " + attr.getProperty()
|
||||
);
|
||||
|
||||
|
||||
// Print the contents
|
||||
String indent = " ";
|
||||
|
||||
|
||||
if(attr instanceof TNEFStringAttribute) {
|
||||
System.out.println(indent + indent + indent + ((TNEFStringAttribute)attr).getString());
|
||||
}
|
||||
if(attr instanceof TNEFDateAttribute) {
|
||||
System.out.println(indent + indent + indent + ((TNEFDateAttribute)attr).getDate());
|
||||
}
|
||||
|
||||
|
||||
System.out.println(indent + "Data of length " + attr.getData().length);
|
||||
if(attr.getData().length > 0) {
|
||||
int len = attr.getData().length;
|
||||
if(truncatePropertyData) {
|
||||
len = Math.min( attr.getData().length, 48 );
|
||||
}
|
||||
|
||||
|
||||
int loops = len/16;
|
||||
if(loops == 0) loops = 1;
|
||||
|
||||
|
||||
for(int i=0; i<loops; i++) {
|
||||
int thisLen = 16;
|
||||
int offset = i*16;
|
||||
|
@ -140,16 +140,15 @@ public final class HMEFDumper {
|
|||
thisLen = len - offset;
|
||||
}
|
||||
|
||||
byte[] data = IOUtils.safelyAllocate(thisLen, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(attr.getData(), offset, data, 0, thisLen);
|
||||
|
||||
byte[] data = IOUtils.safelyClone(attr.getData(), offset, thisLen, MAX_RECORD_LENGTH);
|
||||
|
||||
System.out.print(
|
||||
indent + HexDump.dump(data, 0, 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES ||
|
||||
attr.getProperty() == TNEFProperty.ID_ATTACHMENT) {
|
||||
List<MAPIAttribute> attrs = MAPIAttribute.create(attr);
|
||||
|
|
|
@ -69,8 +69,7 @@ public final class QuillContents extends HPBFPart {
|
|||
int from = (int)LittleEndian.getUInt(data, offset+16);
|
||||
int len = (int)LittleEndian.getUInt(data, offset+20);
|
||||
|
||||
byte[] bitData = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, from, bitData, 0, len);
|
||||
byte[] bitData = IOUtils.safelyClone(data, from, len, MAX_RECORD_LENGTH);
|
||||
|
||||
// Create
|
||||
if(bitType.equals("TEXT")) {
|
||||
|
|
|
@ -39,9 +39,7 @@ public abstract class Bitmap extends HSLFPictureData {
|
|||
public byte[] getData(){
|
||||
byte[] rawdata = getRawData();
|
||||
int prefixLen = 16*getUIDInstanceCount()+1;
|
||||
byte[] imgdata = IOUtils.safelyAllocate(rawdata.length-prefixLen, rawdata.length);
|
||||
System.arraycopy(rawdata, prefixLen, imgdata, 0, imgdata.length);
|
||||
return imgdata;
|
||||
return IOUtils.safelyClone(rawdata, prefixLen, rawdata.length-prefixLen, rawdata.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -62,9 +62,9 @@ public final class DIB extends Bitmap {
|
|||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(signature+" is not a valid instance/signature value for DIB");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getData(){
|
||||
return addBMPHeader ( super.getData() );
|
||||
|
@ -83,14 +83,14 @@ public final class DIB extends Bitmap {
|
|||
int imageSize = LittleEndian.getInt(data, 0x22 - HEADER_SIZE);
|
||||
int fileSize = data.length + HEADER_SIZE;
|
||||
int offset = fileSize - imageSize;
|
||||
|
||||
|
||||
// specifies the size, in bytes, of the bitmap file - must add the length of the header
|
||||
LittleEndian.putInt(header, 2, fileSize);
|
||||
LittleEndian.putInt(header, 2, fileSize);
|
||||
// Reserved; set to zero
|
||||
LittleEndian.putInt(header, 6, 0);
|
||||
// the offset, i.e. starting address, of the byte where the bitmap data can be found
|
||||
LittleEndian.putInt(header, 10, offset);
|
||||
|
||||
|
||||
//DIB data is the header + dib bytes
|
||||
byte[] dib = IOUtils.safelyAllocate(header.length + data.length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(header, 0, dib, 0, header.length);
|
||||
|
@ -102,8 +102,7 @@ public final class DIB extends Bitmap {
|
|||
@Override
|
||||
public void setData(byte[] data) throws IOException {
|
||||
//cut off the bitmap file-header
|
||||
byte[] dib = IOUtils.safelyAllocate(data.length-HEADER_SIZE, data.length);
|
||||
System.arraycopy(data, HEADER_SIZE, dib, 0, dib.length);
|
||||
byte[] dib = IOUtils.safelyClone(data, HEADER_SIZE, data.length-HEADER_SIZE, data.length);
|
||||
super.setData(dib);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ import org.apache.poi.util.Units;
|
|||
*/
|
||||
public final class PICT extends Metafile {
|
||||
private static final POILogger LOG = POILogFactory.getLogger(PICT.class);
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] getData(){
|
||||
byte[] rawdata = getRawData();
|
||||
|
@ -95,7 +95,7 @@ public final class PICT extends Metafile {
|
|||
// skip the first 512 bytes - they are MAC specific crap
|
||||
final int nOffset = ImageHeaderPICT.PICT_HEADER_OFFSET;
|
||||
ImageHeaderPICT nHeader = new ImageHeaderPICT(data, nOffset);
|
||||
|
||||
|
||||
Header header = new Header();
|
||||
int wmfSize = data.length - nOffset;
|
||||
header.setWmfSize(wmfSize);
|
||||
|
@ -144,12 +144,12 @@ public final class PICT extends Metafile {
|
|||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(signature+" is not a valid instance/signature value for PICT");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* initialize a smaller piece of the array and use the System.arraycopy
|
||||
* initialize a smaller piece of the array and use the System.arraycopy
|
||||
* call to fill in the rest of the array in an expanding binary fashion
|
||||
*/
|
||||
private static void bytefill(byte[] array, byte value) {
|
||||
|
@ -161,7 +161,7 @@ public final class PICT extends Metafile {
|
|||
}
|
||||
|
||||
for (int i = 1; i < len; i += i) {
|
||||
System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
|
||||
System.arraycopy(array, 0, array, i, Math.min(len - i, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.OutputStreamWriter;
|
|||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.hslf.record.RecordTypes;
|
||||
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||
|
@ -161,20 +162,18 @@ public final class PPTXMLDump {
|
|||
public void dumpPictures(byte[] data, int padding) throws IOException {
|
||||
int pos = 0;
|
||||
while (pos < data.length) {
|
||||
byte[] header = new byte[PICT_HEADER_SIZE];
|
||||
|
||||
if(data.length - pos < header.length) {
|
||||
if(data.length - pos < PICT_HEADER_SIZE) {
|
||||
// corrupt file, cannot read header
|
||||
return;
|
||||
}
|
||||
System.arraycopy(data, pos, header, 0, header.length);
|
||||
byte[] header = Arrays.copyOfRange(data, pos, pos + PICT_HEADER_SIZE);
|
||||
int size = LittleEndian.getInt(header, 4) - 17;
|
||||
if(size < 0) {
|
||||
// corrupt file, negative image size
|
||||
return;
|
||||
}
|
||||
byte[] pictdata = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, pos + PICT_HEADER_SIZE, pictdata, 0, pictdata.length);
|
||||
|
||||
byte[] pictdata = IOUtils.safelyClone(data, pos + PICT_HEADER_SIZE, size, MAX_RECORD_LENGTH);
|
||||
pos += PICT_HEADER_SIZE + size;
|
||||
|
||||
padding++;
|
||||
|
|
|
@ -58,7 +58,7 @@ public final class SlideShowDumper {
|
|||
private boolean ddfEscher;
|
||||
/** Do we use our own built-in basic escher groker to understand the escher objects? */
|
||||
private boolean basicEscher;
|
||||
|
||||
|
||||
private PrintStream out;
|
||||
|
||||
/**
|
||||
|
@ -213,8 +213,7 @@ public void walkTree(int depth, int startPos, int maxLen) throws IOException {
|
|||
|
||||
final String ind = (indent == 0) ? "%1$s" : "%1$"+indent+"s";
|
||||
|
||||
byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(docstream,pos,contents,0,len);
|
||||
byte[] contents = IOUtils.safelyClone(docstream, pos, len, MAX_RECORD_LENGTH);
|
||||
DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
|
||||
EscherRecord record = erf.createRecord(contents,0);
|
||||
|
||||
|
@ -229,8 +228,8 @@ public void walkTree(int depth, int startPos, int maxLen) throws IOException {
|
|||
|
||||
String fmt = ind+"At position %2$d (%2$04x): type is %3$d (%3$04x), len is %4$d (%4$04x) (%5$d) - record claims %6$d";
|
||||
out.println(String.format(Locale.ROOT, fmt, "", pos, atomType, atomLen, atomLen+8, recordLen));
|
||||
|
||||
|
||||
|
||||
|
||||
// Check for corrupt / lying ones
|
||||
if(recordLen != 8 && (recordLen != (atomLen+8))) {
|
||||
out.println(String.format(Locale.ROOT, ind+"** Atom length of $2d ($3d) doesn't match record length of %4d", "", atomLen, atomLen+8, recordLen));
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -39,8 +40,7 @@ public final class AnimationInfo extends RecordContainer {
|
|||
*/
|
||||
protected AnimationInfo(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
|
@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -101,7 +102,7 @@ public final class AnimationInfoAtom extends RecordAtom {
|
|||
/**
|
||||
* record data
|
||||
*/
|
||||
private byte[] _recdata;
|
||||
private final byte[] _recdata;
|
||||
|
||||
/**
|
||||
* Constructs a brand new link related atom record.
|
||||
|
@ -125,12 +126,10 @@ public final class AnimationInfoAtom extends RecordAtom {
|
|||
*/
|
||||
protected AnimationInfoAtom(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the record data
|
||||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||
_recdata = IOUtils.safelyClone(source,start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* If we come across a record we know has children of (potential)
|
||||
|
@ -44,8 +46,7 @@ public final class BinaryTagDataBlob extends PositionDependentRecordContainer
|
|||
*/
|
||||
protected BinaryTagDataBlob(byte[] source, int start, int len) {
|
||||
// Just grab the header, not the whole contents
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
_type = LittleEndian.getUShort(_header,2);
|
||||
|
||||
// Find our children
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -86,12 +87,10 @@ public final class CString extends RecordAtom {
|
|||
if(len < 8) { len = 8; }
|
||||
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the text
|
||||
_text = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_text,0,len-8);
|
||||
_text = IOUtils.safelyClone(source,start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
/**
|
||||
* Create an empty CString
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
@ -108,11 +109,10 @@ public final class ColorSchemeAtom extends RecordAtom {
|
|||
}
|
||||
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the rgb values
|
||||
backgroundColourRGB = LittleEndian.getInt(source,start+8+0);
|
||||
backgroundColourRGB = LittleEndian.getInt(source, start+8);
|
||||
textAndLinesColourRGB = LittleEndian.getInt(source,start+8+4);
|
||||
shadowsColourRGB = LittleEndian.getInt(source,start+8+8);
|
||||
titleTextColourRGB = LittleEndian.getInt(source,start+8+12);
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -101,8 +102,7 @@ public final class Comment2000 extends RecordContainer {
|
|||
*/
|
||||
protected Comment2000(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = org.apache.poi.hslf.record.Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -72,12 +73,10 @@ public final class Comment2000Atom extends RecordAtom
|
|||
*/
|
||||
protected Comment2000Atom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -192,17 +192,12 @@ public class CurrentUserAtom
|
|||
|
||||
// Grab the unicode username, if stored
|
||||
int start = 28+(int)usernameLen+4;
|
||||
int len = 2*(int)usernameLen;
|
||||
|
||||
if(_contents.length >= start+len) {
|
||||
byte[] textBytes = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(_contents,start,textBytes,0,len);
|
||||
lastEditUser = StringUtil.getFromUnicodeLE(textBytes);
|
||||
if(_contents.length >= start+2*usernameLen) {
|
||||
lastEditUser = StringUtil.getFromUnicodeLE(_contents, start, (int)usernameLen);
|
||||
} else {
|
||||
// Fake from the 8 bit version
|
||||
byte[] textBytes = IOUtils.safelyAllocate(usernameLen, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(_contents,28,textBytes,0,(int)usernameLen);
|
||||
lastEditUser = StringUtil.getFromCompressedUnicode(textBytes,0,(int)usernameLen);
|
||||
lastEditUser = StringUtil.getFromCompressedUnicode(_contents, 28, (int)usernameLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -38,8 +39,7 @@ public final class DocInfoListContainer extends RecordContainer {
|
|||
*/
|
||||
protected DocInfoListContainer(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source,start,start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* Master container for Document. There is one of these for every
|
||||
|
@ -46,24 +47,24 @@ public final class Document extends PositionDependentRecordContainer
|
|||
* Returns the DocumentAtom of this Document
|
||||
*/
|
||||
public DocumentAtom getDocumentAtom() { return documentAtom; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the Environment of this Notes, which lots of
|
||||
* settings for the document in it
|
||||
*/
|
||||
public Environment getEnvironment() { return environment; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the PPDrawingGroup, which holds an Escher Structure
|
||||
* that contains information on pictures in the slides.
|
||||
*/
|
||||
public PPDrawingGroup getPPDrawingGroup() { return ppDrawing; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the ExObjList, which holds the references to
|
||||
* external objects used in the slides. This may be null, if
|
||||
* there are no external references.
|
||||
*
|
||||
*
|
||||
* @param create if true, create an ExObjList if it doesn't exist
|
||||
*/
|
||||
public ExObjList getExObjList(boolean create) {
|
||||
|
@ -126,8 +127,7 @@ public final class Document extends PositionDependentRecordContainer
|
|||
*/
|
||||
/* package */ Document(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -51,8 +52,7 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
|
|||
*/
|
||||
protected DocumentEncryptionAtom(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source,start,start+8);
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(source, start+8, len-8);
|
||||
try (LittleEndianInputStream leis = new LittleEndianInputStream(bis)) {
|
||||
|
@ -67,10 +67,10 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
|
|||
LittleEndian.putShort(_header, 0, (short)0x000F);
|
||||
LittleEndian.putShort(_header, 2, (short)_type);
|
||||
// record length not yet known ...
|
||||
|
||||
|
||||
ei = new EncryptionInfo(EncryptionMode.cryptoAPI);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the encryption settings
|
||||
*
|
||||
|
@ -79,7 +79,7 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
|
|||
public void initializeEncryptionInfo(int keyBits) {
|
||||
ei = new EncryptionInfo(EncryptionMode.cryptoAPI, CipherAlgorithm.rc4, HashAlgorithm.sha1, keyBits, -1, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the length of the encryption key, in bits
|
||||
*/
|
||||
|
@ -100,8 +100,8 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
|
|||
public EncryptionInfo getEncryptionInfo() {
|
||||
return ei;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* We are of type 12052
|
||||
*/
|
||||
|
@ -119,10 +119,10 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
|
|||
bos.writeShort(ei.getVersionMajor());
|
||||
bos.writeShort(ei.getVersionMinor());
|
||||
bos.writeInt(ei.getEncryptionFlags());
|
||||
|
||||
|
||||
((CryptoAPIEncryptionHeader)ei.getHeader()).write(bos);
|
||||
((CryptoAPIEncryptionVerifier)ei.getVerifier()).write(bos);
|
||||
|
||||
|
||||
// Header
|
||||
LittleEndian.putInt(_header, 4, bos.getWriteIndex());
|
||||
out.write(_header);
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* If we come across a record we know has children of (potential)
|
||||
|
@ -44,8 +46,7 @@ public final class DummyPositionSensitiveRecordWithChildren extends PositionDepe
|
|||
*/
|
||||
protected DummyPositionSensitiveRecordWithChildren(byte[] source, int start, int len) {
|
||||
// Just grab the header, not the whole contents
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source,start,start+8);
|
||||
_type = LittleEndian.getUShort(_header,2);
|
||||
|
||||
// Find our children
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* If we come across a record we know has children of (potential)
|
||||
|
@ -39,8 +41,7 @@ public final class DummyRecordWithChildren extends RecordContainer
|
|||
*/
|
||||
protected DummyRecordWithChildren(byte[] source, int start, int len) {
|
||||
// Just grab the header, not the whole contents
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
_type = LittleEndian.getUShort(_header,2);
|
||||
|
||||
// Find our children
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Environment, which contains lots of settings for the document.
|
||||
|
@ -47,8 +48,7 @@ public final class Environment extends PositionDependentRecordContainer
|
|||
*/
|
||||
protected Environment(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -63,8 +64,7 @@ public final class ExControlAtom extends RecordAtom {
|
|||
*/
|
||||
protected ExControlAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source, start, _header, 0, 8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
_id = LittleEndian.getInt(source, start + 8);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -49,8 +50,7 @@ public class ExEmbed extends RecordContainer {
|
|||
*/
|
||||
protected ExEmbed(final byte[] source, final int start, final int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
@ -66,9 +66,9 @@ public class ExEmbed extends RecordContainer {
|
|||
this();
|
||||
_children[0] = this.embedAtom = embedAtom;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ExEmbed, with blank fields
|
||||
*/
|
||||
|
@ -163,7 +163,7 @@ public class ExEmbed extends RecordContainer {
|
|||
|
||||
/**
|
||||
* Gets the OLE Programmatic Identifier.
|
||||
*
|
||||
*
|
||||
* @return the OLE Programmatic Identifier.
|
||||
*/
|
||||
public String getProgId() {
|
||||
|
@ -175,8 +175,8 @@ public class ExEmbed extends RecordContainer {
|
|||
this.progId.setText(progId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the name that appears in the paste special dialog.
|
||||
*
|
||||
|
@ -190,7 +190,7 @@ public class ExEmbed extends RecordContainer {
|
|||
this.clipboardName = safeCString(this.clipboardName, 0x3);
|
||||
this.clipboardName.setText(clipboardName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type (held as a little endian in bytes 3 and 4)
|
||||
* that this class handles.
|
||||
|
@ -213,7 +213,7 @@ public class ExEmbed extends RecordContainer {
|
|||
public void writeOut(final OutputStream out) throws IOException {
|
||||
writeOut(_header[0],_header[1],getRecordType(),_children,out);
|
||||
}
|
||||
|
||||
|
||||
private CString safeCString(CString oldStr, int optionsId) {
|
||||
CString newStr = oldStr;
|
||||
if (newStr == null) {
|
||||
|
@ -233,7 +233,7 @@ public class ExEmbed extends RecordContainer {
|
|||
if (!found) {
|
||||
appendChildRecord(newStr);
|
||||
}
|
||||
|
||||
|
||||
return newStr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -94,12 +95,10 @@ public class ExEmbedAtom extends RecordAtom {
|
|||
*/
|
||||
protected ExEmbedAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source,start+8,len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
// Must be at least 8 bytes long
|
||||
if(_data.length < 8) {
|
||||
|
@ -130,7 +129,7 @@ public class ExEmbedAtom extends RecordAtom {
|
|||
public void setCantLockServerB(boolean cantBeLocked) {
|
||||
_data[4] = (byte)(cantBeLocked ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets whether it is not required to send the dimensions to the embedded object.
|
||||
*
|
||||
|
|
|
@ -18,12 +18,13 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* This class represents the data of a link in the document.
|
||||
* This class represents the data of a link in the document.
|
||||
* @author Nick Burch
|
||||
*/
|
||||
public class ExHyperlink extends RecordContainer {
|
||||
|
@ -35,12 +36,12 @@ public class ExHyperlink extends RecordContainer {
|
|||
private ExHyperlinkAtom linkAtom;
|
||||
private CString linkDetailsA;
|
||||
private CString linkDetailsB;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Returns the ExHyperlinkAtom of this link
|
||||
*/
|
||||
*/
|
||||
public ExHyperlinkAtom getExHyperlinkAtom() { return linkAtom; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the URL of the link.
|
||||
*
|
||||
|
@ -68,7 +69,7 @@ public class ExHyperlink extends RecordContainer {
|
|||
linkDetailsB.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setLinkOptions(int options) {
|
||||
if(linkDetailsB != null) {
|
||||
linkDetailsB.setOptions(options);
|
||||
|
@ -80,7 +81,7 @@ public class ExHyperlink extends RecordContainer {
|
|||
linkDetailsA.setText(title);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the link details (field A)
|
||||
*/
|
||||
|
@ -94,13 +95,12 @@ public class ExHyperlink extends RecordContainer {
|
|||
return linkDetailsB == null ? null : linkDetailsB.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set things up, and find our more interesting children
|
||||
*/
|
||||
protected ExHyperlink(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
@ -111,7 +111,7 @@ public class ExHyperlink extends RecordContainer {
|
|||
* Go through our child records, picking out the ones that are
|
||||
* interesting, and saving those for use by the easy helper
|
||||
* methods.
|
||||
*/
|
||||
*/
|
||||
private void findInterestingChildren() {
|
||||
|
||||
// First child should be the ExHyperlinkAtom
|
||||
|
@ -138,11 +138,11 @@ public class ExHyperlink extends RecordContainer {
|
|||
public ExHyperlink() {
|
||||
_header = new byte[8];
|
||||
_children = new org.apache.poi.hslf.record.Record[3];
|
||||
|
||||
|
||||
// Setup our header block
|
||||
_header[0] = 0x0f; // We are a container record
|
||||
LittleEndian.putShort(_header, 2, (short)_type);
|
||||
|
||||
|
||||
// Setup our child records
|
||||
CString csa = new CString();
|
||||
CString csb = new CString();
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -70,12 +71,10 @@ public final class ExHyperlinkAtom extends RecordAtom {
|
|||
*/
|
||||
protected ExHyperlinkAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
// Must be at least 4 bytes long
|
||||
if(_data.length < 4) {
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -39,8 +40,7 @@ public class ExMCIMovie extends RecordContainer { // TODO - instantiable supercl
|
|||
*/
|
||||
protected ExMCIMovie(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source, start, _header, 0, 8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source, start + 8, len - 8);
|
||||
|
|
|
@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -89,12 +90,10 @@ public final class ExMediaAtom extends RecordAtom
|
|||
*/
|
||||
protected ExMediaAtom(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the record data
|
||||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||
_recdata = IOUtils.safelyClone(source,start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
|
@ -30,15 +31,15 @@ import org.apache.poi.util.LittleEndian;
|
|||
public class ExObjList extends RecordContainer {
|
||||
private byte[] _header;
|
||||
private static final long _type = RecordTypes.ExObjList.typeID;
|
||||
|
||||
|
||||
// Links to our more interesting children
|
||||
private ExObjListAtom exObjListAtom;
|
||||
|
||||
/**
|
||||
private ExObjListAtom exObjListAtom;
|
||||
|
||||
/**
|
||||
* Returns the ExObjListAtom of this list
|
||||
*/
|
||||
*/
|
||||
public ExObjListAtom getExObjListAtom() { return exObjListAtom; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns all the ExHyperlinks
|
||||
*/
|
||||
|
@ -53,13 +54,12 @@ public class ExObjList extends RecordContainer {
|
|||
return links.toArray(new ExHyperlink[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set things up, and find our more interesting children
|
||||
*/
|
||||
protected ExObjList(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
@ -70,7 +70,7 @@ public class ExObjList extends RecordContainer {
|
|||
* Go through our child records, picking out the ones that are
|
||||
* interesting, and saving those for use by the easy helper
|
||||
* methods.
|
||||
*/
|
||||
*/
|
||||
private void findInterestingChildren() {
|
||||
// First child should be the atom
|
||||
if(_children[0] instanceof ExObjListAtom) {
|
||||
|
@ -79,18 +79,18 @@ public class ExObjList extends RecordContainer {
|
|||
throw new IllegalStateException("First child record wasn't a ExObjListAtom, was of type " + _children[0].getRecordType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ExObjList, with blank fields
|
||||
*/
|
||||
public ExObjList() {
|
||||
_header = new byte[8];
|
||||
_children = new org.apache.poi.hslf.record.Record[1];
|
||||
|
||||
|
||||
// Setup our header block
|
||||
_header[0] = 0x0f; // We are a container record
|
||||
LittleEndian.putShort(_header, 2, (short)_type);
|
||||
|
||||
|
||||
// Setup our child records
|
||||
_children[0] = new ExObjListAtom();
|
||||
findInterestingChildren();
|
||||
|
|
|
@ -14,12 +14,13 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -58,7 +59,7 @@ public class ExObjListAtom extends RecordAtom
|
|||
|
||||
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||
LittleEndian.putInt(_header, 4, _data.length);
|
||||
|
||||
|
||||
// It is fine for the other values to be zero
|
||||
}
|
||||
|
||||
|
@ -72,13 +73,11 @@ public class ExObjListAtom extends RecordAtom
|
|||
*/
|
||||
protected ExObjListAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
// Must be at least 4 bytes long
|
||||
if(_data.length < 4) {
|
||||
throw new IllegalArgumentException("The length of the data for a ExObjListAtom must be at least 4 bytes, but was only " + _data.length);
|
||||
|
@ -101,7 +100,7 @@ public class ExObjListAtom extends RecordAtom
|
|||
public void setObjectIDSeed(int seed) {
|
||||
LittleEndian.putInt(_data,0,seed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the record type.
|
||||
* @return the record type.
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -55,17 +56,14 @@ public final class ExObjRefAtom extends RecordAtom {
|
|||
|
||||
/**
|
||||
* Build an instance of <code>ExObjRefAtom</code> from on-disk data
|
||||
*
|
||||
*
|
||||
* @param source the source data as a byte array.
|
||||
* @param start the start offset into the byte array.
|
||||
* @param len the length of the slice in the byte array.
|
||||
*/
|
||||
protected ExObjRefAtom(byte[] source, int start, int len) {
|
||||
_header = new byte[8];
|
||||
int offset = start;
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
offset += _header.length;
|
||||
exObjIdRef = (int)LittleEndian.getUInt(source, offset);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
exObjIdRef = (int)LittleEndian.getUInt(source, start+8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,7 @@ import static org.apache.poi.util.GenericRecordUtil.safeEnum;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -187,12 +188,10 @@ public class ExOleObjAtom extends RecordAtom {
|
|||
*/
|
||||
protected ExOleObjAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
// Must be at least 24 bytes long
|
||||
if(_data.length < 24) {
|
||||
|
@ -258,7 +257,7 @@ public class ExOleObjAtom extends RecordAtom {
|
|||
|
||||
/**
|
||||
* Gets the type of OLE object.
|
||||
*
|
||||
*
|
||||
* @return the sub-type, one of the {@code SUBTYPE_*} constants.
|
||||
*/
|
||||
public int getSubType() {
|
||||
|
@ -303,7 +302,7 @@ public class ExOleObjAtom extends RecordAtom {
|
|||
// Even though this is a mere boolean, KOffice's code says it's an int.
|
||||
return LittleEndian.getInt(_data, 20) != 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets misc options (the last four bytes in the atom).
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
@ -51,7 +52,7 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR
|
|||
* Record data.
|
||||
*/
|
||||
private byte[] _data;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new empty storage container.
|
||||
*/
|
||||
|
@ -74,12 +75,10 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR
|
|||
*/
|
||||
protected ExOleObjStg(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
public boolean isCompressed() {
|
||||
|
@ -155,7 +154,7 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR
|
|||
public int getRecordInstance() {
|
||||
return (LittleEndian.getUShort(_header, 0) >>> 4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the contents of the record back, so it can be written
|
||||
* to disk.
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -41,8 +42,7 @@ public final class ExVideoContainer extends RecordContainer {
|
|||
*/
|
||||
protected ExVideoContainer(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -47,8 +48,7 @@ public final class FontCollection extends RecordContainer {
|
|||
private byte[] _header;
|
||||
|
||||
/* package */ FontCollection(byte[] source, int start, int len) {
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
||||
|
@ -86,10 +86,10 @@ public final class FontCollection extends RecordContainer {
|
|||
|
||||
/**
|
||||
* Add font with the given FontInfo configuration to the font collection.
|
||||
* The returned FontInfo contains the HSLF specific details and the collection
|
||||
* The returned FontInfo contains the HSLF specific details and the collection
|
||||
* uniquely contains fonts based on their typeface, i.e. calling the method with FontInfo
|
||||
* objects having the same name results in the same HSLFFontInfo reference.
|
||||
*
|
||||
*
|
||||
* @param fontInfo the FontInfo configuration, can be a instance of {@link HSLFFontInfo},
|
||||
* {@link HSLFFontInfoPredefined} or a custom implementation
|
||||
* @return the register HSLFFontInfo object
|
||||
|
@ -168,9 +168,9 @@ public final class FontCollection extends RecordContainer {
|
|||
|
||||
/**
|
||||
* Lookup a FontInfo object by its typeface
|
||||
*
|
||||
*
|
||||
* @param typeface the full font name
|
||||
*
|
||||
*
|
||||
* @return the HSLFFontInfo for the given name or {@code null} if not found
|
||||
*/
|
||||
public HSLFFontInfo getFontInfo(String typeface) {
|
||||
|
@ -195,9 +195,9 @@ public final class FontCollection extends RecordContainer {
|
|||
|
||||
/**
|
||||
* Lookup a FontInfo object by its internal font index
|
||||
*
|
||||
*
|
||||
* @param index the internal font index
|
||||
*
|
||||
*
|
||||
* @return the HSLFFontInfo for the given index or {@code null} if not found
|
||||
*/
|
||||
public HSLFFontInfo getFontInfo(int index) {
|
||||
|
@ -208,7 +208,7 @@ public final class FontCollection extends RecordContainer {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the number of registered fonts
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -63,12 +64,10 @@ public class FontEmbeddedData extends RecordAtom implements FontFacet {
|
|||
*/
|
||||
/* package */ FontEmbeddedData(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
// Must be at least 4 bytes long
|
||||
if(_data.length < 4) {
|
||||
|
|
|
@ -62,7 +62,7 @@ public final class FontEntityAtom extends RecordAtom {
|
|||
/**
|
||||
* record header
|
||||
*/
|
||||
private final byte[] _header = new byte[8];
|
||||
private final byte[] _header;
|
||||
|
||||
/**
|
||||
* record data
|
||||
|
@ -74,11 +74,10 @@ public final class FontEntityAtom extends RecordAtom {
|
|||
*/
|
||||
/* package */ FontEntityAtom(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the record data
|
||||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||
_recdata = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,6 +85,7 @@ public final class FontEntityAtom extends RecordAtom {
|
|||
*/
|
||||
public FontEntityAtom() {
|
||||
_recdata = new byte[68];
|
||||
_header = new byte[8];
|
||||
|
||||
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||
LittleEndian.putInt(_header, 4, _recdata.length);
|
||||
|
|
|
@ -68,8 +68,7 @@ public class HSLFEscherClientDataRecord extends EscherClientDataRecord {
|
|||
@Override
|
||||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
||||
int bytesRemaining = readHeader( data, offset );
|
||||
byte[] remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(data, offset+8, remainingData, 0, bytesRemaining);
|
||||
byte[] remainingData = IOUtils.safelyClone(data, offset+8, bytesRemaining, MAX_RECORD_LENGTH);
|
||||
setRemainingData(remainingData);
|
||||
return bytesRemaining + 8;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import static org.apache.poi.util.GenericRecordUtil.safeEnum;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -142,12 +143,10 @@ public final class HeadersFootersAtom extends RecordAtom {
|
|||
*/
|
||||
protected HeadersFootersAtom(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the record data
|
||||
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_recdata,0,len-8);
|
||||
_recdata = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -59,8 +60,7 @@ public final class HeadersFootersContainer extends RecordContainer {
|
|||
|
||||
protected HeadersFootersContainer(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
findInterestingChildren();
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
@ -31,22 +32,21 @@ import org.apache.poi.util.POILogger;
|
|||
public class InteractiveInfo extends RecordContainer {
|
||||
private byte[] _header;
|
||||
private static final long _type = RecordTypes.InteractiveInfo.typeID;
|
||||
|
||||
|
||||
// Links to our more interesting children
|
||||
private InteractiveInfoAtom infoAtom;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Returns the InteractiveInfoAtom of this InteractiveInfo
|
||||
*/
|
||||
*/
|
||||
public InteractiveInfoAtom getInteractiveInfoAtom() { return infoAtom; }
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Set things up, and find our more interesting children
|
||||
*/
|
||||
protected InteractiveInfo(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
@ -57,7 +57,7 @@ public class InteractiveInfo extends RecordContainer {
|
|||
* Go through our child records, picking out the ones that are
|
||||
* interesting, and saving those for use by the easy helper
|
||||
* methods.
|
||||
*/
|
||||
*/
|
||||
private void findInterestingChildren() {
|
||||
// First child should be the InteractiveInfoAtom
|
||||
if (_children == null || _children.length == 0 || !(_children[0] instanceof InteractiveInfoAtom)) {
|
||||
|
@ -67,18 +67,18 @@ public class InteractiveInfo extends RecordContainer {
|
|||
|
||||
infoAtom = (InteractiveInfoAtom)_children[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new InteractiveInfo, with blank fields
|
||||
*/
|
||||
public InteractiveInfo() {
|
||||
_header = new byte[8];
|
||||
_children = new org.apache.poi.hslf.record.Record[1];
|
||||
|
||||
|
||||
// Setup our header block
|
||||
_header[0] = 0x0f; // We are a container record
|
||||
LittleEndian.putShort(_header, 2, (short)_type);
|
||||
|
||||
|
||||
// Setup our child records
|
||||
infoAtom = new InteractiveInfoAtom();
|
||||
_children[0] = infoAtom;
|
||||
|
|
|
@ -22,6 +22,7 @@ import static org.apache.poi.util.GenericRecordUtil.safeEnum;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -153,12 +154,10 @@ public class InteractiveInfoAtom extends RecordAtom {
|
|||
*/
|
||||
protected InteractiveInfoAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
// Must be at least 16 bytes long
|
||||
if(_data.length < 16) {
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Master slide
|
||||
|
@ -57,8 +58,7 @@ public final class MainMaster extends SheetContainer {
|
|||
*/
|
||||
protected MainMaster(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
@ -66,19 +66,19 @@ public final class MainMaster extends SheetContainer {
|
|||
ArrayList<TxMasterStyleAtom> tx = new ArrayList<>();
|
||||
ArrayList<ColorSchemeAtom> clr = new ArrayList<>();
|
||||
// Find the interesting ones in there
|
||||
for(int i=0; i<_children.length; i++) {
|
||||
if(_children[i] instanceof SlideAtom) {
|
||||
slideAtom = (SlideAtom)_children[i];
|
||||
} else if(_children[i] instanceof PPDrawing) {
|
||||
ppDrawing = (PPDrawing)_children[i];
|
||||
} else if(_children[i] instanceof TxMasterStyleAtom) {
|
||||
tx.add( (TxMasterStyleAtom)_children[i] );
|
||||
} else if(_children[i] instanceof ColorSchemeAtom) {
|
||||
clr.add( (ColorSchemeAtom)_children[i] );
|
||||
for (Record child : _children) {
|
||||
if (child instanceof SlideAtom) {
|
||||
slideAtom = (SlideAtom) child;
|
||||
} else if (child instanceof PPDrawing) {
|
||||
ppDrawing = (PPDrawing) child;
|
||||
} else if (child instanceof TxMasterStyleAtom) {
|
||||
tx.add((TxMasterStyleAtom) child);
|
||||
} else if (child instanceof ColorSchemeAtom) {
|
||||
clr.add((ColorSchemeAtom) child);
|
||||
}
|
||||
|
||||
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
|
||||
_colorScheme = (ColorSchemeAtom)_children[i];
|
||||
if (ppDrawing != null && child instanceof ColorSchemeAtom) {
|
||||
_colorScheme = (ColorSchemeAtom) child;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -76,12 +77,10 @@ public final class MasterTextPropAtom extends RecordAtom {
|
|||
*/
|
||||
protected MasterTextPropAtom(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_data,0,len-8);
|
||||
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
try {
|
||||
read();
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Master container for Notes. There is one of these for every page of
|
||||
|
@ -53,23 +54,22 @@ public final class Notes extends SheetContainer
|
|||
*/
|
||||
protected Notes(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
||||
// Find the interesting ones in there
|
||||
for(int i=0; i<_children.length; i++) {
|
||||
if(_children[i] instanceof NotesAtom) {
|
||||
notesAtom = (NotesAtom)_children[i];
|
||||
for (Record child : _children) {
|
||||
if (child instanceof NotesAtom) {
|
||||
notesAtom = (NotesAtom) child;
|
||||
}
|
||||
if(_children[i] instanceof PPDrawing) {
|
||||
ppDrawing = (PPDrawing)_children[i];
|
||||
if (child instanceof PPDrawing) {
|
||||
ppDrawing = (PPDrawing) child;
|
||||
}
|
||||
if (ppDrawing != null && child instanceof ColorSchemeAtom) {
|
||||
_colorScheme = (ColorSchemeAtom) child;
|
||||
}
|
||||
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
|
||||
_colorScheme = (ColorSchemeAtom)_children[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -70,33 +71,19 @@ public final class NotesAtom extends RecordAtom
|
|||
if(len < 8) { len = 8; }
|
||||
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the slide ID
|
||||
slideID = LittleEndian.getInt(source,start+8);
|
||||
|
||||
// Grok the flags, stored as bits
|
||||
int flags = LittleEndian.getUShort(source,start+12);
|
||||
if((flags&4) == 4) {
|
||||
followMasterBackground = true;
|
||||
} else {
|
||||
followMasterBackground = false;
|
||||
}
|
||||
if((flags&2) == 2) {
|
||||
followMasterScheme = true;
|
||||
} else {
|
||||
followMasterScheme = false;
|
||||
}
|
||||
if((flags&1) == 1) {
|
||||
followMasterObjects = true;
|
||||
} else {
|
||||
followMasterObjects = false;
|
||||
}
|
||||
followMasterBackground = (flags & 4) == 4;
|
||||
followMasterScheme = (flags & 2) == 2;
|
||||
followMasterObjects = (flags & 1) == 1;
|
||||
|
||||
// There might be 2 more bytes, which are a reserved field
|
||||
reserved = IOUtils.safelyAllocate(len-14, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+14,reserved,0,reserved.length);
|
||||
reserved = IOUtils.safelyClone(source, start+14, len-14, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -28,7 +29,7 @@ import org.apache.poi.util.LittleEndian;
|
|||
|
||||
/**
|
||||
* OEPlaceholderAtom (3011).<p>
|
||||
*
|
||||
*
|
||||
* An atom record that specifies whether a shape is a placeholder shape.
|
||||
*
|
||||
* @see Placeholder
|
||||
|
@ -77,10 +78,8 @@ public final class OEPlaceholderAtom extends RecordAtom{
|
|||
* Build an instance of {@code OEPlaceholderAtom} from on-disk data
|
||||
*/
|
||||
protected OEPlaceholderAtom(byte[] source, int start, int len) {
|
||||
_header = new byte[8];
|
||||
int offset = start;
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
offset += _header.length;
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
int offset = start+8;
|
||||
|
||||
placementId = LittleEndian.getInt(source, offset); offset += 4;
|
||||
placeholderId = LittleEndian.getUByte(source, offset); offset++;
|
||||
|
@ -96,7 +95,7 @@ public final class OEPlaceholderAtom extends RecordAtom{
|
|||
|
||||
/**
|
||||
* Returns the placement Id.<p>
|
||||
*
|
||||
*
|
||||
* The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders.
|
||||
* It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide.
|
||||
* The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape.
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -55,8 +56,7 @@ public final class OutlineTextRefAtom extends RecordAtom {
|
|||
*/
|
||||
protected OutlineTextRefAtom(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the record data
|
||||
_index = LittleEndian.getInt(source, start+8);
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -114,15 +115,13 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
|
|||
*/
|
||||
PPDrawing(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the type
|
||||
_type = LittleEndian.getUShort(_header,2);
|
||||
|
||||
// Get the contents for now
|
||||
final byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start,contents,0,len);
|
||||
final byte[] contents = IOUtils.safelyClone(source, start, len, MAX_RECORD_LENGTH);
|
||||
|
||||
// Build up a tree of Escher records contained within
|
||||
final DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
|
||||
|
@ -342,7 +341,7 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
|
|||
spContainer.addChildRecord(opt);
|
||||
|
||||
dgContainer.addChildRecord(spContainer);
|
||||
|
||||
|
||||
childRecords.add(dgContainer);
|
||||
}
|
||||
|
||||
|
@ -364,7 +363,7 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
|
|||
public EscherContainerRecord getDgContainer() {
|
||||
return (EscherContainerRecord)firstEscherRecord(this, EscherRecordTypes.DG_CONTAINER).orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return EscherDgRecord which keeps track of the number of shapes and shapeId in this drawing group
|
||||
*
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -50,12 +51,10 @@ public final class PPDrawingGroup extends RecordAtom {
|
|||
|
||||
protected PPDrawingGroup(byte[] source, int start, int len) {
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the contents for now
|
||||
byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start,contents,0,len);
|
||||
byte[] contents = IOUtils.safelyClone(source, start, len, MAX_RECORD_LENGTH);
|
||||
|
||||
DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
|
||||
EscherRecord child = erf.createRecord(contents, 0);
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -65,7 +66,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
|
||||
private static final BitField persistIdFld = BitFieldFactory.getInstance(0X000FFFFF);
|
||||
private static final BitField cntPersistFld = BitFieldFactory.getInstance(0XFFF00000);
|
||||
|
||||
|
||||
/**
|
||||
* Return the value we were given at creation, be it 6001 or 6002
|
||||
*/
|
||||
|
@ -93,7 +94,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
public Map<Integer,Integer> getSlideLocationsLookup() {
|
||||
return Collections.unmodifiableMap(_slideLocations);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new holder for a PersistPtr record
|
||||
*/
|
||||
|
@ -103,8 +104,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
if(len < 8) { len = 8; }
|
||||
|
||||
// Treat as an atom, grab and hold everything
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
_type = LittleEndian.getUShort(_header,2);
|
||||
|
||||
// Try to make sense of the data part:
|
||||
|
@ -115,8 +115,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
// count * 32 bit offsets
|
||||
// Repeat as many times as you have data
|
||||
_slideLocations = new HashMap<>();
|
||||
_ptrData = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+8,_ptrData,0,_ptrData.length);
|
||||
_ptrData = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
|
||||
|
||||
int pos = 0;
|
||||
while(pos < _ptrData.length) {
|
||||
|
@ -127,7 +126,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
// Remaining 12 bits = offset count
|
||||
int offset_no = persistIdFld.getValue(info);
|
||||
int offset_count = cntPersistFld.getValue(info);
|
||||
|
||||
|
||||
// Wind on by the 4 byte info header
|
||||
pos += 4;
|
||||
|
||||
|
@ -145,13 +144,13 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
|
||||
/**
|
||||
* remove all slide references
|
||||
*
|
||||
*
|
||||
* Convenience method provided, for easier reviewing of invocations
|
||||
*/
|
||||
public void clear() {
|
||||
_slideLocations.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new slide, notes or similar, to be looked up by this.
|
||||
*/
|
||||
|
@ -187,7 +186,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
|
||||
private void normalizePersistDirectory() {
|
||||
TreeMap<Integer,Integer> orderedSlideLocations = new TreeMap<>(_slideLocations);
|
||||
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
BufAccessBAOS bos = new BufAccessBAOS(); // NOSONAR
|
||||
byte[] intbuf = new byte[4];
|
||||
|
@ -200,7 +199,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
// Building the info block
|
||||
// First 20 bits = offset number = slide ID (persistIdFld, i.e. first slide ID of a continuous group)
|
||||
// Remaining 12 bits = offset count = 1 (cntPersistFld, i.e. continuous entries in a group)
|
||||
|
||||
|
||||
if (lastSlideId+1 == nextSlideId) {
|
||||
// use existing PersistDirectoryEntry, need to increase entry count
|
||||
assert(lastPersistEntry != -1);
|
||||
|
@ -225,14 +224,14 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
throw new HSLFException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Save the new ptr data
|
||||
_ptrData = bos.toByteArray();
|
||||
|
||||
// Update the atom header
|
||||
LittleEndian.putInt(_header,4,bos.size());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the contents of the record back, so it can be written
|
||||
* to disk
|
||||
|
@ -243,7 +242,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
|
|||
out.write(_header);
|
||||
out.write(_ptrData);
|
||||
}
|
||||
|
||||
|
||||
private static class BufAccessBAOS extends ByteArrayOutputStream {
|
||||
public byte[] getBuf() {
|
||||
return buf;
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -76,8 +77,7 @@ public abstract class RecordContainer extends Record
|
|||
*/
|
||||
private int appendChild(Record newChild) {
|
||||
// Copy over, and pop the child in at the end
|
||||
Record[] nc = new org.apache.poi.hslf.record.Record[(_children.length + 1)];
|
||||
System.arraycopy(_children, 0, nc, 0, _children.length);
|
||||
Record[] nc = Arrays.copyOf(_children, _children.length+1, org.apache.poi.hslf.record.Record[].class);
|
||||
// Switch the arrays
|
||||
nc[_children.length] = newChild;
|
||||
_children = nc;
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -55,7 +56,7 @@ public final class RoundTripHFPlaceholder12 extends RecordAtom {
|
|||
LittleEndian.putInt(_header, 4, 8);
|
||||
_placeholderId = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs the comment atom record from its source data.
|
||||
*
|
||||
|
@ -65,8 +66,7 @@ public final class RoundTripHFPlaceholder12 extends RecordAtom {
|
|||
*/
|
||||
protected RoundTripHFPlaceholder12(byte[] source, int start, int len) {
|
||||
// Get the header.
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Get the record data.
|
||||
_placeholderId = source[start+8];
|
||||
|
|
|
@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -31,7 +32,7 @@ import org.apache.poi.util.LittleEndianConsts;
|
|||
/**
|
||||
* A SlideShowSlideInfo Atom (type 1017).<br>
|
||||
* <br>
|
||||
*
|
||||
*
|
||||
* An atom record that specifies which transition effects to perform
|
||||
* during a slide show, and how to advance to the next presentation slide.<br>
|
||||
* <br>
|
||||
|
@ -70,30 +71,30 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
* manually advanced by the user during the slide show.
|
||||
*/
|
||||
public static final int MANUAL_ADVANCE_BIT = 1 << 0;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the corresponding slide is
|
||||
* A bit that specifies whether the corresponding slide is
|
||||
* hidden and is not displayed during the slide show.
|
||||
*/
|
||||
public static final int HIDDEN_BIT = 1 << 2;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether to play the sound specified by soundIfRef.
|
||||
*/
|
||||
public static final int SOUND_BIT = 1 << 4;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the sound specified by soundIdRef is
|
||||
* looped continuously when playing until the next sound plays.
|
||||
*/
|
||||
public static final int LOOP_SOUND_BIT = 1 << 6;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether to stop any currently playing
|
||||
* A bit that specifies whether to stop any currently playing
|
||||
* sound when the transition starts.
|
||||
*/
|
||||
public static final int STOP_SOUND_BIT = 1 << 8;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the slide will automatically
|
||||
* advance after slideTime milliseconds during the slide show.
|
||||
|
@ -102,10 +103,10 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
|
||||
/**
|
||||
* A bit that specifies whether to display the cursor during
|
||||
* the slide show.
|
||||
* the slide show.
|
||||
*/
|
||||
public static final int CURSOR_VISIBLE_BIT = 1 << 12;
|
||||
|
||||
|
||||
// public static int RESERVED1_BIT = 1 << 1;
|
||||
// public static int RESERVED2_BIT = 1 << 3;
|
||||
// public static int RESERVED3_BIT = 1 << 5;
|
||||
|
@ -144,9 +145,9 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
* less than or equal to 86399000. It MUST be ignored unless AUTO_ADVANCE_BIT is TRUE.
|
||||
*/
|
||||
private int _slideTime;
|
||||
|
||||
|
||||
/**
|
||||
* A SoundIdRef that specifies which sound to play when the transition starts.
|
||||
* A SoundIdRef that specifies which sound to play when the transition starts.
|
||||
*/
|
||||
private int _soundIdRef;
|
||||
|
||||
|
@ -155,23 +156,23 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
* there are further restriction and specification of this field.
|
||||
*/
|
||||
private short _effectDirection; // byte
|
||||
|
||||
|
||||
/**
|
||||
* A byte that specifies which transition is used when transitioning to the
|
||||
* next presentation slide during a slide show. Exact rendering of any transition is
|
||||
* next presentation slide during a slide show. Exact rendering of any transition is
|
||||
* determined by the rendering application. As such, the same transition can have
|
||||
* many variations depending on the implementation.
|
||||
*/
|
||||
private short _effectType; // byte
|
||||
|
||||
|
||||
/**
|
||||
* Various flags - see bitmask for more details
|
||||
*/
|
||||
private short _effectTransitionFlags;
|
||||
|
||||
|
||||
/**
|
||||
* A byte value that specifies how long the transition takes to run.
|
||||
* (0x00 = 0.75 seconds, 0x01 = 0.5 seconds, 0x02 = 0.25 seconds)
|
||||
* (0x00 = 0.75 seconds, 0x01 = 0.5 seconds, 0x02 = 0.25 seconds)
|
||||
*/
|
||||
private short _speed; // byte
|
||||
private byte[] _unused; // 3-byte
|
||||
|
@ -184,18 +185,18 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
LittleEndian.putShort(_header, 6, (short)0);
|
||||
_unused = new byte[3];
|
||||
}
|
||||
|
||||
|
||||
public SSSlideInfoAtom(byte[] source, int offset, int len) {
|
||||
int ofs = offset;
|
||||
|
||||
// Sanity Checking
|
||||
if(len != 24) len = 24;
|
||||
assert(source.length >= offset+len);
|
||||
|
||||
|
||||
// Get the header
|
||||
_header = LittleEndian.getByteArray(source,ofs,8);
|
||||
_header = Arrays.copyOfRange(source, ofs, ofs+8);
|
||||
ofs += _header.length;
|
||||
|
||||
|
||||
assert(LittleEndian.getShort(_header, 0) == 0);
|
||||
assert(LittleEndian.getShort(_header, 2) == RecordTypes.SSSlideInfoAtom.typeID);
|
||||
assert(LittleEndian.getShort(_header, 4) == 0x10);
|
||||
|
@ -214,7 +215,7 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
ofs += LittleEndianConsts.SHORT_SIZE;
|
||||
_speed = LittleEndian.getUByte(source, ofs);
|
||||
ofs += LittleEndianConsts.BYTE_SIZE;
|
||||
_unused = LittleEndian.getByteArray(source,ofs,3);
|
||||
_unused = Arrays.copyOfRange(source,ofs,ofs+3);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +233,7 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
out.write(byteBuf);
|
||||
LittleEndian.putUByte(byteBuf, 0, _effectType);
|
||||
out.write(byteBuf);
|
||||
|
||||
|
||||
writeLittleEndian(_effectTransitionFlags, out);
|
||||
LittleEndian.putUByte(byteBuf, 0, _speed);
|
||||
out.write(byteBuf);
|
||||
|
@ -240,7 +241,7 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
assert(_unused.length == 3);
|
||||
out.write(_unused);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We are of type 1017
|
||||
*/
|
||||
|
@ -303,7 +304,7 @@ public class SSSlideInfoAtom extends RecordAtom {
|
|||
public boolean getEffectTransitionFlagByBit(int bitmask) {
|
||||
return ((_effectTransitionFlags & bitmask) != 0);
|
||||
}
|
||||
|
||||
|
||||
public short getSpeed() {
|
||||
return _speed;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
|
@ -56,24 +57,22 @@ public final class Slide extends SheetContainer
|
|||
*/
|
||||
protected Slide(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
||||
// Find the interesting ones in there
|
||||
for(int i=0; i<_children.length; i++) {
|
||||
if(_children[i] instanceof SlideAtom) {
|
||||
slideAtom = (SlideAtom)_children[i];
|
||||
}
|
||||
else if(_children[i] instanceof PPDrawing) {
|
||||
ppDrawing = (PPDrawing)_children[i];
|
||||
for (Record child : _children) {
|
||||
if (child instanceof SlideAtom) {
|
||||
slideAtom = (SlideAtom) child;
|
||||
} else if (child instanceof PPDrawing) {
|
||||
ppDrawing = (PPDrawing) child;
|
||||
}
|
||||
|
||||
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
|
||||
_colorScheme = (ColorSchemeAtom)_children[i];
|
||||
}
|
||||
if (ppDrawing != null && child instanceof ColorSchemeAtom) {
|
||||
_colorScheme = (ColorSchemeAtom) child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -83,12 +84,10 @@ public final class SlideAtom extends RecordAtom {
|
|||
if(len < 30) { len = 30; }
|
||||
|
||||
// Get the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the 12 bytes that is "SSlideLayoutAtom"
|
||||
byte[] SSlideLayoutAtomData = new byte[12];
|
||||
System.arraycopy(source,start+8,SSlideLayoutAtomData,0,12);
|
||||
byte[] SSlideLayoutAtomData = Arrays.copyOfRange(source,start+8, start+12+8);
|
||||
// Use them to build up the SSlideLayoutAtom
|
||||
layoutAtom = new SlideAtomLayout(SSlideLayoutAtomData);
|
||||
|
||||
|
@ -98,26 +97,13 @@ public final class SlideAtom extends RecordAtom {
|
|||
|
||||
// Grok the flags, stored as bits
|
||||
int flags = LittleEndian.getUShort(source,start+20+8);
|
||||
if((flags&4) == 4) {
|
||||
followMasterBackground = true;
|
||||
} else {
|
||||
followMasterBackground = false;
|
||||
}
|
||||
if((flags&2) == 2) {
|
||||
followMasterScheme = true;
|
||||
} else {
|
||||
followMasterScheme = false;
|
||||
}
|
||||
if((flags&1) == 1) {
|
||||
followMasterObjects = true;
|
||||
} else {
|
||||
followMasterObjects = false;
|
||||
}
|
||||
followMasterBackground = (flags & 4) == 4;
|
||||
followMasterScheme = (flags & 2) == 2;
|
||||
followMasterObjects = (flags & 1) == 1;
|
||||
|
||||
// If there's any other bits of data, keep them about
|
||||
// 8 bytes header + 20 bytes to flags + 2 bytes flags = 30 bytes
|
||||
reserved = IOUtils.safelyAllocate(len-30, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+30,reserved,0,reserved.length);
|
||||
reserved = IOUtils.safelyClone(source,start+30, len-30, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -32,7 +33,7 @@ import org.apache.poi.util.LittleEndian;
|
|||
* Holds the geometry of the Slide, and the ID of the placeholders on the slide.
|
||||
* Embedded inside a SlideAtom is a SlideAtomLayout, without the usual record header.
|
||||
* Since it's a fixed size and tied to the SlideAtom, we'll hold it here.<p>
|
||||
*
|
||||
*
|
||||
* This might eventually merged with the XSLF counterpart
|
||||
*/
|
||||
@Internal
|
||||
|
@ -82,7 +83,7 @@ public class SlideAtomLayout implements GenericRecord {
|
|||
SlideLayoutType(int nativeId) {
|
||||
this.nativeId = nativeId;
|
||||
}
|
||||
|
||||
|
||||
public int getNativeId() {
|
||||
return nativeId;
|
||||
}
|
||||
|
@ -117,8 +118,7 @@ public class SlideAtomLayout implements GenericRecord {
|
|||
|
||||
// Grab out our data
|
||||
geometry = SlideLayoutType.forNativeID(LittleEndian.getInt(data,0));
|
||||
placeholderIDs = new byte[8];
|
||||
System.arraycopy(data,4,placeholderIDs,0,8);
|
||||
placeholderIDs = Arrays.copyOfRange(data,4, 4+8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
@ -74,8 +75,7 @@ public final class SlideListWithText extends RecordContainer {
|
|||
*/
|
||||
protected SlideListWithText(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
@ -96,8 +96,7 @@ public final class SlideListWithText extends RecordContainer {
|
|||
|
||||
// Create a SlideAtomsSets, not caring if they're empty
|
||||
//if(emptySet) { continue; }
|
||||
org.apache.poi.hslf.record.Record[] spaChildren = new org.apache.poi.hslf.record.Record[clen];
|
||||
System.arraycopy(_children,i+1,spaChildren,0,clen);
|
||||
org.apache.poi.hslf.record.Record[] spaChildren = Arrays.copyOfRange(_children,i+1, i+1+clen, org.apache.poi.hslf.record.Record[].class);
|
||||
SlideAtomsSet set = new SlideAtomsSet((SlidePersistAtom)_children[i],spaChildren);
|
||||
sets.add(set);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -44,7 +45,7 @@ public final class SlidePersistAtom extends RecordAtom {
|
|||
private static final String[] FLAGS_NAMES = { "HAS_SHAPES_OTHER_THAN_PLACEHOLDERS" };
|
||||
|
||||
|
||||
private final byte[] _header = new byte[8];
|
||||
private final byte[] _header;
|
||||
|
||||
/** Slide reference ID. Should correspond to the PersistPtr "sheet ID" of the matching slide/notes record */
|
||||
private int refID;
|
||||
|
@ -91,7 +92,7 @@ public final class SlidePersistAtom extends RecordAtom {
|
|||
if(len < 8) { len = 8; }
|
||||
|
||||
// Get the header
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Grab the reference ID
|
||||
refID = LittleEndian.getInt(source,start+8);
|
||||
|
@ -107,14 +108,14 @@ public final class SlidePersistAtom extends RecordAtom {
|
|||
|
||||
// Finally you have typically 4 or 8 bytes of reserved fields,
|
||||
// all zero running from 24 bytes in to the end
|
||||
reservedFields = IOUtils.safelyAllocate(len-24, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(source,start+24,reservedFields,0,reservedFields.length);
|
||||
reservedFields = IOUtils.safelyClone(source,start+24, len-24, MAX_RECORD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SlidePersistAtom, for use with a new Slide
|
||||
*/
|
||||
public SlidePersistAtom() {
|
||||
_header = new byte[8];
|
||||
LittleEndian.putUShort(_header, 0, 0);
|
||||
LittleEndian.putUShort(_header, 2, (int)_type);
|
||||
LittleEndian.putInt(_header, 4, 20);
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
|
||||
package org.apache.poi.hslf.record;
|
||||
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* A container holding information about a sound. It contains:
|
||||
|
@ -55,8 +56,7 @@ public final class Sound extends RecordContainer {
|
|||
*/
|
||||
protected Sound(byte[] source, int start, int len) {
|
||||
// Grab the header
|
||||
_header = new byte[8];
|
||||
System.arraycopy(source,start,_header,0,8);
|
||||
_header = Arrays.copyOfRange(source, start, start+8);
|
||||
|
||||
// Find our children
|
||||
_children = Record.findChildRecords(source,start+8,len-8);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue