aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-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
3 files changed, 52 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) {