From: Sergey Vladimirov Date: Mon, 11 Jul 2011 18:38:03 +0000 (+0000) Subject: refactor SprmOperation, reducing memory consumption for a bit X-Git-Tag: REL_3_8_BETA4~213 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f24c96d0b77c767313f5eb6883a88fa8709ad23a;p=poi.git 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 --- diff --git a/src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmOperation.java b/src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmOperation.java index 836d93617a..6465f3b32b 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmOperation.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmOperation.java @@ -24,142 +24,161 @@ import org.apache.poi.util.LittleEndian; /** * This class is used to represent a sprm operation from a Word 97/2000/XP * document. + * * @author Ryan Ackley * @version 1.0 */ public final class SprmOperation { - final static private BitField OP_BITFIELD = BitFieldFactory.getInstance(0x1ff); - final static private BitField SPECIAL_BITFIELD = BitFieldFactory.getInstance(0x200); - final static private BitField TYPE_BITFIELD = BitFieldFactory.getInstance(0x1c00); - final static private BitField SIZECODE_BITFIELD = BitFieldFactory.getInstance(0xe000); - - final static private short LONG_SPRM_TABLE = (short)0xd608; - final static private short LONG_SPRM_PARAGRAPH = (short)0xc615; - - final static public int PAP_TYPE = 1; - final static public int TAP_TYPE = 5; - - private short _value; - private int _type; - private int _operation; - private int _gOffset; - private byte[] _grpprl; - private int _sizeCode; - private int _size; - - public SprmOperation(byte[] grpprl, int offset) - { - _grpprl = grpprl; - - _value = LittleEndian.getShort(grpprl, offset); - - _gOffset = offset + 2; - - _operation = OP_BITFIELD.getValue(_value); - _type = TYPE_BITFIELD.getValue(_value); - _sizeCode = SIZECODE_BITFIELD.getValue(_value); - _size = initSize(_value); - } - - public static int getOperationFromOpcode(short opcode) - { - return OP_BITFIELD.getValue(opcode); - } - - public static int getTypeFromOpcode(short opcode) - { - return TYPE_BITFIELD.getValue(opcode); - } - - public int getType() - { - return _type; - } - - public int getOperation() - { - return _operation; - } - - public int getGrpprlOffset() - { - return _gOffset; - } - public int getOperand() - { - switch (_sizeCode) + private static final BitField BITFIELD_OP = BitFieldFactory + .getInstance( 0x1ff ); + private static final BitField BITFIELD_SIZECODE = BitFieldFactory + .getInstance( 0xe000 ); + private static final BitField BITFIELD_SPECIAL = BitFieldFactory + .getInstance( 0x200 ); + private static final BitField BITFIELD_TYPE = BitFieldFactory + .getInstance( 0x1c00 ); + + final static private short SPRM_LONG_PARAGRAPH = (short) 0xc615; + final static private short SPRM_LONG_TABLE = (short) 0xd608; + + public static final int TYPE_PAP = 1; + public static final int TYPE_TAP = 5; + + @Deprecated + final static public int PAP_TYPE = TYPE_PAP; + @Deprecated + final static public int TAP_TYPE = TYPE_TAP; + + public static int getOperationFromOpcode( short opcode ) { - case 0: - case 1: - return _grpprl[_gOffset]; - case 2: - case 4: - case 5: - return LittleEndian.getShort(_grpprl, _gOffset); - case 3: - return LittleEndian.getInt(_grpprl, _gOffset); - case 6: - byte operandLength = _grpprl[_gOffset + 1]; //surely shorter than an int... - - byte [] codeBytes = new byte[LittleEndian.INT_SIZE]; //initialized to zeros by JVM - for(int i = 0; i < operandLength; i++) - if(_gOffset + i < _grpprl.length) - codeBytes[i] = _grpprl[_gOffset + 1 + i]; - - return LittleEndian.getInt(codeBytes, 0); - case 7: - byte threeByteInt[] = new byte[4]; - threeByteInt[0] = _grpprl[_gOffset]; - threeByteInt[1] = _grpprl[_gOffset + 1]; - threeByteInt[2] = _grpprl[_gOffset + 2]; - threeByteInt[3] = (byte)0; - return LittleEndian.getInt(threeByteInt, 0); - default: - throw new IllegalArgumentException("SPRM contains an invalid size code"); + return BITFIELD_OP.getValue( opcode ); } - } - public int getSizeCode() - { - return _sizeCode; - } - - public int size() - { - return _size; - } - - public byte[] getGrpprl() - { - return _grpprl; - } - private int initSize(short sprm) - { - switch (_sizeCode) + + public static int getTypeFromOpcode( short opcode ) + { + return BITFIELD_TYPE.getValue( opcode ); + } + + private int _offset; + private int _gOffset; + private byte[] _grpprl; + private int _size; + private short _value; + + public SprmOperation( byte[] grpprl, int offset ) { - case 0: - case 1: - return 3; - case 2: - case 4: - case 5: - return 4; - case 3: - return 6; - case 6: - if (sprm == LONG_SPRM_TABLE || sprm == LONG_SPRM_PARAGRAPH) + _grpprl = grpprl; + _value = LittleEndian.getShort( grpprl, offset ); + _offset = offset; + _gOffset = offset + 2; + _size = initSize( _value ); + } + + public byte[] toByteArray() + { + byte[] result = new byte[size()]; + System.arraycopy( _grpprl, _offset, result, 0, size() ); + return result; + } + + public byte[] getGrpprl() + { + return _grpprl; + } + + public int getGrpprlOffset() + { + return _gOffset; + } + + public int getOperand() + { + switch ( getSizeCode() ) { - int retVal = (0x0000ffff & LittleEndian.getShort(_grpprl, _gOffset)) + 3; - _gOffset += 2; - return retVal; + case 0: + case 1: + return _grpprl[_gOffset]; + case 2: + case 4: + case 5: + return LittleEndian.getShort( _grpprl, _gOffset ); + case 3: + return LittleEndian.getInt( _grpprl, _gOffset ); + case 6: + // surely shorter than an int... + byte operandLength = _grpprl[_gOffset + 1]; + + // initialized to zeros by JVM + byte[] codeBytes = new byte[LittleEndian.INT_SIZE]; + for ( int i = 0; i < operandLength; i++ ) + if ( _gOffset + i < _grpprl.length ) + codeBytes[i] = _grpprl[_gOffset + 1 + i]; + + return LittleEndian.getInt( codeBytes, 0 ); + case 7: + byte threeByteInt[] = new byte[4]; + threeByteInt[0] = _grpprl[_gOffset]; + threeByteInt[1] = _grpprl[_gOffset + 1]; + threeByteInt[2] = _grpprl[_gOffset + 2]; + threeByteInt[3] = (byte) 0; + return LittleEndian.getInt( threeByteInt, 0 ); + default: + throw new IllegalArgumentException( + "SPRM contains an invalid size code" ); } - return (0x000000ff & _grpprl[_gOffset++]) + 3; - case 7: - return 5; - default: - throw new IllegalArgumentException("SPRM contains an invalid size code"); } - } + + public int getOperation() + { + return BITFIELD_OP.getValue( _value ); + } + + public int getSizeCode() + { + return BITFIELD_SIZECODE.getValue( _value ); + } + + public int getType() + { + return BITFIELD_TYPE.getValue( _value ); + } + + private int initSize( short sprm ) + { + switch ( getSizeCode() ) + { + case 0: + case 1: + return 3; + case 2: + case 4: + case 5: + return 4; + case 3: + return 6; + case 6: + int offset = _gOffset; + if ( sprm == SPRM_LONG_TABLE || sprm == SPRM_LONG_PARAGRAPH ) + { + int retVal = ( 0x0000ffff & LittleEndian.getShort( _grpprl, + offset ) ) + 3; + _gOffset += 2; + return retVal; + } + return ( 0x000000ff & _grpprl[_gOffset++] ) + 3; + case 7: + return 5; + default: + throw new IllegalArgumentException( + "SPRM contains an invalid size code" ); + } + } + + public int size() + { + return _size; + } @Override public String toString()