001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /*
018: * Created on May 15, 2005
019: *
020: */
021: package org.apache.poi.hssf.record.formula.functions;
022:
023: import org.apache.poi.hssf.record.formula.eval.BlankEval;
024: import org.apache.poi.hssf.record.formula.eval.ErrorEval;
025: import org.apache.poi.hssf.record.formula.eval.Eval;
026: import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
027: import org.apache.poi.hssf.record.formula.eval.StringEval;
028: import org.apache.poi.hssf.record.formula.eval.StringValueEval;
029: import org.apache.poi.hssf.record.formula.eval.ValueEval;
030:
031: /**
032: * An implementation of the MID function:
033: * Returns a specific number of characters from a text string,
034: * starting at the position you specify, based on the number
035: * of characters you specify.
036: * @author Manda Wilson < wilson at c bio dot msk cc dot org >
037: */
038: public class Mid extends TextFunction {
039: /**
040: * Returns a specific number of characters from a text string,
041: * starting at the position you specify, based on the number
042: * of characters you specify.
043: *
044: * @see org.apache.poi.hssf.record.formula.eval.Eval
045: */
046: public Eval evaluate(Eval[] operands, int srcCellRow,
047: short srcCellCol) {
048: Eval retval = null;
049: String str = null;
050: int startNum = 0;
051: int numChars = 0;
052:
053: switch (operands.length) {
054: default:
055: retval = ErrorEval.VALUE_INVALID;
056: case 3:
057: // first operand is text string containing characters to extract
058: // second operand is position of first character to extract
059: // third operand is the number of characters to return
060: ValueEval firstveval = singleOperandEvaluate(operands[0],
061: srcCellRow, srcCellCol);
062: ValueEval secondveval = singleOperandEvaluate(operands[1],
063: srcCellRow, srcCellCol);
064: ValueEval thirdveval = singleOperandEvaluate(operands[2],
065: srcCellRow, srcCellCol);
066: if (firstveval instanceof StringValueEval
067: && secondveval instanceof NumericValueEval
068: && thirdveval instanceof NumericValueEval) {
069:
070: StringValueEval strEval = (StringValueEval) firstveval;
071: str = strEval.getStringValue();
072:
073: NumericValueEval startNumEval = (NumericValueEval) secondveval;
074: // NOTE: it is safe to cast to int here
075: // because in Excel =MID("test", 1, 1.7) returns t
076: // so 1.7 must be truncated to 1
077: // and =MID("test", 1.9, 2) returns te
078: // so 1.9 must be truncated to 1
079: startNum = (int) startNumEval.getNumberValue();
080:
081: NumericValueEval numCharsEval = (NumericValueEval) thirdveval;
082: numChars = (int) numCharsEval.getNumberValue();
083:
084: } else {
085: retval = ErrorEval.VALUE_INVALID;
086: }
087: }
088:
089: if (retval == null) {
090: if (startNum < 1 || numChars < 0) {
091: retval = ErrorEval.VALUE_INVALID;
092: } else if (startNum > str.length() || numChars == 0) {
093: retval = BlankEval.INSTANCE;
094: } else if (startNum + numChars > str.length()) {
095: retval = new StringEval(str.substring(startNum - 1));
096: } else {
097: retval = new StringEval(str.substring(startNum - 1,
098: numChars));
099: }
100: }
101: return retval;
102: }
103:
104: }
|