blob: 4bf19fe39240be3b3376d111dcf0b1c62546ba7f [file] [log] [blame]
/* Copyright (c) 2012-2014 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.parsers
import edu.illinois.ncsa.daffodil.processors.ElementRuntimeData
import edu.illinois.ncsa.daffodil.processors.PState
import edu.illinois.ncsa.daffodil.processors.PrimParser
import edu.illinois.ncsa.daffodil.processors.TextJustificationType
import edu.illinois.ncsa.daffodil.processors.TextParserRuntimeMixin
import edu.illinois.ncsa.daffodil.util.MaybeChar
import edu.illinois.ncsa.daffodil.util.Misc
import passera.unsigned.ULong
import edu.illinois.ncsa.daffodil.processors.CharsetEv
/**
* Specifically designed to be used inside one of the SpecifiedLength parsers.
*
* This grabs a string as long as it can get, depending on the SpecifiedLength context
* to constrain how much it can get.
*/
final class StringOfSpecifiedLengthParser(
override val parsingPadChar: MaybeChar,
override val justificationTrim: TextJustificationType.Type,
erd: ElementRuntimeData)
extends PrimParser
with StringOfSpecifiedLengthMixin with TextParserRuntimeMixin {
override lazy val runtimeDependencies = List(erd.encInfo.charsetEv)
override lazy val charsetEv = erd.encInfo.charsetEv
override def context = erd
private val eName = erd.name
override def toBriefXML(depthLimit: Int = -1): String = {
"<" + eName + " parser='" + Misc.getNameFromClass(this) + "' />"
}
override def parse(start: PState) {
val field = parseString(start)
start.simpleElement.setDataValue(field)
}
}
trait CaptureParsingValueLength {
def charsetEv: CharsetEv
final def captureValueLength(state: PState, startBitPos0b: ULong, endBitPos0b: ULong) {
val elem = state.infoset
elem.valueLength.setAbsStartPos0bInBits(startBitPos0b)
elem.valueLength.setAbsEndPos0bInBits(endBitPos0b)
}
final def captureValueLengthOfString(state: PState, str: String) {
val lengthInBits = state.lengthInBits(str, charsetEv.evaluate(state))
// TODO: this is a hack, it doesn't actually set the correct start/end
// pos due to padding. But it does set the correct information so that
// the valueLength can be calculated, which is all this is really
// needed for. For debug purposes, we might want to eventually set the
// actual start/end bit positions.
captureValueLength(state, ULong(0), ULong(lengthInBits))
}
}
trait StringOfSpecifiedLengthMixin
extends PaddingRuntimeMixin
with CaptureParsingValueLength {
protected final def parseString(start: PState): String = {
val dis = start.dataInputStream
val maxLen = dis.limits.maximumSimpleElementSizeInCharacters
val startBitPos0b = dis.bitPos0b
val str = dis.getSomeString(maxLen).getOrElse("")
// TODO: Performance - trimByJustification wants to operate on a StringBuilder
// That means that dis.getSomeString wants to return a StringBuilder instead of
// a string itself.
val field = trimByJustification(str)
justificationTrim match {
case TextJustificationType.None => captureValueLength(start, ULong(startBitPos0b), ULong(dis.bitPos0b))
case _ => captureValueLengthOfString(start, field)
}
field
}
}