Skip to content

Instantly share code, notes, and snippets.

@casualjim
Created December 13, 2010 18:06
Show Gist options
  • Save casualjim/739343 to your computer and use it in GitHub Desktop.
Save casualjim/739343 to your computer and use it in GitHub Desktop.
trait InputStreamRenderable extends Renderable {
def in: InputStream
def writeTo(out: OutputStream, cs: Charset) {
val in = this.in // it's a def, and we only want one
streamCopy(Channels.newChannel(in), Channels.newChannel(out))
in.close()
}
private def streamCopy(src: ReadableByteChannel, dest: WritableByteChannel) {
val buffer = getByteBuffer(4 * 1024)
@tailrec
def loop() {
if(src.read(buffer) > 0) {
buffer.flip
dest.write(buffer)
buffer.compact
loop
}
}
loop
buffer.flip
while(buffer.hasRemaining) {
dest.write(buffer)
}
}
protected def getByteBuffer(size: Int) = ByteBuffer.allocate(size)
}
/**
* Extension for types that exist as a File. This is useful primarily for zero-copy optimizations.
*/
trait FileRenderable extends InputStreamRenderable {
def file: File
def in: InputStream = new FileInputStream(file)
override protected def getByteBuffer(size: Int) = ByteBuffer.allocateDirect(size) // zero-copy byte buffer
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment