1 19 20 package jxl.biff.formula; 21 22 import java.util.Stack ; 23 24 import common.Assert; 25 import common.Logger; 26 27 import jxl.WorkbookSettings; 28 import jxl.biff.IntegerHelper; 29 30 34 class VariableArgFunction extends Operator implements ParsedThing 35 { 36 39 private static Logger logger = Logger.getLogger(VariableArgFunction.class); 40 41 44 private Function function; 45 46 49 private int arguments; 50 51 55 private boolean readFromSheet; 56 57 60 private WorkbookSettings settings; 61 62 65 public VariableArgFunction(WorkbookSettings ws) 66 { 67 readFromSheet = true; 68 settings = ws; 69 } 70 71 77 public VariableArgFunction(Function f, int a, WorkbookSettings ws) 78 { 79 function = f; 80 arguments = a; 81 readFromSheet = false; 82 settings = ws; 83 } 84 85 93 public int read(byte[] data, int pos) throws FormulaException 94 { 95 arguments = data[pos]; 96 int index = IntegerHelper.getInt(data[pos+1], data[pos+2]); 97 function = Function.getFunction(index); 98 99 if (function == function.UNKNOWN) 100 { 101 throw new FormulaException(FormulaException.unrecognizedFunction, index); 102 } 103 104 return 3; 105 } 106 107 110 public void getOperands(Stack s) 111 { 112 ParseItem[] items = new ParseItem[arguments]; 114 115 for (int i = arguments - 1; i >= 0 ; i--) 116 { 117 ParseItem pi = (ParseItem) s.pop(); 118 119 items[i] = pi; 120 } 121 122 for (int i = 0 ; i < arguments; i++) 123 { 124 add(items[i]); 125 } 126 } 127 128 public void getString(StringBuffer buf) 129 { 130 buf.append(function.getName(settings)); 131 buf.append('('); 132 133 if (arguments > 0) 134 { 135 ParseItem[] operands = getOperands(); 136 if (readFromSheet) 137 { 138 operands[0].getString(buf); 140 141 for (int i = 1; i < arguments; i++) 142 { 143 buf.append(','); 144 operands[i].getString(buf); 145 } 146 } 147 else 148 { 149 operands[arguments - 1].getString(buf); 152 153 for (int i = arguments - 2; i >= 0 ; i--) 154 { 155 buf.append(','); 156 operands[i].getString(buf); 157 } 158 } 159 } 160 161 buf.append(')'); 162 } 163 164 171 public void adjustRelativeCellReferences(int colAdjust, int rowAdjust) 172 { 173 ParseItem[] operands = getOperands(); 174 175 for (int i = 0 ; i < operands.length ; i++) 176 { 177 operands[i].adjustRelativeCellReferences(colAdjust, rowAdjust); 178 } 179 } 180 181 191 void columnInserted(int sheetIndex, int col, boolean currentSheet) 192 { 193 ParseItem[] operands = getOperands(); 194 for (int i = 0 ; i < operands.length ; i++) 195 { 196 operands[i].columnInserted(sheetIndex, col, currentSheet); 197 } 198 } 199 200 210 void columnRemoved(int sheetIndex, int col, boolean currentSheet) 211 { 212 ParseItem[] operands = getOperands(); 213 for (int i = 0 ; i < operands.length ; i++) 214 { 215 operands[i].columnRemoved(sheetIndex, col, currentSheet); 216 } 217 } 218 219 229 void rowInserted(int sheetIndex, int row, boolean currentSheet) 230 { 231 ParseItem[] operands = getOperands(); 232 for (int i = 0 ; i < operands.length ; i++) 233 { 234 operands[i].rowInserted(sheetIndex, row, currentSheet); 235 } 236 } 237 238 248 void rowRemoved(int sheetIndex, int row, boolean currentSheet) 249 { 250 ParseItem[] operands = getOperands(); 251 for (int i = 0 ; i < operands.length ; i++) 252 { 253 operands[i].rowRemoved(sheetIndex, row, currentSheet); 254 } 255 } 256 257 260 Function getFunction() 261 { 262 return function; 263 } 264 265 270 byte[] getBytes() 271 { 272 handleSpecialCases(); 273 274 ParseItem[] operands = getOperands(); 276 byte[] data = new byte[0]; 277 278 for (int i = 0 ; i < operands.length ; i++) 279 { 280 byte[] opdata = operands[i].getBytes(); 281 282 byte[] newdata = new byte[data.length + opdata.length]; 284 System.arraycopy(data, 0, newdata, 0, data.length); 285 System.arraycopy(opdata, 0, newdata, data.length, opdata.length); 286 data = newdata; 287 } 288 289 byte[] newdata = new byte[data.length + 4]; 291 System.arraycopy(data, 0, newdata, 0, data.length); 292 newdata[data.length] = !useAlternateCode() ? 293 Token.FUNCTIONVARARG.getCode() : Token.FUNCTIONVARARG.getCode2() ; 294 newdata[data.length+1] = (byte) arguments; 295 IntegerHelper.getTwoBytes(function.getCode(), newdata, data.length+2); 296 297 return newdata; 298 } 299 300 306 int getPrecedence() 307 { 308 return 3; 309 } 310 311 314 private void handleSpecialCases() 315 { 316 if (function == Function.SUMPRODUCT) 319 { 320 ParseItem[] operands = getOperands(); 322 323 for (int i = operands.length - 1 ; i >= 0 ; i--) 324 { 325 if (operands[i] instanceof Area) 326 { 327 operands[i].setAlternateCode(); 328 } 329 } 330 } 331 } 332 } 333 334 335 | Popular Tags |