aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2018-11-02 20:14:59 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2018-11-02 20:14:59 +0000
commit504a1d8c0b68ba1235e2ffb56d957f23eb515a35 (patch)
tree7a205974a8a043979973df0892dac7d49a350077
parent45f64df5c56c518a9829f80cadf710f76e58e464 (diff)
downloadjackcess-504a1d8c0b68ba1235e2ffb56d957f23eb515a35.tar.gz
jackcess-504a1d8c0b68ba1235e2ffb56d957f23eb515a35.zip
implement Val function
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1214 f203690c-595d-4dc9-a70b-905162fa7fd2
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/expr/package-info.java2
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java83
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java7
-rw-r--r--src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java10
4 files changed, 62 insertions, 40 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 4db1b0d..e9f84db 100644
--- a/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
+++ b/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
@@ -111,7 +111,7 @@ limitations under the License.
* <tr class="TableRowColor"><td>Oct[$]</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Str[$]</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>StringFromGUID</td><td></td></tr>
- * <tr class="TableRowColor"><td>Val</td><td></td></tr>
+ * <tr class="TableRowColor"><td>Val</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>CBool</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>CByte</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>CCur</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 ae4d268..24f6d99 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
@@ -350,43 +350,52 @@ public class DefaultFunctions
}
});
- // public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
- // @Override
- // protected Value eval1(EvalContext ctx, Value param1) {
- // String str = param1.getAsString(ctx).trim();
-
- // if(str.length() == 0) {
- // return ValueSupport.ZERO_VAL;
- // }
-
- // Matcher m = null;
-
- // if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {
- // // see if we can parse as a radix format
- // if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
- // BigInteger bi = ValueSupport.parseIntegerString(m.group(), 16);
- // // FIXME, what to do with large numbers? to double or decimal?
- // return ValueSupport.toValue(bi.intValue());
- // } else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
- // BigInteger bi = ValueSupport.parseIntegerString(m.group(), 8);
- // // FIXME, what to do with large numbers? to double or decimal?
- // return ValueSupport.toValue(bi.intValue());
- // }
-
- // return ValueSupport.ZERO_VAL;
- // }
-
- // // parse ase normal "decimal" number.
- // // FIXME - leading '+'? exponent?
- // if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
-
- // }
-
- // // return ValueSupport.toValue(Integer.toHexString(lv).toUpperCase());
- // return null;
- // }
- // });
-
+ public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
+ @Override
+ protected Value eval1(EvalContext ctx, Value param1) {
+
+ // strip all whitespace from string
+ String str = ValueSupport.WHITESPACE_PAT.matcher(param1.getAsString(ctx))
+ .replaceAll("");
+
+ if(str.length() == 0) {
+ return ValueSupport.ZERO_D_VAL;
+ }
+
+ Matcher m = null;
+
+ if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {
+
+ // see if we can parse as a radix format
+ BigInteger bi = null;
+ if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
+ bi = ValueSupport.parseIntegerString(m.group(), 16);
+ } else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
+ bi = ValueSupport.parseIntegerString(m.group(), 8);
+ }
+
+ if(bi != null) {
+ // this function works differently than normal string to number
+ // conversion. it seems to coerce these values to a short/long int
+ // depending on the size of the number (which creates
+ // positive/negative values dependent on the value length)
+ int iVal = ((bi.bitLength() <= 16) ? bi.shortValue() : bi.intValue());
+ return ValueSupport.toValue((double)iVal);
+ }
+
+ } else {
+
+ // parse as normal "decimal" number.
+ if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
+ BigDecimal bd = new BigDecimal(m.group());
+ return ValueSupport.toValue(bd.doubleValue());
+ }
+ }
+
+ return ValueSupport.ZERO_D_VAL;
+ }
+ });
+
private static boolean stringIsNumeric(EvalContext ctx, Value param) {
try {
param.getAsBigDecimal(ctx);
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
index e2a7173..d0f8bf8 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
@@ -53,6 +53,7 @@ public class ValueSupport
public static final Value ZERO_VAL = FALSE_VAL;
public static final Value NEG_ONE_VAL = TRUE_VAL;
public static final Value ONE_VAL = new LongValue(1);
+ public static final Value ZERO_D_VAL = new DoubleValue(0d);
static final char NUMBER_BASE_PREFIX = '&';
static final Pattern OCTAL_PAT =
@@ -60,8 +61,10 @@ public class ValueSupport
static final Pattern HEX_PAT =
Pattern.compile("^" + NUMBER_BASE_PREFIX + "[hH]\\p{XDigit}+");
static final char CANON_DEC_SEP = '.';
- static final Pattern NUMBER_PAT = Pattern.compile("^[-+]?[0-9]*[.]?[0-9]*");
-
+ static final Pattern NUMBER_PAT =
+ Pattern.compile("^[+-]?(([0-9]+[.]?[0-9]*)|([.][0-9]+))([eE][+-]?[0-9]+)?");
+ static final Pattern WHITESPACE_PAT = Pattern.compile("[ \\t\\r\\n]+");
+
private ValueSupport() {}
public static Value toValue(boolean b) {
diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java
index 5f0a045..98aea88 100644
--- a/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java
@@ -195,6 +195,16 @@ public class DefaultFunctionsTest extends TestCase
} catch(EvalException e) {
assertTrue(e.getMessage().contains("Invalid function call"));
}
+
+ assertEquals(1615198d, eval("=Val(' 1615 198th Street N.E.')"));
+ assertEquals(-1d, eval("=Val(' &HFFFFwhatever')"));
+ assertEquals(131071d, eval("=Val(' &H1FFFFwhatever')"));
+ assertEquals(-1d, eval("=Val(' &HFFFFFFFFwhatever')"));
+ assertEquals(291d, eval("=Val(' &H123whatever')"));
+ assertEquals(83d, eval("=Val(' &O123whatever')"));
+ assertEquals(1.23d, eval("=Val(' 1 2 3 e -2 whatever')"));
+ assertEquals(0d, eval("=Val(' whatever123 ')"));
+ assertEquals(0d, eval("=Val('')"));
}
public void testNumberFuncs() throws Exception