This repository has been archived by the owner. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add bytestring independent coded streams implementations
- Loading branch information
0 parents
commit eb75ba4
Showing
13 changed files
with
1,725 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.DS_Store | ||
.idea* | ||
target/ | ||
.cache | ||
.classpath | ||
.project | ||
.settings/ | ||
*.iml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import Dependencies._ | ||
|
||
ThisBuild / scalaVersion := "2.12.8" | ||
ThisBuild / version := "0.1.0-SNAPSHOT" | ||
ThisBuild / organization := "com.github.fomkin" | ||
ThisBuild / organizationName := "zhukov" | ||
|
||
lazy val protobuf = project | ||
.in(file("protobuf")) | ||
.settings( | ||
name := "zhukov-protobuf" | ||
) | ||
|
||
lazy val core = project | ||
.in(file("core")) | ||
.settings( | ||
name := "zhukov-core" | ||
) | ||
.dependsOn(protobuf) | ||
|
||
lazy val derivation = project | ||
.in(file("derivation")) | ||
.settings(Project.inConfig(Test)(sbtprotoc.ProtocPlugin.protobufConfigSettings):_*) | ||
.settings( | ||
name := "zhukov-derivation", | ||
testFrameworks += new TestFramework("utest.runner.Framework"), | ||
PB.targets in Test := Seq(scalapb.gen() -> (sourceManaged in Test).value), | ||
PB.targets in Compile := Nil, | ||
PB.protoSources in Test := Seq(file("derivation/src/test/protobuf")), | ||
libraryDependencies := Seq( | ||
scalaPb % Test, utest, // testing | ||
macroCompat, macroParadise, scalaCompiler(scalaVersion.value) // macros | ||
) | ||
) | ||
.dependsOn(core) | ||
lazy val root = (project in file(".")) | ||
.aggregate(protobuf, core, derivation) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package zhukov | ||
|
||
import zhukov.protobuf.{CodedOutputStream, WireFormat} | ||
|
||
abstract class Marshaller[@specialized T](val wireType: Int) { | ||
|
||
|
||
def apply[B: Bytes](stream: CodedOutputStream, value: T): Unit | ||
def apply[B: Bytes](value: T, bufferSize: Int = CodedOutputStream.DEFAULT_BUFFER_SIZE): B | ||
} | ||
|
||
object Marshaller { | ||
|
||
def apply[T](wireType: Int)(f: (CodedOutputStream, T) => Unit): Marshaller[T] = new Marshaller[T](wireType) { | ||
def apply[B: Bytes](stream: CodedOutputStream, value: T): Unit = f(stream, value) | ||
def apply[B](value: T, bufferSize: Int = CodedOutputStream.DEFAULT_BUFFER_SIZE)(implicit bytes: Bytes[B]): B = { | ||
val buffer = new Array[Byte](bufferSize) | ||
val stream = CodedOutputStream.newInstance(buffer) | ||
apply(stream, value) | ||
bytes.copyFromArray(buffer, 0, bufferSize - stream.spaceLeft()) | ||
} | ||
} | ||
|
||
// Primitives default instances | ||
implicit val int: Marshaller[Int] = Marshaller(WireFormat.WIRETYPE_VARINT)(_.writeInt32NoTag(_)) | ||
implicit val long: Marshaller[Long] = Marshaller(WireFormat.WIRETYPE_VARINT)(_.writeInt64NoTag(_)) | ||
implicit val float: Marshaller[Float] = Marshaller(WireFormat.WIRETYPE_FIXED32)(_.writeFloatNoTag(_)) | ||
implicit val double: Marshaller[Double] = Marshaller(WireFormat.WIRETYPE_FIXED32)(_.writeDoubleNoTag(_)) | ||
implicit val string: Marshaller[String] = Marshaller(WireFormat.WIRETYPE_LENGTH_DELIMITED)(_.writeStringNoTag(_)) | ||
|
||
// // Sequences | ||
// implicit def iterable[T]: Marshaller[Iterable[T]] = | ||
// Marshaller(WireFormat.WIRETYPE_LENGTH_DELIMITED) { (stream, value) => | ||
// | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package zhukov | ||
|
||
import zhukov.protobuf.CodedInputStream | ||
|
||
sealed trait Unmarshaller[A] { | ||
|
||
def read(stream: CodedInputStream): A | ||
|
||
def read[B: Bytes](bytes: B): A = { | ||
val stream = CodedInputStream.newInstance(bytes) | ||
read(stream) | ||
} | ||
} | ||
|
||
|
||
object Unmarshaller { | ||
|
||
trait LengthDelimitedUnmarshaller[A] extends Unmarshaller[A] { self => | ||
def map[B](f: A => B): LengthDelimitedUnmarshaller[B] = | ||
(stream: CodedInputStream) => f(self.read(stream)) | ||
} | ||
|
||
trait VarintUnmarshaller[A] extends Unmarshaller[A] { self => | ||
def map[B](f: A => B): VarintUnmarshaller[B] = | ||
(stream: CodedInputStream) => f(self.read(stream)) | ||
} | ||
|
||
trait Fixed32Unmarshaller[A] extends Unmarshaller[A] { self => | ||
def map[B](f: A => B): Fixed32Unmarshaller[B] = | ||
(stream: CodedInputStream) => f(self.read(stream)) | ||
} | ||
|
||
trait Fixed64Unmarshaller[A] extends Unmarshaller[A] { self => | ||
def map[B](f: A => B): Fixed64Unmarshaller[B] = | ||
(stream: CodedInputStream) => f(self.read(stream)) | ||
} | ||
|
||
def apply[T](implicit unmarshaller: Unmarshaller[T]): Unmarshaller[T] = | ||
unmarshaller | ||
|
||
implicit val int: VarintUnmarshaller[Int] = _.readRawVarint32() | ||
implicit val long: VarintUnmarshaller[Long] = _.readRawVarint64() | ||
implicit val string: LengthDelimitedUnmarshaller[String] = _.readString() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import sbt._ | ||
|
||
object Dependencies { | ||
|
||
lazy val scalaPb = "com.thesamet.scalapb" %% "scalapb-runtime" % scalapb.compiler.Version.scalapbVersion | ||
lazy val utest = "com.lihaoyi" %% "utest" % "0.6.6" % Test | ||
lazy val macroCompat = "org.typelevel" %% "macro-compat" % "1.1.1" | ||
lazy val macroParadise = compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.patch) | ||
|
||
def scalaCompiler(scalaVersion: String): ModuleID = "org.scala-lang" % "scala-compiler" % scalaVersion % "provided" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sbt.version=1.2.8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
addSbtPlugin("com.thesamet" % "sbt-protoc" % "0.99.19") | ||
|
||
libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.8.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package zhukov | ||
|
||
import java.nio.ByteBuffer | ||
|
||
trait Bytes[T] { | ||
def empty: T | ||
def copyFromArray(bytes: Array[Byte]): T | ||
def copyFromArray(bytes: Array[Byte], offset: Long, size: Long): T | ||
def copyToArray(value: T, array: Array[Byte], sourceOffset: Int, targetOffset: Int, length: Int): Unit | ||
def wrapArray(bytes: Array[Byte]): T | ||
def copyBuffer(buffer: ByteBuffer): T | ||
def toArray(bytes: T): Array[Byte] | ||
def toBuffer(bytes: T): ByteBuffer | ||
def get(bytes: T, i: Long): Int | ||
def size(bytes: T): Long | ||
def concat(left: T, right: T): T | ||
def slice(value: T, start: Long, end: Long): T | ||
} | ||
|
||
object Bytes { | ||
|
||
def apply[T: Bytes]: Bytes[T] = implicitly[Bytes[T]] | ||
|
||
implicit final class BytesOps[T](bytes: T)(implicit instance: Bytes[T]) { | ||
def apply(i: Int): Int = apply(i.toLong) | ||
def apply(i: Long): Int = instance.get(bytes, i) | ||
def concat(right: T): T = instance.concat(bytes, right) | ||
} | ||
|
||
implicit object ArrayInstance extends Bytes[Array[Byte]] { | ||
|
||
val empty: Array[Byte] = | ||
Array() | ||
|
||
def copyFromArray(bytes: Array[Byte]): Array[Byte] = | ||
bytes.clone() | ||
|
||
def copyFromArray(bytes: Array[Byte], offset: Long, size: Long): Array[Byte] = | ||
bytes.slice(offset.toInt, (offset + size).toInt) | ||
|
||
def copyToArray(value: Array[Byte], array: Array[Byte], sourceOffset: Int, targetOffset: Int, length: Int): Unit = | ||
System.arraycopy(value, sourceOffset, array, targetOffset, length) | ||
|
||
def wrapArray(bytes: Array[Byte]): Array[Byte] = | ||
bytes | ||
|
||
def copyBuffer(buffer: ByteBuffer): Array[Byte] = | ||
buffer.array() | ||
|
||
def toArray(bytes: Array[Byte]): Array[Byte] = | ||
bytes | ||
|
||
def toBuffer(bytes: Array[Byte]): ByteBuffer = | ||
ByteBuffer.wrap(bytes) | ||
|
||
def get(bytes: Array[Byte], i: Long): Int = | ||
bytes(i.toInt) | ||
|
||
def size(bytes: Array[Byte]): Long = | ||
bytes.length.toLong | ||
|
||
def concat(left: Array[Byte], right: Array[Byte]): Array[Byte] = | ||
left ++ right | ||
|
||
def slice(value: Array[Byte], start: Long, end: Long): Array[Byte] = | ||
value.slice(start.toInt, end.toInt) | ||
} | ||
} |
Oops, something went wrong.