]> source.dussan.org Git - poi.git/commitdiff
refactor SprmOperation, reducing memory consumption for a bit
authorSergey Vladimirov <sergey@apache.org>
Mon, 11 Jul 2011 18:38:03 +0000 (18:38 +0000)
committerSergey Vladimirov <sergey@apache.org>
Mon, 11 Jul 2011 18:38:03 +0000 (18:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1145279 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hwpf/sprm/SprmOperation.java

index 836d93617a7d43a7e8bb69336112edd4b8dcdf1a..6465f3b32b2a8510644c4f6aa7493f6b9617f519 100644 (file)
@@ -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()