-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new primitive, parser, and unparser to handle non base-10 text numbers. Actual logic from converting to/from bases is handled by Java's built-in functions. To maintain backwards compatibility, if the textStandardBase property is not defined it defaults to "10" unless the requireTextStandardBaseProperty tunable is set to true, default to false. Also noticed some unordered sequence tests were commented out and work with minor tweaks due to incorrect tests. DAFFODIL-840
- Loading branch information
1 parent
0ba8cfd
commit 02e6504
Showing
17 changed files
with
1,769 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
...rc/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesNonBaseTenTextNumber.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* 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.grammar.primitives | ||
|
||
import java.math.{ BigInteger => JBigInt } | ||
|
||
import org.apache.daffodil.dsom.ElementBase | ||
import org.apache.daffodil.grammar.Terminal | ||
import org.apache.daffodil.processors.parsers.Parser | ||
import org.apache.daffodil.processors.unparsers.Unparser | ||
import org.apache.daffodil.processors.parsers.ConvertNonBaseTenTextNumberParser | ||
import org.apache.daffodil.processors.unparsers.ConvertNonBaseTenTextNumberUnparser | ||
|
||
import org.apache.daffodil.processors.unparsers.NadaUnparser | ||
|
||
|
||
case class ConvertNonBaseTenTextNumberPrim(e: ElementBase) | ||
extends Terminal(e, true) { | ||
|
||
override lazy val parser: Parser = | ||
new ConvertNonBaseTenTextNumberParser( | ||
e.elementRuntimeData, | ||
e.textStandardBaseDefaulted) | ||
|
||
override lazy val unparser: Unparser = | ||
new ConvertNonBaseTenTextNumberUnparser( | ||
e.elementRuntimeData, | ||
e.textStandardBaseDefaulted) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
.../scala/org/apache/daffodil/processors/unparsers/ConvertNonBaseTenTextNumberUnparser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* 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.processors.unparsers | ||
|
||
import java.lang.{ Long => JLong } | ||
import java.lang.{ Number => JNumber } | ||
import java.math.{ BigInteger => JBigInt } | ||
|
||
import org.apache.daffodil.processors.ElementRuntimeData | ||
|
||
case class ConvertNonBaseTenTextNumberUnparser( | ||
override val context: ElementRuntimeData, | ||
base: Int) | ||
extends TextPrimUnparser { | ||
|
||
override lazy val runtimeDependencies = Vector() | ||
|
||
override def unparse(state: UState): Unit = { | ||
|
||
val node = state.currentInfosetNode.asSimple | ||
val value = node.dataValue | ||
|
||
val baseStr = value.getNumber match { | ||
case bi: JBigInt => { | ||
if (bi.compareTo(JBigInt.ZERO) < 0) { | ||
UE(state, "Unable to unparse negative values when dfdl:textStandardBase=\"%d\": %s", base, bi.toString) | ||
} | ||
bi.toString(base) | ||
} | ||
case n: JNumber => { | ||
val l = n.longValue | ||
if (l < 0) { | ||
UE(state, "Unable to unparse negative values when dfdl:textStandardBase=\"%d\": %s", base, l.toString) | ||
} | ||
base match { | ||
case 2 => JLong.toBinaryString(l) | ||
case 8 => JLong.toOctalString(l) | ||
case 16 => JLong.toHexString(l) | ||
} | ||
} | ||
} | ||
|
||
node.overwriteDataValue(baseStr) | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
...e1/src/main/scala/org/apache/daffodil/processors/parsers/NonBaseTenTextNumberParser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* 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.processors.parsers | ||
|
||
import java.math.{ BigInteger => JBigInt } | ||
import java.lang.{ Number => JNumber } | ||
|
||
import org.apache.daffodil.dpath.NodeInfo | ||
import org.apache.daffodil.processors.ElementRuntimeData | ||
|
||
class ConvertNonBaseTenTextNumberParser( | ||
override val context: ElementRuntimeData, | ||
base: Int) | ||
extends TextPrimParser { | ||
|
||
override lazy val runtimeDependencies = Vector() | ||
|
||
private val primNumeric = context.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric] | ||
|
||
final def parse(state: PState): Unit = { | ||
|
||
val node = state.simpleElement | ||
val baseStr = node.dataValueAsString | ||
|
||
if (baseStr == "") { | ||
PE(state, "Unable to parse %s from empty string", context.optPrimType.get.globalQName) | ||
return | ||
} | ||
|
||
// Must explicitly check for and error on text that start with + or - | ||
// because DFDL does not allow a leading sign character, but parseInt and | ||
// friends will accept them. Note that textNumberPattern is not used when | ||
// textStandardBase is not 10--one might otherwise think that a +/- in the | ||
// pattern would allow this. | ||
val firstChar = baseStr(0) | ||
if (firstChar == '-' || firstChar == '+') { | ||
PE(state, "Unable to parse %s from base-%d text with leading sign: %s", | ||
context.optPrimType.get.globalQName, base, baseStr) | ||
return | ||
} | ||
|
||
// always parse the base string a BigInt since it allows us to differentiate | ||
// between invalid characters or just too many characters for the prim type | ||
val bi = try { | ||
new JBigInt(baseStr, base) | ||
} catch { | ||
case e: NumberFormatException => | ||
PE(state, "Unable to parse %s from base-%d text due to invalid characters: %s", | ||
context.optPrimType.get.globalQName, base, baseStr) | ||
return | ||
} | ||
|
||
if (!primNumeric.isValidRange(bi)) { | ||
PE(state, "Parsed %s is out of range for the type: %s", | ||
context.optPrimType.get.globalQName, bi.toString) | ||
return | ||
} | ||
|
||
val num = primNumeric.fromNumber(bi) | ||
node.overwriteDataValue(num) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.