Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1628,6 +1628,14 @@ case class FunctionCallExpression(functionQNameString: String, expressions: List
case (RefQName(_, "exactly-one", FUNC), args) =>
FNExactlyOneExpr(functionQNameString, functionQName, args)

case (RefQName(_, "leftShift", DFDLX), args) =>
DFDLXShiftExpr(functionQNameString, functionQName, args,
DFDLXLeftShift(_, _))
case (RefQName(_, "rightShift", DFDLX), args) =>
Comment thread
mbeckerle marked this conversation as resolved.
DFDLXShiftExpr(functionQNameString, functionQName, args,
DFDLXRightShift(_, _))


case (RefQName(_, "year-from-dateTime", FUNC), args) => FNOneArgExpr(functionQNameString, functionQName, args, NodeInfo.Integer, NodeInfo.DateTime, FNYearFromDateTime(_, _))
case (RefQName(_, "month-from-dateTime", FUNC), args) => FNOneArgExpr(functionQNameString, functionQName, args, NodeInfo.Integer, NodeInfo.DateTime, FNMonthFromDateTime(_, _))
case (RefQName(_, "day-from-dateTime", FUNC), args) => FNOneArgExpr(functionQNameString, functionQName, args, NodeInfo.Integer, NodeInfo.DateTime, FNDayFromDateTime(_, _))
Expand Down Expand Up @@ -2135,6 +2143,41 @@ case class FNTwoArgsMathExpr(nameAsParsed: String, fnQName: RefQName,
}
}

case class DFDLXShiftExpr(nameAsParsed: String, fnQName: RefQName,
args: List[Expression], constructor: (List[CompiledDPath], NodeInfo.Kind) => RecipeOp)
extends FunctionCallBase(nameAsParsed, fnQName, args) {
override lazy val inherentType = {
val argInherentType = args(0).inherentType
schemaDefinitionUnless(
argInherentType.isSubtypeOf(NodeInfo.PrimType.UnsignedLong) ||
argInherentType.isSubtypeOf(NodeInfo.PrimType.Long),
"First argument for %s must be either xs:unsignedLong or xs:long or a subtype of those, but was %s.",
nameAsParsed,argInherentType.globalQName)
argInherentType
}

override def targetTypeForSubexpression(subexp: Expression): NodeInfo.Kind = {
if (subexp == args(0))
inherentType
else if (subexp == args(1))
NodeInfo.UnsignedInt
else
//$COVERAGE-OFF$
Assert.invariantFailed("subexpression %s is not an argument.".format(subexp))
Comment thread
mbeckerle marked this conversation as resolved.
//$COVERAGE-ON$
}

override def compiledDPath: CompiledDPath = {
Comment thread
mbeckerle marked this conversation as resolved.
checkArgCount(2)
val arg0Recipe = args(0).compiledDPath
val arg0Type = args(0).inherentType
val arg1Recipe=args(1).compiledDPath
val c=conversions
val res = new CompiledDPath(constructor(List(arg0Recipe,arg1Recipe),arg0Type)+:c)
res
}
}

case class FNZeroArgExpr(nameAsParsed: String, fnQName: RefQName,
resultType: NodeInfo.Kind, argType: NodeInfo.Kind, constructor: (CompiledDPath, NodeInfo.Kind) => RecipeOp)
extends FunctionCallBase(nameAsParsed, fnQName, Nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

package org.apache.daffodil.dpath

import java.math.{ BigInteger => JBigInt }
import java.math.{BigInteger => JBigInt}

import org.apache.daffodil.dpath.NodeInfo.PrimType.PrimNumeric
import org.apache.daffodil.exceptions.Assert
import org.apache.daffodil.infoset.DINode
import org.apache.daffodil.infoset.DISimple
Expand All @@ -29,6 +30,74 @@ import org.apache.daffodil.processors.unparsers.UState
import org.apache.daffodil.processors.unparsers.UnparseError
import org.apache.daffodil.util.Maybe.Nope
import org.apache.daffodil.util.Maybe.One
import passera.unsigned.{UInt, ULong}

/**
* This is the "logical" shift left.
* The left-most bits shifted out are discarded. Zeros are shifted in for the right-most bits.
*
* @param recipes
* @param argType
*/
case class DFDLXLeftShift(recipes: List[CompiledDPath], argType: NodeInfo.Kind) extends FNTwoArgs(recipes) {
override def computeValue(arg1: DataValuePrimitive, arg2: DataValuePrimitive, dstate: DState): DataValuePrimitive = {

val shiftLong = arg2.getLong
val shift = shiftLong.toInt
val width = argType.asInstanceOf[PrimNumeric].width.get
Assert.invariant(shift >= 0)
if(shift>=width)
dstate.SDE("dfdlx:leftShift not supported for shift greater or equal to %s for %s. Shift was %s", width, argType.globalQName, shift)

argType match {
case NodeInfo.Long => arg1.getLong << shift
case NodeInfo.Int => arg1.getInt << shift
case NodeInfo.Short => (arg1.getShort << shift).toShort
case NodeInfo.Byte => (arg1.getByte << shift).toByte
case NodeInfo.UnsignedLong => (ULong(arg1.getBigInt.longValue()) << shift).toBigInt
Comment thread
stevedlawrence marked this conversation as resolved.
case NodeInfo.UnsignedInt => ULong(arg1.getLong << shift).toUInt.toLong
case NodeInfo.UnsignedShort => UInt(arg1.getInt << shift).toUShort.toInt
case NodeInfo.UnsignedByte => UInt(arg1.getShort << shift).toUByte.toShort
//$COVERAGE-OFF$
case _ => Assert.invariantFailed(s"Should not have gotten ${argType.globalQName} for left shift argument type")
// $COVERAGE-ON$
}
}
}

/**
* This is the "arithmetic" shift right. The right-most bits shifted out are discarded.
* The sign bit is shifted in for the left-most bits. This means for signed primitives the values are sign-extended.
* If "logical" (zero-filling) shift right is needed, you must use unsigned primitives.
*
*
* @param recipes
* @param argType
*/
case class DFDLXRightShift(recipes: List[CompiledDPath], argType: NodeInfo.Kind) extends FNTwoArgs(recipes) {
override def computeValue(arg1: DataValuePrimitive, arg2: DataValuePrimitive, dstate: DState): DataValuePrimitive = {
val shiftLong = arg2.getLong
val shift = shiftLong.toInt
val width = argType.asInstanceOf[PrimNumeric].width.get
Assert.invariant(shift >= 0)
if(shift>=width)
dstate.SDE("dfdlx:rightShift not supported for shift greater or equal to %s for %s. Shift was %s", width, argType.globalQName, shift)
argType match {
case NodeInfo.Long => arg1.getLong >> shift
case NodeInfo.Int => arg1.getInt >> shift
case NodeInfo.Short => (arg1.getShort >> shift).toShort
case NodeInfo.Byte => (arg1.getByte >> shift).toByte
case NodeInfo.UnsignedLong => (ULong(arg1.getBigInt.longValue()) >> shift).toBigInt
case NodeInfo.UnsignedInt => ULong(arg1.getLong.toInt >> shift).toUInt.toLong
case NodeInfo.UnsignedShort => UInt(arg1.getInt.toShort >> shift).toUShort.toInt
case NodeInfo.UnsignedByte => UInt(arg1.getShort.toByte >> shift).toUByte.toShort
//$COVERAGE-OFF$
case _ => Assert.invariantFailed(s"Should not have gotten ${argType.globalQName} for right shift argument type")
// $COVERAGE-ON$
}
}
}


case class DFDLXTrace(recipe: CompiledDPath, msg: String)
extends RecipeOpWithSubRecipes(recipe) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

package org.apache.daffodil.dpath

import java.lang.{ Byte => JByte, Double => JDouble, Float => JFloat, Integer => JInt, Long => JLong, Short => JShort }
import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt }
import java.lang.{Byte => JByte, Double => JDouble, Float => JFloat, Integer => JInt, Long => JLong, Short => JShort}
import java.math.{BigDecimal => JBigDecimal, BigInteger => JBigInt}
import java.net.URI
import java.net.URISyntaxException

Expand All @@ -44,8 +44,7 @@ import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
import org.apache.daffodil.infoset.DataValue.DataValueShort
import org.apache.daffodil.infoset.DataValue.DataValueTime
import org.apache.daffodil.infoset.DataValue.DataValueURI
import org.apache.daffodil.util.Enum
import org.apache.daffodil.util.Misc
import org.apache.daffodil.util.{Enum, MaybeInt, Misc}
import org.apache.daffodil.util.Numbers.asBigInt
import org.apache.daffodil.util.Numbers.asBigDecimal
import org.apache.daffodil.xml.GlobalQName
Expand Down Expand Up @@ -473,6 +472,7 @@ object NodeInfo extends Enum {
}

trait PrimNumeric { self: Numeric.Kind =>
def width:MaybeInt
def isValid(n: Number): Boolean
protected def fromNumberNoCheck(n: Number): DataValueNumber
def fromNumber(n: Number): DataValueNumber = {
Expand Down Expand Up @@ -561,6 +561,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueFloat = n.floatValue
override val min = -JFloat.MAX_VALUE.doubleValue
override val max = JFloat.MAX_VALUE.doubleValue
override val width: MaybeInt = MaybeInt(32)
}

protected sealed trait DoubleKind extends SignedNumeric.Kind
Expand All @@ -578,6 +579,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueDouble = n.doubleValue
override val min = -JDouble.MAX_VALUE
override val max = JDouble.MAX_VALUE
override val width: MaybeInt = MaybeInt(64)
}

protected sealed trait DecimalKind extends SignedNumeric.Kind
Expand All @@ -586,6 +588,8 @@ object NodeInfo extends Enum {
protected override def fromString(s: String): DataValueBigDecimal = new JBigDecimal(s)
protected override def fromNumberNoCheck(n: Number): DataValueBigDecimal = asBigDecimal(n)
override def isValid(n: Number): Boolean = true

override val width: MaybeInt = MaybeInt.Nope
}

protected sealed trait IntegerKind extends Decimal.Kind
Expand All @@ -595,6 +599,8 @@ object NodeInfo extends Enum {
protected override def fromString(s: String): DataValueBigInt = new JBigInt(s)
protected override def fromNumberNoCheck(n: Number): DataValueBigInt = asBigInt(n)
override def isValid(n: Number): Boolean = true

override val width: MaybeInt = MaybeInt.Nope
}

protected sealed trait LongKind extends Integer.Kind
Expand All @@ -604,6 +610,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueLong = n.longValue
override val min = JLong.MIN_VALUE
override val max = JLong.MAX_VALUE
override val width: MaybeInt = MaybeInt(64)
}

protected sealed trait IntKind extends Long.Kind
Expand All @@ -613,6 +620,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueInt = n.intValue
override val min = JInt.MIN_VALUE.toLong
override val max = JInt.MAX_VALUE.toLong
override val width: MaybeInt = MaybeInt(32)
}

protected sealed trait ShortKind extends Int.Kind
Expand All @@ -622,6 +630,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueShort = n.shortValue
override val min = JShort.MIN_VALUE.toLong
override val max = JShort.MAX_VALUE.toLong
override val width: MaybeInt = MaybeInt(16)
}

protected sealed trait ByteKind extends Short.Kind
Expand All @@ -631,6 +640,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueByte = n.byteValue
override val min = JByte.MIN_VALUE.toLong
override val max = JByte.MAX_VALUE.toLong
override val width: MaybeInt = MaybeInt(8)
}

protected sealed trait NonNegativeIntegerKind extends Integer.Kind
Expand All @@ -643,6 +653,8 @@ object NodeInfo extends Enum {
case bi: JBigInt => bi.signum >= 0
case _ => n.longValue >= 0
}

override val width: MaybeInt = MaybeInt.Nope
}

protected sealed trait UnsignedLongKind extends NonNegativeInteger.Kind
Expand All @@ -658,6 +670,7 @@ object NodeInfo extends Enum {
}
val max = new JBigInt(1, scala.Array.fill(8)(0xFF.toByte))
val maxBD = new JBigDecimal(max)
override val width: MaybeInt = MaybeInt(64)
}

protected sealed trait UnsignedIntKind extends UnsignedLong.Kind
Expand All @@ -668,6 +681,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueLong = n.longValue
override val min = 0L
override val max = 0xFFFFFFFFL
override val width: MaybeInt = MaybeInt(32)
}

protected sealed trait UnsignedShortKind extends UnsignedInt.Kind
Expand All @@ -678,6 +692,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueInt = n.intValue
override val min = 0L
override val max = 0xFFFFL
override val width: MaybeInt = MaybeInt(16)
}

protected sealed trait UnsignedByteKind extends UnsignedShort.Kind
Expand All @@ -688,6 +703,7 @@ object NodeInfo extends Enum {
protected override def fromNumberNoCheck(n: Number): DataValueShort = n.shortValue
override val min = 0L
override val max = 0xFFL
override val width: MaybeInt = MaybeInt(8)
}

protected sealed trait StringKind extends AnyAtomic.Kind
Expand Down
Loading