com.twitter.finagle.netty3.BufChannelBuffer.scala Maven / Gradle / Ivy
The newest version!
package com.twitter.finagle.netty3
import com.twitter.io.Buf
import java.lang.UnsupportedOperationException
import java.io.{InputStream, OutputStream}
import java.nio.{ByteBuffer, ByteOrder, ReadOnlyBufferException}
import java.nio.channels.{GatheringByteChannel, ScatteringByteChannel}
import org.jboss.netty.buffer.{AbstractChannelBuffer, ChannelBuffer, ChannelBuffers, ChannelBufferFactory}
/**
* Class BufChannelBufferFactory is a Netty ChannelBufferFactory that
* creates read-only ChannelBuffers based on [[com.twitter.util.Buf
* Buf]]s. They are a thin API wrapper on top of
* [[com.twitter.util.Buf Buf]]; no additional allocations are
* performed.
*/
object BufChannelBufferFactory {
private val beFactory = new BufChannelBufferFactory(ByteOrder.BIG_ENDIAN)
private val leFactory = new BufChannelBufferFactory(ByteOrder.LITTLE_ENDIAN)
/**
* Get a ChannelBufferFactory with ByteOrder.BIG_ENDIAN
*/
def apply(): ChannelBufferFactory = beFactory
/**
* Get a ChannelBufferFactory with `endianness` ByteOrder
*/
def apply(endianness: ByteOrder): ChannelBufferFactory = endianness match {
case ByteOrder.BIG_ENDIAN => beFactory
case ByteOrder.LITTLE_ENDIAN => leFactory
}
}
/**
* A ChannelBufferFactory which produces read-only ChannelBuffers.
*/
private class BufChannelBufferFactory(defaultOrder: ByteOrder) extends ChannelBufferFactory {
/**
* Returns a read-only ChannelBuffer whose content is filled with
* `capacity` zeros and ByteOrder.BIG_ENDIAN.
*/
def getBuffer(capacity: Int): ChannelBuffer = getBuffer(defaultOrder, capacity)
/**
* Returns a read-only ChannelBuffer whose content is filled with
* `capacity` zeros and `order` endianness.
*/
def getBuffer(order: ByteOrder, capacity: Int): ChannelBuffer =
BufChannelBuffer(Buf.ByteArray(new Array[Byte](capacity)), order)
/**
* Returns a read-only ChannelBuffer whose content is equal to the
* sub-region of the specified array with BytOrder.BIG_ENDIAN.
*/
def getBuffer(array: Array[Byte], offset: Int, length: Int): ChannelBuffer =
getBuffer(defaultOrder, array, offset, length)
/**
* Returns a read-only ChannelBuffer whose content is equal to the
* sub-region of the specified array with `order` endianness.
*/
def getBuffer(order: ByteOrder, array: Array[Byte], offset: Int, length: Int): ChannelBuffer = {
ChannelBuffers.unmodifiableBuffer(
ChannelBuffers.wrappedBuffer(order, array, offset, length))
}
/**
* Returns a read-only ChannelBuffer whose content is equal to the sub-region
* of the specified nioBuffer.
*/
def getBuffer(nioBuffer: ByteBuffer): ChannelBuffer = {
val bytes = new Array[Byte](nioBuffer.remaining())
nioBuffer.get(bytes)
getBuffer(bytes, 0, bytes.length)
}
def getDefaultOrder(): ByteOrder = defaultOrder
}
object BufChannelBuffer {
/**
* Creates a read-only ChannelBuffer from `buf` with big-endian ByteOrder.
*/
def apply(buf: Buf): ChannelBuffer = this(buf, ByteOrder.BIG_ENDIAN)
/**
* Creates a read-only ChannelBuffer from `buf` with `endianness` ByteOrder.
*/
def apply(buf: Buf, endianness: ByteOrder): ChannelBuffer = buf match {
case Buf.ByteArray(bytes, begin, end) =>
ChannelBuffers.unmodifiableBuffer(
ChannelBuffers.wrappedBuffer(endianness, bytes, begin, end - begin))
case _ =>
new BufChannelBuffer(buf, endianness)
}
}
private class BufChannelBuffer(buf: Buf, endianness: ByteOrder) extends AbstractChannelBuffer {
writerIndex(buf.length)
def this(buf: Buf) = this(buf, ByteOrder.BIG_ENDIAN)
def factory(): ChannelBufferFactory = BufChannelBufferFactory(endianness)
def order() = endianness
def isDirect(): Boolean = false
def hasArray() = false
def array() = throw new ReadOnlyBufferException()
def arrayOffset(): Int = throw new ReadOnlyBufferException()
override def discardReadBytes() { throw new ReadOnlyBufferException() }
def setByte(index: Int, value: Int) { throw new ReadOnlyBufferException() }
def setBytes(index: Int, src: ChannelBuffer, srcIndex: Int, length: Int) {
throw new ReadOnlyBufferException()
}
def setBytes(index: Int, src: Array[Byte], srcIndex: Int, length: Int) {
throw new ReadOnlyBufferException()
}
def setBytes(index: Int, src: ByteBuffer) {
throw new ReadOnlyBufferException()
}
def setShort(index: Int, value: Int) {
throw new ReadOnlyBufferException()
}
def setMedium(index: Int, value: Int) {
throw new ReadOnlyBufferException()
}
def setInt(index: Int, value: Int) {
throw new ReadOnlyBufferException()
}
def setLong(index: Int, value: Long) {
throw new ReadOnlyBufferException()
}
def setBytes(index: Int, in: InputStream, length: Int): Int = {
throw new ReadOnlyBufferException()
}
def setBytes(index: Int, in: ScatteringByteChannel, length: Int): Int = {
throw new ReadOnlyBufferException()
}
def getBytes(index: Int, out: GatheringByteChannel, length: Int): Int = {
throw new UnsupportedOperationException()
}
def getBytes(index: Int, out: OutputStream, length: Int) {
val s = buf.slice(index, index + length)
val a = new Array[Byte](s.length)
s.write(a, 0)
out.write(a)
}
def getBytes(index: Int, dst: Array[Byte], dstIndex: Int, length: Int) {
if (index < 0 || dstIndex < 0 || index + length > buf.length || dstIndex + length > dst.length)
throw new IndexOutOfBoundsException()
buf.slice(index, index + length).write(dst, dstIndex)
}
def getBytes(index: Int, dst: ChannelBuffer, dstIndex: Int, length: Int) {
val s = buf.slice(index, index + length)
val a = new Array[Byte](s.length)
s.write(a, 0)
dst.setBytes(dstIndex, a)
}
def getBytes(index: Int, dst: ByteBuffer) {
if (index < 0)
throw new IndexOutOfBoundsException()
if (index >= buf.length)
throw new IndexOutOfBoundsException()
val c = (buf.length - index) min dst.remaining()
val a = new Array[Byte](c)
buf.slice(index, index + c).write(a, 0)
dst.put(a)
}
def duplicate(): ChannelBuffer = {
val dup = BufChannelBuffer(buf, endianness)
dup.setIndex(readerIndex(), writerIndex())
dup
}
def copy(index: Int, length: Int): ChannelBuffer = {
if (index < 0)
throw new IndexOutOfBoundsException("index < 0")
if (index > buf.length)
throw new IndexOutOfBoundsException("index > buf.length")
if (index + length > buf.length)
throw new IndexOutOfBoundsException("index + length > buf.length")
val bcb = BufChannelBuffer(buf.slice(index, index + length), endianness)
bcb.writerIndex(length)
bcb
}
def slice(index: Int, length: Int): ChannelBuffer = {
if (index < 0)
throw new IndexOutOfBoundsException("index < 0")
if (index > buf.length)
throw new IndexOutOfBoundsException("index > buf.length")
if (index + length > buf.length)
throw new IndexOutOfBoundsException("index + length > buf.length")
val bcb = BufChannelBuffer(buf.slice(index, index + length), endianness)
bcb.writerIndex(length)
bcb
}
def getByte(index: Int): Byte = {
if (index < 0)
throw new IndexOutOfBoundsException()
if (index >= buf.length)
throw new IndexOutOfBoundsException()
val one = new Array[Byte](1)
buf.slice(index, index + 1).write(one, 0)
one(0)
}
def getShort(index: Int): Short = {
if (index < 0)
throw new IndexOutOfBoundsException()
if (index + 2 > buf.length)
throw new IndexOutOfBoundsException()
val bytes = new Array[Byte](2)
buf.slice(index, index + 2).write(bytes, 0)
endianness match {
case ByteOrder.BIG_ENDIAN =>
(((bytes(0) & 0xff) << 8) | (bytes(1) & 0xff)).toShort
case ByteOrder.LITTLE_ENDIAN =>
((bytes(0) & 0xff) | ((bytes(1) & 0xff) << 8)).toShort
}
}
def getUnsignedMedium(index: Int): Int = {
if (index < 0)
throw new IndexOutOfBoundsException()
if (index + 3 > buf.length)
throw new IndexOutOfBoundsException()
val bytes = new Array[Byte](3)
buf.slice(index, index + 3).write(bytes, 0)
endianness match {
case ByteOrder.BIG_ENDIAN =>
((bytes(0) & 0xff) << 16) |
((bytes(1) & 0xff) << 8) |
(bytes(2) & 0xff)
case ByteOrder.LITTLE_ENDIAN =>
(bytes(0) & 0xff) |
((bytes(1) & 0xff) << 8) |
((bytes(2) & 0xff) << 16)
}
}
def getInt(index: Int): Int = {
if (index < 0)
throw new IndexOutOfBoundsException()
if (index + 4 > buf.length)
throw new IndexOutOfBoundsException()
val bytes = new Array[Byte](4)
buf.slice(index, index + 4).write(bytes, 0)
endianness match {
case ByteOrder.BIG_ENDIAN =>
((bytes(0) & 0xff) << 24) |
((bytes(1) & 0xff) << 16) |
((bytes(2) & 0xff) << 8) |
(bytes(3) & 0xff)
case ByteOrder.LITTLE_ENDIAN =>
(bytes(0) & 0xff) |
((bytes(1) & 0xff) << 8) |
((bytes(2) & 0xff) << 16) |
((bytes(3) & 0xff) << 24)
}
}
def getLong(index: Int): Long = {
if (index < 0)
throw new IndexOutOfBoundsException()
if (index + 8 > buf.length)
throw new IndexOutOfBoundsException()
val bytes = new Array[Byte](8)
buf.slice(index, index + 8).write(bytes, 0)
endianness match {
case ByteOrder.BIG_ENDIAN =>
((bytes(0) & 0xff).toLong << 56) |
((bytes(1) & 0xff).toLong << 48) |
((bytes(2) & 0xff).toLong << 40) |
((bytes(3) & 0xff).toLong << 32) |
((bytes(4) & 0xff).toLong << 24) |
((bytes(5) & 0xff).toLong << 16) |
((bytes(6) & 0xff).toLong << 8) |
(bytes(7) & 0xff).toLong
case ByteOrder.LITTLE_ENDIAN =>
(bytes(0) & 0xff).toLong |
((bytes(1) & 0xff).toLong << 8) |
((bytes(2) & 0xff).toLong << 16) |
((bytes(3) & 0xff).toLong << 24)
((bytes(4) & 0xff).toLong << 32)
((bytes(5) & 0xff).toLong << 40)
((bytes(6) & 0xff).toLong << 48)
((bytes(7) & 0xff).toLong << 56)
}
}
def toByteBuffer(index: Int, length: Int): ByteBuffer = {
if (index + length > buf.length)
throw new IndexOutOfBoundsException()
val bytes = new Array[Byte](length)
buf.slice(index, index + length).write(bytes, 0)
ByteBuffer.wrap(bytes)
}
def capacity(): Int = buf.length
override def readBytes(length: Int): ChannelBuffer = {
checkReadableBytes(length)
if (length == 0)
return ChannelBuffers.EMPTY_BUFFER
val offset = readerIndex()
readerIndex(offset + length)
val bcb = new BufChannelBuffer(buf.slice(offset, offset + length), endianness)
bcb.writerIndex(length)
bcb
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy