Skip to content

Commit

Permalink
Add IoUtils.writeFrameAsDelimited (#246)
Browse files Browse the repository at this point in the history
The utility will be useful in nanopub-registry to quickly return the nanopub from the DB, just by prepending a delimiter.
  • Loading branch information
Ostrzyciel authored Dec 21, 2024
1 parent 0486da9 commit 3d9f467
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
21 changes: 20 additions & 1 deletion core/src/main/scala/eu/ostrzyciel/jelly/core/IoUtils.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package eu.ostrzyciel.jelly.core

import java.io.{ByteArrayInputStream, InputStream, SequenceInputStream}
import com.google.protobuf.CodedOutputStream
import scalapb.LiteParser

import java.io.{ByteArrayInputStream, InputStream, OutputStream, SequenceInputStream}

object IoUtils:
/**
Expand Down Expand Up @@ -28,3 +31,19 @@ object IoUtils:
scout(0) != 0x0A || scout(1) == 0x0A && scout(2) != 0x0A
)
(isDelimited, newInput)

/**
* Utility method to transform a non-delimited Jelly frame (as a byte array) into a delimited one,
* writing it to a byte stream.
*
* This is useful if you for example store non-delimited frames in a database, but want to write them to a stream.
*
* @param nonDelimitedFrame EXACTLY one non-delimited Jelly frame
* @param output the output stream to write the frame to
*/
def writeFrameAsDelimited(nonDelimitedFrame: Array[Byte], output: OutputStream): Unit =
// Don't worry, the buffer won't really have 0-size. It will be of minimal size able to fit the varint.
val codedOutput: CodedOutputStream = CodedOutputStream.newInstance(output, bufferSize = 0)
codedOutput.writeUInt32NoTag(nonDelimitedFrame.length)
codedOutput.flush()
output.write(nonDelimitedFrame)
11 changes: 11 additions & 0 deletions core/src/test/scala/eu/ostrzyciel/jelly/core/IoUtilsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,15 @@ class IoUtilsSpec extends AnyWordSpec, Matchers:
newIn.readAllBytes() shouldBe Array[Byte](0x12, 0x34)
}
}

"writeFrameAsDelimited" in {
val os = ByteArrayOutputStream()
IoUtils.writeFrameAsDelimited(frameLarge.toByteArray, os)
val bytes = os.toByteArray

val in = new ByteArrayInputStream(bytes)
val (isDelimited, newIn) = IoUtils.autodetectDelimiting(in)
isDelimited shouldBe true
RdfStreamFrame.parseDelimitedFrom(newIn).get shouldBe frameLarge
}
}

0 comments on commit 3d9f467

Please sign in to comment.