You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by sl...@apache.org on 2021/11/10 16:17:00 UTC
[daffodil] branch main updated: Add dfdlx:doubleToRawLong and
dfdlx:doubleFromRawLong functions
This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new 098bb66 Add dfdlx:doubleToRawLong and dfdlx:doubleFromRawLong functions
098bb66 is described below
commit 098bb66fc44da51e7fabbc0eff178e1a7cafc8df
Author: Min Phyo Aung <ma...@owlcyberdefense.com>
AuthorDate: Fri Nov 5 15:30:57 2021 -0400
Add dfdlx:doubleToRawLong and dfdlx:doubleFromRawLong functions
Added two new functions for converting to/from double and long to preserve binary data floating point conversion.
DAFFODIL-2353
---
.../org/apache/daffodil/dpath/Expression.scala | 15 ++++++-
.../org/apache/daffodil/dpath/DFDLXFunctions.scala | 19 +++++++-
.../section23/dfdl_functions/Functions.tdml | 52 ++++++++++++++++++++++
.../dfdl_expressions/TestDFDLExpressions.scala | 3 ++
4 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
index fa44ca0..7f437b0 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
@@ -584,7 +584,6 @@ case class WholeExpression(
// object will have been created and given this as its parent pointer.
//
Assert.invariant(subExpr == ifor || ifor.isInstanceOf[FunctionCallExpression])
-
// The result of this function will be used to coerce the result of the
// expression to the target type. However, we do not always want to allow
// type coercion even when it might be possible. For example, if the
@@ -596,7 +595,6 @@ case class WholeExpression(
// then we should still allow that coercion. Below we allow coercion
// between decimal-like types where precision would not be lost, and all
// integer-like types (which check for precision loss when evaluated).
-
val allowCoercion = (inherentType, targetType) match {
case (_, _) if inherentType == targetType => true
case (_, _) if (inherentType.isSubtypeOf(NodeInfo.String) && targetType.isSubtypeOf(NodeInfo.String)) => true
@@ -1663,6 +1661,9 @@ case class FunctionCallExpression(functionQNameString: String, expressions: List
NodeInfo.Boolean, NodeInfo.String, DFDLContainsDFDLEntities(_, _))
}
+
+
+
case (RefQName(_, "testBit", DFDL), args) => {
DFDLTestBitExpr(functionQNameString, functionQName, args)
}
@@ -1687,6 +1688,16 @@ case class FunctionCallExpression(functionQNameString: String, expressions: List
//End typeValueCalc related functions
+ case (RefQName(_, "doubleFromRawLong", DFDLX), args) => {
+ FNOneArgExpr(functionQNameString, functionQName, args,
+ NodeInfo.Double, NodeInfo.Long, DFDLXDoubleFromRawLong(_, _))
+ }
+
+ case (RefQName(_, "doubleToRawLong", DFDLX), args) => {
+ FNOneArgExpr(functionQNameString, functionQName, args,
+ NodeInfo.Long, NodeInfo.Double, DFDLXDoubleToRawLong(_, _))
+ }
+
case (RefQName(_, "lookAhead", DFDLX), args) =>
FNTwoArgsExpr(functionQNameString, functionQName, args,
NodeInfo.NonNegativeInteger, NodeInfo.UnsignedInt, NodeInfo.UnsignedInt, DFDLXLookAhead(_))
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
index cf87e3c..bb29b26 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
@@ -18,7 +18,7 @@
package org.apache.daffodil.dpath
import java.math.{BigInteger => JBigInt}
-
+import java.lang.{Double => JDouble}
import org.apache.daffodil.dpath.NodeInfo.PrimType.PrimNumeric
import org.apache.daffodil.exceptions.Assert
import org.apache.daffodil.infoset.DINode
@@ -31,6 +31,8 @@ import org.apache.daffodil.processors.unparsers.UnparseError
import org.apache.daffodil.util.Maybe.Nope
import org.apache.daffodil.util.Maybe.One
import passera.unsigned.{UByte, UInt, ULong, UShort}
+import org.apache.daffodil.infoset.DataValue.DataValueLong
+import org.apache.daffodil.infoset.DataValue.DataValueDouble
/**
* This is the "logical" shift left.
@@ -269,3 +271,18 @@ case class DFDLXLookAhead(recipes: List[CompiledDPath])
}
}
}
+
+
+case class DFDLXDoubleFromRawLong(recipes: CompiledDPath, argType: NodeInfo.Kind )
+ extends FNOneArg(recipes, argType) {
+ override def computeValue(value: DataValuePrimitive, dstate: DState): DataValueDouble = {
+ JDouble.longBitsToDouble(value.getLong)
+ }
+}
+
+case class DFDLXDoubleToRawLong(recipes: CompiledDPath, argType: NodeInfo.Kind )
+ extends FNOneArg(recipes, argType) {
+ override def computeValue(value: DataValuePrimitive, dstate: DState): DataValueLong = {
+ JDouble.doubleToRawLongBits(value.getDouble)
+ }
+}
\ No newline at end of file
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
index bfc5542..fc2e4b8 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
@@ -13920,4 +13920,56 @@
<tdml:infoset><tdml:dfdlInfoset><pow34>NaN</pow34></tdml:dfdlInfoset></tdml:infoset>
</tdml:parserTestCase>
+ <tdml:defineSchema name="DoubleToRawLong.dfdl.xsd">
+ <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+ <dfdl:format ref="ex:GeneralFormat" lengthUnits="bytes" representation="binary" />
+ <xs:element name="root">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element type="xs:double" name="DoubleValue" dfdl:length="8" />
+ <xs:element type="xs:long" name="LongValue" dfdl:inputValueCalc="{ dfdlx:doubleToRawLong(../ex:DoubleValue) }" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </tdml:defineSchema>
+ <tdml:parserTestCase name="DoubleToRawLong" root="root" model="DoubleToRawLong.dfdl.xsd" description="Extensions - DoubleToRawLong">
+ <tdml:document>
+ <tdml:documentPart type="byte">5DC8 225C AF53 6E1F</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <root>
+ <DoubleValue>5.886014640420331E143</DoubleValue>
+ <LongValue>6757689022343245343</LongValue>
+ </root>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+ <tdml:defineSchema name="DoubleFromRawLong.dfdl.xsd">
+ <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+ <dfdl:format ref="ex:GeneralFormat" lengthUnits="bytes" representation="binary" />
+ <xs:element name="root">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element type="xs:long" name="LongValue" dfdl:length="8" />
+ <xs:element type="xs:double" name="DoubleValue" dfdl:inputValueCalc="{ dfdlx:doubleFromRawLong(../ex:LongValue) }" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </tdml:defineSchema>
+
+ <tdml:parserTestCase name="DoubleFromRawLong" root="root" model="DoubleFromRawLong.dfdl.xsd" description="Extensions - doubleFromRawLong">
+ <tdml:document>
+ <tdml:documentPart type="byte">5DC8 225C AF53 6E1F</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <root>
+ <LongValue>6757689022343245343</LongValue>
+ <DoubleValue>5.886014640420331E143</DoubleValue>
+ </root>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
</tdml:testSuite>
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
index 67a4574..fc63c00 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
@@ -1031,4 +1031,7 @@ class TestDFDLExpressions {
@Test def test_short_parent_axis_01(): Unit = { runner.runOneTest("short_parent_axis_01") }
@Test def test_element_long_form_whitespace(): Unit = { runner.runOneTest("element_long_form_whitespace") }
+
+ @Test def test_DoubleFromRawLong(): Unit = { runner2.runOneTest("DoubleFromRawLong") }
+ @Test def test_DoubleToRawLong(): Unit = { runner2.runOneTest("DoubleToRawLong") }
}