Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
well that was rough. add java array support. don't look too closely.
Browse files Browse the repository at this point in the history
  • Loading branch information
Robey Pointer committed Aug 22, 2010
1 parent 32f9035 commit 40b2ac1
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 12 deletions.
66 changes: 54 additions & 12 deletions src/main/scala/com/twitter/streamyj/StreamyUnpacker.scala
Expand Up @@ -16,16 +16,22 @@ class StreamyUnpacker {
var ignoreExtraFields = false

def coerce[A, B](name: String, obj: A, cls: Class[B])(implicit manifest: Manifest[A]): B = {
if (manifest.erasure == classOf[Long]) {
coerce(name, obj, manifest.erasure.asInstanceOf[Class[A]], cls)
}

def coerce[A, B](name: String, obj: A, objcls: Class[A], cls: Class[B]): B = {
if (objcls == classOf[Long] || objcls == classOf[java.lang.Long]) {
coerceLong(name, cls, obj.asInstanceOf[Long])
} else if (manifest.erasure == classOf[Double]) {
} else if (objcls == classOf[Double]) {
coerceDouble(name, cls, obj.asInstanceOf[Double])
} else if (manifest.erasure == classOf[String]) {
} else if (objcls == classOf[String]) {
coerceString(name, cls, obj.asInstanceOf[String])
} else if (manifest.erasure == classOf[Boolean]) {
} else if (objcls == classOf[Boolean]) {
coerceBoolean(name, cls, obj.asInstanceOf[Boolean])
} else if (objcls == classOf[List[AnyRef]]) {
coerceList(name, cls, obj.asInstanceOf[List[AnyRef]])
} else {
throw new JsonUnpackingException("foo")
throw new JsonUnpackingException("foo: " + objcls)
}
}

Expand Down Expand Up @@ -117,28 +123,64 @@ class StreamyUnpacker {
rv.asInstanceOf[T]
}

private def coerceList[T, A <: AnyRef](name: String, cls: Class[T], list: List[A]): T = {
val rv: Any = if (cls == classOf[Seq[A]]) {
list.toSeq
} else if (cls == classOf[List[A]]) {
list
} else if (cls.isArray) {
// eww.
val coercedItems = list.map { item => coerce(name, item, item.getClass.asInstanceOf[Class[Any]], cls.getComponentType) }
val array = Array.newInstance(cls.getComponentType, list.size)
for (i <- 0 until list.size) {
Array.set(array, i, coercedItems(i))
}
array
} else {
throw new JsonUnpackingException(name, cls, "list")
}
rv.asInstanceOf[T]
}

def setField[T](obj: T, field: Field, streamy: Streamy) {
streamy.next() match {
case ValueLong(x) => field.set(obj, coerce(field.getName, x, field.getType))
case ValueDouble(x) => field.set(obj, coerce(field.getName, x, field.getType))
case ValueString(x) => field.set(obj, coerce(field.getName, x, field.getType))
case ValueFalse => field.set(obj, coerce(field.getName, false, field.getType))
case ValueTrue => field.set(obj, coerce(field.getName, true, field.getType))
// case StartArray => setArrayField(obj, field, getArray(streamy))
case StartArray => field.set(obj, coerce(field.getName, getArray(streamy), field.getType))
case x =>
throw new JsonUnpackingException("Unexpected token: " + x)

/*
case object StartArray extends StreamyToken
case object EndArray extends StreamyToken
case object StartObject extends StreamyToken
case object EndObject extends StreamyToken
case object ValueNull extends StreamyToken
*/
}
}

def getArray(streamy: Streamy) = {
val list = new mutable.ListBuffer[Any]
getArrayNext(streamy, list).toList
}

// null
// array, object
def getArrayNext(streamy: Streamy, list: mutable.ListBuffer[Any]): mutable.ListBuffer[Any] = {
streamy.next() match {
case EndArray => return list
case ValueLong(x) => list += x
case ValueDouble(x) => list += x
case ValueString(x) => list += x
case ValueFalse => list += false
case ValueTrue => list += true
case ValueNull => list += null
case StartArray => list += getArray(streamy)
// case object StartObject extends StreamyToken
case x =>
throw new JsonUnpackingException("Unexpected token: " + x)
}
getArrayNext(streamy, list)
}

@throws(classOf[JsonProcessingException])
Expand Down Expand Up @@ -192,6 +234,6 @@ class StreamyUnpacker {
}

object StreamyUnpacker {
def apply[T](s: String)(implicit manifest: Manifest[T]) =
new StreamyUnpacker().unpackObject(new Streamy(s), manifest.erasure)
def apply[T](s: String)(implicit manifest: Manifest[T]): T =
new StreamyUnpacker().unpackObject(new Streamy(s), manifest.erasure.asInstanceOf[Class[T]])
}
17 changes: 17 additions & 0 deletions src/test/scala/com/twitter/streamyj/StreamyUnpackerSpec.scala
Expand Up @@ -93,5 +93,22 @@ object StreamyUnpackerSpec extends Specification {
StreamyUnpacker[CryForMe]("""{"cry":false}""") mustEqual CryForMe(false)
StreamyUnpacker[CryForMe]("""{"cry":true}""") mustEqual CryForMe(true)
}

"object of arrays" in {
val data = """{"name":"Santa","grades":[95, 79, 88, 90]}"""

case class SeqGrades(name: String, grades: Seq[Int])
StreamyUnpacker[SeqGrades](data) mustEqual SeqGrades("Santa", List(95, 79, 88, 90).toSeq)

case class ListGrades(name: String, grades: List[Int])
StreamyUnpacker[ListGrades](data) mustEqual ListGrades("Santa", List(95, 79, 88, 90))

case class ArrayGrades(name: String, grades: Array[Int])
StreamyUnpacker[ArrayGrades](data).grades.toList mustEqual List(95, 79, 88, 90)

val data2 = """{"name":"Santa","friends":["Rudolph","Frosty"]}"""
case class ArrayFriends(name: String, friends: Array[String])
StreamyUnpacker[ArrayFriends](data2).friends.toList mustEqual List("Rudolph", "Frosty")
}
}
}

0 comments on commit 40b2ac1

Please sign in to comment.