Skip to content

Instantly share code, notes, and snippets.

@9len
Created March 29, 2012 18:55
Show Gist options
  • Save 9len/2242038 to your computer and use it in GitHub Desktop.
Save 9len/2242038 to your computer and use it in GitHub Desktop.
A simple debug TProtocol
import com.twitter.conversions.string._
import java.nio.ByteBuffer
import org.apache.thrift.protocol._
import org.apache.thrift.transport.TTransport
import scala.collection.mutable
object ThriftDebugProtocol {
val Tab = " "
val KeyValueDelim = " = "
val NewLine = "\n"
val StructOpen = "{"
val StructClose = "}"
val SetOpen = "["
val SetClose = "]"
val ListOpen = "("
val ListClose = ")"
class Factory(
tab: String = Tab,
keyValueDelim: String = KeyValueDelim,
newline: String = NewLine,
structOpen: String = StructOpen,
structClose: String = StructClose,
setOpen: String = SetOpen,
setClose: String = SetClose,
listOpen: String = ListOpen,
listClose: String = ListClose)
extends TProtocolFactory
{
override def getProtocol(transport: TTransport): TProtocol =
new ThriftDebugProtocol(
transport,
tab,
keyValueDelim,
newline,
structOpen,
structClose,
setOpen,
setClose,
listOpen,
listClose)
}
}
/**
* A write-only protocol for generating human-readable representations of thrift structures
*/
class ThriftDebugProtocol(
transport: TTransport,
tab: String,
keyValueDelim: String,
newline: String,
structOpen: String,
structClose: String,
setOpen: String,
setClose: String,
listOpen: String,
listClose: String)
extends TProtocol(transport)
{
import ThriftDebugProtocol._
protected[this] def unsupported[A]: A = {
throw new UnsupportedOperationException(
"read operations not supported, TDebugProtocol is write-only")
}
override def readBinary() = unsupported
override def readBool() = unsupported
override def readByte() = unsupported
override def readDouble() = unsupported
override def readFieldBegin() = unsupported
override def readFieldEnd() = unsupported
override def readI16() = unsupported
override def readI32() = unsupported
override def readI64() = unsupported
override def readListBegin() = unsupported
override def readListEnd() = unsupported
override def readMapBegin() = unsupported
override def readMapEnd() = unsupported
override def readMessageBegin() = unsupported
override def readMessageEnd() = unsupported
override def readSetBegin() = unsupported
override def readSetEnd() = unsupported
override def readString() = unsupported
override def readStructBegin() = unsupported
override def readStructEnd() = unsupported
/**
* used to determine indent amount
*/
protected[this] var depth = 0
/**
* used to determine if we're inside a list or set, so we can
* indent the values properly.
*/
protected[this] val collectionStack = new mutable.Stack[Unit]
protected def indent = (tab * depth)
protected[this] def push(brace: String) {
transport.write(brace.getBytes)
transport.write(newline.getBytes)
depth += 1
}
protected[this] def pop(brace: String) {
depth -= 1
transport.write(indent.getBytes)
writeString(brace)
}
override def reset() {
depth = 0
collectionStack.clear()
}
override def writeBinary(buf: ByteBuffer) {
writeString(buf.array.hexlify)
}
override def writeString(str: String) {
if (collectionStack.nonEmpty) {
transport.write(indent.getBytes)
}
transport.write(str.quoteC.getBytes)
transport.write(newline.getBytes)
}
override def writeDouble(dub: Double) {
writeString(dub.toString)
}
override def writeI64(i64: Long) {
writeString(i64.toString)
}
override def writeI32(i32: Int) {
writeI64(i32)
}
override def writeI16(i16: Short) {
writeI64(i16)
}
override def writeByte(b: Byte) {
writeI64(b)
}
override def writeBool(b: Boolean) {
writeString(b.toString)
}
override def writeSetBegin(s: TSet) {
collectionStack.push()
push(setOpen)
}
override def writeSetEnd() {
collectionStack.pop()
pop(setClose)
}
override def writeListBegin(l: TList) {
collectionStack.push()
push(listOpen)
}
override def writeListEnd() {
collectionStack.pop()
pop(listClose)
}
override def writeMapBegin(m: TMap) {
push(structOpen)
}
override def writeMapEnd() {
pop(structClose)
}
override def writeStructBegin(s: TStruct) {
push(structOpen)
}
override def writeStructEnd() {
pop(structClose)
}
override def writeFieldBegin(f: TField) {
transport.write(indent.getBytes)
transport.write(f.name.getBytes)
transport.write(keyValueDelim.getBytes)
}
override def writeFieldStop() = ()
override def writeFieldEnd() = ()
override def writeMessageBegin(m: TMessage) {
push(structOpen)
}
override def writeMessageEnd() {
pop(structClose)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment