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 */ 70 71 public abstract class Ptg 72 { 73 74 75 /** convert infix order ptg list to rpn order ptg list 76 * @return List ptgs in RPN order 77 * @param infixPtgs List of ptgs in infix order 78 */ 79 80 /* DO NOT REMOVE 81 *we keep this method in case we wish to change the way we parse 82 *It needs a getPrecedence in OperationsPtg 83 84 public static List ptgsToRpn(List infixPtgs) { 85 java.util.Stack operands = new java.util.Stack(); 86 java.util.List retval = new java.util.Stack(); 87 88 java.util.ListIterator i = infixPtgs.listIterator(); 89 Object p; 90 OperationPtg o ; 91 boolean weHaveABracket = false; 92 while (i.hasNext()) { 93 p=i.next(); 94 if (p instanceof OperationPtg) { 95 if (p instanceof ParenthesisPtg) { 96 if (!weHaveABracket) { 97 operands.push(p); 98 weHaveABracket = true; 99 } else { 100 o = (OperationPtg) operands.pop(); 101 while (!(o instanceof ParenthesisPtg)) { 102 retval.add(o); 103 } 104 weHaveABracket = false; 105 } 106 } else { 107 108 while (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative 109 retval.add(operands.pop()); 110 } 111 operands.push(p); 112 } 113 } else { 114 retval.add(p); 115 } 116 } 117 while (!operands.isEmpty()) { 118 if (operands.peek() instanceof ParenthesisPtg ){ 119 //throw some error 120 } else { 121 retval.add(operands.pop()); 122 } 123 } 124 return retval; 125 } 126 */ 127 128 129 130 /* 131 private static List ptgsToList(Class [] ptgs) 132 { 133 List result = new ArrayList(); 134 Constructor constructor; 135 136 for (int i = 0; i < ptgs.length; i++) 137 { 138 Class ptg = null; 139 140 ptg = ptgs[ i ]; 141 try 142 { 143 144 constructor = ptg.getConstructor(new Class[] 145 { 146 byte [].class, int.class 147 }); 148 } 149 catch (Exception illegalArgumentException) 150 { 151 throw new RuntimeException( 152 "Now that didn't work nicely at all (couldn't do that there list of ptgs)"); 153 } 154 result.add(constructor); 155 } 156 return result; 157 }*/ 158 159 160 public static Ptg createPtg(byte [] data, int offset) 161 { 162 byte id = data[ offset + 0 ]; 163 Ptg retval = null; 164 165 final int refRef = ReferencePtg.sid - 0x20; 166 final int arrayRef = ReferencePtg.sid + 0x20; 167 168 169 final int valueFunc = FunctionPtg.sid + 0x20; 170 final int arrayFunc = FunctionPtg.sid + 0x40; 171 172 173 final int refArea = AreaPtg.sid-0x20; 174 final int arrayArea = AreaPtg.sid+0x20; 175 176 177 switch (id) 178 { 179 180 case AddPtg.sid : 181 retval = new AddPtg(data, offset); 182 break; 183 184 case SubtractPtg.sid : 185 retval = new SubtractPtg(data, offset); 186 break; 187 188 case IntPtg.sid : 189 retval = new IntPtg(data, offset); 190 break; 191 192 case DividePtg.sid : 193 retval = new DividePtg(data, offset); 194 break; 195 196 case MultiplyPtg.sid : 197 retval = new MultiplyPtg(data, offset); 198 break; 199 200 case PowerPtg.sid : 201 retval = new PowerPtg(data, offset); 202 break; 203 204 case ConcatPtg.sid : 205 retval = new ConcatPtg(data, offset); 206 break; 207 208 209 case AreaPtg.sid : 210 retval = new AreaPtg(data, offset); 211 break; 212 213 case MemErrPtg.sid : 214 retval = new MemErrPtg(data, offset); 215 break; 216 217 case AttrPtg.sid : 218 retval = new AttrPtg(data, offset); 219 break; 220 221 case ReferencePtg.sid : 222 retval = new ReferencePtg(data, offset); 223 break; 224 225 case refRef : 226 retval = new ReferencePtg(data, offset); 227 break; 228 229 case arrayRef : 230 retval = new ReferencePtg(data, offset); 231 break; 232 233 case ParenthesisPtg.sid : 234 retval = new ParenthesisPtg(data, offset); 235 break; 236 237 case FunctionPtg.sid : 238 retval = new FunctionPtg(data, offset); 239 break; 240 241 case valueFunc : 242 retval = new FunctionPtg(data, offset); 243 break; 244 245 case arrayFunc : 246 retval = new FunctionPtg(data, offset); 247 break; 248 249 250 case NumberPtg.sid : 251 retval = new NumberPtg(data, offset); 252 break; 253 254 255 256 257 case NamePtg.sid : 258 retval = new NamePtg(data, offset); 259 break; 260 261 case ExpPtg.sid : 262 retval = new ExpPtg(data, offset); 263 break; 264 265 case Area3DPtg.sid : 266 retval = new Area3DPtg(data, offset); 267 break; 268 269 case Ref3DPtg.sid: 270 retval = new Ref3DPtg(data, offset); 271 break; 272 273 default : 274 275 // retval = new UnknownPtg(); 276 throw new RuntimeException("Unknown PTG = " 277 + Integer.toHexString(( int ) id) 278 + " (" + ( int ) id + ")"); 279 } 280 return retval; 281 } 282 283 public abstract int getSize(); 284 285 public final byte [] getBytes() 286 { 287 int size = getSize(); 288 byte[] bytes = new byte[ size ]; 289 290 writeBytes(bytes, 0); 291 return bytes; 292 } 293 /** write this Ptg to a byte array*/ 294 public abstract void writeBytes(byte [] array, int offset); 295 296 /** 297 * return a string representation of this token alone 298 */ 299 public abstract String toFormulaString(); 300 /** 301 * dump a debug representation (hexdump) to a strnig 302 */ 303 public String toDebugString() { 304 byte[] ba = new byte[getSize()]; 305 String retval=null; 306 writeBytes(ba,0); 307 try { 308 retval = org.apache.poi.util.HexDump.dump(ba,0,0); 309 } catch (Exception e) { 310 e.printStackTrace(); 311 } 312 return retval; 313 } 314 315 316 } 317