mbeckerle commented on a change in pull request #218: Implement
dfdl:choiceLength='explicit'
URL: https://github.com/apache/incubator-daffodil/pull/218#discussion_r286458049
##########
File path:
daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/SpecifiedLengthUnparsers.scala
##########
@@ -428,3 +429,20 @@ class SpecifiedLengthPrefixedUnparser(
}
}
+
+class ChoiceLengthUnparser(
+ eUnparser: Unparser,
+ rd: TermRuntimeData)
+ extends CombinatorUnparser(rd)
+ with CaptureUnparsingValueLength {
+
+ override lazy val runtimeDependencies = Vector()
+ override lazy val childProcessors = Vector(eUnparser)
+
+ override def unparse(state: UState): Unit = {
+ val elem = state.currentInfosetNode.asInstanceOf[DIElement]
+ captureValueLengthStart(state, elem)
+ eUnparser.unparse1(state)
+ captureValueLengthEnd(state, elem)
+ }
Review comment:
Actually, this is harder than that.
Due to the fact that the contents of the choice may have interior alignment,
or variable-length things in it computed by dfdl:outputValueCalc, we can't just
unparse, and know the length at the point the call returns.
I have almost the identical problem in the new separators code. I need to
measure how big something is when unparsing, and decide to lay down a separator
or not depending on whether it came out to be zero-length or not.
Here the situation is almost the same I think. We need to unparse, measure
relative to the choiceLength, and skip the unused bytes. But we can't know that
length until, well, it's known.
So the technique is to unparse a suspendable unparser that does nothing,
just causes a new DataOutputStream to be split off of the prior, so as to
establish a base position. Then unparse the choice, then unparse a suspendable
unparser that does a skip N, where N is computed based on the starting position
and ending positions of the data output streams being known, and the
choiceLength. This would also be able to signal an error if it is too long.
If that makes sense to everyone, then I suggest we finish review on the
separators/sequences branch, merge it, and use the suspendable unparsers
created there (one of them - the does-nothing one - can be reused).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services