in daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/BinaryValueCodeGenerator.scala [31:99]
def binaryValueGenerateCode(
e: ElementBase,
addField: String => Unit,
validateFixed: String => Unit,
cgState: CodeGeneratorState
): Unit = {
// For the time being this is a very limited back end.
// So there are some restrictions to enforce.
e.schemaDefinitionUnless(
e.bitOrder eq BitOrder.MostSignificantBitFirst,
"Only dfdl:bitOrder 'mostSignificantBitFirst' is supported."
)
e.schemaDefinitionUnless(
e.maybeByteOrderEv == Nope || e.byteOrderEv.isConstant,
"Runtime dfdl:byteOrder expressions not supported."
)
// Call the given partially applied function values with their remaining unbound argument (deref)
val deref = if (cgState.hasArray) "[i]" else ""
addField(deref)
if (e.hasFixedValue && e.fixedValueAsString.nonEmpty) {
validateFixed(deref)
}
// Check if the element's value is restricted to a set of enumerations
if (e.typeDef.optRestriction.exists(_.hasEnumeration)) {
// Get the raw enumeration values to be inserted into the C code
val enums = e.typeDef.optRestriction.get.enumerations.map(_.enumValueRaw)
valueValidateEnumeration(e, deref, enums, cgState)
}
// Check if the element's value is restricted to a range (we will need to handle any
// combination of inclusive and exclusive endpoints when generating our C expression)
val hasMinExclusive = e.typeDef.optRestriction.exists(_.hasMinExclusive)
val hasMinInclusive = e.typeDef.optRestriction.exists(_.hasMinInclusive)
val hasMaxExclusive = e.typeDef.optRestriction.exists(_.hasMaxExclusive)
val hasMaxInclusive = e.typeDef.optRestriction.exists(_.hasMaxInclusive)
if (hasMinExclusive || hasMinInclusive || hasMaxExclusive || hasMaxInclusive) {
// Generate the minimum endpoint comparison
val minEndpoint = if (hasMinExclusive) {
val endpoint = e.typeDef.optRestriction.map(_.minExclusiveValue).get
s"""> $endpoint"""
} else if (hasMinInclusive) {
val endpoint = e.typeDef.optRestriction.map(_.minInclusiveValue).get
e.optPrimType.get match {
case PrimType.UnsignedByte | PrimType.UnsignedShort | PrimType.UnsignedInt |
PrimType.UnsignedLong | PrimType.NonNegativeInteger if endpoint.toString == "0" =>
// Avoid unsigned >= 0 comparisons (causes gcc warnings)
""
case _ =>
s""">= $endpoint"""
}
} else {
""
}
// Generate the maximum endpoint comparison
val maxEndpoint = if (hasMaxExclusive) {
val endpoint = e.typeDef.optRestriction.map(_.maxExclusiveValue).get
s"""< $endpoint"""
} else if (hasMaxInclusive) {
val endpoint = e.typeDef.optRestriction.map(_.maxInclusiveValue).get
s"""<= $endpoint"""
} else {
""
}
// Call another function which can be redefined differently if necessary
valueValidateRange(e, deref, minEndpoint, maxEndpoint, cgState)
}
}