refactor SprmOperation, reducing memory consumption for a bit

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1145279 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sergey Vladimirov 2011-07-11 18:38:03 +00:00
parent 0c281fd3f7
commit f24c96d0b7
1 changed files with 139 additions and 120 deletions

View File

@ -24,71 +24,77 @@ import org.apache.poi.util.LittleEndian;
/** /**
* This class is used to represent a sprm operation from a Word 97/2000/XP * This class is used to represent a sprm operation from a Word 97/2000/XP
* document. * document.
*
* @author Ryan Ackley * @author Ryan Ackley
* @version 1.0 * @version 1.0
*/ */
public final class SprmOperation public final class SprmOperation
{ {
final static private BitField OP_BITFIELD = BitFieldFactory.getInstance(0x1ff); private static final BitField BITFIELD_OP = BitFieldFactory
final static private BitField SPECIAL_BITFIELD = BitFieldFactory.getInstance(0x200); .getInstance( 0x1ff );
final static private BitField TYPE_BITFIELD = BitFieldFactory.getInstance(0x1c00); private static final BitField BITFIELD_SIZECODE = BitFieldFactory
final static private BitField SIZECODE_BITFIELD = BitFieldFactory.getInstance(0xe000); .getInstance( 0xe000 );
private static final BitField BITFIELD_SPECIAL = BitFieldFactory
.getInstance( 0x200 );
private static final BitField BITFIELD_TYPE = BitFieldFactory
.getInstance( 0x1c00 );
final static private short LONG_SPRM_TABLE = (short)0xd608; final static private short SPRM_LONG_PARAGRAPH = (short) 0xc615;
final static private short LONG_SPRM_PARAGRAPH = (short)0xc615; final static private short SPRM_LONG_TABLE = (short) 0xd608;
final static public int PAP_TYPE = 1; public static final int TYPE_PAP = 1;
final static public int TAP_TYPE = 5; public static final int TYPE_TAP = 5;
private short _value; @Deprecated
private int _type; final static public int PAP_TYPE = TYPE_PAP;
private int _operation; @Deprecated
final static public int TAP_TYPE = TYPE_TAP;
public static int getOperationFromOpcode( short opcode )
{
return BITFIELD_OP.getValue( opcode );
}
public static int getTypeFromOpcode( short opcode )
{
return BITFIELD_TYPE.getValue( opcode );
}
private int _offset;
private int _gOffset; private int _gOffset;
private byte[] _grpprl; private byte[] _grpprl;
private int _sizeCode;
private int _size; private int _size;
private short _value;
public SprmOperation(byte[] grpprl, int offset) public SprmOperation( byte[] grpprl, int offset )
{ {
_grpprl = grpprl; _grpprl = grpprl;
_value = LittleEndian.getShort( grpprl, offset );
_value = LittleEndian.getShort(grpprl, offset); _offset = offset;
_gOffset = offset + 2; _gOffset = offset + 2;
_size = initSize( _value );
_operation = OP_BITFIELD.getValue(_value);
_type = TYPE_BITFIELD.getValue(_value);
_sizeCode = SIZECODE_BITFIELD.getValue(_value);
_size = initSize(_value);
} }
public static int getOperationFromOpcode(short opcode) public byte[] toByteArray()
{ {
return OP_BITFIELD.getValue(opcode); byte[] result = new byte[size()];
System.arraycopy( _grpprl, _offset, result, 0, size() );
return result;
} }
public static int getTypeFromOpcode(short opcode) public byte[] getGrpprl()
{ {
return TYPE_BITFIELD.getValue(opcode); return _grpprl;
}
public int getType()
{
return _type;
}
public int getOperation()
{
return _operation;
} }
public int getGrpprlOffset() public int getGrpprlOffset()
{ {
return _gOffset; return _gOffset;
} }
public int getOperand() public int getOperand()
{ {
switch (_sizeCode) switch ( getSizeCode() )
{ {
case 0: case 0:
case 1: case 1:
@ -96,46 +102,51 @@ public final class SprmOperation
case 2: case 2:
case 4: case 4:
case 5: case 5:
return LittleEndian.getShort(_grpprl, _gOffset); return LittleEndian.getShort( _grpprl, _gOffset );
case 3: case 3:
return LittleEndian.getInt(_grpprl, _gOffset); return LittleEndian.getInt( _grpprl, _gOffset );
case 6: case 6:
byte operandLength = _grpprl[_gOffset + 1]; //surely shorter than an int... // surely shorter than an int...
byte operandLength = _grpprl[_gOffset + 1];
byte [] codeBytes = new byte[LittleEndian.INT_SIZE]; //initialized to zeros by JVM // initialized to zeros by JVM
for(int i = 0; i < operandLength; i++) byte[] codeBytes = new byte[LittleEndian.INT_SIZE];
if(_gOffset + i < _grpprl.length) for ( int i = 0; i < operandLength; i++ )
if ( _gOffset + i < _grpprl.length )
codeBytes[i] = _grpprl[_gOffset + 1 + i]; codeBytes[i] = _grpprl[_gOffset + 1 + i];
return LittleEndian.getInt(codeBytes, 0); return LittleEndian.getInt( codeBytes, 0 );
case 7: case 7:
byte threeByteInt[] = new byte[4]; byte threeByteInt[] = new byte[4];
threeByteInt[0] = _grpprl[_gOffset]; threeByteInt[0] = _grpprl[_gOffset];
threeByteInt[1] = _grpprl[_gOffset + 1]; threeByteInt[1] = _grpprl[_gOffset + 1];
threeByteInt[2] = _grpprl[_gOffset + 2]; threeByteInt[2] = _grpprl[_gOffset + 2];
threeByteInt[3] = (byte)0; threeByteInt[3] = (byte) 0;
return LittleEndian.getInt(threeByteInt, 0); return LittleEndian.getInt( threeByteInt, 0 );
default: default:
throw new IllegalArgumentException("SPRM contains an invalid size code"); throw new IllegalArgumentException(
"SPRM contains an invalid size code" );
} }
} }
public int getOperation()
{
return BITFIELD_OP.getValue( _value );
}
public int getSizeCode() public int getSizeCode()
{ {
return _sizeCode; return BITFIELD_SIZECODE.getValue( _value );
} }
public int size() public int getType()
{ {
return _size; return BITFIELD_TYPE.getValue( _value );
} }
public byte[] getGrpprl() private int initSize( short sprm )
{ {
return _grpprl; switch ( getSizeCode() )
}
private int initSize(short sprm)
{
switch (_sizeCode)
{ {
case 0: case 0:
case 1: case 1:
@ -147,20 +158,28 @@ public final class SprmOperation
case 3: case 3:
return 6; return 6;
case 6: case 6:
if (sprm == LONG_SPRM_TABLE || sprm == LONG_SPRM_PARAGRAPH) int offset = _gOffset;
if ( sprm == SPRM_LONG_TABLE || sprm == SPRM_LONG_PARAGRAPH )
{ {
int retVal = (0x0000ffff & LittleEndian.getShort(_grpprl, _gOffset)) + 3; int retVal = ( 0x0000ffff & LittleEndian.getShort( _grpprl,
offset ) ) + 3;
_gOffset += 2; _gOffset += 2;
return retVal; return retVal;
} }
return (0x000000ff & _grpprl[_gOffset++]) + 3; return ( 0x000000ff & _grpprl[_gOffset++] ) + 3;
case 7: case 7:
return 5; return 5;
default: default:
throw new IllegalArgumentException("SPRM contains an invalid size code"); throw new IllegalArgumentException(
"SPRM contains an invalid size code" );
} }
} }
public int size()
{
return _size;
}
@Override @Override
public String toString() public String toString()
{ {