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 java.nio.charset.MalformedInputException
import java.nio.charset.UnmappableCharacterException
import org.apache.daffodil.lib.equality.ViewEqual
import org.apache.daffodil.lib.schema.annotation.props.gen.GenerateEscape
import org.apache.daffodil.lib.util.Logger
import org.apache.daffodil.lib.util.Maybe
import org.apache.daffodil.lib.util.Maybe.Nope
import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.runtime1.processors.ElementRuntimeData
import org.apache.daffodil.runtime1.processors.EscapeSchemeBlockUnparserHelper
import org.apache.daffodil.runtime1.processors.EscapeSchemeCharUnparserHelper
import org.apache.daffodil.runtime1.processors.EscapeSchemeUnparseEv
import org.apache.daffodil.runtime1.processors.dfa.CreateFieldDFA
import org.apache.daffodil.runtime1.processors.dfa.TextDelimitedUnparser
import org.apache.daffodil.runtime1.processors.unparsers._
sealed class StringDelimitedUnparser(
override val context: ElementRuntimeData,
escapeScheme: Maybe[EscapeSchemeUnparseEv],
isDelimRequired: Boolean
) extends TextPrimUnparser {
override lazy val runtimeDependencies = Vector()
val fieldDFA = CreateFieldDFA()
val textUnparser = new TextDelimitedUnparser(context)
protected def theString(state: UState) =
state.currentInfosetNode.asSimple.dataValueAsString
def unparse(state: UState): Unit = {
val schemeOpt = if (escapeScheme.isDefined) One(escapeScheme.get.evaluate(state)) else Nope
try {
val valueString = theString(state)
val escapedValue: String =
if (schemeOpt.isDefined) {
state.withUnparserDataInputStream { dis =>
val terminatingMarkup = state.allTerminatingMarkup
dis.reset(valueString, state)
val scheme = schemeOpt.get
val (result, _) = {
if (scheme.isInstanceOf[EscapeSchemeCharUnparserHelper]) {
val theScheme = scheme.asInstanceOf[EscapeSchemeCharUnparserHelper]
val hasEscCharAsDelimiter =
terminatingMarkup.exists(d => d.lookingFor(0) =#= theScheme.ec)
val thingsToEscape = (terminatingMarkup ++ scheme.lookingFor).toArray
textUnparser.escapeCharacter(
dis,
fieldDFA,
thingsToEscape,
hasEscCharAsDelimiter,
theScheme.ec,
theScheme.eec,
state
)
} else {
val theScheme = scheme.asInstanceOf[EscapeSchemeBlockUnparserHelper]
def hasInscopeTerminatingDelimiters(): Boolean = {
// Need to do this so we can 'break' the loop early
//
for (d <- terminatingMarkup) {
if (valueString.contains(d.lookingFor)) return true
}
false
}
val generateEscapeBlock =
(theScheme.generateEscapeBlock == GenerateEscape.Always) ||
valueString.startsWith(
theScheme.blockStart
) || hasInscopeTerminatingDelimiters()
val thingsToEscape = theScheme.lookingFor // blockEnd and extraEscapedCharacters
textUnparser.escape(
dis,
fieldDFA,
thingsToEscape,
theScheme.blockEndDFA,
theScheme.eec,
theScheme.blockStart,
theScheme.blockEnd,
generateEscapeBlock,
state
)
}
}
result
}
} else valueString // No EscapeScheme
val outStream = state.dataOutputStream
val nCharsWritten = outStream.putString(escapedValue, state)
if (nCharsWritten != escapedValue.length)
UE(
state,
"%s - Too many bits in field: IndexOutOfBounds. Insufficient space to write %s characters.",
nom,
escapedValue.length
)
Logger.log.debug(s"Ended at bit position ${outStream.relBitPos0b}")
} catch {
// Characters in infoset element cannot be encoded without error.
//
// This won't actually be thrown until encodingErrorPolicy='error' is
// implemented.
//
case m: MalformedInputException => {
UE(state, "%s - MalformedInputException: \n%s", nom, m.getMessage())
}
case u: UnmappableCharacterException => {
UE(state, "%s - UnmappableCharacterException: \n%s", nom, u.getMessage())
}
}
}
}
class LiteralNilDelimitedEndOfDataUnparser(
erd: ElementRuntimeData,
slForUnparserEv: NilStringLiteralForUnparserEv,
isDelimRequired: Boolean
) extends StringDelimitedUnparser(erd, Nope, isDelimRequired) {
final override def theString(ustate: UState) = slForUnparserEv.evaluate(ustate)
}