Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Bug with valueLength being overwritten after Trim #1338

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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 @@ -49,7 +49,7 @@ import org.apache.daffodil.core.grammar.primitives.ChoiceCombinator
import org.apache.daffodil.core.grammar.primitives.ElementCombinator
import org.apache.daffodil.core.grammar.primitives.ElementParseAndUnspecifiedLength
import org.apache.daffodil.core.grammar.primitives.ElementUnused
import org.apache.daffodil.core.grammar.primitives.HexBinaryLengthPrefixed
import org.apache.daffodil.core.grammar.primitives.HexBinaryEndOfBitLimit
import org.apache.daffodil.core.grammar.primitives.HexBinarySpecifiedLength
import org.apache.daffodil.core.grammar.primitives.OrderedSequence
import org.apache.daffodil.core.grammar.primitives.RepOrderedExactlyNSequenceChild
Expand All @@ -59,6 +59,7 @@ import org.apache.daffodil.core.grammar.primitives.RightFill
import org.apache.daffodil.core.grammar.primitives.ScalarOrderedSequenceChild
import org.apache.daffodil.core.grammar.primitives.SpecifiedLengthExplicit
import org.apache.daffodil.core.grammar.primitives.SpecifiedLengthImplicit
import org.apache.daffodil.core.grammar.primitives.SpecifiedLengthPrefixed
import org.apache.daffodil.lib.api.Diagnostic
import org.apache.daffodil.lib.api.WarnID
import org.apache.daffodil.lib.schema.annotation.props.gen.FailureType
Expand Down Expand Up @@ -288,7 +289,8 @@ object DaffodilCCodeGenerator
case g: ElementParseAndUnspecifiedLength =>
elementParseAndUnspecifiedLengthGenerateCode(g, cgState)
case g: ElementUnused => noop(g)
case g: HexBinaryLengthPrefixed => hexBinaryLengthPrefixedGenerateCode(g.e, cgState)
case g: HexBinaryEndOfBitLimit if g.e.isPrefixed =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe my suggestion was wrong and the primitive still wants to be something like HexBInaryLengthPrefixed so that the grammar is obvious and things like code generators/etc can use the obvious grammar names? The parsers generated don't necessarily have to match the names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm...do you mean the suggestion to remove HexBinaryLengthPrefixed or the suggestion to rename all PrefixedLength parsers/unparser to BitLimitLength/MinimumLength?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that wasn't clear. I'm suggesting that we should keep the old grammar name HexBinaryLengthPrefixed so this change isn't needed. This way the grammar is a more clear for things like the code generator that examine it. But it's still fine to call the parsers BitLimitLength/MinimumLength etc from that grammar.

hexBinaryLengthPrefixedGenerateCode(g.e, cgState)
case g: HexBinarySpecifiedLength => hexBinarySpecifiedLengthGenerateCode(g.e, cgState)
case g: OrderedSequence => orderedSequenceGenerateCode(g, cgState)
case g: Prod => prod(g, cgState)
Expand All @@ -301,6 +303,7 @@ object DaffodilCCodeGenerator
case g: SeqComp => seqCompGenerateCode(g, cgState)
case g: SpecifiedLengthExplicit => specifiedLengthExplicit(g, cgState)
case g: SpecifiedLengthImplicit => specifiedLengthImplicit(g, cgState)
case g: SpecifiedLengthPrefixed => specifiedLengthPrefixed(g, cgState)
case _ => gram.SDE("Code generation not supported for: %s", Misc.getNameFromClass(gram))
}
}
Expand Down Expand Up @@ -409,4 +412,11 @@ object DaffodilCCodeGenerator
): Unit = {
DaffodilCCodeGenerator.generateCode(g.eGram, cgState)
}

private def specifiedLengthPrefixed(
g: SpecifiedLengthPrefixed,
cgState: CodeGeneratorState
): Unit = {
DaffodilCCodeGenerator.generateCode(g.eGram, cgState)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ trait ElementBaseGrammarMixin
}
}

protected lazy val isDelimitedPrefixedPattern = {
lazy val isPrefixed: Boolean = lengthKind == LengthKind.Prefixed

protected lazy val isDelimitedPrefixedPattern: Boolean = {
import LengthKind._
lengthKind match {
case Delimited =>
Expand Down Expand Up @@ -474,12 +476,16 @@ trait ElementBaseGrammarMixin
lazy val leftPadding = leftPaddingArg
lazy val rightPadFill = rightPadFillArg
lazy val body = bodyArg
CaptureContentLengthStart(this) ~
leftPadding ~
CaptureValueLengthStart(this) ~
body ~
CaptureValueLengthEnd(this) ~
rightPadFill ~
specifiedLength(
CaptureContentLengthStart(this) ~
leftPadding ~
CaptureValueLengthStart(this) ~
body ~
CaptureValueLengthEnd(this) ~
rightPadFill
) ~
// CaptureContentLengthEnd must be outside the specified length so it can
// do any skipping of bits it needs to before capturing the end of content length
CaptureContentLengthEnd(this)
}

Expand Down Expand Up @@ -623,14 +629,14 @@ trait ElementBaseGrammarMixin

private lazy val stringPrim = {
lengthKind match {
case LengthKind.Explicit => specifiedLength(StringOfSpecifiedLength(this))
case LengthKind.Prefixed => specifiedLength(StringOfSpecifiedLength(this))
case LengthKind.Explicit => StringOfSpecifiedLength(this)
case LengthKind.Prefixed => StringOfSpecifiedLength(this)
case LengthKind.Delimited => stringDelimitedEndOfData
case LengthKind.Pattern => specifiedLength(StringOfSpecifiedLength(this))
case LengthKind.Pattern => StringOfSpecifiedLength(this)
case LengthKind.Implicit => {
val pt = this.simpleType.primType
Assert.invariant(pt == PrimType.String)
specifiedLength(StringOfSpecifiedLength(this))
StringOfSpecifiedLength(this)
}
case LengthKind.EndOfParent if isComplexType =>
notYetImplemented("lengthKind='endOfParent' for complex type")
Expand All @@ -645,11 +651,11 @@ trait ElementBaseGrammarMixin
}

private lazy val hexBinaryLengthPattern = prod("hexBinaryLengthPattern") {
new SpecifiedLengthPattern(this, new HexBinaryEndOfBitLimit(this))
new HexBinaryEndOfBitLimit(this)
}

private lazy val hexBinaryLengthPrefixed = prod("hexBinaryLengthPrefixed") {
new HexBinaryLengthPrefixed(this)
new HexBinaryEndOfBitLimit(this)
}

private lazy val hexBinaryValue = prod("hexBinaryValue") {
Expand Down Expand Up @@ -1226,7 +1232,7 @@ trait ElementBaseGrammarMixin
}

private lazy val nilLitSimple = prod("nilLitSimple", isSimpleType) {
captureLengthRegions(leftPadding, specifiedLength(nilLitContent), rightPadding ~ rightFill)
captureLengthRegions(leftPadding, nilLitContent, rightPadding ~ rightFill)
}

private lazy val nilLitComplex = prod("nilLitComplex", isComplexType) {
Expand Down Expand Up @@ -1329,7 +1335,10 @@ trait ElementBaseGrammarMixin
* as well, by not enclosing the body in a specified length enforcer.
*/
private def specifiedLength(bodyArg: => Gram) = {
lazy val body = bodyArg
// we need this to evaluate before we wrap in specified length parser,
// so it can do any internal checks for example blobValue's check for
// non-explicit lengthKind
val body = bodyArg
lazy val bitsMultiplier = lengthUnits match {
case LengthUnits.Bits => 1
case LengthUnits.Bytes => 8
Expand All @@ -1341,7 +1350,13 @@ trait ElementBaseGrammarMixin
case LengthKind.Delimited => body
case LengthKind.Pattern => new SpecifiedLengthPattern(this, body)
case LengthKind.Explicit if bitsMultiplier != 0 =>
new SpecifiedLengthExplicit(this, body, bitsMultiplier)
if (isSimpleType && primType == PrimType.HexBinary) {
// hexBinary has some checks that need to be done that SpecifiedLengthExplicit
// gets in the way of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think instead of this comment, we can say HexBinary has it's own HexBinarySpecifiedLength parser that handles calculating the length, so we do not need the SpecifiedLengthExplicit parser?

In fact, do we need to exclude a number of other primitive types that do their own explicit length handling? Looking at the current code base, I think maybe only simple types that are strings and complex types use the SpecifiedLengthExplicit parser? I think all other primitives implement their own specified length handling?

So maybe this wants to be

if (isComplexType || primType == PrimType.String) {
  SpecifiedLengthExplicit(...)
} else {
  // non-string simple types have their own custom parsers/unparsers for handling explicit lengths
  body
}

In fact, I wonder if we eventually want to refactor all of this to completely get rid of all the custom explicit/implicit length parsers? We just have various SpecifiedLength parser that sets a bit limit (based on a pattern, a prefix length, evaluaating a length expression etc) and then we just have a single parser that just reads all bit up until that current bit limit. Separation of concerns kind of thing. It would get rid of this condiation and all these BinaryIntegerKnownLength/RuntimeLength/PrefixLength/etc parsers. There's just a single BinaryNumberParser, and it just gets the length from the bitLimit.

Maybe that generality would take performance hit? I'm also not exactly sure how that would work with unparsing--the SpecifiedLengthUnparser would need to somehow pass the calculated length to the child unparser, I guess it could still use bitLimit since that is a thing in UState?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbeckerle , any thoughts on refactoring the code to have various specified length parser as described above, and any idea on how that would work with unparsing?

body
} else {
new SpecifiedLengthExplicit(this, body, bitsMultiplier)
}
case LengthKind.Explicit => {
Assert.invariant(!knownEncodingIsFixedWidth)
Assert.invariant(lengthUnits eq LengthUnits.Characters)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below this we have cases for implicit lengths. Do we need to do anything special for non-string simple types? I think those primitives have custom parsers that handle the implict length logic and don't need a SpecifiedLengthImplicit gramar? My concern is we could be adding that grammar and it would do something like set a bit limit, but the child paser that actually parsrers a the thing would just use it's own calculate and wouldn't need the bit limit, so we are just wasting effort.

Expand All @@ -1366,14 +1381,15 @@ trait ElementBaseGrammarMixin
}
case LengthKind.Implicit if isSimpleType && primType == PrimType.String =>
new SpecifiedLengthImplicitCharacters(this, body, this.maxLength.longValue)

case LengthKind.Implicit if isSimpleType && primType == PrimType.HexBinary =>
new SpecifiedLengthImplicit(this, body, this.maxLength.longValue * bitsMultiplier)
case LengthKind.Implicit
if isSimpleType && impliedRepresentation == Representation.Binary =>
if isSimpleType &&
impliedRepresentation == Representation.Binary &&
primType != PrimType.HexBinary =>
new SpecifiedLengthImplicit(this, body, implicitBinaryLengthInBits)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition feels like it doesn't exclude enough things. For example, this matches all binary types except hex binary. But, for example, integers with length kind implicit use something like BinaryIntegerKnownLength primitive/parser, which doesn't rely on SpecifiedLengthImplicit parser. It doesn't necessarily hurt, but it's just unnecessary work and might slow things down, since the BinaryIntegerKnownLengthParser is going to do that work.

I'm wonder if it's just string types that really make use of specified length stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So It look like nillable binary types need SpecifiedLengthImplicit., they are the only tests failing when I comment out that chunk of code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that means we only need the SpecifiedLengthImplicit when we are trying to parse the nillable part of a number. For example, the way things currently work is we have something like a SimpleNilOrValueParser and that has two children parsers, one is the nil parser (which sounds like it requires SpecifiedLengthImplicit) and the other is the binary paser (which probably does not need SpecifiedLenghtImplicit).

I wonder if captureLengthRegion needs a new paramater (e.g. forNilContent: Boolean) which is passed into specifiedLength. This way specifiedLength can do different things depending on if it's trying to represent nil content or non-nil content.

case LengthKind.Implicit if isComplexType =>
case LengthKind.Implicit =>
body // for complex types, implicit means "roll up from the bottom"
// for simple types, the primitives have custom parsers that handle implicit length logic
// and don't use the limit provided by the SpecifiedLengthImplicit parser
olabusayoT marked this conversation as resolved.
Show resolved Hide resolved
case LengthKind.EndOfParent if isComplexType =>
notYetImplemented("lengthKind='endOfParent' for complex type")
case LengthKind.EndOfParent =>
Expand Down Expand Up @@ -1403,7 +1419,7 @@ trait ElementBaseGrammarMixin
private lazy val sharedComplexContentRegion: Gram =
schemaSet.sharedComplexContentFactory.getShared(
shareKey,
captureLengthRegions(EmptyGram, specifiedLength(complexContent), elementUnused) ~
captureLengthRegions(EmptyGram, complexContent, elementUnused) ~
terminatorRegion
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ package org.apache.daffodil.core.grammar.primitives

import org.apache.daffodil.core.dsom.ElementBase
import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.runtime1.processors.parsers.BCDDecimalBitLimitLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDDecimalKnownLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDDecimalPrefixedLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDDecimalRuntimeLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDIntegerBitLimitLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDIntegerKnownLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDIntegerPrefixedLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BCDIntegerRuntimeLengthParser
import org.apache.daffodil.runtime1.processors.unparsers.Unparser
import org.apache.daffodil.unparsers.runtime1.BCDDecimalKnownLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDDecimalPrefixedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDDecimalMinimumLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDDecimalRuntimeLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDIntegerKnownLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDIntegerPrefixedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDIntegerMinimumLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BCDIntegerRuntimeLengthUnparser

class BCDIntegerRuntimeLength(val e: ElementBase) extends Terminal(e, true) {
Expand All @@ -52,20 +52,10 @@ class BCDIntegerKnownLength(val e: ElementBase, lengthInBits: Long) extends Term

class BCDIntegerPrefixedLength(val e: ElementBase) extends Terminal(e, true) {

override lazy val parser = new BCDIntegerPrefixedLengthParser(
e.elementRuntimeData,
e.prefixedLengthBody.parser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
)
override lazy val parser = new BCDIntegerBitLimitLengthParser(e.elementRuntimeData)

override lazy val unparser: Unparser = new BCDIntegerPrefixedLengthUnparser(
e.elementRuntimeData,
e.prefixedLengthBody.unparser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
override lazy val unparser: Unparser = new BCDIntegerMinimumLengthUnparser(
e.elementRuntimeData
)
}

Expand Down Expand Up @@ -102,21 +92,9 @@ class BCDDecimalKnownLength(val e: ElementBase, lengthInBits: Long) extends Term

class BCDDecimalPrefixedLength(val e: ElementBase) extends Terminal(e, true) {

override lazy val parser = new BCDDecimalPrefixedLengthParser(
e.elementRuntimeData,
e.prefixedLengthBody.parser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.binaryDecimalVirtualPoint,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
)
override lazy val parser =
new BCDDecimalBitLimitLengthParser(e.elementRuntimeData, e.binaryDecimalVirtualPoint)

override lazy val unparser: Unparser = new BCDDecimalPrefixedLengthUnparser(
e.elementRuntimeData,
e.prefixedLengthBody.unparser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.binaryDecimalVirtualPoint,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
)
override lazy val unparser: Unparser =
new BCDDecimalMinimumLengthUnparser(e.elementRuntimeData, e.binaryDecimalVirtualPoint)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ package org.apache.daffodil.core.grammar.primitives

import org.apache.daffodil.core.dsom.ElementBase
import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.runtime1.processors.parsers.BinaryBooleanBitLimitLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryBooleanParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryBooleanPrefixedLengthParser
import org.apache.daffodil.runtime1.processors.unparsers.Unparser
import org.apache.daffodil.unparsers.runtime1.BinaryBooleanPrefixedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryBooleanMinimumLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryBooleanUnparser

class BinaryBoolean(val e: ElementBase) extends Terminal(e, true) {
Expand All @@ -46,23 +46,17 @@ class BinaryBoolean(val e: ElementBase) extends Terminal(e, true) {
}

class BinaryBooleanPrefixedLength(val e: ElementBase) extends Terminal(e, true) {
override lazy val parser = new BinaryBooleanPrefixedLengthParser(
override lazy val parser = new BinaryBooleanBitLimitLengthParser(
e.elementRuntimeData,
e.prefixedLengthBody.parser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.binaryBooleanTrueRep,
e.binaryBooleanFalseRep,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
e.lengthUnits
)

override lazy val unparser: Unparser = new BinaryBooleanPrefixedLengthUnparser(
override lazy val unparser: Unparser = new BinaryBooleanMinimumLengthUnparser(
e.elementRuntimeData,
e.prefixedLengthBody.unparser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.binaryBooleanTrueRep,
e.binaryBooleanFalseRep,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
e.lengthUnits
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ import org.apache.daffodil.core.grammar.Terminal
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.util.MaybeInt
import org.apache.daffodil.runtime1.dpath.NodeInfo
import org.apache.daffodil.runtime1.processors.parsers.BinaryDecimalBitLimitLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryDecimalKnownLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryDecimalPrefixedLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryDecimalRuntimeLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryDoubleParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryFloatParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryIntegerBitLimitLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryIntegerKnownLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryIntegerPrefixedLengthParser
import org.apache.daffodil.runtime1.processors.parsers.BinaryIntegerRuntimeLengthParser
import org.apache.daffodil.runtime1.processors.unparsers.Unparser
import org.apache.daffodil.unparsers.runtime1.BinaryDecimalKnownLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryDecimalPrefixedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryDecimalMinimumLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryDecimalRuntimeLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryDoubleUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryFloatUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryIntegerKnownLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryIntegerPrefixedLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryIntegerMinimumLengthUnparser
import org.apache.daffodil.unparsers.runtime1.BinaryIntegerRuntimeLengthUnparser

class BinaryIntegerRuntimeLength(val e: ElementBase, signed: Boolean)
Expand Down Expand Up @@ -77,14 +77,7 @@ class BinaryIntegerPrefixedLength(val e: ElementBase, signed: Boolean)
private lazy val pladj = e.prefixedLengthAdjustmentInUnits

override lazy val parser =
new BinaryIntegerPrefixedLengthParser(
erd,
e.prefixedLengthBody.parser,
plerd,
signed,
e.lengthUnits,
pladj
)
new BinaryIntegerBitLimitLengthParser(erd, signed)

override lazy val unparser: Unparser = {
val maybeNBits = e.primType match {
Expand All @@ -96,15 +89,7 @@ class BinaryIntegerPrefixedLength(val e: ElementBase, signed: Boolean)
case _ =>
Assert.invariantFailed("Only integer base types should be used for this primitive")
}
new BinaryIntegerPrefixedLengthUnparser(
erd,
e.prefixedLengthBody.unparser,
plerd,
maybeNBits,
signed,
e.lengthUnits,
pladj
)
new BinaryIntegerMinimumLengthUnparser(erd, maybeNBits, signed)
}
}

Expand Down Expand Up @@ -149,25 +134,17 @@ class BinaryDecimalKnownLength(val e: ElementBase, lengthInBits: Long)
class BinaryDecimalPrefixedLength(val e: ElementBase) extends Terminal(e, true) {

override lazy val parser =
new BinaryDecimalPrefixedLengthParser(
new BinaryDecimalBitLimitLengthParser(
e.elementRuntimeData,
e.prefixedLengthBody.parser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.decimalSigned,
e.binaryDecimalVirtualPoint,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
e.binaryDecimalVirtualPoint
)

override lazy val unparser: Unparser =
new BinaryDecimalPrefixedLengthUnparser(
new BinaryDecimalMinimumLengthUnparser(
e.elementRuntimeData,
e.prefixedLengthBody.unparser,
e.prefixedLengthElementDecl.elementRuntimeData,
e.decimalSigned,
e.binaryDecimalVirtualPoint,
e.lengthUnits,
e.prefixedLengthAdjustmentInUnits
e.binaryDecimalVirtualPoint
)

}
Expand Down
Loading
Loading