001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hwpf.sprm;
019:
020: import org.apache.poi.util.BitField;
021: import org.apache.poi.util.BitFieldFactory;
022: import org.apache.poi.util.LittleEndian;
023:
024: /**
025: * This class is used to represent a sprm operation from a Word 97/2000/XP
026: * document.
027: * @author Ryan Ackley
028: * @version 1.0
029: */
030: public class SprmOperation {
031: final static private BitField OP_BITFIELD = BitFieldFactory
032: .getInstance(0x1ff);
033: final static private BitField SPECIAL_BITFIELD = BitFieldFactory
034: .getInstance(0x200);
035: final static private BitField TYPE_BITFIELD = BitFieldFactory
036: .getInstance(0x1c00);
037: final static private BitField SIZECODE_BITFIELD = BitFieldFactory
038: .getInstance(0xe000);
039:
040: final static private short LONG_SPRM_TABLE = (short) 0xd608;
041: final static private short LONG_SPRM_PARAGRAPH = (short) 0xc615;
042:
043: final static public int PAP_TYPE = 1;
044: final static public int TAP_TYPE = 5;
045:
046: private int _type;
047: private int _operation;
048: private int _gOffset;
049: private byte[] _grpprl;
050: private int _sizeCode;
051: private int _size;
052:
053: public SprmOperation(byte[] grpprl, int offset) {
054: _grpprl = grpprl;
055:
056: short sprmStart = LittleEndian.getShort(grpprl, offset);
057:
058: _gOffset = offset + 2;
059:
060: _operation = OP_BITFIELD.getValue(sprmStart);
061: _type = TYPE_BITFIELD.getValue(sprmStart);
062: _sizeCode = SIZECODE_BITFIELD.getValue(sprmStart);
063: _size = initSize(sprmStart);
064: }
065:
066: public static int getOperationFromOpcode(short opcode) {
067: return OP_BITFIELD.getValue(opcode);
068: }
069:
070: public static int getTypeFromOpcode(short opcode) {
071: return TYPE_BITFIELD.getValue(opcode);
072: }
073:
074: public int getType() {
075: return _type;
076: }
077:
078: public int getOperation() {
079: return _operation;
080: }
081:
082: public int getGrpprlOffset() {
083: return _gOffset;
084: }
085:
086: public int getOperand() {
087: switch (_sizeCode) {
088: case 0:
089: case 1:
090: return _grpprl[_gOffset];
091: case 2:
092: case 4:
093: case 5:
094: return LittleEndian.getShort(_grpprl, _gOffset);
095: case 3:
096: return LittleEndian.getInt(_grpprl, _gOffset);
097: case 6:
098: throw new UnsupportedOperationException(
099: "This SPRM contains a variable length operand");
100: case 7:
101: byte threeByteInt[] = new byte[4];
102: threeByteInt[0] = _grpprl[_gOffset];
103: threeByteInt[1] = _grpprl[_gOffset + 1];
104: threeByteInt[2] = _grpprl[_gOffset + 2];
105: threeByteInt[3] = (byte) 0;
106: return LittleEndian.getInt(threeByteInt, 0);
107: default:
108: throw new IllegalArgumentException(
109: "SPRM contains an invalid size code");
110: }
111: }
112:
113: public int getSizeCode() {
114: return _sizeCode;
115: }
116:
117: public int size() {
118: return _size;
119: }
120:
121: public byte[] getGrpprl() {
122: return _grpprl;
123: }
124:
125: private int initSize(short sprm) {
126: switch (_sizeCode) {
127: case 0:
128: case 1:
129: return 3;
130: case 2:
131: case 4:
132: case 5:
133: return 4;
134: case 3:
135: return 6;
136: case 6:
137: if (sprm == LONG_SPRM_TABLE || sprm == LONG_SPRM_PARAGRAPH) {
138: int retVal = (0x0000ffff & LittleEndian.getShort(
139: _grpprl, _gOffset)) + 3;
140: _gOffset += 2;
141: return retVal;
142: } else {
143: return (0x000000ff & _grpprl[_gOffset++]) + 3;
144: }
145: case 7:
146: return 5;
147: default:
148: throw new IllegalArgumentException(
149: "SPRM contains an invalid size code");
150: }
151: }
152: }
|