/*
|
* Licensed to the Apache Software Foundation (ASF) Under one or more
|
* contributor license agreements. See the NOTICE file distributed with
|
* this work for Additional information regarding copyright ownership.
|
* The ASF licenses this file to You Under the Apache License, Version 2.0
|
* (the "License"); you may not use this file except in compliance with
|
* the License. You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed Under the License is distributed on an "AS Is" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations Under the License.
|
*/
|
/*
|
* Created on May 14, 2005
|
*
|
*/
|
namespace HH.WMS.Utils.NPOI.SS.Formula.Eval
|
{
|
using System;
|
/**
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
*
|
*/
|
public class ValueEvalToNumericXlator
|
{
|
|
public static int STRING_IS_PARSED = 0x0001;
|
public static int BOOL_IS_PARSED = 0x0002;
|
public static int BLANK_IS_PARSED = 0x0004; // => blanks are not ignored, Converted to 0
|
|
public static int REF_STRING_IS_PARSED = 0x0008;
|
public static int REF_BOOL_IS_PARSED = 0x0010;
|
public static int REF_BLANK_IS_PARSED = 0x0020;
|
|
public static int STRING_IS_INVALID_VALUE = 0x0800;
|
|
private int flags;
|
|
|
public ValueEvalToNumericXlator(int flags)
|
{
|
this.flags = flags;
|
}
|
|
/**
|
* returned value can be either A NumericValueEval, BlankEval or ErrorEval.
|
* The params can be either NumberEval, BoolEval, StringEval, or
|
* RefEval
|
* @param eval
|
*/
|
public ValueEval AttemptXlateToNumeric(ValueEval eval)
|
{
|
ValueEval retval = null;
|
|
if (eval == null)
|
{
|
retval = BlankEval.instance;
|
}
|
|
// most common case - least worries :)
|
else if (eval is NumberEval)
|
{
|
retval = eval;
|
}
|
|
// booleval
|
else if (eval is BoolEval)
|
{
|
retval = ((flags & BOOL_IS_PARSED) > 0)
|
? (NumericValueEval)eval
|
: XlateBlankEval(BLANK_IS_PARSED);
|
}
|
|
// stringeval
|
else if (eval is StringEval)
|
{
|
retval = XlateStringEval((StringEval)eval); // TODO: recursive call needed
|
}
|
|
// refeval
|
else if (eval is RefEval)
|
{
|
retval = XlateRefEval((RefEval)eval);
|
}
|
|
// erroreval
|
else if (eval is ErrorEval)
|
{
|
retval = eval;
|
}
|
|
else if (eval is BlankEval)
|
{
|
retval = XlateBlankEval(BLANK_IS_PARSED);
|
}
|
|
// probably AreaEval? then not acceptable.
|
else
|
{
|
throw new Exception("Invalid ValueEval type passed for conversion: " + eval.GetType());
|
}
|
|
return retval;
|
}
|
|
/**
|
* no args are required since BlankEval has only one
|
* instance. If flag is Set, a zero
|
* valued numbereval is returned, else BlankEval.INSTANCE
|
* is returned.
|
*/
|
private ValueEval XlateBlankEval(int flag)
|
{
|
return ((flags & flag) > 0)
|
? (ValueEval)NumberEval.ZERO
|
: BlankEval.instance;
|
}
|
|
/**
|
* uses the relevant flags to decode the supplied RefVal
|
* @param eval
|
*/
|
private ValueEval XlateRefEval(RefEval reval)
|
{
|
ValueEval eval = reval.InnerValueEval;
|
|
// most common case - least worries :)
|
if (eval is NumberEval)
|
{
|
return eval;
|
}
|
|
if (eval is BoolEval)
|
{
|
return ((flags & REF_BOOL_IS_PARSED) > 0)
|
? (ValueEval)eval
|
: BlankEval.instance;
|
}
|
|
if (eval is StringEval)
|
{
|
return XlateRefStringEval((StringEval)eval);
|
}
|
|
if (eval is ErrorEval)
|
{
|
return eval;
|
}
|
|
if (eval is BlankEval)
|
{
|
return XlateBlankEval(REF_BLANK_IS_PARSED);
|
}
|
|
throw new Exception("Invalid ValueEval type passed for conversion: ("
|
+ eval.GetType().Name + ")");
|
}
|
|
/**
|
* uses the relevant flags to decode the StringEval
|
* @param eval
|
*/
|
private ValueEval XlateStringEval(StringEval eval)
|
{
|
|
if ((flags & STRING_IS_PARSED) > 0)
|
{
|
String s = eval.StringValue;
|
double d = OperandResolver.ParseDouble(s);
|
if (double.IsNaN(d))
|
{
|
return ErrorEval.VALUE_INVALID;
|
}
|
return new NumberEval(d);
|
}
|
// strings are errors?
|
if ((flags & STRING_IS_INVALID_VALUE) > 0)
|
{
|
return ErrorEval.VALUE_INVALID;
|
}
|
|
// ignore strings
|
return XlateBlankEval(BLANK_IS_PARSED);
|
}
|
|
/**
|
* uses the relevant flags to decode the StringEval
|
* @param eval
|
*/
|
private ValueEval XlateRefStringEval(StringEval sve)
|
{
|
if ((flags & REF_STRING_IS_PARSED) > 0)
|
{
|
String s = sve.StringValue;
|
double d = OperandResolver.ParseDouble(s);
|
if (double.IsNaN(d))
|
{
|
return ErrorEval.VALUE_INVALID;
|
}
|
return new NumberEval(d);
|
}
|
// strings are blanks
|
return BlankEval.instance;
|
}
|
}
|
}
|