1 2 /* ==================================================================== 3 * The Apache Software License, Version 1.1 4 * 5 * Copyright (c) 2002 The Apache Software Foundation. All rights 6 * reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The end-user documentation included with the redistribution, 21 * if any, must include the following acknowledgment: 22 * "This product includes software developed by the 23 * Apache Software Foundation (http://www.apache.org/)." 24 * Alternately, this acknowledgment may appear in the software itself, 25 * if and wherever such third-party acknowledgments normally appear. 26 * 27 * 4. The names "Apache" and "Apache Software Foundation" and 28 * "Apache POI" must not be used to endorse or promote products 29 * derived from this software without prior written permission. For 30 * written permission, please contact apache@apache.org. 31 * 32 * 5. Products derived from this software may not be called "Apache", 33 * "Apache POI", nor may "Apache" appear in their name, without 34 * prior written permission of the Apache Software Foundation. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This software consists of voluntary contributions made by many 51 * individuals on behalf of the Apache Software Foundation. For more 52 * information on the Apache Software Foundation, please see 53 * <http://www.apache.org/>. 54 */ 55 56 /* 57 * Ptg.java 58 * 59 * Created on October 28, 2001, 6:30 PM 60 */ 61 package org.apache.poi.hssf.record.formula; 62 63 import java.util.List; 64 import java.util.ArrayList; 65 66 /** 67 * 68 * @author andy 69 * @author avik 70 */ 71 72 public abstract class Ptg 73 { 74 75 76 /** convert infix order ptg list to rpn order ptg list 77 * @return List ptgs in RPN order 78 * @param infixPtgs List of ptgs in infix order 79 */ 80 81 /* DO NOT REMOVE 82 *we keep this method in case we wish to change the way we parse 83 *It needs a getPrecedence in OperationsPtg 84 85 public static List ptgsToRpn(List infixPtgs) { 86 java.util.Stack operands = new java.util.Stack(); 87 java.util.List retval = new java.util.Stack(); 88 89 java.util.ListIterator i = infixPtgs.listIterator(); 90 Object p; 91 OperationPtg o ; 92 boolean weHaveABracket = false; 93 while (i.hasNext()) { 94 p=i.next(); 95 if (p instanceof OperationPtg) { 96 if (p instanceof ParenthesisPtg) { 97 if (!weHaveABracket) { 98 operands.push(p); 99 weHaveABracket = true; 100 } else { 101 o = (OperationPtg) operands.pop(); 102 while (!(o instanceof ParenthesisPtg)) { 103 retval.add(o); 104 } 105 weHaveABracket = false; 106 } 107 } else { 108 109 while (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative 110 retval.add(operands.pop()); 111 } 112 operands.push(p); 113 } 114 } else { 115 retval.add(p); 116 } 117 } 118 while (!operands.isEmpty()) { 119 if (operands.peek() instanceof ParenthesisPtg ){ 120 //throw some error 121 } else { 122 retval.add(operands.pop()); 123 } 124 } 125 return retval; 126 } 127 */ 128 129 public static Ptg createPtg(byte [] data, int offset) 130 { 131 byte id = data[ offset + 0 ]; 132 Ptg retval = null; 133 134 final byte valueRef = ReferencePtg.sid + 0x20; 135 final byte arrayRef = ReferencePtg.sid + 0x40; 136 final byte valueFunc = FuncPtg.sid + 0x20; 137 final byte arrayFunc = FuncPtg.sid + 0x40; 138 final byte valueFuncVar = FuncVarPtg.sid +0x20; 139 final byte arrayFuncVar = FuncVarPtg.sid+0x40; 140 final byte valueArea = AreaPtg.sid + 0x20; 141 final byte arrayArea = AreaPtg.sid + 0x40; 142 143 switch (id) 144 { 145 case AddPtg.sid : 146 retval = new AddPtg(data, offset); 147 break; 148 149 case SubtractPtg.sid : 150 retval = new SubtractPtg(data, offset); 151 break; 152 153 case IntPtg.sid : 154 retval = new IntPtg(data, offset); 155 break; 156 157 case DividePtg.sid : 158 retval = new DividePtg(data, offset); 159 break; 160 161 case MultiplyPtg.sid : 162 retval = new MultiplyPtg(data, offset); 163 break; 164 165 case PowerPtg.sid : 166 retval = new PowerPtg(data, offset); 167 break; 168 169 case ConcatPtg.sid : 170 retval = new ConcatPtg(data, offset); 171 break; 172 173 case AreaPtg.sid : 174 retval = new AreaPtg(data, offset); 175 break; 176 case valueArea: 177 retval = new AreaPtg(data, offset); 178 break; 179 case arrayArea: 180 retval = new AreaPtg(data, offset); 181 break; 182 case MemErrPtg.sid : // 0x27 These 3 values 183 case MemErrPtg.sid+0x20 : // 0x47 documented in 184 case MemErrPtg.sid+0x40 : // 0x67 openOffice.org doc. 185 retval = new MemErrPtg(data, offset); 186 break; 187 188 case AttrPtg.sid : 189 retval = new AttrPtg(data, offset); 190 break; 191 192 case ReferencePtg.sid : 193 retval = new ReferencePtg(data, offset); 194 break; 195 case valueRef : 196 retval = new ReferencePtg(data, offset); 197 break; 198 case arrayRef : 199 retval = new ReferencePtg(data, offset); 200 break; 201 202 case ParenthesisPtg.sid : 203 retval = new ParenthesisPtg(data, offset); 204 break; 205 206 case FuncPtg.sid : 207 retval = new FuncPtg(data, offset); 208 break; 209 210 case valueFunc : 211 retval = new FuncPtg(data, offset); 212 break; 213 case arrayFunc : 214 retval = new FuncPtg(data, offset); 215 break; 216 217 case FuncVarPtg.sid : 218 retval = new FuncVarPtg(data, offset); 219 break; 220 221 case valueFuncVar : 222 retval = new FuncVarPtg(data, offset); 223 break; 224 case arrayFuncVar : 225 retval = new FuncVarPtg(data, offset); 226 break; 227 228 case NumberPtg.sid : 229 retval = new NumberPtg(data, offset); 230 break; 231 232 case StringPtg.sid : 233 retval = new StringPtg(data, offset); 234 break; 235 236 case NamePtg.sid : // 0x23 These 3 values 237 case NamePtg.sid+0x20 : // 0x43 documented in 238 case NamePtg.sid+0x40 : // 0x63 openOffice.org doc. 239 240 retval = new NamePtg(data, offset); 241 break; 242 243 case ExpPtg.sid : 244 retval = new ExpPtg(data, offset); 245 break; 246 247 case Area3DPtg.sid : // 0x3b These 3 values 248 case Area3DPtg.sid+0x20 : // 0x5b documented in 249 case Area3DPtg.sid+0x40 : // 0x7b openOffice.org doc. 250 251 retval = new Area3DPtg(data, offset); 252 break; 253 254 case Ref3DPtg.sid: // 0x3a These 3 values 255 case Ref3DPtg.sid+0x20: // 0x5a documented in 256 case Ref3DPtg.sid+0x40: // 0x7a openOffice.org doc. 257 258 retval = new Ref3DPtg(data, offset); 259 break; 260 261 case MissingArgPtg.sid: 262 retval = new MissingArgPtg(data,offset); 263 break; 264 265 default : 266 267 //retval = new UnknownPtg(); 268 throw new java.lang.UnsupportedOperationException( 269 Integer.toHexString(( int ) id) + " (" + ( int ) id + ")"); 270 } 271 272 if (id > 0x60) { 273 retval.setClass(CLASS_ARRAY); 274 } else if (id > 0x40) { 275 retval.setClass(CLASS_VALUE); 276 } else 277 retval.setClass(CLASS_REF); 278 return retval; 279 280 } 281 282 public abstract int getSize(); 283 284 public final byte [] getBytes() 285 { 286 int size = getSize(); 287 byte[] bytes = new byte[ size ]; 288 289 writeBytes(bytes, 0); 290 return bytes; 291 } 292 /** write this Ptg to a byte array*/ 293 public abstract void writeBytes(byte [] array, int offset); 294 295 /** 296 * return a string representation of this token alone 297 */ 298 public abstract String toFormulaString(); 299 /** 300 * dump a debug representation (hexdump) to a strnig 301 */ 302 public String toDebugString() { 303 byte[] ba = new byte[getSize()]; 304 String retval=null; 305 writeBytes(ba,0); 306 try { 307 retval = org.apache.poi.util.HexDump.dump(ba,0,0); 308 } catch (Exception e) { 309 e.printStackTrace(); 310 } 311 return retval; 312 } 313 314 public static final byte CLASS_REF = 0x00; 315 public static final byte CLASS_VALUE = 0x20; 316 public static final byte CLASS_ARRAY = 0x40; 317 318 protected byte ptgClass = CLASS_REF; //base ptg 319 320 public void setClass(byte thePtgClass) { 321 ptgClass = thePtgClass; 322 } 323 324 /** returns the class (REF/VALUE/ARRAY) for this Ptg */ 325 public byte getPtgClass() { 326 return ptgClass; 327 } 328 329 public abstract byte getDefaultOperandClass(); 330 331 332 333 } 334