diff options
-rw-r--r-- | CHANGELOG | 12 | ||||
-rw-r--r-- | README.markdown | 6 | ||||
-rw-r--r-- | build.sbt | 2 | ||||
-rw-r--r-- | src/main/scala/spray/json/JsonParser.scala | 27 | ||||
-rw-r--r-- | src/test/scala/spray/json/BasicFormatsSpec.scala | 2 |
5 files changed, 36 insertions, 13 deletions
@@ -1,3 +1,15 @@ +Version 1.3.3 (1016-12-29) +-------------------------- + +For Scala 2.12, this release brings no updates over 1.3.2 because the 2.12 release +of 1.3.2 was released from a later version of the master branch. Version 1.3.3 +brings the artifacts for Scala 2.10 and 2.11 also to this latest state. + +- Fixed decoding of 4-byte UTF-8 characters +- Refactored UTF-8 decoding into better reusable superclass +- Decode BigInt / BigDecimal values from JsString (#182) +- Cross published for Scala 2.10.x, 2.11.x, and 2.12.x + Version 1.3.2 (2015-05-06) -------------------------- - Fixed performance bottleneck in `ProductFormats::fromField` (#132) diff --git a/README.markdown b/README.markdown index 69e5327..19f6a8f 100644 --- a/README.markdown +++ b/README.markdown @@ -19,13 +19,13 @@ as depicted in this diagram: ### Installation -_spray-json_ is available from the [repo.spray.io] repository. -The latest release is `1.3.2` and is built against Scala 2.10.5 and Scala 2.11.6. +_spray-json_ is available from maven central. +The latest release is `1.3.3` and is built against Scala 2.10.x, 2.11.x, and 2.12.x. If you use SBT you can include _spray-json_ in your project with ```scala -libraryDependencies += "io.spray" %% "spray-json" % "1.3.2" +libraryDependencies += "io.spray" %% "spray-json" % "1.3.3" ``` ### Usage @@ -1,6 +1,6 @@ name := "spray-json" -version := "1.3.2" +version := "1.3.3" organization := "io.spray" diff --git a/src/main/scala/spray/json/JsonParser.scala b/src/main/scala/spray/json/JsonParser.scala index b1e59d5..20057c1 100644 --- a/src/main/scala/spray/json/JsonParser.scala +++ b/src/main/scala/spray/json/JsonParser.scala @@ -266,23 +266,25 @@ object ParserInput { private val UTF8 = Charset.forName("UTF-8") /** - * ParserInput reading directly off a byte array which is assumed to contain the UTF-8 encoded representation - * of the JSON input, without requiring a separate decoding step. + * ParserInput that allows to create a ParserInput from any randomly accessible indexed byte storage. */ - class ByteArrayBasedParserInput(bytes: Array[Byte]) extends DefaultParserInput { + abstract class IndexedBytesParserInput extends DefaultParserInput { + def length: Int + protected def byteAt(offset: Int): Byte + private val byteBuffer = ByteBuffer.allocate(4) private val charBuffer = CharBuffer.allocate(2) private val decoder = UTF8.newDecoder() def nextChar() = { _cursor += 1 - if (_cursor < bytes.length) (bytes(_cursor) & 0xFF).toChar else EOI + if (_cursor < length) (byteAt(_cursor) & 0xFF).toChar else EOI } def nextUtf8Char() = { @tailrec def decode(byte: Byte, remainingBytes: Int): Char = { byteBuffer.put(byte) if (remainingBytes > 0) { _cursor += 1 - if (_cursor < bytes.length) decode(bytes(_cursor), remainingBytes - 1) else ErrorChar + if (_cursor < length) decode(byteAt(_cursor), remainingBytes - 1) else ErrorChar } else { byteBuffer.flip() val coderResult = decoder.decode(byteBuffer, charBuffer, false) @@ -300,8 +302,8 @@ object ParserInput { result } else { _cursor += 1 - if (_cursor < bytes.length) { - val byte = bytes(_cursor) + if (_cursor < length) { + val byte = byteAt(_cursor) if (byte >= 0) byte.toChar // 7-Bit ASCII else if ((byte & 0xE0) == 0xC0) decode(byte, 1) // 2-byte UTF-8 sequence else if ((byte & 0xF0) == 0xE0) decode(byte, 2) // 3-byte UTF-8 sequence @@ -310,7 +312,16 @@ object ParserInput { } else EOI } } - def length = bytes.length + } + + /** + * ParserInput reading directly off a byte array which is assumed to contain the UTF-8 encoded representation + * of the JSON input, without requiring a separate decoding step. + */ + class ByteArrayBasedParserInput(bytes: Array[Byte]) extends IndexedBytesParserInput { + protected def byteAt(offset: Int): Byte = bytes(offset) + def length: Int = bytes.length + def sliceString(start: Int, end: Int) = new String(bytes, start, end - start, UTF8) def sliceCharArray(start: Int, end: Int) = UTF8.decode(ByteBuffer.wrap(java.util.Arrays.copyOfRange(bytes, start, end))).array() diff --git a/src/test/scala/spray/json/BasicFormatsSpec.scala b/src/test/scala/spray/json/BasicFormatsSpec.scala index 00da813..8417df2 100644 --- a/src/test/scala/spray/json/BasicFormatsSpec.scala +++ b/src/test/scala/spray/json/BasicFormatsSpec.scala @@ -127,7 +127,7 @@ class BasicFormatsSpec extends Specification with DefaultJsonProtocol { ().toJson mustEqual JsNumber(1) } "convert a JsNumber to Unit" in { - JsNumber(1).convertTo[Unit] mustEqual () + JsNumber(1).convertTo[Unit] mustEqual (()) } } |