This is an automated email from the ASF dual-hosted git repository.

olabusayo 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 ba465e3ac Fix Bug with valueLength being overwritten after Trim
ba465e3ac is described below

commit ba465e3aca286a0b0b76efebdbf26c3b0219ee6e
Author: olabusayoT <[email protected]>
AuthorDate: Wed Oct 9 14:06:23 2024 -0400

    Fix Bug with valueLength being overwritten after Trim
    
    - currently after trimming the value of the element, we set the 
valueLength, and then overwrite it after returning from the parse that does the 
trimming. This results in the wrong value for value length. This fixes it by 
checking if the valueLength has already been set, and only setting it in 
SpecifiedLengthParserBase.parse if it hasn't
    - add asserts to setAbsStartPos0bInBits and setAbsEndPos0bInBits to ensure 
they're not being overwritten
    - do not capture the value lengths of choices/complexTypes in specified 
length parser base
    - fix bug where padding is being added around prefixed length element 
(DAFFODIL-2943) by changing CaptureLengthRegion to wrap around 
contentlengthStart and padding
    - fix bug where we use the valuelength to calculate the prefix length, 
according to the spec it should be the content length
    - fix bug where we were missing return after PE for Out of Range Binary 
Integers (DAFFODIL-2942)
    - refactor Prefixed parsers to use state's bitLimit to get the prefix 
length (BitLengthFromBitLimitMixin) since the specifiedLengthPrefixedParser 
will take care of parsing the prefix length
    - refactored Prefixed unparsers to not try to unparse prefix length since 
that is taken care of by SpecifiedLengthPrefixedUnparser
    - refactored prefixed parsers and unparsers to remove unused prefixed 
length parser related members
    - rename custom prefixedlength parsers to *BitLengthParsers to more 
accurately reflect what they're doing
    - rename custom prefixedlength unparsers to MinimumLengthUnparsers to more 
accurately reflect what they're doing
    - add tests
    
    DAFFODIL-2658
---
 .../codegen/c/DaffodilCCodeGenerator.scala         |   9 ++
 .../core/grammar/ElementBaseGrammarMixin.scala     | 149 ++++++++++++---------
 .../core/grammar/primitives/PrimitivesBCD.scala    |  44 ++----
 .../primitives/PrimitivesBinaryBoolean.scala       |  18 +--
 .../primitives/PrimitivesBinaryNumber.scala        |  43 ++----
 .../primitives/PrimitivesIBM4690Packed.scala       |  41 ++----
 .../grammar/primitives/PrimitivesLengthKind.scala  |  20 +--
 .../core/grammar/primitives/PrimitivesPacked.scala |  44 ++----
 .../core/runtime1/ElementBaseRuntime1Mixin.scala   |  18 ++-
 .../daffodil/unparsers/runtime1/BCDUnparsers.scala |  34 +----
 .../runtime1/BinaryBooleanUnparsers.scala          |  23 ++--
 .../unparsers/runtime1/BinaryNumberUnparsers.scala |  35 +----
 .../runtime1/HexBinaryLengthUnparser.scala         |  26 ----
 .../runtime1/IBM4690PackedDecimalUnparsers.scala   |  34 +----
 .../runtime1/PackedDecimalUnparsers.scala          |  35 +----
 .../unparsers/runtime1/SpecifiedLength2.scala      |   4 +-
 .../runtime1/SpecifiedLengthUnparsers.scala        |  98 ++------------
 .../daffodil/runtime1/infoset/InfosetImpl.scala    |   8 ++
 .../daffodil/runtime1/processors/BCDParsers.scala  |  36 +----
 .../processors/IBM4690PackedDecimalParsers.scala   |  34 +----
 .../runtime1/processors/PackedDecimalParsers.scala |  34 +----
 .../processors/parsers/BinaryBooleanParsers.scala  |  13 +-
 .../processors/parsers/BinaryNumberParsers.scala   |  36 +----
 .../processors/parsers/BinaryNumberTraits.scala    |  22 ++-
 .../parsers/HexBinaryLengthParsers.scala           |  19 ---
 .../parsers/SpecifiedLengthParsers.scala           |   6 +-
 .../section12/lengthKind/PrefixedTests.tdml        |  88 +++++++++++-
 .../lengthKind/TestLengthKindPrefixed.scala        |   6 +-
 28 files changed, 348 insertions(+), 629 deletions(-)

diff --git 
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
 
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
index 92348ee81..a42fab04f 100644
--- 
a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
+++ 
b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
@@ -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
@@ -301,6 +302,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))
     }
   }
@@ -409,4 +411,11 @@ object DaffodilCCodeGenerator
   ): Unit = {
     DaffodilCCodeGenerator.generateCode(g.eGram, cgState)
   }
+
+  private def specifiedLengthPrefixed(
+    g: SpecifiedLengthPrefixed,
+    cgState: CodeGeneratorState
+  ): Unit = {
+    DaffodilCCodeGenerator.generateCode(g.eGram, cgState)
+  }
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
index 12b53c352..6f3378450 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
@@ -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 =>
@@ -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)
   }
 
@@ -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")
@@ -645,7 +651,7 @@ trait ElementBaseGrammarMixin
   }
 
   private lazy val hexBinaryLengthPattern = prod("hexBinaryLengthPattern") {
-    new SpecifiedLengthPattern(this, new HexBinaryEndOfBitLimit(this))
+    new HexBinaryEndOfBitLimit(this)
   }
 
   private lazy val hexBinaryLengthPrefixed = prod("hexBinaryLengthPrefixed") {
@@ -1219,7 +1225,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) {
@@ -1322,59 +1328,70 @@ trait ElementBaseGrammarMixin
    * as well, by not enclosing the body in a specified length enforcer.
    */
   private def specifiedLength(bodyArg: => Gram) = {
-    lazy val body = bodyArg
-    lazy val bitsMultiplier = lengthUnits match {
-      case LengthUnits.Bits => 1
-      case LengthUnits.Bytes => 8
-      case LengthUnits.Characters if knownEncodingIsFixedWidth => 
this.knownEncodingWidthInBits
-      case _ => 0 // zero means can't multiply to get width in bits.
-    }
-    val lk = lengthKind
-    lk match {
-      case LengthKind.Delimited => body
-      case LengthKind.Pattern => new SpecifiedLengthPattern(this, body)
-      case LengthKind.Explicit if bitsMultiplier != 0 =>
-        new SpecifiedLengthExplicit(this, body, bitsMultiplier)
-      case LengthKind.Explicit => {
-        Assert.invariant(!knownEncodingIsFixedWidth)
-        Assert.invariant(lengthUnits eq LengthUnits.Characters)
-        new SpecifiedLengthExplicitCharacters(this, body)
-      }
-      case LengthKind.Prefixed if (bitsMultiplier != 0) =>
-        new SpecifiedLengthPrefixed(this, body, bitsMultiplier)
-      case LengthKind.Prefixed => {
-        Assert.invariant(!knownEncodingIsFixedWidth)
-        Assert.invariant(lengthUnits eq LengthUnits.Characters)
-        new SpecifiedLengthPrefixedCharacters(this, body)
-      }
-      case LengthKind.Implicit
-          if isSimpleType && primType == PrimType.String &&
-            encodingInfo.knownEncodingIsFixedWidth => {
-        //
-        // Important case to optimize
-        // If we can convert to a number of bits, then we should do so
-        //
-        val nBits = 
encodingInfo.knownFixedWidthEncodingInCharsToBits(this.maxLength.longValue)
-        new SpecifiedLengthImplicit(this, body, nBits)
+    // 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
+
+    // there are essentially two categories of processors that read/write data 
input/output
+    // stream: those that calculate lengths themselves and those that expect 
another
+    // processor to calculate the length and set the bit limit which this 
processor will use as
+    // the length. The following determines if this element requires another 
processor to
+    // calculate and set the bit limit, and if so adds the appropriate grammar 
to do that
+    val bodyRequiresSpecifiedLengthBitLimit = lengthKind != 
LengthKind.Delimited && (
+      isSimpleType && impliedRepresentation == Representation.Text ||
+        isSimpleType && isNillable ||
+        isComplexType && lengthKind != LengthKind.Implicit ||
+        lengthKind == LengthKind.Prefixed ||
+        isSimpleType && primType == PrimType.HexBinary && lengthKind == 
LengthKind.Pattern
+    )
+    if (!bodyRequiresSpecifiedLengthBitLimit) {
+      body
+    } else {
+      lazy val bitsMultiplier = lengthUnits match {
+        case LengthUnits.Bits => 1
+        case LengthUnits.Bytes => 8
+        case LengthUnits.Characters if knownEncodingIsFixedWidth =>
+          this.knownEncodingWidthInBits
+        case _ => 0 // zero means can't multiply to get width in bits.
       }
-      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 =>
-        new SpecifiedLengthImplicit(this, body, implicitBinaryLengthInBits)
-      case LengthKind.Implicit if isComplexType =>
-        body // for complex types, implicit means "roll up from the bottom"
-      case LengthKind.EndOfParent if isComplexType =>
-        notYetImplemented("lengthKind='endOfParent' for complex type")
-      case LengthKind.EndOfParent =>
-        notYetImplemented("lengthKind='endOfParent' for simple type")
-      case _ => {
-        // TODO: implement other specified length like end of parent
-        // for now, no restriction
-        body
+      val lk = lengthKind
+      lk match {
+        case LengthKind.Pattern => new SpecifiedLengthPattern(this, body)
+        case LengthKind.Explicit if bitsMultiplier != 0 =>
+          new SpecifiedLengthExplicit(this, body, bitsMultiplier)
+        case LengthKind.Explicit => {
+          Assert.invariant(!knownEncodingIsFixedWidth)
+          Assert.invariant(lengthUnits eq LengthUnits.Characters)
+          new SpecifiedLengthExplicitCharacters(this, body)
+        }
+        case LengthKind.Prefixed if (bitsMultiplier != 0) =>
+          new SpecifiedLengthPrefixed(this, body, bitsMultiplier)
+        case LengthKind.Prefixed => {
+          Assert.invariant(!knownEncodingIsFixedWidth)
+          Assert.invariant(lengthUnits eq LengthUnits.Characters)
+          new SpecifiedLengthPrefixedCharacters(this, body)
+        }
+        case LengthKind.Implicit
+            if isSimpleType && primType == PrimType.String &&
+              encodingInfo.knownEncodingIsFixedWidth => {
+          //
+          // Important case to optimize
+          // If we can convert to a number of bits, then we should do so
+          //
+          val nBits =
+            
encodingInfo.knownFixedWidthEncodingInCharsToBits(this.maxLength.longValue)
+          new SpecifiedLengthImplicit(this, body, nBits)
+        }
+        case LengthKind.Implicit if isSimpleType && primType == 
PrimType.String =>
+          new SpecifiedLengthImplicitCharacters(this, body, 
this.maxLength.longValue)
+        case LengthKind.Implicit
+            if isSimpleType && impliedRepresentation == Representation.Binary 
=>
+          new SpecifiedLengthImplicit(this, body, implicitBinaryLengthInBits)
+        case LengthKind.EndOfParent if isComplexType =>
+          notYetImplemented("lengthKind='endOfParent' for complex type")
+        case LengthKind.EndOfParent =>
+          notYetImplemented("lengthKind='endOfParent' for simple type")
       }
     }
   }
@@ -1396,7 +1413,7 @@ trait ElementBaseGrammarMixin
   private lazy val sharedComplexContentRegion: Gram =
     schemaSet.sharedComplexContentFactory.getShared(
       shareKey,
-      captureLengthRegions(EmptyGram, specifiedLength(complexContent), 
elementUnused) ~
+      captureLengthRegions(EmptyGram, complexContent, elementUnused) ~
         terminatorRegion
     )
 
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBCD.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBCD.scala
index 550daffa7..154e22137 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBCD.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBCD.scala
@@ -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) {
@@ -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
   )
 }
 
@@ -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)
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryBoolean.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryBoolean.scala
index 05a6dfd9b..b934a24fb 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryBoolean.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryBoolean.scala
@@ -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) {
@@ -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
   )
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
index 8c2b4b594..655f580bf 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesBinaryNumber.scala
@@ -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) extends Terminal(e, true) 
{
@@ -69,17 +69,9 @@ class BinaryIntegerKnownLength(val e: ElementBase, val 
lengthInBits: Long)
 class BinaryIntegerPrefixedLength(val e: ElementBase) extends Terminal(e, 
true) {
 
   private lazy val erd = e.elementRuntimeData
-  private lazy val plerd = e.prefixedLengthElementDecl.elementRuntimeData
-  private lazy val pladj = e.prefixedLengthAdjustmentInUnits
 
   override lazy val parser =
-    new BinaryIntegerPrefixedLengthParser(
-      erd,
-      e.prefixedLengthBody.parser,
-      plerd,
-      e.lengthUnits,
-      pladj
-    )
+    new BinaryIntegerBitLimitLengthParser(erd)
 
   override lazy val unparser: Unparser = {
     val maybeNBits = e.primType match {
@@ -91,14 +83,7 @@ class BinaryIntegerPrefixedLength(val e: ElementBase) 
extends Terminal(e, true)
       case _ =>
         Assert.invariantFailed("Only integer base types should be used for 
this primitive")
     }
-    new BinaryIntegerPrefixedLengthUnparser(
-      erd,
-      e.prefixedLengthBody.unparser,
-      plerd,
-      maybeNBits,
-      e.lengthUnits,
-      pladj
-    )
+    new BinaryIntegerMinimumLengthUnparser(erd, maybeNBits)
   }
 }
 
@@ -143,25 +128,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
     )
 
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
index a5380474f..1316426de 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesIBM4690Packed.scala
@@ -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.IBM4690PackedDecimalBitLimitLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedDecimalKnownLengthParser
-import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedDecimalPrefixedLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedDecimalRuntimeLengthParser
+import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedIntegerBitLimitLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedIntegerKnownLengthParser
-import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedIntegerPrefixedLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedIntegerRuntimeLengthParser
 import org.apache.daffodil.runtime1.processors.unparsers.Unparser
 import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedDecimalKnownLengthUnparser
-import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedDecimalPrefixedLengthUnparser
+import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedDecimalMinimumLengthUnparser
 import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedDecimalRuntimeLengthUnparser
 import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerKnownLengthUnparser
-import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerPrefixedLengthUnparser
+import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerMinimumLengthUnparser
 import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedIntegerRuntimeLengthUnparser
 
 class IBM4690PackedIntegerRuntimeLength(val e: ElementBase) extends 
Terminal(e, true) {
@@ -58,20 +58,11 @@ class IBM4690PackedIntegerKnownLength(val e: ElementBase, 
lengthInBits: Long)
 }
 
 class IBM4690PackedIntegerPrefixedLength(val e: ElementBase) extends 
Terminal(e, true) {
-  override lazy val parser = new IBM4690PackedIntegerPrefixedLengthParser(
-    e.elementRuntimeData,
-    e.prefixedLengthBody.parser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
-  )
+  override lazy val parser =
+    new IBM4690PackedIntegerBitLimitLengthParser(e.elementRuntimeData)
 
-  override lazy val unparser: Unparser = new 
IBM4690PackedIntegerPrefixedLengthUnparser(
-    e.elementRuntimeData,
-    e.prefixedLengthBody.unparser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
+  override lazy val unparser: Unparser = new 
IBM4690PackedIntegerMinimumLengthUnparser(
+    e.elementRuntimeData
   )
 }
 
@@ -108,21 +99,13 @@ class IBM4690PackedDecimalKnownLength(val e: ElementBase, 
lengthInBits: Long)
 }
 
 class IBM4690PackedDecimalPrefixedLength(val e: ElementBase) extends 
Terminal(e, true) {
-  override lazy val parser = new IBM4690PackedDecimalPrefixedLengthParser(
+  override lazy val parser = new IBM4690PackedDecimalBitLimitLengthParser(
     e.elementRuntimeData,
-    e.prefixedLengthBody.parser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    e.binaryDecimalVirtualPoint,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
+    e.binaryDecimalVirtualPoint
   )
 
-  override lazy val unparser: Unparser = new 
IBM4690PackedDecimalPrefixedLengthUnparser(
+  override lazy val unparser: Unparser = new 
IBM4690PackedDecimalMinimumLengthUnparser(
     e.elementRuntimeData,
-    e.prefixedLengthBody.unparser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    e.binaryDecimalVirtualPoint,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
+    e.binaryDecimalVirtualPoint
   )
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
index 21baad565..09ce2c1df 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesLengthKind.scala
@@ -34,7 +34,6 @@ import 
org.apache.daffodil.runtime1.processors.parsers.BCDIntegerDelimitedParser
 import 
org.apache.daffodil.runtime1.processors.parsers.BlobSpecifiedLengthParser
 import org.apache.daffodil.runtime1.processors.parsers.HexBinaryDelimitedParser
 import 
org.apache.daffodil.runtime1.processors.parsers.HexBinaryEndOfBitLimitParser
-import 
org.apache.daffodil.runtime1.processors.parsers.HexBinaryLengthPrefixedParser
 import 
org.apache.daffodil.runtime1.processors.parsers.HexBinarySpecifiedLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedDecimalDelimitedParser
 import 
org.apache.daffodil.runtime1.processors.parsers.IBM4690PackedIntegerDelimitedParser
@@ -48,7 +47,6 @@ import org.apache.daffodil.runtime1.processors.unparsers.{ 
Unparser => DaffodilU
 import org.apache.daffodil.unparsers.runtime1.BCDDecimalDelimitedUnparser
 import org.apache.daffodil.unparsers.runtime1.BCDIntegerDelimitedUnparser
 import org.apache.daffodil.unparsers.runtime1.BlobSpecifiedLengthUnparser
-import org.apache.daffodil.unparsers.runtime1.HexBinaryLengthPrefixedUnparser
 import org.apache.daffodil.unparsers.runtime1.HexBinaryMinLengthInBytesUnparser
 import org.apache.daffodil.unparsers.runtime1.HexBinarySpecifiedLengthUnparser
 import 
org.apache.daffodil.unparsers.runtime1.IBM4690PackedDecimalDelimitedUnparser
@@ -185,22 +183,12 @@ case class HexBinaryEndOfBitLimit(e: ElementBase) extends 
Terminal(e, true) {
 
 case class HexBinaryLengthPrefixed(e: ElementBase) extends Terminal(e, true) {
 
-  override lazy val parser: DaffodilParser = new HexBinaryLengthPrefixedParser(
-    e.elementRuntimeData,
-    e.prefixedLengthBody.parser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
+  override lazy val parser: DaffodilParser = new HexBinaryEndOfBitLimitParser(
+    e.elementRuntimeData
   )
 
-  override lazy val unparser: DaffodilUnparser = new 
HexBinaryLengthPrefixedUnparser(
-    e.elementRuntimeData,
-    e.prefixedLengthBody.unparser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    e.minLength.longValue,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
-  )
+  override lazy val unparser: DaffodilUnparser =
+    new HexBinaryMinLengthInBytesUnparser(e.minLength.longValue, 
e.elementRuntimeData)
 }
 
 abstract class PackedIntegerDelimited(
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
index c0f7a73ec..109abfef9 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesPacked.scala
@@ -20,18 +20,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.lib.util.PackedSignCodes
+import 
org.apache.daffodil.runtime1.processors.parsers.PackedDecimalBitLimitLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.PackedDecimalKnownLengthParser
-import 
org.apache.daffodil.runtime1.processors.parsers.PackedDecimalPrefixedLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.PackedDecimalRuntimeLengthParser
+import 
org.apache.daffodil.runtime1.processors.parsers.PackedIntegerBitLimitLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.PackedIntegerKnownLengthParser
-import 
org.apache.daffodil.runtime1.processors.parsers.PackedIntegerPrefixedLengthParser
 import 
org.apache.daffodil.runtime1.processors.parsers.PackedIntegerRuntimeLengthParser
 import org.apache.daffodil.runtime1.processors.unparsers.Unparser
 import org.apache.daffodil.unparsers.runtime1.PackedDecimalKnownLengthUnparser
-import 
org.apache.daffodil.unparsers.runtime1.PackedDecimalPrefixedLengthUnparser
+import 
org.apache.daffodil.unparsers.runtime1.PackedDecimalMinimumLengthUnparser
 import 
org.apache.daffodil.unparsers.runtime1.PackedDecimalRuntimeLengthUnparser
 import org.apache.daffodil.unparsers.runtime1.PackedIntegerKnownLengthUnparser
-import 
org.apache.daffodil.unparsers.runtime1.PackedIntegerPrefixedLengthUnparser
+import 
org.apache.daffodil.unparsers.runtime1.PackedIntegerMinimumLengthUnparser
 import 
org.apache.daffodil.unparsers.runtime1.PackedIntegerRuntimeLengthUnparser
 
 class PackedIntegerRuntimeLength(
@@ -77,23 +77,11 @@ class PackedIntegerPrefixedLength(
   packedSignCodes: PackedSignCodes
 ) extends Terminal(e, true) {
 
-  override lazy val parser = new PackedIntegerPrefixedLengthParser(
-    e.elementRuntimeData,
-    e.prefixedLengthBody.parser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    packedSignCodes,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
-  )
+  override lazy val parser =
+    new PackedIntegerBitLimitLengthParser(e.elementRuntimeData, 
packedSignCodes)
 
-  override lazy val unparser: Unparser = new 
PackedIntegerPrefixedLengthUnparser(
-    e.elementRuntimeData,
-    e.prefixedLengthBody.unparser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
-    packedSignCodes,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
-  )
+  override lazy val unparser: Unparser =
+    new PackedIntegerMinimumLengthUnparser(e.elementRuntimeData, 
packedSignCodes)
 }
 
 class PackedDecimalRuntimeLength(val e: ElementBase, packedSignCodes: 
PackedSignCodes)
@@ -139,23 +127,15 @@ class PackedDecimalKnownLength(
 class PackedDecimalPrefixedLength(val e: ElementBase, packedSignCodes: 
PackedSignCodes)
   extends Terminal(e, true) {
 
-  override lazy val parser = new PackedDecimalPrefixedLengthParser(
+  override lazy val parser = new PackedDecimalBitLimitLengthParser(
     e.elementRuntimeData,
-    e.prefixedLengthBody.parser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
     e.binaryDecimalVirtualPoint,
-    packedSignCodes,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
+    packedSignCodes
   )
 
-  override lazy val unparser: Unparser = new 
PackedDecimalPrefixedLengthUnparser(
+  override lazy val unparser: Unparser = new 
PackedDecimalMinimumLengthUnparser(
     e.elementRuntimeData,
-    e.prefixedLengthBody.unparser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
     e.binaryDecimalVirtualPoint,
-    packedSignCodes,
-    e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits
+    packedSignCodes
   )
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
index aa2e6a1dd..2a4ef31fa 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
@@ -24,7 +24,7 @@ import org.apache.daffodil.core.dsom.PrimitiveType
 import org.apache.daffodil.core.dsom.Root
 import org.apache.daffodil.core.dsom.SimpleTypeDefBase
 import org.apache.daffodil.lib.schema.annotation.props.gen.LengthKind
-import org.apache.daffodil.lib.schema.annotation.props.gen.Representation
+import org.apache.daffodil.lib.schema.annotation.props.gen.Representation.Text
 import org.apache.daffodil.lib.util.Delay
 import org.apache.daffodil.lib.util.Maybe
 import org.apache.daffodil.runtime1.dsom.DPathElementCompileInfo
@@ -65,7 +65,12 @@ trait ElementBaseRuntime1Mixin { self: ElementBase =>
     // no reason (unless it is referenced in a contentLength expression).
     val mightHaveSuspensions = (maybeFixedLengthInBits.isDefined && 
couldHaveSuspensions)
 
-    isReferenced || mightHaveSuspensions
+    // we want to capture contentlength when LK = prefixed because
+    // some prefixed length unparsers are unable to calculate the prefixed 
length
+    // of the field. Instead, they unparse the field to a buffer and the 
captured
+    // content length of the buffer is used. For this reason, prefixed length
+    // elements must capture content length for unparse.
+    lengthKind == LengthKind.Prefixed || isReferenced || mightHaveSuspensions
   }
 
   /**
@@ -89,17 +94,18 @@ trait ElementBaseRuntime1Mixin { self: ElementBase =>
     //
     // For complex elements with specified length, value length is captured in
     // the specified length parsers, since they handle skipping unused
-    // element regions. For complex elements, this means lengthKind is not
+    // element regions, and the length capturing has to be done before that.
+    // For complex elements, this means lengthKind is not
     // implicit or delimited.
     //
     // So for these cases we do not want to capture value length with the
     // Capture{Start,End}OfValueLengthParsers, since those lengths are captured
     // by the value parsers
-    val capturedByParsers =
-      (isSimpleType && (impliedRepresentation == Representation.Text || 
lengthKind == LengthKind.Delimited)) ||
+    val capturedByValueParsers =
+      (isSimpleType && (impliedRepresentation == Text || lengthKind == 
LengthKind.Delimited)) ||
         (isComplexType && (lengthKind != LengthKind.Implicit && lengthKind != 
LengthKind.Delimited))
 
-    !capturedByParsers && isReferenced
+    !capturedByValueParsers && isReferenced
   }
 
   /**
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BCDUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BCDUnparsers.scala
index 84dde6a12..86c80ba43 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BCDUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BCDUnparsers.scala
@@ -25,7 +25,6 @@ import org.apache.daffodil.lib.util.DecimalUtils
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
 import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.parsers.HasKnownLengthInBits
 import org.apache.daffodil.runtime1.processors.parsers.HasRuntimeExplicitLength
 import org.apache.daffodil.runtime1.processors.unparsers._
@@ -57,16 +56,9 @@ final class BCDIntegerDelimitedUnparser(e: 
ElementRuntimeData)
   override def getBitLength(state: ParseOrUnparseState): Int = { 0 }
 }
 
-final class BCDIntegerPrefixedLengthUnparser(
-  e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends BCDIntegerBaseUnparser(e)
-  with KnownPrefixedLengthUnparserMixin {
+final class BCDIntegerMinimumLengthUnparser(e: ElementRuntimeData)
+  extends BCDIntegerBaseUnparser(e) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -75,11 +67,6 @@ final class BCDIntegerPrefixedLengthUnparser(
     val (byteLength, _) = DecimalUtils.bcdFromBigIntegerLength(absBigIntStr, 0)
     byteLength * 8
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
 
 abstract class BCDDecimalBaseUnparser(e: ElementRuntimeData, 
binaryDecimalVirtualPoint: Int)
@@ -113,17 +100,11 @@ final class BCDDecimalDelimitedUnparser(e: 
ElementRuntimeData, binaryDecimalVirt
   override def getBitLength(state: ParseOrUnparseState): Int = { 0 }
 }
 
-final class BCDDecimalPrefixedLengthUnparser(
+final class BCDDecimalMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  binaryDecimalVirtualPoint: Int,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends BCDDecimalBaseUnparser(e, binaryDecimalVirtualPoint)
-  with KnownPrefixedLengthUnparserMixin {
+  binaryDecimalVirtualPoint: Int
+) extends BCDDecimalBaseUnparser(e, binaryDecimalVirtualPoint) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -132,9 +113,4 @@ final class BCDDecimalPrefixedLengthUnparser(
     val (byteLength, _) = DecimalUtils.bcdFromBigIntegerLength(absBigIntStr, 0)
     byteLength * 8
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryBooleanUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryBooleanUnparsers.scala
index 8f57d2b59..59bb85d04 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryBooleanUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryBooleanUnparsers.scala
@@ -30,7 +30,6 @@ import org.apache.daffodil.lib.util.Numbers
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
 import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.unparsers._
 
 import passera.unsigned.ULong
@@ -129,26 +128,20 @@ class BinaryBooleanUnparser(
   }
 }
 
-class BinaryBooleanPrefixedLengthUnparser(
+class BinaryBooleanMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
   binaryBooleanTrueRep: MaybeULong,
   binaryBooleanFalseRep: ULong,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends BinaryBooleanUnparserBase(e, binaryBooleanTrueRep, 
binaryBooleanFalseRep, lengthUnits)
-  with KnownPrefixedLengthUnparserMixin {
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
+  lengthUnits: LengthUnits
+) extends BinaryBooleanUnparserBase(
+    e,
+    binaryBooleanTrueRep,
+    binaryBooleanFalseRep,
+    lengthUnits
+  ) {
 
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = 32
 
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
-
 }
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
index b4f99d9ab..437587def 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala
@@ -32,7 +32,6 @@ import org.apache.daffodil.runtime1.dpath.NodeInfo
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
 import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.parsers.BinaryNumberCheckWidth
 import org.apache.daffodil.runtime1.processors.parsers.HasKnownLengthInBits
 import org.apache.daffodil.runtime1.processors.parsers.HasRuntimeExplicitLength
@@ -126,19 +125,13 @@ class BinaryIntegerRuntimeLengthUnparser(
   override val runtimeDependencies = Vector(lengthEv)
 }
 
-class BinaryIntegerPrefixedLengthUnparser(
+class BinaryIntegerMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  maybeNBits: MaybeInt,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends BinaryIntegerBaseUnparser(e: ElementRuntimeData)
-  with KnownPrefixedLengthUnparserMixin {
+  maybeNBits: MaybeInt
+) extends BinaryIntegerBaseUnparser(e: ElementRuntimeData) {
 
   private val primNumeric = 
e.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -154,11 +147,6 @@ class BinaryIntegerPrefixedLengthUnparser(
       (signedLen + 7) & ~0x7 // round up to nearest multilpe of 8
     }
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
 
 class BinaryFloatUnparser(e: ElementRuntimeData) extends 
BinaryNumberBaseUnparser(e) {
@@ -218,18 +206,12 @@ class BinaryDecimalRuntimeLengthUnparser(
   override val runtimeDependencies = Vector(lengthEv)
 }
 
-class BinaryDecimalPrefixedLengthUnparser(
+class BinaryDecimalMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
   signed: YesNo,
-  binaryDecimalVirtualPoint: Int,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends BinaryDecimalUnparserBase(e, signed, binaryDecimalVirtualPoint)
-  with KnownPrefixedLengthUnparserMixin {
+  binaryDecimalVirtualPoint: Int
+) extends BinaryDecimalUnparserBase(e, signed, binaryDecimalVirtualPoint) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -240,11 +222,6 @@ class BinaryDecimalPrefixedLengthUnparser(
     val signedLen = if (signed == YesNo.Yes) len + 1 else len
     (signedLen + 7) & ~0x7 // round up to nearest multilpe of 8
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
 
 abstract class BinaryDecimalUnparserBase(
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/HexBinaryLengthUnparser.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/HexBinaryLengthUnparser.scala
index 6fa3d845e..2bd7d316f 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/HexBinaryLengthUnparser.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/HexBinaryLengthUnparser.scala
@@ -18,12 +18,9 @@
 package org.apache.daffodil.unparsers.runtime1
 
 import org.apache.daffodil.lib.exceptions.Assert
-import org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.lib.util.Maybe._
 import org.apache.daffodil.runtime1.infoset.RetryableException
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
-import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.UnparseTargetLengthInBitsEv
 import org.apache.daffodil.runtime1.processors.unparsers._
 
@@ -129,26 +126,3 @@ final class HexBinarySpecifiedLengthUnparser(
     l
   }
 }
-
-final class HexBinaryLengthPrefixedUnparser(
-  erd: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  minLengthInBytes: Long,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends HexBinaryMinLengthInBytesUnparser(minLengthInBytes, erd)
-  with KnownPrefixedLengthUnparserMixin {
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    val bits = getLengthInBits(state.asInstanceOf[UState])
-    bits.toInt
-  }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
-}
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/IBM4690PackedDecimalUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/IBM4690PackedDecimalUnparsers.scala
index c401643e7..1fb458cf9 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/IBM4690PackedDecimalUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/IBM4690PackedDecimalUnparsers.scala
@@ -25,7 +25,6 @@ import org.apache.daffodil.lib.util.DecimalUtils
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
 import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.parsers.HasKnownLengthInBits
 import org.apache.daffodil.runtime1.processors.parsers.HasRuntimeExplicitLength
 import org.apache.daffodil.runtime1.processors.unparsers._
@@ -59,16 +58,9 @@ final class IBM4690PackedIntegerDelimitedUnparser(e: 
ElementRuntimeData)
   override def getBitLength(state: ParseOrUnparseState): Int = { 0 }
 }
 
-final class IBM4690PackedIntegerPrefixedLengthUnparser(
-  e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends IBM4690PackedIntegerBaseUnparser(e)
-  with KnownPrefixedLengthUnparserMixin {
+final class IBM4690PackedIntegerMinimumLengthUnparser(e: ElementRuntimeData)
+  extends IBM4690PackedIntegerBaseUnparser(e) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -79,11 +71,6 @@ final class IBM4690PackedIntegerPrefixedLengthUnparser(
     val (byteLength, _) = 
DecimalUtils.ibm4690FromBigIntegerLength(absBigIntStr, 0, negative)
     byteLength * 8
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
 
 abstract class IBM4690PackedDecimalBaseUnparser(
@@ -121,17 +108,11 @@ final class IBM4690PackedDecimalDelimitedUnparser(
   override def getBitLength(state: ParseOrUnparseState): Int = { 0 }
 }
 
-final class IBM4690PackedDecimalPrefixedLengthUnparser(
+final class IBM4690PackedDecimalMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  binaryDecimalVirtualPoint: Int,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends IBM4690PackedDecimalBaseUnparser(e, binaryDecimalVirtualPoint)
-  with KnownPrefixedLengthUnparserMixin {
+  binaryDecimalVirtualPoint: Int
+) extends IBM4690PackedDecimalBaseUnparser(e, binaryDecimalVirtualPoint) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -142,9 +123,4 @@ final class IBM4690PackedDecimalPrefixedLengthUnparser(
     val (byteLength, _) = 
DecimalUtils.ibm4690FromBigIntegerLength(absBigIntStr, 0, negative)
     byteLength * 8
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/PackedDecimalUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/PackedDecimalUnparsers.scala
index ccad3a7a4..c378f80b3 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/PackedDecimalUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/PackedDecimalUnparsers.scala
@@ -25,7 +25,6 @@ import org.apache.daffodil.lib.util.{ DecimalUtils, 
PackedSignCodes }
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
 import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.parsers.HasKnownLengthInBits
 import org.apache.daffodil.runtime1.processors.parsers.HasRuntimeExplicitLength
 import org.apache.daffodil.runtime1.processors.unparsers._
@@ -65,17 +64,11 @@ final class PackedIntegerDelimitedUnparser(
   override def getBitLength(state: ParseOrUnparseState): Int = { 0 }
 }
 
-final class PackedIntegerPrefixedLengthUnparser(
+final class PackedIntegerMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  packedSignCodes: PackedSignCodes,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends PackedIntegerBaseUnparser(e, packedSignCodes)
-  with KnownPrefixedLengthUnparserMixin {
+  packedSignCodes: PackedSignCodes
+) extends PackedIntegerBaseUnparser(e, packedSignCodes) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -84,11 +77,6 @@ final class PackedIntegerPrefixedLengthUnparser(
     val (byteLength, _) = 
DecimalUtils.packedFromBigIntegerLength(absBigIntStr, 0)
     byteLength * 8
   }
-
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
 }
 
 abstract class PackedDecimalBaseUnparser(
@@ -130,18 +118,12 @@ final class PackedDecimalDelimitedUnparser(
   override def getBitLength(state: ParseOrUnparseState): Int = { 0 }
 }
 
-final class PackedDecimalPrefixedLengthUnparser(
+final class PackedDecimalMinimumLengthUnparser(
   e: ElementRuntimeData,
-  override val prefixedLengthUnparser: Unparser,
-  override val prefixedLengthERD: ElementRuntimeData,
   binaryDecimalVirtualPoint: Int,
-  packedSignCodes: PackedSignCodes,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends PackedDecimalBaseUnparser(e, binaryDecimalVirtualPoint, 
packedSignCodes)
-  with KnownPrefixedLengthUnparserMixin {
+  packedSignCodes: PackedSignCodes
+) extends PackedDecimalBaseUnparser(e, binaryDecimalVirtualPoint, 
packedSignCodes) {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthUnparser)
   override lazy val runtimeDependencies = Vector()
 
   override def getBitLength(s: ParseOrUnparseState): Int = {
@@ -151,9 +133,4 @@ final class PackedDecimalPrefixedLengthUnparser(
     byteLength * 8
   }
 
-  override def unparse(state: UState): Unit = {
-    unparsePrefixedLength(state)
-    super.unparse(state)
-  }
-
 }
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLength2.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLength2.scala
index 3dcebfa9d..957110f4e 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLength2.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLength2.scala
@@ -931,11 +931,11 @@ class PrefixLengthSuspendableOperation(
   override protected def maybeKnownLengthInBits(ustate: UState): MaybeULong = 
MaybeULong(0L)
 
   override def test(ustate: UState): Boolean = {
-    elem.valueLength.maybeLengthInBits.isDefined
+    elem.contentLength.maybeLengthInBits.isDefined
   }
 
   override def continuation(state: UState): Unit = {
-    val len = elem.valueLength.maybeLengthInBits.isDefined
+    val len = elem.contentLength.maybeLengthInBits.isDefined
     assignPrefixLength(state, elem, plElem)
   }
 }
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
index f2ec32e9b..d8e9bc3c4 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/SpecifiedLengthUnparsers.scala
@@ -26,7 +26,6 @@ import org.apache.daffodil.runtime1.infoset.DISimple
 import org.apache.daffodil.runtime1.infoset.Infoset
 import org.apache.daffodil.runtime1.processors.CharsetEv
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
-import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
 import org.apache.daffodil.runtime1.processors.UnparseTargetLengthInBitsEv
 import org.apache.daffodil.runtime1.processors.unparsers._
 
@@ -73,85 +72,10 @@ final class SpecifiedLengthExplicitImplicitUnparser(
   }
 }
 
-// TODO: implement the capture length unparsers as just using this trait?
-trait CaptureUnparsingValueLength {
-
-  def captureValueLengthStart(state: UState, elem: DIElement): Unit = {
-    val dos = state.dataOutputStream
-    if (dos.maybeAbsBitPos0b.isDefined) {
-      elem.valueLength.setAbsStartPos0bInBits(dos.maybeAbsBitPos0b.getULong)
-    } else {
-      elem.valueLength.setRelStartPos0bInBits(dos.relBitPos0b, dos)
-    }
-  }
-
-  def captureValueLengthEnd(state: UState, elem: DIElement): Unit = {
-    val dos = state.dataOutputStream
-    if (dos.maybeAbsBitPos0b.isDefined) {
-      elem.valueLength.setAbsEndPos0bInBits(dos.maybeAbsBitPos0b.getULong)
-    } else {
-      elem.valueLength.setRelEndPos0bInBits(dos.relBitPos0b, dos)
-    }
-  }
-}
-
-/**
- * This trait is to be used with prefixed length unparsers where the length is
- * known without needing to unparse the data. This means there is either a
- * fixed length (like in the case of some binary numbers), or the length can be
- * determined completly be inspecting the infoset data (like in the case of
- * packed decimals). The length calculation performed in the getBitLength
- * function, which returns the length of the data in bits.
- */
-trait KnownPrefixedLengthUnparserMixin {
-  def prefixedLengthERD: ElementRuntimeData
-  def prefixedLengthUnparser: Unparser
-  def lengthUnits: LengthUnits
-  def getBitLength(s: ParseOrUnparseState): Int
-  def prefixedLengthAdjustmentInUnits: Long
-
-  def unparsePrefixedLength(state: UState): Unit = {
-    val bits = getBitLength(state)
-    val lenInUnits =
-      if (lengthUnits == LengthUnits.Bytes) {
-        bits >> 3
-      } else {
-        bits
-      }
-    val adjustedLenInUnits = lenInUnits + prefixedLengthAdjustmentInUnits
-    // Create a "detached" DIDocument with a single child element that the
-    // prefix length will be unparsed from. This creates a completely new
-    // infoset and unparses from that, so care is taken to ensure this infoset
-    // is only used for the prefix length unparsing and is removed afterwards
-    val plElement = Infoset.newDetachedElement(state, 
prefixedLengthERD).asInstanceOf[DISimple]
-
-    plElement.setDataValue(java.lang.Integer.valueOf(adjustedLenInUnits.toInt))
-
-    // do checks on facets expressed on prefixLengthType
-    val optSTRD = plElement.erd.optSimpleTypeRuntimeData
-    if (optSTRD.isDefined) {
-      val strd = optSTRD.get
-      val check = strd.executeCheck(plElement)
-      if (check.isError) {
-        UnparseError(
-          One(state.schemaFileLocation),
-          One(state.currentLocation),
-          s"The calculated value of ${prefixedLengthERD.namedQName} 
($adjustedLenInUnits) failed check due to ${check.errMsg}"
-        )
-      }
-    }
-
-    // unparse the prefixed length element
-    state.currentInfosetNodeStack.push(One(plElement))
-    prefixedLengthUnparser.unparse1(state)
-    state.currentInfosetNodeStack.pop
-  }
-}
-
 /**
  * This trait is to be used with prefixed length unparsers where the length
- * must be calculated based on the value length of the data. This means the
- * data must be unparsed, the value length calculated, and that value will be
+ * must be calculated based on the content length of the data. This means the
+ * data must be unparsed, the content length calculated, and that value will be
  * assigned to the prefix length element.
  */
 trait CalculatedPrefixedLengthUnparserMixin {
@@ -168,16 +92,16 @@ trait CalculatedPrefixedLengthUnparserMixin {
    */
   def assignPrefixLength(state: UState, elem: DIElement, plElem: DISimple): 
Unit = {
     val lenInUnits = lengthUnits match {
-      case LengthUnits.Bits => elem.valueLength.lengthInBits
-      case LengthUnits.Bytes => elem.valueLength.lengthInBytes
+      case LengthUnits.Bits => elem.contentLength.lengthInBits
+      case LengthUnits.Bytes => elem.contentLength.lengthInBytes
       case LengthUnits.Characters => {
         val maybeFixedWidth =
           
elem.erd.encInfo.getEncoderInfo(state).coder.bitsCharset.maybeFixedWidth
         val lengthInChars =
           if (maybeFixedWidth.isDefined) {
             val fixedWidth = maybeFixedWidth.get
-            Assert.invariant((elem.valueLength.lengthInBits % fixedWidth) == 
0) // divisible
-            elem.valueLength.lengthInBits / fixedWidth
+            Assert.invariant((elem.contentLength.lengthInBits % fixedWidth) == 
0) // divisible
+            elem.contentLength.lengthInBits / fixedWidth
           } else {
             // This is checked for statically, so should not get here.
             // $COVERAGE-OFF$
@@ -200,7 +124,7 @@ trait CalculatedPrefixedLengthUnparserMixin {
         UnparseError(
           One(state.schemaFileLocation),
           One(state.currentLocation),
-          s"The calculated value of ${elem.namedQName} ($adjustedLenInUnits) 
failed check due to ${check.errMsg}"
+          s"The prefix length value of ${elem.namedQName} 
($adjustedLenInUnits) failed check due to ${check.errMsg}"
         )
       }
     }
@@ -215,7 +139,6 @@ class SpecifiedLengthPrefixedUnparser(
   override val lengthUnits: LengthUnits,
   override val prefixedLengthAdjustmentInUnits: Long
 ) extends CombinatorUnparser(erd)
-  with CaptureUnparsingValueLength
   with CalculatedPrefixedLengthUnparserMixin {
 
   override lazy val runtimeDependencies = Vector()
@@ -238,13 +161,10 @@ class SpecifiedLengthPrefixedUnparser(
     prefixedLengthUnparser.unparse1(state)
     state.currentInfosetNodeStack.pop
 
-    // We now need to capture the length of the actual element
     val elem = state.currentInfosetNode.asInstanceOf[DIElement]
-    captureValueLengthStart(state, elem)
     eUnparser.unparse1(state)
-    captureValueLengthEnd(state, elem)
 
-    if (elem.valueLength.maybeLengthInBits.isDefined) {
+    if (elem.contentLength.maybeLengthInBits.isDefined) {
       // If we were able to immediately calculate the length of the element,
       // then just set it as the value of the detached element created above so
       // that when the prefixedLengthUnparser suspension resumes it can unparse
@@ -253,7 +173,7 @@ class SpecifiedLengthPrefixedUnparser(
     } else {
       // The length was not able to be calculated, likely because there was a
       // suspension when unparsing the eUnparser. So let's create a new
-      // suspension with the only goal to retry until the valueLength of this
+      // suspension with the only goal to retry until the contentLength of this
       // element is determined. Once determined, it will set the value of the
       // prefix length element, ultimately allowing the prefix length element
       // suspension to resume and unparse the value
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala
index 1aed39f82..03c4c15e1 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala
@@ -733,6 +733,10 @@ sealed abstract class LengthState(ie: DIElement) {
   }
 
   def setAbsStartPos0bInBits(absPosInBits0b: ULong): Unit = {
+    Assert.invariant(
+      maybeStartPos0bInBits.isEmpty,
+      s"maybeStartPos0bInBits already has a value: $maybeStartPos0bInBits"
+    )
     maybeStartPos0bInBits = MaybeULong(absPosInBits0b.longValue)
     maybeStartDataOutputStream = Nope
   }
@@ -743,6 +747,10 @@ sealed abstract class LengthState(ie: DIElement) {
   }
 
   def setAbsEndPos0bInBits(absPosInBits0b: ULong): Unit = {
+    Assert.invariant(
+      maybeEndPos0bInBits.isEmpty,
+      s"maybeEndPos0bInBits already has a value: $maybeEndPos0bInBits"
+    )
     maybeEndPos0bInBits = MaybeULong(absPosInBits0b.longValue)
     maybeEndDataOutputStream = Nope
   }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/BCDParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/BCDParsers.scala
index e18eecd50..60dae9090 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/BCDParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/BCDParsers.scala
@@ -24,8 +24,6 @@ import 
org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.lib.util.DecimalUtils
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
-import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 
 class BCDDecimalKnownLengthParser(
   e: ElementRuntimeData,
@@ -52,25 +50,14 @@ class BCDDecimalRuntimeLengthParser(
 
 }
 
-class BCDDecimalPrefixedLengthParser(
+class BCDDecimalBitLimitLengthParser(
   e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  binaryDecimalVirtualPoint: Int,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
+  binaryDecimalVirtualPoint: Int
 ) extends PackedBinaryDecimalBaseParser(e, binaryDecimalVirtualPoint)
-  with PrefixedLengthParserMixin {
+  with BitLengthFromBitLimitMixin {
 
   override def toNumber(num: Array[Byte]): JBigDecimal =
     DecimalUtils.bcdToBigDecimal(num, binaryDecimalVirtualPoint)
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
-
 }
 
 class BCDIntegerRuntimeLengthParser(
@@ -92,20 +79,9 @@ class BCDIntegerKnownLengthParser(e: ElementRuntimeData, val 
lengthInBits: Int)
 
 }
 
-class BCDIntegerPrefixedLengthParser(
-  e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends PackedBinaryIntegerBaseParser(e)
-  with PrefixedLengthParserMixin {
+class BCDIntegerBitLimitLengthParser(e: ElementRuntimeData)
+  extends PackedBinaryIntegerBaseParser(e)
+  with BitLengthFromBitLimitMixin {
 
   override def toNumber(num: Array[Byte]): JBigInteger = 
DecimalUtils.bcdToBigInteger(num)
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
 }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
index e0a359818..077c76671 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/IBM4690PackedDecimalParsers.scala
@@ -24,8 +24,6 @@ import 
org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.lib.util.DecimalUtils
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
-import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 
 class IBM4690PackedDecimalKnownLengthParser(
   e: ElementRuntimeData,
@@ -52,25 +50,15 @@ class IBM4690PackedDecimalRuntimeLengthParser(
 
 }
 
-class IBM4690PackedDecimalPrefixedLengthParser(
+class IBM4690PackedDecimalBitLimitLengthParser(
   e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  binaryDecimalVirtualPoint: Int,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
+  binaryDecimalVirtualPoint: Int
 ) extends PackedBinaryDecimalBaseParser(e, binaryDecimalVirtualPoint)
-  with PrefixedLengthParserMixin {
+  with BitLengthFromBitLimitMixin {
 
   override def toNumber(num: Array[Byte]): JBigDecimal =
     DecimalUtils.ibm4690ToBigDecimal(num, binaryDecimalVirtualPoint)
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
-
 }
 
 class IBM4690PackedIntegerRuntimeLengthParser(
@@ -96,21 +84,11 @@ class IBM4690PackedIntegerKnownLengthParser(
 
 }
 
-class IBM4690PackedIntegerPrefixedLengthParser(
-  e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends PackedBinaryIntegerBaseParser(e)
-  with PrefixedLengthParserMixin {
+class IBM4690PackedIntegerBitLimitLengthParser(e: ElementRuntimeData)
+  extends PackedBinaryIntegerBaseParser(e)
+  with BitLengthFromBitLimitMixin {
 
   override def toNumber(num: Array[Byte]): JBigInteger =
     DecimalUtils.ibm4690ToBigInteger(num)
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
 }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
index 7e19f2d1f..1ac74993d 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/PackedDecimalParsers.scala
@@ -24,8 +24,6 @@ import 
org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.lib.util.{ DecimalUtils, PackedSignCodes }
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
-import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 
 class PackedDecimalKnownLengthParser(
   e: ElementRuntimeData,
@@ -53,26 +51,15 @@ class PackedDecimalRuntimeLengthParser(
     DecimalUtils.packedToBigDecimal(num, binaryDecimalVirtualPoint, 
packedSignCodes)
 }
 
-class PackedDecimalPrefixedLengthParser(
+class PackedDecimalBitLimitLengthParser(
   e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
   binaryDecimalVirtualPoint: Int,
-  packedSignCodes: PackedSignCodes,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
+  packedSignCodes: PackedSignCodes
 ) extends PackedBinaryDecimalBaseParser(e, binaryDecimalVirtualPoint)
-  with PrefixedLengthParserMixin {
+  with BitLengthFromBitLimitMixin {
 
   override def toNumber(num: Array[Byte]): JBigDecimal =
     DecimalUtils.packedToBigDecimal(num, binaryDecimalVirtualPoint, 
packedSignCodes)
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
-
 }
 
 class PackedIntegerRuntimeLengthParser(
@@ -100,22 +87,13 @@ class PackedIntegerKnownLengthParser(
 
 }
 
-class PackedIntegerPrefixedLengthParser(
+class PackedIntegerBitLimitLengthParser(
   e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  packedSignCodes: PackedSignCodes,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
+  packedSignCodes: PackedSignCodes
 ) extends PackedBinaryIntegerBaseParser(e)
-  with PrefixedLengthParserMixin {
+  with BitLengthFromBitLimitMixin {
 
   override def toNumber(num: Array[Byte]): JBigInteger =
     DecimalUtils.packedToBigInteger(num, packedSignCodes)
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
 }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryBooleanParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryBooleanParsers.scala
index ee7e85ba3..3ce64df07 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryBooleanParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryBooleanParsers.scala
@@ -26,7 +26,6 @@ import org.apache.daffodil.lib.util.MaybeULong
 import org.apache.daffodil.lib.util.Numbers
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
-import org.apache.daffodil.runtime1.processors.Processor
 
 import passera.unsigned.ULong
 
@@ -106,21 +105,17 @@ class BinaryBooleanParser(
   }
 }
 
-class BinaryBooleanPrefixedLengthParser(
+class BinaryBooleanBitLimitLengthParser(
   override val context: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
   binaryBooleanTrueRep: MaybeULong,
   binaryBooleanFalseRep: ULong,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
+  lengthUnits: LengthUnits
 ) extends BinaryBooleanParserBase(binaryBooleanTrueRep, binaryBooleanFalseRep, 
lengthUnits)
-  with PrefixedLengthParserMixin {
+  with BitLengthFromBitLimitMixin {
 
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
   override val runtimeDependencies = Vector()
 
   override def getBitLength(state: PState): Int = {
-    getPrefixedLengthInBits(state).toInt
+    getLengthInBits(state).toInt
   }
 }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
index fac7a9078..1b65a6e08 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberParsers.scala
@@ -28,7 +28,6 @@ import org.apache.daffodil.runtime1.dpath.NodeInfo
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.Evaluatable
 import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
-import org.apache.daffodil.runtime1.processors.Processor
 import org.apache.daffodil.runtime1.processors.unparsers.UState
 
 class BinaryFloatParser(override val context: ElementRuntimeData) extends 
PrimParser {
@@ -80,23 +79,12 @@ class BinaryDecimalRuntimeLengthParser(
 ) extends BinaryDecimalParserBase(e, signed, binaryDecimalVirtualPoint)
   with HasRuntimeExplicitLength {}
 
-class BinaryDecimalPrefixedLengthParser(
+class BinaryDecimalBitLimitLengthParser(
   e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
   signed: YesNo,
-  binaryDecimalVirtualPoint: Int,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
+  binaryDecimalVirtualPoint: Int
 ) extends BinaryDecimalParserBase(e, signed, binaryDecimalVirtualPoint)
-  with PrefixedLengthParserMixin {
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
-}
+  with BitLengthFromBitLimitMixin
 
 abstract class BinaryDecimalParserBase(
   override val context: ElementRuntimeData,
@@ -142,21 +130,9 @@ class BinaryIntegerKnownLengthParser(
 ) extends BinaryIntegerBaseParser(e)
   with HasKnownLengthInBits {}
 
-class BinaryIntegerPrefixedLengthParser(
-  e: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends BinaryIntegerBaseParser(e)
-  with PrefixedLengthParserMixin {
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-
-  override def getBitLength(state: ParseOrUnparseState): Int = {
-    getPrefixedLengthInBits(state.asInstanceOf[PState]).toInt
-  }
-}
+class BinaryIntegerBitLimitLengthParser(e: ElementRuntimeData)
+  extends BinaryIntegerBaseParser(e)
+  with BitLengthFromBitLimitMixin
 
 abstract class BinaryIntegerBaseParser(
   override val context: ElementRuntimeData
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberTraits.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberTraits.scala
index 29317a295..9641aef5f 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberTraits.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/BinaryNumberTraits.scala
@@ -110,7 +110,7 @@ trait PrefixedLengthParserMixin {
         val check = strd.executeCheck(plElement)
         if (check.isError) {
           val pe = state.toProcessingError(
-            s"The value of ${prefixedLengthERD.namedQName} ($parsedLen) failed 
check due to ${check.errMsg}"
+            s"The prefix length value of ${savedInfoset.namedQName} 
($parsedLen) failed check due to ${check.errMsg}"
           )
           state.setFailed(pe)
         }
@@ -165,3 +165,23 @@ trait PrefixedLengthParserMixin {
     }
   }
 }
+
+/**
+ * Some parsers do not calculate their own length, but instead expect another 
parser
+ * to set the bit limit, and then they use that bit limit as the length.
+ * An example of this is prefix length parsers. This trait can be used by those
+ * parsers to do determine the length based on the bitLimit and position.
+ */
+trait BitLengthFromBitLimitMixin {
+
+  def getBitLength(s: ParseOrUnparseState): Int = {
+    val pState = s.asInstanceOf[PState]
+    val len = getLengthInBits(pState)
+    len.toInt
+  }
+
+  def getLengthInBits(pstate: PState): Long = {
+    val len = pstate.bitLimit0b.get - pstate.bitPos0b
+    len
+  }
+}
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
index 5f00208a4..b211ce2ee 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/HexBinaryLengthParsers.scala
@@ -19,10 +19,8 @@ package org.apache.daffodil.runtime1.processors.parsers
 
 import java.nio.ByteBuffer
 
-import org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.runtime1.processors.ElementRuntimeData
 import org.apache.daffodil.runtime1.processors.LengthInBitsEv
-import org.apache.daffodil.runtime1.processors.Processor
 
 sealed abstract class HexBinaryLengthParser(override val context: 
ElementRuntimeData)
   extends PrimParser
@@ -94,20 +92,3 @@ final class HexBinaryEndOfBitLimitParser(erd: 
ElementRuntimeData)
     pstate.bitLimit0b.get - pstate.bitPos0b
   }
 }
-
-final class HexBinaryLengthPrefixedParser(
-  erd: ElementRuntimeData,
-  override val prefixedLengthParser: Parser,
-  override val prefixedLengthERD: ElementRuntimeData,
-  override val lengthUnits: LengthUnits,
-  override val prefixedLengthAdjustmentInUnits: Long
-) extends HexBinaryLengthParser(erd)
-  with PrefixedLengthParserMixin {
-
-  override def childProcessors: Vector[Processor] = 
Vector(prefixedLengthParser)
-  override val runtimeDependencies = Vector()
-
-  override def getLengthInBits(pstate: PState): Long = {
-    getPrefixedLengthInBits(pstate)
-  }
-}
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
index a969ba8b6..42e42f10e 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/SpecifiedLengthParsers.scala
@@ -85,7 +85,11 @@ sealed abstract class SpecifiedLengthParserBase(eParser: 
Parser, erd: RuntimeDat
     if (pState.processorStatus ne Success) return
     val finalEndPos0b = startingBitPos0b + nBits
 
-    captureValueLength(pState, ULong(startingBitPos0b), ULong(dis.bitPos0b))
+    // we want to capture the length before we do any skipping
+    // value length of simple types is captured by the eParser if needed
+    // the SpecifiedLengthParserBase is extended by 
SpecifiedLengthChoiceParser which should not have its valueLength captured here
+    if (pState.infoset.isComplex && !erd.isInstanceOf[ChoiceRuntimeData])
+      captureValueLength(pState, ULong(startingBitPos0b), ULong(dis.bitPos0b))
 
     Assert.invariant(dis eq pState.dataInputStream)
     val bitsToSkip = finalEndPos0b - dis.bitPos0b
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
index 6882e2057..4a331602b 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/lengthKind/PrefixedTests.tdml
@@ -19,7 +19,7 @@
 <tdml:testSuite suiteName="PrefixedTests"
   description="Section 12 - lengthKind=prefixed" 
xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData";
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
-  xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema";
   xmlns:fn="http://www.w3.org/2005/xpath-functions";
   xmlns:ex="http://example.com";
   xmlns:tns="http://example.com";
@@ -2314,10 +2314,31 @@
     <xs:element name="root7">
       <xs:complexType>
         <xs:sequence>
-          <xs:element name="s" type="xs:string" dfdl:lengthKind="prefixed"
+          <xs:element name="s" dfdl:lengthKind="prefixed"
                       dfdl:prefixLengthType="ex:prefixType2"
+                      dfdl:prefixIncludesPrefixLength="yes"
+                      dfdl:textTrimKind="padChar"
+                      dfdl:textPadKind="padChar"
+                      dfdl:textStringPadCharacter="%SP;"
+                      dfdl:textStringJustification="center">
+            <xs:simpleType>
+              <xs:restriction base="xs:string">
+                <xs:minLength value="7"/>
+              </xs:restriction>
+            </xs:simpleType>
+          </xs:element>
+          <xs:element name="e" type="xs:int" dfdl:inputValueCalc='{ 
dfdl:valueLength(../s, "bytes") }'>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+    <xs:element name="root8">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="s" type="xs:string" dfdl:lengthKind="explicit"
+                      dfdl:length="7"
                       dfdl:textTrimKind="padChar"
-                      dfdl:textPadKind="none"
+                      dfdl:textPadKind="padChar"
                       dfdl:textStringPadCharacter="%SP;"
                       dfdl:textStringJustification="center"/>
           <xs:element name="e" type="xs:int" dfdl:inputValueCalc='{ 
dfdl:valueLength(../s, "bytes") }'>
@@ -2326,6 +2347,28 @@
       </xs:complexType>
     </xs:element>
 
+    <xs:element name="root9">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="s" dfdl:lengthKind="prefixed"
+              dfdl:prefixLengthType="ex:prefixType2"
+              dfdl:textTrimKind="padChar"
+              dfdl:textPadKind="padChar"
+              dfdl:textStringPadCharacter="%SP;"
+              dfdl:textStringJustification="center">
+            <xs:simpleType>
+              <xs:restriction base="xs:string">
+                <xs:minLength value="7"/>
+              </xs:restriction>
+            </xs:simpleType>
+          </xs:element>
+          <xs:element name="e" type="xs:int"
+              dfdl:inputValueCalc='{ dfdl:valueLength(../s, "bytes") }'>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
   </tdml:defineSchema>
 
   <tdml:parserTestCase name="pl_implicit_1"
@@ -2439,6 +2482,37 @@
     </tdml:infoset>
   </tdml:parserTestCase>
 
+  <tdml:parserTestCase name="pl_simpleValueLengthBytes_2"
+                       model="lengthKindPrefixed-2">
+    <tdml:document>
+      <tdml:documentPart type="text">  ABC  </tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:root8>
+          <s>ABC</s>
+          <e>3</e>
+        </ex:root8>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="pl_simpleValueLengthBytes_3"
+      model="lengthKindPrefixed-2">
+    <tdml:document>
+      <tdml:documentPart type="byte">00 00 00 0B</tdml:documentPart>
+      <tdml:documentPart type="text">  ABC  </tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:root9>
+          <s>ABC</s>
+          <e>3</e>
+        </ex:root9>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
   <tdml:defineSchema name="lengthKindPrefixed-3"
                      useDefaultNamespace="false"
                      elementFormDefault="unqualified">
@@ -2580,7 +2654,7 @@
   </tdml:defineSchema>
 
   <tdml:parserTestCase name="lengthUnitsBitsForNonNegativeInteger_prefixed" 
root="r1" model="lengthUnitsBitsForNonNegativeInteger_prefixed"
-                       ignoreUnexpectedWarnings="false">
+      ignoreUnexpectedWarnings="false">
   <tdml:document>
       <tdml:documentPart type="byte">08 ff</tdml:documentPart>
     </tdml:document>
@@ -2913,7 +2987,7 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>failed check</tdml:error>
-      <tdml:error>field2 (prefixLength) (5)</tdml:error>
+      <tdml:error>field2 (5)</tdml:error>
       <tdml:error>facet maxInclusive (4)</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
@@ -2926,7 +3000,7 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>failed check</tdml:error>
-      <tdml:error>field1 (prefixLength) (6)</tdml:error>
+      <tdml:error>field1 (6)</tdml:error>
       <tdml:error>facet maxInclusive (4)</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
@@ -2956,7 +3030,7 @@
     </tdml:infoset>
     <tdml:errors>
       <tdml:error>failed check</tdml:error>
-      <tdml:error>field3 (prefixLength) (1)</tdml:error>
+      <tdml:error>field3 (1)</tdml:error>
       <tdml:error>facet minInclusive (2)</tdml:error>
     </tdml:errors>
   </tdml:unparserTestCase>
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
index 99a563fd9..3ec2eec76 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section12/lengthKind/TestLengthKindPrefixed.scala
@@ -172,7 +172,11 @@ class TestLengthKindPrefixed extends TdmlTests {
   @Test def pl_simpleContentLengthBytes_1 = test
 
   // DAFFODIL-2658
-  @Ignore @Test def pl_simpleValueLengthBytes_1 = test
+  @Test def pl_simpleValueLengthBytes_1() = test
+  @Test def pl_simpleValueLengthBytes_2() = test
+
+  // DAFFODIL-2948
+  @Test def pl_simpleValueLengthBytes_3() = test
 
   @Test def pl_simpleContentLengthCharacters_1 = test
   @Test def pl_complexContentLengthCharacters_1 = test


Reply via email to