Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.daffodil.unparsers.runtime1
import org.apache.daffodil.lib.exceptions.Assert
import org.apache.daffodil.lib.schema.annotation.props.gen.OccursCountKind
import org.apache.daffodil.runtime1.processors.ElementRuntimeData
import org.apache.daffodil.runtime1.processors.unparsers._
import org.apache.daffodil.runtime1.processors.{ SequenceRuntimeData, TermRuntimeData }
trait Unseparated { self: SequenceChildUnparser =>
val childProcessors = Vector(childUnparser)
}
class ScalarOrderedUnseparatedSequenceChildUnparser(
childUnparser: Unparser,
srd: SequenceRuntimeData,
trd: TermRuntimeData
) extends SequenceChildUnparser(childUnparser, srd, trd)
with Unseparated {
override protected def unparse(state: UState) = childUnparser.unparse1(state)
}
class RepOrderedUnseparatedSequenceChildUnparser(
childUnparser: Unparser,
srd: SequenceRuntimeData,
erd: ElementRuntimeData
) extends RepeatingChildUnparser(childUnparser, srd, erd)
with Unseparated {
override def checkArrayPosAgainstMaxOccurs(state: UState): Boolean = {
if (ock eq OccursCountKind.Implicit)
state.arrayIterationPos <= maxRepeats(state)
else
true
}
}
class OrderedUnseparatedSequenceUnparser(
rd: SequenceRuntimeData,
childUnparsers: Seq[SequenceChildUnparser]
) extends OrderedSequenceUnparserBase(rd, childUnparsers.toVector) {
/**
* Unparses one iteration of an array/optional element
*/
protected def unparseOne(
unparser: SequenceChildUnparser,
trd: TermRuntimeData,
state: UState
): Unit = {
unparser.unparse1(state)
}
/**
* Unparses an entire sequence, including both scalar and array/optional children.
*/
protected def unparse(state: UState): Unit = {
state.groupIndexStack.push(1L) // one-based indexing
var index = 0
var doUnparser = false
val limit = childUnparsers.length
while (index < limit) {
val childUnparser = childUnparsers(index)
val trd = childUnparser.trd
state.pushTRD(trd) // because we inspect before we invoke the unparser
//
// Unparsing an ordered sequence depends on the incoming
// stream of infoset events matching up with the order that
// they are expected as the unparser recurses through the
// child term unparsers.
//
childUnparser match {
case unparser: RepeatingChildUnparser => {
state.arrayIterationIndexStack.push(1L)
state.occursIndexStack.push(1L)
val erd = unparser.erd
var numOccurrences = 0
val maxReps = unparser.maxRepeats(state)
//
// The number of occurrances we unparse is always exactly driven
// by the number of infoset events for the repeating/optional element.
//
// For RepUnparser - array/optional case - in all cases we should get a
// startArray event. If we don't then
// the element must be entirely optional, so we get no events for it
// at all.
// we must have an event
Assert.invariant(state.inspect, "No event for unparing.")
val ev = state.inspectAccessor
if (ev.erd eq erd) {
// must be a start event for this array/optional unparser
val isArr = ev.isArray
Assert.invariant(ev.isStart && (isArr || ev.erd.isOptional))
//
// StartArray for this unparser's array element
//
unparser.startArrayOrOptional(state)
while ({
doUnparser = unparser.shouldDoUnparser(unparser, state)
doUnparser
}) {
if (isArr)
if (state.dataProc.isDefined)
state.dataProc.get.beforeRepetition(state, this)
unparseOne(unparser, erd, state)
numOccurrences += 1
state.moveOverOneArrayIterationIndexOnly()
state.moveOverOneOccursIndexOnly()
state.moveOverOneGroupIndexOnly() // array elements are always represented.
if (isArr)
if (state.dataProc.isDefined)
state.dataProc.get.afterRepetition(state, this)
}
// DAFFODIL-115: if the number of occurrences is less than minOccurs we are supposed
// to check if the element is defaultable and add elements until we reach that
// number. Daffodil does not currently support defaulting during unparsing.
unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(
state,
unparser,
numOccurrences,
maxReps,
state.arrayIterationPos - 1
)
unparser.endArrayOrOptional(erd, state)
} else {
// this is either a start event for a following element or an end event for a
// parent element. Either way, we never saw a start event for this array/optional,
// which means there were zero occurrenes. Make sure that is allowed for this array
//
// DAFFODIL-115: if the number of occurrences is less than minOccurs we are supposed
// to check if the element is defaultable and add elements until we reach that
// number. Daffodil does not currently support defaulting during unparsing.
unparser.checkFinalOccursCountBetweenMinAndMaxOccurs(
state,
unparser,
numOccurrences,
maxReps,
0
)
}
state.arrayIterationIndexStack.pop()
state.occursIndexStack.pop()
}
//
case scalarUnparser => {
unparseOne(scalarUnparser, trd, state)
// only move over in group if the scalar "thing" is an element
// that is represented.
scalarUnparser.trd match {
case erd: ElementRuntimeData if (!erd.isRepresented) => // ok, skip group advance
case _ => state.moveOverOneGroupIndexOnly()
}
}
}
state.popTRD(trd)
index += 1
//
// Note: the invariant is that unparsers move over 1 within their group themselves
// we do not do the moving over here as we are the caller of the unparser.
//
}
state.groupIndexStack.pop()
//
// this is establishing the invariant that unparsers (in this case the sequence unparser)
// moves over within its containing group. The caller of an unparser does not do this move.
//
// state.moveOverOneGroupIndexOnly() // move past this sequence itself, next group child it ITS parent.
}
}