summaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
authorMathias <mathias@spray.io>2015-05-06 12:02:50 +0200
committerMathias <mathias@spray.io>2015-05-06 12:41:50 +0200
commit36a845cb6b889b7255021edf1c891c8c5069b923 (patch)
tree89da8cc2265d695a935f6b7b8a9117f073841153 /src/main/scala
parent51e1af64175e1c01a0383e6018839fc374bca164 (diff)
downloadspray-json-36a845cb6b889b7255021edf1c891c8c5069b923.tar.gz
spray-json-36a845cb6b889b7255021edf1c891c8c5069b923.tar.bz2
spray-json-36a845cb6b889b7255021edf1c891c8c5069b923.zip
Introduce `JsObject.empty`, `JsArray.empty`, `JsString.empty` and `JsNumber.zero`, closes #143
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/spray/json/JsValue.scala4
-rw-r--r--src/main/scala/spray/json/JsonParser.scala59
2 files changed, 40 insertions, 23 deletions
diff --git a/src/main/scala/spray/json/JsValue.scala b/src/main/scala/spray/json/JsValue.scala
index 1f9bb05..b21672d 100644
--- a/src/main/scala/spray/json/JsValue.scala
+++ b/src/main/scala/spray/json/JsValue.scala
@@ -52,6 +52,7 @@ case class JsObject(fields: Map[String, JsValue]) extends JsValue {
def getFields(fieldNames: String*): immutable.Seq[JsValue] = fieldNames.flatMap(fields.get)(collection.breakOut)
}
object JsObject {
+ val empty = JsObject(Map.empty[String, JsValue])
def apply(members: JsField*) = new JsObject(Map(members: _*))
@deprecated("Use JsObject(JsValue*) instead", "1.3.0")
def apply(members: List[JsField]) = new JsObject(Map(members: _*))
@@ -65,6 +66,7 @@ case class JsArray(elements: Vector[JsValue]) extends JsValue {
def this(elements: List[JsValue]) = this(elements.toVector)
}
object JsArray {
+ val empty = JsArray(Vector.empty)
def apply(elements: JsValue*) = new JsArray(elements.toVector)
@deprecated("Use JsArray(Vector[JsValue]) instead", "1.3.0")
def apply(elements: List[JsValue]) = new JsArray(elements.toVector)
@@ -76,6 +78,7 @@ object JsArray {
case class JsString(value: String) extends JsValue
object JsString {
+ val empty = JsString("")
def apply(value: Symbol) = new JsString(value.name)
}
@@ -84,6 +87,7 @@ object JsString {
*/
case class JsNumber(value: BigDecimal) extends JsValue
object JsNumber {
+ val zero: JsNumber = apply(0)
def apply(n: Int) = new JsNumber(BigDecimal(n))
def apply(n: Long) = new JsNumber(BigDecimal(n))
def apply(n: Double) = n match {
diff --git a/src/main/scala/spray/json/JsonParser.scala b/src/main/scala/spray/json/JsonParser.scala
index 674d8ea..bed8dbd 100644
--- a/src/main/scala/spray/json/JsonParser.scala
+++ b/src/main/scala/spray/json/JsonParser.scala
@@ -16,10 +16,10 @@
package spray.json
+import scala.annotation.{switch, tailrec}
import java.lang.{StringBuilder => JStringBuilder}
import java.nio.{CharBuffer, ByteBuffer}
import java.nio.charset.Charset
-import scala.annotation.{switch, tailrec}
/**
* Fast, no-dependency parser for JSON as defined by http://tools.ietf.org/html/rfc4627.
@@ -59,7 +59,7 @@ class JsonParser(input: ParserInput) {
case '{' => advance(); `object`()
case '[' => advance(); `array`()
case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '-' => `number`()
- case '"' => `string`(); jsValue = JsString(sb.toString)
+ case '"' => `string`(); jsValue = if (sb.length == 0) JsString.empty else JsString(sb.toString)
case _ => fail("JSON Value")
}
}
@@ -71,45 +71,58 @@ class JsonParser(input: ParserInput) {
// http://tools.ietf.org/html/rfc4627#section-2.2
private def `object`(): Unit = {
ws()
- @tailrec def members(map: Map[String, JsValue]): Map[String, JsValue] = {
- `string`()
- require(':')
- ws()
- val key = sb.toString
- `value`()
- val nextMap = map.updated(key, jsValue)
- if (ws(',')) members(nextMap) else nextMap
+ jsValue = if (cursorChar != '}') {
+ @tailrec def members(map: Map[String, JsValue]): Map[String, JsValue] = {
+ `string`()
+ require(':')
+ ws()
+ val key = sb.toString
+ `value`()
+ val nextMap = map.updated(key, jsValue)
+ if (ws(',')) members(nextMap) else nextMap
+ }
+ var map = Map.empty[String, JsValue]
+ map = members(map)
+ require('}')
+ JsObject(map)
+ } else {
+ advance()
+ JsObject.empty
}
- var map = Map.empty[String, JsValue]
- if (cursorChar != '}') map = members(map)
- require('}')
ws()
- jsValue = JsObject(map)
}
// http://tools.ietf.org/html/rfc4627#section-2.3
private def `array`(): Unit = {
ws()
- val list = Vector.newBuilder[JsValue]
- @tailrec def values(): Unit = {
- `value`()
- list += jsValue
- if (ws(',')) values()
+ jsValue = if (cursorChar != ']') {
+ val list = Vector.newBuilder[JsValue]
+ @tailrec def values(): Unit = {
+ `value`()
+ list += jsValue
+ if (ws(',')) values()
+ }
+ values()
+ require(']')
+ JsArray(list.result())
+ } else {
+ advance()
+ JsArray.empty
}
- if (cursorChar != ']') values()
- require(']')
ws()
- jsValue = JsArray(list.result())
}
// http://tools.ietf.org/html/rfc4627#section-2.4
private def `number`() = {
val start = input.cursor
+ val startChar = cursorChar
ch('-')
`int`()
`frac`()
`exp`()
- jsValue = JsNumber(input.sliceCharArray(start, input.cursor))
+ jsValue =
+ if (startChar == '0' && input.cursor - start == 1) JsNumber.zero
+ else JsNumber(input.sliceCharArray(start, input.cursor))
ws()
}