Description
The following schema parses a double and then has an expression to convert that double to an unsignedLong:
<element name="root"> <complexType> <sequence> <element name="double" type="xs:double" /> <element name="ulong" type="xs:unsignedLong" dfdl:inputValueCalc="{ xs:unsignedLong(../double) }" /> </sequence> </complexType> </element>
This fails with the exception:
rg.apache.daffodil.lib.exceptions.Abort: Invariant broken. Runtime.scala - Leaked exception: java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long at org.apache.daffodil.runtime1.infoset.DataValue$.getLong$extension(DataValue.scala:91) at org.apache.daffodil.runtime1.dpath.LongToUnsignedLong$.computeValue(ConverterOps.scala:219) at org.apache.daffodil.runtime1.dpath.LongToUnsignedLong$.computeValue(ConverterOps.scala:217) at org.apache.daffodil.runtime1.dpath.Converter.run(DPathRuntime.scala:311) at org.apache.daffodil.runtime1.dpath.CompiledDPath.run(DPathRuntime.scala:148) at org.apache.daffodil.runtime1.dpath.CompiledDPath.runExpression(DPathRuntime.scala:73) at org.apache.daffodil.runtime1.dpath.RuntimeExpressionDPath.evaluateExpression(DPath.scala:283) at org.apache.daffodil.runtime1.dpath.RuntimeExpressionDPath.evaluateMaybe(DPath.scala:294) at org.apache.daffodil.runtime1.dpath.RuntimeExpressionDPath.evaluate(DPath.scala:307)
It seems like our expression compiler first converts the double to a long and then converts the long to an unsigned long, failing with the latter. Note that this is probably incorrect, since converting from a double to long first will limit the value to maxLong which it should not do.
A sortof workaround is to change the expression to this:
xs:unsignedLong(xs:long(../double))
So we explicitly cast the double to a long, and then cast the long to the unsigned long. This still limits the range to maxLong, but does allow the conversion to succeed as expected as long as the double is in the range of 0 to maxLong.