blob: 2990943a416f89408f7e19b6bbd0ed73eb08a588 [file] [log] [blame]
/* Copyright (c) 2016 Tresys Technology, LLC. All rights reserved.
*
* Developed by: Tresys Technology, LLC
* http://www.tresys.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal with
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of Tresys Technology, nor the names of its contributors
* may be used to endorse or promote products derived from this Software
* without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
* SOFTWARE.
*/
package edu.illinois.ncsa.daffodil.processors
import edu.illinois.ncsa.daffodil.dsom._
import edu.illinois.ncsa.daffodil.processors.dfa.DFADelimiter
import edu.illinois.ncsa.daffodil.processors.dfa.CreateDelimiterDFA
import edu.illinois.ncsa.daffodil.exceptions.Assert
import edu.illinois.ncsa.daffodil.processors.unparsers.UState
import edu.illinois.ncsa.daffodil.processors.parsers.DelimiterTextType
trait DelimiterEvMixin[+T <: AnyRef]
extends ExprEvalMixin[String] { self: Evaluatable[T] =>
final def isKnownNonEmpty = expr.isKnownNonEmpty
def expr: CompiledExpression[String]
def converter: Converter[String, List[String]]
def trd: TermRuntimeData
override final def toBriefXML(depth: Int = -1) = if (this.isConstant) this.constValue.toString else expr.toBriefXML(depth)
protected def evalAndConvert(state: ParseOrUnparseState): List[String] = {
val expressionResult = eval(expr, state)
val converterResult = state match {
case cs: CompileState => converter.convertConstant(expressionResult, trd, false)
case _ => converter.convertRuntime(expressionResult, trd, false)
}
converterResult
}
}
abstract class DelimiterParseEv(delimType: DelimiterTextType.Type, override val expr: CompiledExpression[String], override val trd: TermRuntimeData)
extends Evaluatable[Array[DFADelimiter]](trd)
with InfosetCachedEvaluatable[Array[DFADelimiter]]
with DelimiterEvMixin[Array[DFADelimiter]] {
override lazy val runtimeDependencies = Nil
override protected def compute(state: ParseOrUnparseState): Array[DFADelimiter] = {
if (state.isInstanceOf[UState]) {
Assert.invariantFailed("State was UState in Parser Evaluatable")
}
val converterResult = evalAndConvert(state)
if (converterResult.length == 1 && converterResult(0) == "") {
Array()
} else {
CreateDelimiterDFA(delimType, trd, converterResult)
}
}
}
abstract class DelimiterUnparseEv(delimType: DelimiterTextType.Type, override val expr: CompiledExpression[String], outputNewLine: OutputNewLineEv, override val trd: TermRuntimeData)
extends Evaluatable[Option[DFADelimiter]](trd)
with InfosetCachedEvaluatable[Option[DFADelimiter]]
with DelimiterEvMixin[Option[DFADelimiter]] {
override lazy val runtimeDependencies = Seq(outputNewLine)
override protected def compute(state: ParseOrUnparseState): Option[DFADelimiter] = {
if (state.isInstanceOf[PState]) {
Assert.invariantFailed("State was PState in Unparser Evaluatable")
}
val converterResult = evalAndConvert(state)
if (converterResult.length == 1 && converterResult(0) == "") {
None
} else {
val onl = outputNewLine.evaluate(state)
Some(CreateDelimiterDFA(delimType, trd, converterResult(0), onl))
}
}
}
class InitiatorParseEv(expr: CompiledExpression[String], trd: TermRuntimeData)
extends DelimiterParseEv(DelimiterTextType.Initiator, expr, trd) {
override val converter = InitiatorCooker
}
class InitiatorUnparseEv(expr: CompiledExpression[String], outputNewLine: OutputNewLineEv, trd: TermRuntimeData)
extends DelimiterUnparseEv(DelimiterTextType.Initiator, expr, outputNewLine, trd) {
override val converter = InitiatorCooker
}
class TerminatorParseEv(expr: CompiledExpression[String], isLengthKindDelimited: Boolean, trd: TermRuntimeData)
extends DelimiterParseEv(DelimiterTextType.Terminator, expr, trd) {
override val converter = if (isLengthKindDelimited) TerminatorCookerNoES else TerminatorCooker
}
class TerminatorUnparseEv(expr: CompiledExpression[String], isLengthKindDelimited: Boolean, outputNewLine: OutputNewLineEv, trd: TermRuntimeData)
extends DelimiterUnparseEv(DelimiterTextType.Terminator, expr, outputNewLine, trd) {
override val converter = if (isLengthKindDelimited) TerminatorCookerNoES else TerminatorCooker
}
class SeparatorParseEv(expr: CompiledExpression[String], trd: TermRuntimeData)
extends DelimiterParseEv(DelimiterTextType.Separator, expr, trd) {
override val converter = SeparatorCooker
}
class SeparatorUnparseEv(expr: CompiledExpression[String], outputNewLine: OutputNewLineEv, trd: TermRuntimeData)
extends DelimiterUnparseEv(DelimiterTextType.Separator, expr, outputNewLine, trd) {
override val converter = SeparatorCooker
}