stevedlawrence commented on a change in pull request #75: Daffodil 1738 zoned
decimal
URL: https://github.com/apache/incubator-daffodil/pull/75#discussion_r195396945
##########
File path:
daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesZoned.scala
##########
@@ -17,13 +17,162 @@
package org.apache.daffodil.grammar.primitives
-import org.apache.daffodil.dsom.ElementBase
+import org.apache.daffodil.dsom._
+import org.apache.daffodil.dpath.NodeInfo.PrimType
+import org.apache.daffodil.grammar.Gram
+import org.apache.daffodil.grammar.Terminal
+import com.ibm.icu.text.DecimalFormat
+import org.apache.daffodil.processors.unparsers.Unparser
+import org.apache.daffodil.processors.unparsers.ConvertZonedNumberUnparser
+import org.apache.daffodil.processors.unparsers.ConvertZonedCombinatorUnparser
+import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt }
+import
org.apache.daffodil.processors.parsers.ConvertZonedByteParserUnparserHelper
+import org.apache.daffodil.processors.parsers.ConvertZonedCombinatorParser
+import
org.apache.daffodil.processors.parsers.ConvertZonedDecimalParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedIntParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedIntegerParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedLongParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedNonNegativeIntegerParserUnparserHelper
+import org.apache.daffodil.processors.parsers.ConvertZonedNumberParser
+import
org.apache.daffodil.processors.parsers.ConvertZonedNumberParserUnparserHelperBase
+import
org.apache.daffodil.processors.parsers.ConvertZonedShortParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedUnsignedByteParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedUnsignedLongParserUnparserHelper
+import
org.apache.daffodil.processors.parsers.ConvertZonedUnsignedShortParserUnparserHelper
+import org.apache.daffodil.processors.parsers.ZonedFormatFactoryBase
+import org.apache.daffodil.processors.parsers.ZonedFormatFactoryStatic
+import
org.apache.daffodil.processors.parsers.ConvertZonedUnsignedIntParserUnparserHelper
+import org.apache.daffodil.processors.parsers.Parser
+import org.apache.daffodil.schema.annotation.props.gen.TextNumberCheckPolicy
+import org.apache.daffodil.schema.annotation.props.gen.TextNumberRounding
+import org.apache.daffodil.util.Maybe._
+import org.apache.daffodil.util.MaybeDouble
-abstract class ZonedTextNumberPrim(e: ElementBase, guard: Boolean) extends
UnimplementedPrimitive(e, guard) {
- // lazy val parser: DaffodilParser = new
ZonedTextNumberParser(e.elementRuntimeData)
+case class ConvertZonedCombinator(e: ElementBase, value: Gram, converter: Gram)
+ extends Terminal(e, !(value.isEmpty || converter.isEmpty)) {
+
+ lazy val parser = new ConvertZonedCombinatorParser(e.termRuntimeData,
value.parser, converter.parser)
+
+ override lazy val unparser = new
ConvertZonedCombinatorUnparser(e.termRuntimeData, value.unparser,
converter.unparser)
+}
+
+abstract class ConvertZonedNumberPrim[S](e: ElementBase)
+ extends Terminal(e, true) {
+
+ def helper: ConvertZonedNumberParserUnparserHelperBase[S]
+
+ def numFormatFactory: ZonedFormatFactoryBase[S] = {
+ val h = helper
+
+ val pattern = {
+ val p = e.textNumberPattern
+
+ val noEscapedTicksRegex = """''""".r
+ val patternNoEscapedTicks = noEscapedTicksRegex.replaceAllIn(p, "")
+ val noQuotedRegex = """'[^']+'""".r
+ val patternNoQuoted = noQuotedRegex.replaceAllIn(patternNoEscapedTicks,
"")
+
+ if (patternNoQuoted.contains("V")) {
+ e.notYetImplemented("textNumberPattern with V symbol")
+ }
+
+ if (patternNoQuoted.contains("P")) {
+ e.notYetImplemented("textNumberPattern with P symbol")
+ }
+
+ if (patternNoQuoted.contains("@")) {
+ e.SDE("The '@' symbol may not be used in textNumberPattern for
textNumberRep='zoned'")
+ }
+
+ if (patternNoQuoted.contains(";")) {
+ e.SDE("Negative patterns may not be used in textNumberPattern for
textNumberRep='zoned'")
+ }
+
+ e.primType match {
+ case PrimType.Double | PrimType.Float =>
e.SDE("textZonedFormat='zoned' does not support Doubles/Floats")
+ case PrimType.UnsignedLong | PrimType.UnsignedInt |
PrimType.UnsignedShort | PrimType.UnsignedByte => {
+ if (e.textNumberCheckPolicy == TextNumberCheckPolicy.Lax) {
+ if ((patternNoQuoted.charAt(0) != '+') &&
(patternNoQuoted.charAt(patternNoQuoted.length - 1) != '+'))
+ e.SDE("textNumberPattern must have '+' at the beginning or the
end of the pattern when textZonedFormat='zoned' and textNumberPolicy='lax' for
unsigned numbers")
+ }
+ }
+ case _ => {
+ if ((patternNoQuoted.charAt(0) != '+') &&
(patternNoQuoted.charAt(patternNoQuoted.length - 1) != '+'))
+ e.SDE("textNumberPattern must have '+' at the beginning or the end
of the pattern when textZonedFormat='zoned' for signed numbers")
+ }
+ }
+
+ // Load the pattern to make sure it is valid
+ try {
+ new DecimalFormat(p)
+ } catch {
+ case ex: IllegalArgumentException => e.SDE("Invalid textNumberPattern:
" + ex.getMessage())
+ }
+
+ p
+ }
+
+ val (roundingIncrement: MaybeDouble, roundingMode) =
+ e.textNumberRounding match {
+ case TextNumberRounding.Explicit =>
(MaybeDouble(e.textNumberRoundingIncrement), One(e.textNumberRoundingMode))
+ case TextNumberRounding.Pattern => (MaybeDouble.Nope, Nope)
+ }
+
+ val nff = new ZonedFormatFactoryStatic[S](
Review comment:
It looks like zoned does not need use any properties that can be
expressoins, so the Static/Dynamic split that TextStandardNumbers has doesn't
apply. Since there's no Dynamic version of this factory, it probably makes
sense to remove "Static" so people (like me) aren't searching for the Dynamic
version and get rid of the Base class/merge it all into one.
I *think* we still need this as a factory since DecimalFormat isn't thread
safe. This factory enables us to get ThreadLocal version of the DecimalFormat.
Might be worth adding a comment to that affect.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on 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