Skip to content

Commit

Permalink
Change character replacemnet form regex to iterator based. Add suppor…
Browse files Browse the repository at this point in the history
…t for supplementary chars via UTF-16 surrogate pairs
  • Loading branch information
Matt Sanford committed Mar 25, 2010
1 parent d1cd2ff commit 8b0f00c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
31 changes: 21 additions & 10 deletions src/main/scala/com/twitter/json/Json.scala
Expand Up @@ -81,17 +81,28 @@ object Json {
* Quote a string according to "JSON rules".
*/
def quote(s: String) = {
"\"" + s.regexSub("""[^\u0021\u0023-\u002c\-\.\u0030-\u005a\[\]\u005e-\u007e]""".r) { m =>
m.matched.charAt(0) match {
case '\r' => "\\r"
case '\n' => "\\n"
case '\t' => "\\t"
case '"' => "\\\""
case '\\' => "\\\\"
case '/' => "\\/" // to avoid sending "</"
case c => "\\u%04x" format c.asInstanceOf[Int]
val charCount = s.codePointCount(0, s.length)
// TODO: Make this for loop more functional-ish
var quoted = "\""
for (i <- 0 until charCount) {
val codePoint = s.codePointAt(i)
val b = codePoint match {
case 0x0d => "\\r"
case 0x0a => "\\n"
case 0x09 => "\\t"
case 0x22 => "\\\""
case 0x5c => "\\\\"
case 0x2f => "\\/" // to avoid sending "</"
case c if c > 0xffff =>
val chars = Character.toChars(c)
("\\u%04x" format chars(0).asInstanceOf[Int]) + ("\\u%04x" format chars(1).asInstanceOf[Int])
case c if c > 0x7e => "\\u%04x" format c.asInstanceOf[Int]
case c => c.toChar
}
} + "\""
quoted += b
}
quoted += "\""
quoted
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/com/twitter/json/JsonSpec.scala
Expand Up @@ -33,9 +33,9 @@ object JsonSpec extends Specification {
}

"outside of the BMP (using UTF-16 surrogate pairs)" in {
skip("PENDING: JSON spec unclear on supplementary character handling")
// NOTE: The josn.org spec is unclear on how to handle supplementary characters.
val str = new String(Character.toChars(Character.toCodePoint(0xD834.toChar, 0xDD22.toChar)))
Json.quote(str) mustEqual "\"" + str + "\""
Json.quote(str) mustEqual "\"\\ud834\\udd22\""
}

"xml" in {
Expand Down

0 comments on commit 8b0f00c

Please sign in to comment.