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