summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/util/parsing/json/JSON.scala28
-rw-r--r--src/library/scala/util/parsing/json/Parser.scala13
2 files changed, 39 insertions, 2 deletions
diff --git a/src/library/scala/util/parsing/json/JSON.scala b/src/library/scala/util/parsing/json/JSON.scala
index 07f48a6061..ab71a44898 100644
--- a/src/library/scala/util/parsing/json/JSON.scala
+++ b/src/library/scala/util/parsing/json/JSON.scala
@@ -12,7 +12,21 @@
package scala.util.parsing.json
/**
- * This object provides a simple interface to the JSON parser class.
+ * This object provides a simple interface to the JSON parser class. The default conversion
+ * for numerics is into a double. If you wish to override this behavior at the global level,
+ * you can set the globalNumberParser property to your own (String => Any) function. If you only
+ * want to override at the per-thread level then you can set the perThreadNumberParser property to your
+ * function. For example:
+ *
+ * <pre>
+ * val myConversionFunc = {input : String => BigDecimal(input)}
+ *
+ * // Global override
+ * JSON.globalNumberParser = myConversionFunc
+ *
+ * // Per-thread override
+ * JSON.perThreadNumberParser = myConversionFunc
+ * </pre>
*
* @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org">
*/
@@ -66,4 +80,16 @@ object JSON extends Parser {
input
}
+ /**
+ * The global (VM) default function for converting a string to a numeric value.
+ */
+ def globalNumberParser_=(f: NumericParser) { defaultNumberParser = f }
+ def globalNumberParser : NumericParser = defaultNumberParser
+
+ /**
+ * Defines the function used to convert a numeric string literal into a numeric format on a per-thread
+ * basis. Use globalNumberParser for a global override
+ */
+ def perThreadNumberParser_=(f : NumericParser) { numberParser.set(f) }
+ def perThreadNumberParser : NumericParser = numberParser.get()
}
diff --git a/src/library/scala/util/parsing/json/Parser.scala b/src/library/scala/util/parsing/json/Parser.scala
index 70b48fb394..3d278e52c8 100644
--- a/src/library/scala/util/parsing/json/Parser.scala
+++ b/src/library/scala/util/parsing/json/Parser.scala
@@ -27,6 +27,17 @@ class Parser extends StdTokenParsers with ImplicitConversions {
lexical.reserved ++= List("true", "false", "null")
lexical.delimiters ++= List("{", "}", "[", "]", ":", ",")
+ /** Type signature for functions that can parse numeric literals */
+ type NumericParser = String => Any
+
+ // Global default number parsing function
+ protected var defaultNumberParser : NumericParser = {_.toDouble}
+
+ // Per-thread default number parsing function
+ protected val numberParser = new ThreadLocal[NumericParser]() {
+ override def initialValue() = defaultNumberParser
+ }
+
// Define the grammar
def root = jsonObj | jsonArray
def jsonObj = "{" ~> repsep(objEntry, ",") <~ "}"
@@ -34,6 +45,6 @@ class Parser extends StdTokenParsers with ImplicitConversions {
def objEntry = stringVal ~ (":" ~> value) ^^ { case x ~ y => (x, y) }
def value: Parser[Any] = (jsonObj | jsonArray | number | "true" ^^^ true | "false" ^^^ false | "null" ^^^ null | stringVal)
def stringVal = accept("string", { case lexical.StringLit(n) => n} )
- def number = accept("number", { case lexical.NumericLit(n) => n.toDouble} )
+ def number = accept("number", { case lexical.NumericLit(n) => numberParser.get.apply(n)} )
}