Skip to content

Commit

Permalink
Add weejson-jsoniter-scala
Browse files Browse the repository at this point in the history
  • Loading branch information
htmldoug committed Dec 19, 2021
1 parent 82824fb commit 060184f
Show file tree
Hide file tree
Showing 4 changed files with 390 additions and 0 deletions.
16 changes: 16 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ lazy val bench = project
.dependsOn(
`weepickle-tests` % "compile;test",
`weejson-upickle`,
`weejson-jsoniter-scala`,
)
.enablePlugins(JmhPlugin)
.settings(
Expand Down Expand Up @@ -137,6 +138,21 @@ lazy val `weejson-jackson` = project
)
)

/**
* A very fast JSON parser.
*
* Uses MiMa, but not shaded. Package naming strategy across major versions is unknown.
*
* @see https://github.com/plokhotnyuk/jsoniter-scala
*/
lazy val `weejson-jsoniter-scala` = project
.dependsOn(`weepickle-core`)
.settings(
libraryDependencies ++= Seq(
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "2.12.0"
),
)

lazy val `weejson-circe` = project
.dependsOn(weejson)
.settings(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.rallyhealth.weejson.v1.wee_jsoniter_scala

import com.github.plokhotnyuk.jsoniter_scala.core._
import com.rallyhealth.weejson.v1.wee_jsoniter_scala.WeePickleJsonValueCodecs.VisitorJsonValueEncoder
import com.rallyhealth.weepickle.v1.core.{FromInput, Visitor}

import java.io.InputStream
import java.nio.ByteBuffer

/**
* A very fast UTF-8-only JSON parser.
*
* This integration:
* - tracks paths and returns as JsonPointer
* - does not deduplicate strings
* - throws below a fixed depth limit
*
* @see https://github.com/plokhotnyuk/jsoniter-scala
*/
object FromJsoniterScala extends FromJsoniterScala(ReaderConfig)

class FromJsoniterScala(config: ReaderConfig) {

def apply(
bytes: Array[Byte]
): FromInput = new FromInput {

override def transform[T](
to: Visitor[_, T]
): T = readFromArray(bytes, config)(readerCodec(to))
}

def apply(
in: InputStream
): FromInput = new FromInput {

override def transform[T](
to: Visitor[_, T]
): T = readFromStream(in, config)(readerCodec(to))
}

def apply(
buf: ByteBuffer
): FromInput = new FromInput {

override def transform[T](
to: Visitor[_, T]
): T = readFromByteBuffer(buf, config)(readerCodec(to))
}

private def readerCodec[J](
v: Visitor[_, J]
): JsonValueCodec[J] = new VisitorJsonValueEncoder[J](v, maxDepth = 64)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.rallyhealth.weejson.v1.wee_jsoniter_scala

import com.github.plokhotnyuk.jsoniter_scala.core.JsonWriter
import com.rallyhealth.weepickle.v1.core._

import java.time.Instant

class JsonWriterVisitor(
writer: JsonWriter
) extends JsVisitor[Any, JsonWriter] {

private[this] val arrVisitor = new ArrVisitor[Any, JsonWriter] {
override def subVisitor: Visitor[_, _] = JsonWriterVisitor.this

override def visitValue(
v: Any
): Unit = ()

override def visitEnd(): JsonWriter = {
writer.writeArrayEnd()
writer
}
}

private[this] val objVisitor = new ObjVisitor[Any, JsonWriter] {
writer.writeObjectStart()
override def visitKey(): Visitor[_, _] = StringVisitor

override def visitKeyValue(
v: Any
): Unit = writer.writeKey(v.toString)

override def subVisitor: Visitor[_, _] = JsonWriterVisitor.this

override def visitValue(
v: Any
): Unit = ()

override def visitEnd(): JsonWriter = {
writer.writeObjectEnd()
writer
}
}

override def visitArray(
length: Int
): ArrVisitor[Any, JsonWriter] = arrVisitor

override def visitObject(
length: Int
): ObjVisitor[Any, JsonWriter] = objVisitor

override def visitNull(): JsonWriter = {
writer.writeNull()
writer
}

override def visitFalse(): JsonWriter = {
writer.writeVal(false)
writer
}

override def visitTrue(): JsonWriter = {
writer.writeVal(true)
writer
}

override def visitFloat64StringParts(
cs: CharSequence,
decIndex: Int,
expIndex: Int
): JsonWriter = {
writer.writeNonEscapedAsciiVal(cs.toString)
writer
}

override def visitFloat64(
d: Double
): JsonWriter = {
writer.writeVal(d)
writer
}

override def visitFloat32(
d: Float
): JsonWriter = {
writer.writeVal(d)
writer
}

override def visitInt32(
i: Int
): JsonWriter = {
writer.writeVal(i)
writer
}

override def visitInt64(
l: Long
): JsonWriter = {
writer.writeVal(l)
writer
}

override def visitFloat64String(
s: String
): JsonWriter = {
writer.writeNonEscapedAsciiVal(s)
writer
}

override def visitString(
cs: CharSequence
): JsonWriter = {
writer.writeVal(cs.toString)
writer
}

override def visitChar(
c: Char
): JsonWriter = {
writer.writeVal(c)
writer
}

override def visitTimestamp(
instant: Instant
): JsonWriter = {
writer.writeVal(instant)
writer
}

override def visitBinary(
bytes: Array[Byte],
offset: Int,
len: Int
): JsonWriter = {
val trimmed = if (bytes.length != len) bytes.take(len) else bytes
writer.writeBase64Val(trimmed, true)
writer
}
}
Loading

0 comments on commit 060184f

Please sign in to comment.