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 import org.apache.poi.hssf.util.SheetReferences; 67 68 /** 69 * 70 * @author andy 71 * @author avik 72 * @author Jason Height (jheight at chariot dot net dot au) 73 */ 74 75 public abstract class Ptg 76 { 77 78 79 /** convert infix order ptg list to rpn order ptg list 80 * @return List ptgs in RPN order 81 * @param infixPtgs List of ptgs in infix order 82 */ 83 84 /* DO NOT REMOVE 85 *we keep this method in case we wish to change the way we parse 86 *It needs a getPrecedence in OperationsPtg 87 88 public static List ptgsToRpn(List infixPtgs) { 89 java.util.Stack operands = new java.util.Stack(); 90 java.util.List retval = new java.util.Stack(); 91 92 java.util.ListIterator i = infixPtgs.listIterator(); 93 Object p; 94 OperationPtg o ; 95 boolean weHaveABracket = false; 96 while (i.hasNext()) { 97 p=i.next(); 98 if (p instanceof OperationPtg) { 99 if (p instanceof ParenthesisPtg) { 100 if (!weHaveABracket) { 101 operands.push(p); 102 weHaveABracket = true; 103 } else { 104 o = (OperationPtg) operands.pop(); 105 while (!(o instanceof ParenthesisPtg)) { 106 retval.add(o); 107 } 108 weHaveABracket = false; 109 } 110 } else { 111 112 while (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative 113 retval.add(operands.pop()); 114 } 115 operands.push(p); 116 } 117 } else { 118 retval.add(p); 119 } 120 } 121 while (!operands.isEmpty()) { 122 if (operands.peek() instanceof ParenthesisPtg ){ 123 //throw some error 124 } else { 125 retval.add(operands.pop()); 126 } 127 } 128 return retval; 129 } 130 */ 131 132 public static Ptg createPtg(byte [] data, int offset) 133 { 134 byte id = data[ offset + 0 ]; 135 Ptg retval = null; 136 137 final byte valueRef = ReferencePtg.sid + 0x20; 138 final byte arrayRef = ReferencePtg.sid + 0x40; 139 final byte valueFunc = FuncPtg.sid + 0x20; 140 final byte arrayFunc = FuncPtg.sid + 0x40; 141 final byte valueFuncVar = FuncVarPtg.sid +0x20; 142 final byte arrayFuncVar = FuncVarPtg.sid+0x40; 143 final byte valueArea = AreaPtg.sid + 0x20; 144 final byte arrayArea = AreaPtg.sid + 0x40; 145 146 switch (id) 147 { 148 case AddPtg.sid : 149 retval = new AddPtg(data, offset); 150 break; 151 152 case SubtractPtg.sid : 153 retval = new SubtractPtg(data, offset); 154 break; 155 156 case IntPtg.sid : 157 retval = new IntPtg(data, offset); 158 break; 159 160 case DividePtg.sid : 161 retval = new DividePtg(data, offset); 162 break; 163 164 case MultiplyPtg.sid : 165 retval = new MultiplyPtg(data, offset); 166 break; 167 168 case PowerPtg.sid : 169 retval = new PowerPtg(data, offset); 170 break; 171 172 case EqualPtg.sid: 173 retval = new EqualPtg(data, offset); 174 break; 175 176 case ConcatPtg.sid : 177 retval = new ConcatPtg(data, offset); 178 break; 179 180 case AreaPtg.sid : 181 retval = new AreaPtg(data, offset); 182 break; 183 case valueArea: 184 retval = new AreaPtg(data, offset); 185 break; 186 case arrayArea: 187 retval = new AreaPtg(data, offset); 188 break; 189 case MemErrPtg.sid : // 0x27 These 3 values 190 case MemErrPtg.sid+0x20 : // 0x47 documented in 191 case MemErrPtg.sid+0x40 : // 0x67 openOffice.org doc. 192 retval = new MemErrPtg(data, offset); 193 break; 194 195 case AttrPtg.sid : 196 retval = new AttrPtg(data, offset); 197 break; 198 199 case ReferencePtg.sid : 200 retval = new ReferencePtg(data, offset); 201 break; 202 case valueRef : 203 retval = new ReferencePtg(data, offset); 204 break; 205 case arrayRef : 206 retval = new ReferencePtg(data, offset); 207 break; 208 209 case ParenthesisPtg.sid : 210 retval = new ParenthesisPtg(data, offset); 211 break; 212 213 case FuncPtg.sid : 214 retval = new FuncPtg(data, offset); 215 break; 216 217 case valueFunc : 218 retval = new FuncPtg(data, offset); 219 break; 220 case arrayFunc : 221 retval = new FuncPtg(data, offset); 222 break; 223 224 case FuncVarPtg.sid : 225 retval = new FuncVarPtg(data, offset); 226 break; 227 228 case valueFuncVar : 229 retval = new FuncVarPtg(data, offset); 230 break; 231 case arrayFuncVar : 232 retval = new FuncVarPtg(data, offset); 233 break; 234 235 case NumberPtg.sid : 236 retval = new NumberPtg(data, offset); 237 break; 238 239 case StringPtg.sid : 240 retval = new StringPtg(data, offset); 241 break; 242 243 case NamePtg.sid : // 0x23 These 3 values 244 case NamePtg.sid+0x20 : // 0x43 documented in 245 case NamePtg.sid+0x40 : // 0x63 openOffice.org doc. 246 247 retval = new NamePtg(data, offset); 248 break; 249 250 case ExpPtg.sid : 251 retval = new ExpPtg(data, offset); 252 break; 253 254 case Area3DPtg.sid : // 0x3b These 3 values 255 case Area3DPtg.sid+0x20 : // 0x5b documented in 256 case Area3DPtg.sid+0x40 : // 0x7b openOffice.org doc. 257 258 retval = new Area3DPtg(data, offset); 259 break; 260 261 case Ref3DPtg.sid: // 0x3a These 3 values 262 case Ref3DPtg.sid+0x20: // 0x5a documented in 263 case Ref3DPtg.sid+0x40: // 0x7a openOffice.org doc. 264 265 retval = new Ref3DPtg(data, offset); 266 break; 267 268 case MissingArgPtg.sid: 269 retval = new MissingArgPtg(data,offset); 270 break; 271 272 default : 273 274 //retval = new UnknownPtg(); 275 throw new java.lang.UnsupportedOperationException( 276 Integer.toHexString(( int ) id) + " (" + ( int ) id + ")"); 277 } 278 279 if (id > 0x60) { 280 retval.setClass(CLASS_ARRAY); 281 } else if (id > 0x40) { 282 retval.setClass(CLASS_VALUE); 283 } else 284 retval.setClass(CLASS_REF); 285 return retval; 286 287 } 288 289 public abstract int getSize(); 290 291 public final byte [] getBytes() 292 { 293 int size = getSize(); 294 byte[] bytes = new byte[ size ]; 295 296 writeBytes(bytes, 0); 297 return bytes; 298 } 299 /** write this Ptg to a byte array*/ 300 public abstract void writeBytes(byte [] array, int offset); 301 302 /** 303 * return a string representation of this token alone 304 */ 305 public abstract String toFormulaString(SheetReferences refs); 306 /** 307 * dump a debug representation (hexdump) to a string 308 */ 309 public String toDebugString() { 310 byte[] ba = new byte[getSize()]; 311 String retval=null; 312 writeBytes(ba,0); 313 try { 314 retval = org.apache.poi.util.HexDump.dump(ba,0,0); 315 } catch (Exception e) { 316 e.printStackTrace(); 317 } 318 return retval; 319 } 320 321 public static final byte CLASS_REF = 0x00; 322 public static final byte CLASS_VALUE = 0x20; 323 public static final byte CLASS_ARRAY = 0x40; 324 325 protected byte ptgClass = CLASS_REF; //base ptg 326 327 public void setClass(byte thePtgClass) { 328 ptgClass = thePtgClass; 329 } 330 331 /** returns the class (REF/VALUE/ARRAY) for this Ptg */ 332 public byte getPtgClass() { 333 return ptgClass; 334 } 335 336 public abstract byte getDefaultOperandClass(); 337 338 public abstract Object clone(); 339 340 341 342 } 343