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 62d9bb016 Add logic for separator/initiator/prefixed/terminator 
alignment
62d9bb016 is described below

commit 62d9bb016b8893d3906763a701c0f71c0c4c239f
Author: olabusayoT <[email protected]>
AuthorDate: Mon Nov 24 17:17:59 2025 -0500

    Add logic for separator/initiator/prefixed/terminator alignment
    
    - Implement logic to calculate prefix, infix, and postfix separator 
alignments and lengths in sequence terms.
    - Added new alignment logic/test cases covering initiator alignment, 
prefixed length elements, terminator alignment and value MTA (for optimization) 
behavior.
    - Add new variables to more accurately represent alignment, such as 
contentEndAlignment, which is useful for delimiter text alignment before the 
terminator and trailing skip is considered.
    - Updated schemas and TDML files to include test data for new alignment 
scenarios.
    
    DAFFODIL-2295, DAFFODIL-3056, DAFFODIL-3057
---
 .../daffodil/core/grammar/AlignedMixin.scala       | 270 ++++++--
 .../section12/aligned_data/Aligned_Data.tdml       | 703 +++++++++++++++++++++
 .../org/apache/daffodil/usertests/SepTests.tdml    | 185 +++++-
 .../section12/aligned_data/TestAlignedData.scala   |  23 +
 .../apache/daffodil/usertests/TestSepTests.scala   |   7 +
 5 files changed, 1113 insertions(+), 75 deletions(-)

diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
index a6d52b8a5..00ebdee13 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/AlignedMixin.scala
@@ -21,17 +21,26 @@ import org.apache.daffodil.core.dsom.ElementBase
 import org.apache.daffodil.core.dsom.ModelGroup
 import org.apache.daffodil.core.dsom.QuasiElementDeclBase
 import org.apache.daffodil.core.dsom.Root
+import org.apache.daffodil.core.dsom.SequenceTermBase
 import org.apache.daffodil.core.dsom.Term
 import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.schema.annotation.props.gen.AlignmentKind
 import org.apache.daffodil.lib.schema.annotation.props.gen.AlignmentUnits
 import org.apache.daffodil.lib.schema.annotation.props.gen.LengthKind
+import org.apache.daffodil.lib.schema.annotation.props.gen.LengthKind.Prefixed
 import org.apache.daffodil.lib.schema.annotation.props.gen.LengthUnits
+import org.apache.daffodil.lib.schema.annotation.props.gen.Representation
+import org.apache.daffodil.lib.schema.annotation.props.gen.SeparatorPosition
 import org.apache.daffodil.lib.util.Math
 
 case class AlignmentMultipleOf(nBits: Long) {
+  // To combine alignments that could all happen at the same point in data, 
use *,
+  // To add new alignment to an existing approximate alignment, use +
   def *(that: AlignmentMultipleOf) = AlignmentMultipleOf(Math.gcd(nBits, 
that.nBits))
   def %(that: AlignmentMultipleOf) = nBits % that.nBits
+  def +(that: AlignmentMultipleOf) =
+    if (this.nBits % that.nBits == 0) this else that
+  // To combine AlignmentMultipleOfs and lengths, use +
   def +(that: LengthApprox) = AlignmentMultipleOf(Math.gcd(nBits, nBits + 
that.nBits))
 }
 
@@ -63,13 +72,14 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
    * Hence we are guaranteed to be properly aligned.
    */
   final lazy val isKnownToBeAligned: Boolean = 
LV(Symbol("isKnownToBeAligned")) {
-    if (!isRepresented || (alignmentKindDefaulted == AlignmentKind.Manual)) 
true
-    else {
-      val pa = priorAlignmentWithLeadingSkipApprox
-      val aa = alignmentApprox
-      val res = (pa % aa) == 0
-      res
-    }
+    val res =
+      if (!isRepresented || (alignmentKindDefaulted == AlignmentKind.Manual)) 
true
+      else {
+        val pa = priorAlignmentWithLeadingSkipApprox
+        val aa = alignmentApprox
+        (pa % aa) == 0
+      }
+    res
   }.value
 
   /**
@@ -81,33 +91,37 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
    * considers the surrounding context meeting the alignment needs.
    */
   final lazy val isKnownToBeTextAligned: Boolean = 
LV(Symbol("isKnownToBeTextAligned")) {
-    if (alignmentKindDefaulted == AlignmentKind.Manual) true // manual 
alignment
-    else if (isKnownEncoding) {
-      if (knownEncodingAlignmentInBits == 1)
-        true
-      else if (priorAlignmentWithLeadingSkipApprox.nBits % 
knownEncodingAlignmentInBits == 0)
+    val res =
+      if (alignmentKindDefaulted == AlignmentKind.Manual) true // manual 
alignment
+      else if (isKnownEncoding) {
+        if (knownEncodingAlignmentInBits == 1)
+          true
+        else if (priorAlignmentWithLeadingSkipApprox.nBits % 
knownEncodingAlignmentInBits == 0)
+          true
+        else
+          false
+      } else if (schemaSet.root.isScannable)
         true
       else
         false
-    } else if (schemaSet.root.isScannable)
-      true
-    else
-      false
+    res
   }.value
 
   final lazy val isDelimiterKnownToBeTextAligned: Boolean = {
-    if (alignmentKindDefaulted == AlignmentKind.Manual) true // manual 
alignment
-    else if (isKnownEncoding) {
-      if (knownEncodingAlignmentInBits == 1)
-        true
-      else if (endingAlignmentApprox.nBits % knownEncodingAlignmentInBits == 0)
+    val res =
+      if (alignmentKindDefaulted == AlignmentKind.Manual) true // manual 
alignment
+      else if (isKnownEncoding) {
+        if (knownEncodingAlignmentInBits == 1)
+          true
+        else if (contentEndAlignment.nBits % knownEncodingAlignmentInBits == 0)
+          true
+        else
+          false
+      } else if (schemaSet.root.isScannable)
         true
       else
         false
-    } else if (schemaSet.root.isScannable)
-      true
-    else
-      false
+    res
   }
 
   final lazy val hasNoSkipRegions = LV(Symbol("hasNoSkipRegions")) {
@@ -134,17 +148,17 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
     LengthExact(trailingSkipInBits)
   }
 
-  // FIXME: DAFFODIL-2295
-  // Does not take into account that in a sequence, what may be prior may be a 
separator.
-  // The separator is text in some encoding, might not be the same as this 
term's encoding, and
-  // the alignment will be left where that text leaves it.
-  //
+  /**
+   * The priorAlignmentApprox doesn't need to take into account the separator
+   * alignment/length as that comes after the priorAlignmentApprox, but before
+   * the leadingSkip.
+   */
   private lazy val priorAlignmentApprox: AlignmentMultipleOf =
     LV(Symbol("priorAlignmentApprox")) {
       if (this.isInstanceOf[Root] || this.isInstanceOf[QuasiElementDeclBase]) {
         AlignmentMultipleOf(
           0
-        ) // root and quasi elements are aligned with anything // TODO: 
really? Why quasi-elements - they should have implicit alignment ?
+        ) // root and quasi elements are aligned with anything (quasi elements 
are always 1 aligned)
       } else {
         val priorSibs = potentialPriorTerms
         val arraySelfAlignment =
@@ -201,7 +215,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
             // Return 0 here, unordered alignment will be handled by 
unorderedSequenceSelfAlignment
             AlignmentMultipleOf(0)
           } else {
-            ps.endingAlignmentApprox
+            ps.endingAlignmentWithRightFramingApprox
           }
           eaa
         }
@@ -222,75 +236,197 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
         val priorAlignmentsApprox =
           priorSibsAlignmentsApprox ++ parentAlignmentApprox ++ 
arraySelfAlignment ++ unorderedSequenceSelfAlignment
         if (priorAlignmentsApprox.isEmpty)
-          alignmentApprox // it will be the containing context's 
responsibility to insure this IS where we start.
+          alignmentApprox // it will be the containing context's 
responsibility to ensure this IS where we start.
         else
           priorAlignmentsApprox.reduce(_ * _)
       }
     }.value
 
-  private lazy val priorAlignmentWithLeadingSkipApprox: AlignmentMultipleOf = {
-    priorAlignmentApprox + leadingSkipApprox
+  private lazy val separatorPrefixInfixMTAApprox =
+    this.optLexicalParent match {
+      case Some(s: SequenceTermBase) if s.hasSeparator =>
+        import SeparatorPosition.*
+        s.separatorPosition match {
+          case Prefix | Infix => 
AlignmentMultipleOf(s.knownEncodingAlignmentInBits)
+          case Postfix => AlignmentMultipleOf(1)
+        }
+      case _ => AlignmentMultipleOf(1)
+    }
+
+  private lazy val separatorPostfixMTAApprox =
+    this.optLexicalParent match {
+      case Some(s: SequenceTermBase) if s.hasSeparator =>
+        import SeparatorPosition.*
+        s.separatorPosition match {
+          case Prefix | Infix => AlignmentMultipleOf(1)
+          case Postfix => AlignmentMultipleOf(s.knownEncodingAlignmentInBits)
+        }
+      case _ => AlignmentMultipleOf(1)
+    }
+
+  private lazy val separatorLengthApprox = this.optLexicalParent match {
+    case Some(s: SequenceTermBase) if s.hasSeparator =>
+      s.encodingLengthApprox
+    case _ => LengthExact(0)
   }
 
-  protected lazy val contentStartAlignment: AlignmentMultipleOf = {
-    if (priorAlignmentWithLeadingSkipApprox % alignmentApprox == 0) {
-      // alignment won't be needed, continue using prior alignment as start 
alignment
-      priorAlignmentWithLeadingSkipApprox
+  private lazy val initiatorMTAApprox =
+    if (this.hasInitiator) {
+      AlignmentMultipleOf(this.knownEncodingAlignmentInBits)
+    } else {
+      AlignmentMultipleOf(1)
+    }
+
+  private lazy val initiatorLengthApprox = if (this.hasInitiator) {
+    this.encodingLengthApprox
+  } else {
+    LengthExact(0)
+  }
+
+  private lazy val terminatorMTAApprox =
+    if (this.hasTerminator) {
+      AlignmentMultipleOf(this.knownEncodingAlignmentInBits)
     } else {
-      // alignment will be needed, it will be forced to be aligned to 
alignmentApprox
-      alignmentApprox
+      AlignmentMultipleOf(1)
+    }
+
+  private lazy val terminatorLengthApprox = if (this.hasTerminator) {
+    this.encodingLengthApprox
+  } else {
+    LengthExact(0)
+  }
+
+  /**
+   * prior alignment with leading skip includes the prefix/infix separator MTA 
and length,
+   * any leading skips
+   */
+  private lazy val priorAlignmentWithLeadingSkipApprox: AlignmentMultipleOf = {
+    val priorAlignmentWithSeparatorApprox = priorAlignmentApprox
+      + separatorPrefixInfixMTAApprox
+      + separatorLengthApprox
+    val leadingAlignmentApprox = (priorAlignmentWithSeparatorApprox
+      + leadingSkipApprox)
+    leadingAlignmentApprox
+  }
+
+  /**
+   * The length of the prefix length quasi element.
+   *
+   * This is only relevant for quasi elements, or prefixed terms.
+   */
+  protected lazy val prefixLengthElementLength: LengthApprox = {
+    this match {
+      case eb: ElementBase => {
+        if (eb.lengthKind == Prefixed) {
+          val prefixTypeElem = eb.prefixedLengthElementDecl
+          prefixTypeElem.elementSpecifiedLengthApprox
+        } else {
+          LengthExact(0)
+        }
+      }
+      case _ => LengthExact(0)
+    }
+  }
+
+  /**
+   * The alignment of the term's value.
+   *
+   * This is only relevant for simple elements with textual representation.
+   */
+  private lazy val valueMTAApprox = {
+    this match {
+      case eb: ElementBase if eb.isSimpleType && eb.representation == 
Representation.Text => {
+        AlignmentMultipleOf(eb.knownEncodingAlignmentInBits)
+      }
+      case _ => AlignmentMultipleOf(1)
     }
   }
 
-  protected lazy val endingAlignmentApprox: AlignmentMultipleOf = {
+  /**
+   * This alignment is made up of the alignment of the term itself,
+   * the initiator MTA and length, the prefix length quasi
+   * element length, and the value MTA (we add it for optimization
+   * but is extremely difficult to test, as other things such
+   * as unparsers will provide MTA, even elementSpecifiedLengthApprox
+   * considers the encoding also).
+   */
+  protected lazy val contentStartAlignment: AlignmentMultipleOf = {
+    val leftFramingApprox = priorAlignmentWithLeadingSkipApprox
+      + alignmentApprox
+      + initiatorMTAApprox
+      + initiatorLengthApprox
+    val csa = (leftFramingApprox + prefixLengthElementLength) + valueMTAApprox
+    csa
+  }
+
+  /**
+   * Accounts for the start of the content start alignment and element length.
+   * This is used to determine the alignment before the terminator and 
trailing skip
+   */
+  protected lazy val contentEndAlignment: AlignmentMultipleOf = {
     this match {
       case eb: ElementBase => {
-        if (eb.isComplexType && eb.lengthKind == LengthKind.Implicit) {
-          eb.complexType.group.endingAlignmentApprox + trailingSkipApprox
+        val res = if (eb.isComplexType && eb.lengthKind == 
LengthKind.Implicit) {
+          eb.complexType.group.contentEndAlignment
         } else {
           // simple type or complex type with specified length
-          contentStartAlignment + (elementSpecifiedLengthApprox + 
trailingSkipApprox)
+          contentStartAlignment + elementSpecifiedLengthApprox
         }
+        res
       }
       case mg: ModelGroup => {
         //
         // We're interested in how the model group ends. Whatever could be
-        // the last term, each individual such possibility has an 
endingAlignmentApprox,
-        // and we need to aggregate those to get the summary 
endingAlignmentApprox.
+        // the last term, each individual such possibility has an 
endingAlignmentWithRightFramingApprox,
+        // and we need to aggregate those to get the summary 
endingAlignmentWithRightFramingApprox.
         //
         val (lastChildren, couldBeLast) = mg.potentialLastChildren
         val lastApproxesConsideringChildren: Seq[AlignmentMultipleOf] = 
lastChildren.map { lc =>
-          //
-          // for each possible last child, add its ending alignment
-          // to our trailing skip to get where it would leave off were
-          // it the actual last child.
-          //
-          val lceaa = lc.endingAlignmentApprox
-          val res = lceaa + trailingSkipApprox
-          res
+          // for each possible last child, gather its 
endingAlignmentWithRightFramingApprox
+          // as we want to account for the separators that are a part of the 
SequenceContent (see DFDL spec)
+          val lceaa = lc.endingAlignmentWithRightFramingApprox
+          lceaa
         }
         val optApproxIfNoChildren =
           //
           // gather possibilities for this item itself
           //
-          if (couldBeLast)
+          if (couldBeLast) {
             //
             // if this model group could be last, then consider
             // if none of its content was present.
-            // We'd just have the contentStart, nothing, and the trailing Skip.
+            // We'd just have the contentStart
             //
-            Some(contentStartAlignment + trailingSkipApprox)
-          else
+            Some(contentStartAlignment)
+          } else
             // can't be last, no possibilities to gather.
             None
         val lastApproxes = lastApproxesConsideringChildren ++ 
optApproxIfNoChildren
+        // take all the gathered possibilities to get where it would leave off 
were
+        // each the actual last child.
         Assert.invariant(lastApproxes.nonEmpty)
-        val res = lastApproxes.reduce { _ * _ }
-        res
+        lastApproxes.reduce(_ * _)
       }
     }
   }
 
+  /**
+   * Add the ending alignment of the term
+   * to terminator MTA/length and our trailing skip
+   *
+   * The postfix separator MTA/length needs to be added after the trailing skip
+   */
+  protected lazy val endingAlignmentWithRightFramingApprox: 
AlignmentMultipleOf = {
+    val endingAlignmentApprox = this.contentEndAlignment
+      + terminatorMTAApprox
+      + terminatorLengthApprox
+      + trailingSkipApprox
+    val res = endingAlignmentApprox
+      + separatorPostfixMTAApprox
+      + separatorLengthApprox
+    res
+  }
+
   protected lazy val elementSpecifiedLengthApprox: LengthApprox = {
     this match {
       case eb: ElementBase => {
@@ -315,22 +451,24 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
               eb.lengthUnits match {
                 case LengthUnits.Bits => LengthMultipleOf(1)
                 case LengthUnits.Bytes => LengthMultipleOf(8)
-                case LengthUnits.Characters => encodingLengthApprox
+                case LengthUnits.Characters => eb.encodingLengthApprox
               }
           }
           case LengthKind.Delimited => encodingLengthApprox
           case LengthKind.Pattern => encodingLengthApprox
           case LengthKind.EndOfParent => LengthMultipleOf(1) // NYI
-          case LengthKind.Prefixed => LengthMultipleOf(1) // NYI
+          // If an element is lengthKind="prefixed", the element's length is 
the length
+          // of the value of the prefix element, which can't be known till 
runtime
+          case LengthKind.Prefixed => LengthMultipleOf(1) // NYI (see 
DAFFODIL-3066)
         }
       }
       case _: ModelGroup => Assert.usageError("Only for elements")
     }
   }
 
-  private lazy val encodingLengthApprox: LengthApprox = {
-    if (isKnownEncoding) {
-      val dfdlCharset = charsetEv.optConstant.get
+  protected lazy val encodingLengthApprox: LengthApprox = {
+    if (this.isKnownEncoding) {
+      val dfdlCharset = this.charsetEv.optConstant.get
       val fixedWidth =
         if (dfdlCharset.maybeFixedWidth.isDefined) 
dfdlCharset.maybeFixedWidth.get else 8
       LengthMultipleOf(fixedWidth)
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
index 119c79985..c2be97ef3 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
@@ -603,6 +603,438 @@
     </xs:element>
   </tdml:defineSchema>
 
+  <tdml:defineSchema name="s2" elementFormDefault="unqualified">
+
+    <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormatPortable.dfdl.xsd"/>
+    <dfdl:format
+      ref="ex:GeneralFormat"
+      representation="text"
+      lengthKind="delimited"
+      separatorPosition="infix"
+      lengthUnits="bits"
+      alignmentUnits="bits"
+      encoding="US-ASCII"
+    />
+
+    <xs:element name="postfix_init">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:string"
+                  dfdl:initiator="I"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="postfix_init_2">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:fillByte="1" dfdl:initiator="I">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+          <xs:element name="e2" type="xs:string"
+            dfdl:length="16" dfdl:fillByte="2"
+            dfdl:lengthKind="explicit" dfdl:alignment="16"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+     <xs:element name="postfix_term">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="A" dfdl:terminator="T"/>
+                <xs:element name="b" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="postfix_term_2">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:fillByte="1" dfdl:terminator="T">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+          <xs:element name="e2" type="xs:string"
+            dfdl:length="16" dfdl:fillByte="2"
+            dfdl:lengthKind="explicit" dfdl:alignment="16"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:simpleType name="prefixType" dfdl:lengthKind="explicit" 
dfdl:length="8">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:element name="prefixed_element">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+                      dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="c" type="xs:string"
+                            dfdl:length="16"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="16"
+                            dfdl:fillByte="C"/>
+                <xs:element name="a" type="xs:string"
+                            dfdl:prefixLengthType="ex:prefixType"
+                            dfdl:prefixIncludesPrefixLength="no"
+                            dfdl:lengthKind="prefixed"
+                            dfdl:alignment="16"
+                            dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="16"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="16"
+                            dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+  </tdml:defineSchema>
+
+  <tdml:defineSchema name="s3" elementFormDefault="unqualified">
+
+    <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormatPortable.dfdl.xsd"/>
+    <dfdl:format
+        ref="ex:GeneralFormat"
+        representation="text"
+        lengthKind="delimited"
+        separatorPosition="infix"
+        lengthUnits="bytes"
+        alignmentUnits="bytes"
+        encoding="US-ASCII"
+    />
+    <xs:simpleType name="prefixType" dfdl:lengthKind="explicit" 
dfdl:length="1">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:element name="prefixed_element">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+                      dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="c" type="xs:string"
+                            dfdl:length="2"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="C"/>
+                <xs:element name="a" type="xs:string"
+                            dfdl:prefixLengthType="ex:prefixType"
+                            dfdl:prefixIncludesPrefixLength="no"
+                            dfdl:lengthKind="prefixed"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="2"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+
+    <xs:simpleType name="prefixType_bits" dfdl:lengthKind="explicit" 
dfdl:lengthUnits="bits" dfdl:length="16">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:simpleType name="deep_prefixed_inner" dfdl:lengthKind="explicit" 
dfdl:lengthUnits="bits" dfdl:length="16">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:simpleType name="deep_prefixed_outer"
+      dfdl:lengthKind="prefixed"
+      dfdl:prefixLengthType="ex:prefixType_bits"
+      dfdl:prefixIncludesPrefixLength="no">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:element name="prefixed_element_bits">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+                      dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="c" type="xs:string"
+                            dfdl:length="2"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="C"/>
+                <xs:element name="a" type="xs:string"
+                            dfdl:lengthUnits="bits"
+                            dfdl:prefixLengthType="ex:prefixType_bits"
+                            dfdl:prefixIncludesPrefixLength="no"
+                            dfdl:lengthKind="prefixed"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="2"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="prefixed_element_nested">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+                      dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="c" type="xs:string"
+                            dfdl:length="2"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="C"/>
+                <xs:element name="a" type="xs:string"
+                            dfdl:lengthUnits="bits"
+                            dfdl:prefixLengthType="ex:deep_prefixed_outer"
+                            dfdl:prefixIncludesPrefixLength="no"
+                            dfdl:lengthKind="prefixed"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="A"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="2"
+                            dfdl:lengthKind="explicit"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:defineSchema name="s4" elementFormDefault="unqualified">
+
+  <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormatPortable.dfdl.xsd"/>
+  <dfdl:format
+      ref="ex:GeneralFormat"
+      representation="text"
+      lengthKind="delimited"
+      separatorPosition="infix"
+      lengthUnits="bytes"
+      alignmentUnits="bytes"
+      encoding="US-ASCII"
+  />
+
+    <xs:element name="elem">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+                      dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:string"
+                            dfdl:encoding="X-DFDL-BITS-MSBF"
+                            dfdl:lengthUnits="bits"
+                            dfdl:fillByte="%#r00;"
+                            dfdl:length="4"
+                            dfdl:lengthKind="explicit"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="0"
+                            dfdl:lengthKind="explicit"
+                            dfdl:trailingSkip="4"
+                            dfdl:fillByte="%#rFF;"/>
+                <xs:element name="c" type="xs:string"
+                            dfdl:encoding="X-DFDL-BITS-MSBF"
+                            dfdl:lengthUnits="bits"
+                            dfdl:fillByte="%#r00;"
+                            dfdl:length="4"
+                            dfdl:lengthKind="explicit"
+                />
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:defineSchema name="s5" elementFormDefault="unqualified">
+
+  <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormatPortable.dfdl.xsd"/>
+  <dfdl:format
+      ref="ex:GeneralFormat"
+      representation="text"
+      lengthKind="explicit"
+      lengthUnits="bytes"
+      alignmentUnits="bytes"
+      encoding="US-ASCII"
+  />
+
+    <xs:element name="elem1" dfdl:lengthKind="implicit">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e0" type="xs:string" dfdl:length="1"/>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:alignment="2"
+            dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:string"
+                  dfdl:fillByte="A"
+                  dfdl:length="1"
+                  dfdl:alignment="2"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="1"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="elem2" dfdl:lengthKind="implicit">
+      <xs:complexType>
+        <xs:sequence>
+<!--          <xs:element name="e0" type="xs:string" dfdl:length="1"/>-->
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:alignment="2"
+            dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="a" type="xs:int"
+                  dfdl:representation="binary"
+                  dfdl:fillByte="%#rFF;"
+                  dfdl:encoding="X-DFDL-BITS-MSBF"
+                  dfdl:lengthUnits="bits"
+                  dfdl:alignmentUnits="bits"
+                  dfdl:length="4"/>
+                <xs:element name="b" type="xs:int"
+                  minOccurs="0"
+                  dfdl:representation="binary"
+                  dfdl:initiator="-"
+                  dfdl:fillByte="%#r00;"
+                  dfdl:length="1"
+                  dfdl:alignment="1"/>
+                <xs:element name="c" type="xs:int"
+                  dfdl:representation="binary"
+                            dfdl:length="1"
+                            dfdl:alignment="1"
+                            dfdl:fillByte="%#rFF;"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="elem3" dfdl:lengthKind="implicit">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e0" type="xs:string" dfdl:length="1"/>
+          <xs:element name="e1" dfdl:lengthKind="implicit"
+            dfdl:alignment="2"
+            dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="opt" type="xs:string"
+                  minOccurs="0"
+                  dfdl:initiator="-"
+                  dfdl:fillByte="O"
+                  dfdl:length="1"
+                  dfdl:alignment="2"/>
+                <xs:element name="b" type="xs:string"
+                            dfdl:length="1"
+                            dfdl:alignment="2"
+                            dfdl:fillByte="B"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:simpleType name="innerPrefixType" dfdl:lengthKind="explicit" 
dfdl:representation="binary" dfdl:length="1">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+    <xs:simpleType name="outerPrefixType" dfdl:lengthKind="prefixed"
+      dfdl:prefixLengthType="ex:innerPrefixType"
+      dfdl:prefixIncludesPrefixLength="no"
+      dfdl:representation="binary">
+      <xs:restriction base="xs:int"/>
+    </xs:simpleType>
+
+
+
+    <xs:element name="elem4" type="xs:int"
+      dfdl:representation="binary" dfdl:lengthKind="prefixed"
+      dfdl:prefixLengthType="ex:outerPrefixType"
+      dfdl:prefixIncludesPrefixLength="no"
+      dfdl:initiator="FOO:" dfdl:encoding="US-ASCII" />
+  </tdml:defineSchema>
+
   <!--
      Test Name: impAlignmentHexBinary
         Schema: implicitAlignmentSchema
@@ -3909,5 +4341,276 @@
       <tdml:documentPart type="bits">01</tdml:documentPart> <!-- base-4 "1" 
string (no mta fill bits)-->
     </tdml:document>
   </tdml:unparserTestCase>
+  
+    <tdml:unparserTestCase name="test_init_alignment_1" root="postfix_init" 
model="s2" roundTrip="onePass">
+    <tdml:document>IaaBbb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:postfix_init xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:postfix_init>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_init_alignment_2" root="postfix_init_2" 
model="s2" roundTrip="onePass">
+    <tdml:document>IAaabbee</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:postfix_init_2 xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+          <e2>ee</e2>
+        </ex:postfix_init_2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_term_alignment_1" root="postfix_term" 
model="s2" roundTrip="onePass">
+    <tdml:document>aaTBbb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:postfix_term xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:postfix_term>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_term_alignment_2" root="postfix_term_2" 
model="s2" roundTrip="onePass">
+    <tdml:document>aabbT2ee</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:postfix_term_2 xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+          <e2>ee</e2>
+        </ex:postfix_term_2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_prefix_alignment_0" 
root="prefixed_element" model="s2" roundTrip="onePass">
+    <!-- can't be 1 bit aligned, and no way to set to 8 bits without it 
complaining -->
+    <!--    <tdml:document>cc16aaBbb</tdml:document>-->
+
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>1 bits</tdml:error>
+      <tdml:error>must be a multiple</tdml:error>
+      <tdml:error>8 bits</tdml:error>
+      <tdml:error>US-ASCII</tdml:error>
+    </tdml:errors>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:prefixed_element xmlns:ex="http://example.com";>
+          <e1>
+            <c>cc</c>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:prefixed_element>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_prefix_alignment_1" 
root="prefixed_element" model="s3" roundTrip="onePass">
+    <tdml:document>cc2aaBbb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:prefixed_element xmlns:ex="http://example.com";>
+          <e1>
+            <c>cc</c>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:prefixed_element>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_prefix_alignment_2" 
root="prefixed_element_bits" model="s3" roundTrip="onePass">
+    <tdml:document>cc16aabb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:prefixed_element_bits xmlns:ex="http://example.com";>
+          <e1>
+            <c>cc</c>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:prefixed_element_bits>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_prefix_alignment_3" 
root="prefixed_element_nested" model="s3" roundTrip="onePass">
+    <tdml:document>cc16aabb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:prefixed_element_nested xmlns:ex="http://example.com";>
+          <e1>
+            <c>cc</c>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:prefixed_element_nested>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+
+    <tdml:errors>
+      <tdml:error>Nested</tdml:error>
+      <tdml:error>prefixed</tdml:error>
+      <tdml:error>not supported</tdml:error>
+    </tdml:errors>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_prefix_alignment_4" root="elem4" 
model="s5" roundTrip="onePass">
+    <tdml:document>
+      <tdml:documentPart type="text">FOO:</tdml:documentPart>
+      <tdml:documentPart type="byte">040000FFFF</tdml:documentPart>
+    </tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem4 xmlns:ex="http://example.com";>65535</ex:elem4>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+
+    <tdml:errors>
+      <tdml:error>Nested</tdml:error>
+      <tdml:error>prefixed</tdml:error>
+      <tdml:error>not supported</tdml:error>
+    </tdml:errors>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_valueMTA_alignment_1" root="elem" 
model="s4" roundTrip="onePass">
+    <tdml:document>
+      <tdml:documentPart type="bits">1110</tdml:documentPart>
+      <tdml:documentPart type="bits">1111</tdml:documentPart> <!-- pre b 
alignment -->
+      <tdml:documentPart type="byte">FFFFFFFF</tdml:documentPart> <!-- post b 
trailing skip -->
+      <tdml:documentPart type="bits">0111</tdml:documentPart><!-- c -->
+      <tdml:documentPart type="bits">0000</tdml:documentPart><!-- c -->
+    </tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem xmlns:ex="http://example.com";>
+          <e1>
+            <a>1110</a>
+            <b></b>
+            <c>0111</c>
+          </e1>
+        </ex:elem>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="prior_siblings_1" root="elem1" model="s5" 
roundTrip="onePass">
+    <tdml:document>eEaBb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem1 xmlns:ex="http://example.com";>
+          <e0>e</e0>
+          <e1>
+            <a>a</a>
+            <b>b</b>
+          </e1>
+        </ex:elem1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="prior_siblings_2" root="elem2" model="s5" 
roundTrip="onePass">
+    <tdml:document>
+      <tdml:documentPart type="bits">0011</tdml:documentPart>
+      <tdml:documentPart type="bits">1111</tdml:documentPart> <!-- pre c 
alignment -->
+      <tdml:documentPart type="bits">0000</tdml:documentPart> <!-- c -->
+      <tdml:documentPart type="bits">0100</tdml:documentPart> <!-- c -->
+    </tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem2 xmlns:ex="http://example.com";>
+          <e1>
+            <a>3</a>
+            <c>4</c>
+          </e1>
+        </ex:elem2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="prior_siblings_3" root="elem2" model="s5" 
roundTrip="onePass">
+    <tdml:document>
+      <tdml:documentPart type="bits">0011</tdml:documentPart>
+      <tdml:documentPart type="bits">0000</tdml:documentPart> <!-- pre b 
alignment -->
+      <tdml:documentPart type="text">-</tdml:documentPart> <!-- b initiator-->
+      <tdml:documentPart type="bits">00000101</tdml:documentPart> <!-- b -->
+      <tdml:documentPart type="bits">00000100</tdml:documentPart> <!-- c -->
+    </tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem2 xmlns:ex="http://example.com";>
+          <e1>
+            <a>3</a>
+            <b>5</b>
+            <c>4</c>
+          </e1>
+        </ex:elem2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="prior_siblings_4" root="elem3" model="s5" 
roundTrip="onePass">
+    <tdml:document>eE-ob</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem3 xmlns:ex="http://example.com";>
+          <e0>e</e0>
+          <e1>
+            <opt>o</opt>
+            <b>b</b>
+          </e1>
+        </ex:elem3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="prior_siblings_5" root="elem3" model="s5" 
roundTrip="onePass">
+    <tdml:document>eEb</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:elem3 xmlns:ex="http://example.com";>
+          <e0>e</e0>
+          <e1>
+            <b>b</b>
+          </e1>
+        </ex:elem3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
 
 </tdml:testSuite>
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml 
b/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml
index 0ab4ea916..61d08de6b 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/usertests/SepTests.tdml
@@ -143,14 +143,6 @@
       separatorPosition="infix"
       emptyElementParsePolicy="treatAsEmpty"/>
 
-    <!-- DAFFODIL-2217
-      These additional tests give another case where trailingEmptyStrict 
should be causing a
-      parse error, but it does not in a case where maxOccurs="3" but works 
correctly when maxOccurs="4".
-      -->
-
-    <!-- maxOccurs='3' fails to detect the trailing "/" i.e., this should fail 
with a parse error
-    due to trailingEmptyStrict -->
-
     <xs:element name="file1">
       <xs:complexType>
         <xs:sequence dfdl:separator="/" dfdl:separatorPosition="infix"
@@ -160,7 +152,6 @@
       </xs:complexType>
     </xs:element>
 
-    <!-- same, but maxOccurs is 4. This works, as in detects the error. -->
     <xs:element name="file2">
       <xs:complexType>
         <xs:sequence dfdl:separator="/" dfdl:separatorPosition="infix"
@@ -680,4 +671,180 @@
       </tdml:dfdlInfoset>
     </tdml:infoset>
   </tdml:parserTestCase>
+
+  <tdml:defineSchema name="s8" elementFormDefault="unqualified">
+
+    <xs:include 
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormatPortable.dfdl.xsd"/>
+    <dfdl:format
+      ref="ex:GeneralFormat"
+      representation="text"
+      lengthKind="delimited"
+      separatorPosition="infix"
+      lengthUnits="bits"
+      alignmentUnits="bits"
+    />
+
+    <xs:element name="infix">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit" dfdl:fillByte="E">
+            <xs:complexType>
+                <xs:sequence
+                  dfdl:separator="/"
+                  dfdl:separatorPosition="infix" dfdl:fillByte="S">
+                  <xs:element name="a" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="A"/>
+                  <xs:element name="b" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="B"/>
+                </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="prefix">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit" dfdl:fillByte="E">
+            <xs:complexType>
+                <xs:sequence
+                  dfdl:separator="/"
+                  dfdl:separatorPosition="prefix" dfdl:fillByte="S">
+                  <xs:element name="a" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="A"/>
+                  <xs:element name="b" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="B"/>
+                </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="postfix">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit" dfdl:fillByte="E">
+            <xs:complexType>
+                <xs:sequence
+                  dfdl:separator="/"
+                  dfdl:separatorPosition="postfix" dfdl:fillByte="S">
+                  <xs:element name="a" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="A"/>
+                  <xs:element name="b" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="B"/>
+                </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="postfix_2">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" dfdl:lengthKind="implicit" dfdl:fillByte="E">
+            <xs:complexType>
+              <xs:sequence dfdl:separator="-" dfdl:separatorPosition="postfix" 
dfdl:fillByte="0">
+                <xs:element name="c" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="C"/>
+                <xs:sequence
+                  dfdl:separator="/"
+                  dfdl:separatorPosition="postfix" dfdl:fillByte="1">
+                  <xs:element name="a" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="A"/>
+                  <xs:element name="b" type="xs:string"
+                    dfdl:length="16"
+                    dfdl:lengthKind="explicit" dfdl:alignment="16"
+                    dfdl:fillByte="B"/>
+                </xs:sequence>
+                <xs:element name="d" type="xs:string"
+                  dfdl:length="16"
+                  dfdl:lengthKind="explicit" dfdl:alignment="16"
+                  dfdl:fillByte="D"/>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+   <tdml:unparserTestCase name="test_sep_alignment_1" root="infix" model="s8" 
roundTrip="onePass">
+    <tdml:document>aa/Bbb</tdml:document>
+     <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:infix xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:infix>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+   <tdml:unparserTestCase name="test_sep_alignment_2" root="prefix" model="s8" 
roundTrip="onePass">
+    <tdml:document>/Aaa/Bbb</tdml:document>
+     <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:prefix xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:prefix>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+   <tdml:unparserTestCase name="test_sep_alignment_3" root="postfix" 
model="s8" roundTrip="onePass">
+    <tdml:document>aa/Bbb/</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:postfix xmlns:ex="http://example.com";>
+          <e1>
+            <a>aa</a>
+            <b>bb</b>
+          </e1>
+        </ex:postfix>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="test_sep_alignment_4" root="postfix_2" 
model="s8" roundTrip="onePass">
+    <tdml:document>cc-Aaa/Bbb/-dd-</tdml:document>
+
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:postfix_2 xmlns:ex="http://example.com";>
+          <e1>
+            <c>cc</c>
+            <a>aa</a>
+            <b>bb</b>
+            <d>dd</d>
+          </e1>
+        </ex:postfix_2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
 </tdml:testSuite>
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
index 23967c96a..3c4de0add 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section12/aligned_data/TestAlignedData.scala
@@ -186,6 +186,29 @@ class TestAlignedData extends TdmlTests {
   @Test def alignmentFillByteDefined = test
 
   @Test def separatorMTA_01 = test
+
+  // DAFFODIL-3056
+  @Test def test_init_alignment_1 = test
+  @Test def test_init_alignment_2 = test
+  @Test def test_prefix_alignment_1 = test
+  @Test def test_prefix_alignment_2 = test
+  @Test def test_prefix_alignment_3 = test
+  @Test def test_prefix_alignment_4 = test
+  @Test def test_valueMTA_alignment_1 = test
+
+  // DAFFODIL-3057
+  @Test def test_term_alignment_1 = test
+  @Test def test_term_alignment_2 = test
+
+  // DAFFODIL-3059
+  @Test def test_prefix_alignment_0 = test
+
+  // DAFFODIL-3060
+  @Test def prior_siblings_1 = test
+  @Test def prior_siblings_2 = test
+  @Test def prior_siblings_3 = test
+  @Test def prior_siblings_4 = test
+  @Test def prior_siblings_5 = test
 }
 
 class TestBinaryInput extends TdmlTests {
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala 
b/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala
index 3ffd03612..9c27ba726 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/usertests/TestSepTests.scala
@@ -55,4 +55,11 @@ class TestSepTests extends TdmlTests {
 
   // DAFFODIL-2791
   @Test def test_treatAsAbsent_occursIndex = test
+
+  // DAFFODIL-2295
+  @Test def test_sep_alignment_1 = test
+  @Test def test_sep_alignment_2 = test
+  @Test def test_sep_alignment_3 = test
+
+  @Test def test_sep_alignment_4 = test
 }

Reply via email to