diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2018-09-18 02:55:40 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2018-09-18 02:55:40 +0000 |
commit | 010cc904a5ab759f24825f34f2924c347b3b2790 (patch) | |
tree | 7cb6358c8ef9621673754e13d5d62c89b7051561 /src/main/java | |
parent | 8d5ae34b81cfc38744be68ebd9871359a8e6cbe8 (diff) | |
download | jackcess-010cc904a5ab759f24825f34f2924c347b3b2790.tar.gz jackcess-010cc904a5ab759f24825f34f2924c347b3b2790.zip |
implement IsNumeric; add support for hex/oct integer strings
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1199 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/main/java')
3 files changed, 57 insertions, 6 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java b/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java index 6531eea..416c96e 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java @@ -178,7 +178,7 @@ limitations under the License. * <tr class="TableRowColor"><td>IsError</td><td></td></tr> * <tr class="TableRowColor"><td>IsMissing</td><td></td></tr> * <tr class="TableRowColor"><td>IsNull</td><td>Y</td></tr> - * <tr class="TableRowColor"><td>IsNumeric</td><td></td></tr> + * <tr class="TableRowColor"><td>IsNumeric</td><td>Y</td></tr> * <tr class="TableRowColor"><td>IsObject</td><td></td></tr> * <tr class="TableRowColor"><td>TypeName</td><td>Y</td></tr> * <tr class="TableRowColor"><td>VarType</td><td>Y</td></tr> @@ -216,7 +216,7 @@ limitations under the License. * * <table border="1" width="25%" cellpadding="3" cellspacing="0"> * <tr class="TableHeadingColor" align="left"><th>Function</th><th>Supported</th></tr> - * <tr class="TableRowColor"><td>Format</td><td></td></tr> + * <tr class="TableRowColor"><td>Format[$]</td><td></td></tr> * <tr class="TableRowColor"><td>InStr</td><td>Y</td></tr> * <tr class="TableRowColor"><td>InStrRev</td><td>Y</td></tr> * <tr class="TableRowColor"><td>LCase[$]</td><td>Y</td></tr> diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java index e927f9a..20de8ca 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java @@ -246,6 +246,26 @@ public class DefaultFunctions } }); + public static final Function ISNUMERIC = registerFunc(new Func1("IsNumeric") { + @Override + protected Value eval1(EvalContext ctx, Value param1) { + if(param1.getType().isNumeric()) { + return ValueSupport.TRUE_VAL; + } + + if(param1.getType() == Value.Type.STRING) { + try { + param1.getAsBigDecimal(); + return ValueSupport.TRUE_VAL; + } catch(NumberFormatException ignored) { + // fall through to FALSE_VAL + } + } + + return ValueSupport.FALSE_VAL; + } + }); + public static final Function VARTYPE = registerFunc(new Func1("VarType") { @Override protected Value eval1(EvalContext ctx, Value param1) { diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java index d3e2cac..51b9c6a 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java @@ -17,6 +17,8 @@ limitations under the License. package com.healthmarketscience.jackcess.impl.expr; import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.regex.Pattern; /** * @@ -26,6 +28,12 @@ public class StringValue extends BaseValue { private static final Object NOT_A_NUMBER = new Object(); + private static final char NUMBER_BASE_PREFIX = '&'; + private static final Pattern OCTAL_PAT = + Pattern.compile(NUMBER_BASE_PREFIX + "[oO][0-7]+"); + private static final Pattern HEX_PAT = + Pattern.compile(NUMBER_BASE_PREFIX + "[hH]\\p{XDigit}+"); + private final String _val; private Object _num; @@ -75,13 +83,36 @@ public class StringValue extends BaseValue if(_num == null) { // see if it is parseable as a number try { - _num = ValueSupport.normalize(new BigDecimal(_val)); - return (BigDecimal)_num; + // ignore extraneous whitespace whitespace and handle "&[hH]" or + // "&[oO]" prefix (only supports integers) + String tmpVal = _val.trim(); + if(tmpVal.length() > 0) { + + if(tmpVal.charAt(0) != NUMBER_BASE_PREFIX) { + // parse using standard numeric support + _num = ValueSupport.normalize(new BigDecimal(tmpVal)); + return (BigDecimal)_num; + } + + // parse as hex/octal symbolic value + if(HEX_PAT.matcher(tmpVal).matches()) { + return parseIntegerString(tmpVal, 16); + } else if(OCTAL_PAT.matcher(tmpVal).matches()) { + return parseIntegerString(tmpVal, 8); + } + + // fall through to NaN + } } catch(NumberFormatException nfe) { - _num = NOT_A_NUMBER; - // fall through to throw... + // fall through to NaN... } + _num = NOT_A_NUMBER; } throw new NumberFormatException("Invalid number '" + _val + "'"); } + + private BigDecimal parseIntegerString(String tmpVal, int radix) { + _num = new BigDecimal(new BigInteger(tmpVal.substring(2), radix)); + return (BigDecimal)_num; + } } |