incubator-blur-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amccu...@apache.org
Subject [23/51] [partial] Fixed BLUR-126.
Date Thu, 06 Jun 2013 18:57:55 GMT
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TCompactProtocol.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TCompactProtocol.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TCompactProtocol.java
new file mode 100644
index 0000000..363458a
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TCompactProtocol.java
@@ -0,0 +1,854 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.ShortStack;
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+import org.apache.blur.thirdparty.thrift_0_9_0.transport.TTransport;
+
+/**
+ * TCompactProtocol2 is the Java implementation of the compact protocol specified
+ * in THRIFT-110. The fundamental approach to reducing the overhead of 
+ * structures is a) use variable-length integers all over the place and b) make
+ * use of unused bits wherever possible. Your savings will obviously vary 
+ * based on the specific makeup of your structs, but in general, the more 
+ * fields, nested structures, short strings and collections, and low-value i32
+ * and i64 fields you have, the more benefit you'll see.
+ */
+public class TCompactProtocol extends TProtocol {
+
+  private final static TStruct ANONYMOUS_STRUCT = new TStruct("");
+  private final static TField TSTOP = new TField("", TType.STOP, (short)0);
+
+  private final static byte[] ttypeToCompactType = new byte[16];
+
+  static {
+    ttypeToCompactType[TType.STOP] = TType.STOP;
+    ttypeToCompactType[TType.BOOL] = Types.BOOLEAN_TRUE;
+    ttypeToCompactType[TType.BYTE] = Types.BYTE;
+    ttypeToCompactType[TType.I16] = Types.I16;
+    ttypeToCompactType[TType.I32] = Types.I32;
+    ttypeToCompactType[TType.I64] = Types.I64;
+    ttypeToCompactType[TType.DOUBLE] = Types.DOUBLE;
+    ttypeToCompactType[TType.STRING] = Types.BINARY;
+    ttypeToCompactType[TType.LIST] = Types.LIST;
+    ttypeToCompactType[TType.SET] = Types.SET;
+    ttypeToCompactType[TType.MAP] = Types.MAP;
+    ttypeToCompactType[TType.STRUCT] = Types.STRUCT;
+  }
+
+  /**
+   * TProtocolFactory that produces TCompactProtocols.
+   */
+  public static class Factory implements TProtocolFactory {
+    private final long maxNetworkBytes_;
+
+    public Factory() {
+      maxNetworkBytes_ = -1;
+    }
+
+    public Factory(int maxNetworkBytes) {
+      maxNetworkBytes_ = maxNetworkBytes;
+    }
+
+    public TProtocol getProtocol(TTransport trans) {
+      return new TCompactProtocol(trans, maxNetworkBytes_);
+    }
+  }
+
+  private static final byte PROTOCOL_ID = (byte)0x82;
+  private static final byte VERSION = 1;
+  private static final byte VERSION_MASK = 0x1f; // 0001 1111
+  private static final byte TYPE_MASK = (byte)0xE0; // 1110 0000
+  private static final int  TYPE_SHIFT_AMOUNT = 5;
+
+  /**
+   * All of the on-wire type codes.
+   */
+  private static class Types {
+    public static final byte BOOLEAN_TRUE   = 0x01;
+    public static final byte BOOLEAN_FALSE  = 0x02;
+    public static final byte BYTE           = 0x03;
+    public static final byte I16            = 0x04;
+    public static final byte I32            = 0x05;
+    public static final byte I64            = 0x06;
+    public static final byte DOUBLE         = 0x07;
+    public static final byte BINARY         = 0x08;
+    public static final byte LIST           = 0x09;
+    public static final byte SET            = 0x0A;
+    public static final byte MAP            = 0x0B;
+    public static final byte STRUCT         = 0x0C;
+  }
+
+  /** 
+   * Used to keep track of the last field for the current and previous structs,
+   * so we can do the delta stuff.
+   */
+  private ShortStack lastField_ = new ShortStack(15);
+
+  private short lastFieldId_ = 0;
+
+  /**
+   * If we encounter a boolean field begin, save the TField here so it can 
+   * have the value incorporated.
+   */
+  private TField booleanField_ = null;
+
+  /**
+   * If we read a field header, and it's a boolean field, save the boolean 
+   * value here so that readBool can use it.
+   */
+  private Boolean boolValue_ = null;
+
+  /**
+   * The maximum number of bytes to read from the network for
+   * variable-length fields (such as strings or binary) or -1 for
+   * unlimited.
+   */
+  private final long maxNetworkBytes_;
+
+  /**
+   * Create a TCompactProtocol.
+   *
+   * @param transport the TTransport object to read from or write to.
+   * @param maxNetworkBytes the maximum number of bytes to read for
+   *     variable-length fields.
+   */
+  public TCompactProtocol(TTransport transport, long maxNetworkBytes) {
+    super(transport);
+    maxNetworkBytes_ = maxNetworkBytes;
+  }
+
+  /**
+   * Create a TCompactProtocol.
+   *
+   * @param transport the TTransport object to read from or write to.
+   */
+  public TCompactProtocol(TTransport transport) {
+    this(transport, -1);
+  }
+
+  @Override
+  public void reset() {
+    lastField_.clear();
+    lastFieldId_ = 0;
+  }
+
+  //
+  // Public Writing methods.
+  //
+
+  /**
+   * Write a message header to the wire. Compact Protocol messages contain the
+   * protocol version so we can migrate forwards in the future if need be.
+   */
+  public void writeMessageBegin(TMessage message) throws TException {
+    writeByteDirect(PROTOCOL_ID);
+    writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
+    writeVarint32(message.seqid);
+    writeString(message.name);
+  }
+
+  /**
+   * Write a struct begin. This doesn't actually put anything on the wire. We 
+   * use it as an opportunity to put special placeholder markers on the field
+   * stack so we can get the field id deltas correct.
+   */
+  public void writeStructBegin(TStruct struct) throws TException {
+    lastField_.push(lastFieldId_);
+    lastFieldId_ = 0;
+  }
+
+  /**
+   * Write a struct end. This doesn't actually put anything on the wire. We use
+   * this as an opportunity to pop the last field from the current struct off
+   * of the field stack.
+   */
+  public void writeStructEnd() throws TException {
+    lastFieldId_ = lastField_.pop();
+  }
+
+  /**
+   * Write a field header containing the field id and field type. If the
+   * difference between the current field id and the last one is small (< 15),
+   * then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
+   * field id will follow the type header as a zigzag varint.
+   */ 
+  public void writeFieldBegin(TField field) throws TException {
+    if (field.type == TType.BOOL) {
+      // we want to possibly include the value, so we'll wait.
+      booleanField_ = field;
+    } else {
+      writeFieldBeginInternal(field, (byte)-1);
+    }
+  }
+
+  /**
+   * The workhorse of writeFieldBegin. It has the option of doing a 
+   * 'type override' of the type header. This is used specifically in the 
+   * boolean field case.
+   */
+  private void writeFieldBeginInternal(TField field, byte typeOverride) throws TException {
+    // short lastField = lastField_.pop();
+
+    // if there's a type override, use that.
+    byte typeToWrite = typeOverride == -1 ? getCompactType(field.type) : typeOverride;
+
+    // check if we can use delta encoding for the field id
+    if (field.id > lastFieldId_ && field.id - lastFieldId_ <= 15) {
+      // write them together
+      writeByteDirect((field.id - lastFieldId_) << 4 | typeToWrite);
+    } else {
+      // write them separate
+      writeByteDirect(typeToWrite);
+      writeI16(field.id);
+    }
+
+    lastFieldId_ = field.id;
+    // lastField_.push(field.id);
+  }
+
+  /**
+   * Write the STOP symbol so we know there are no more fields in this struct.
+   */
+  public void writeFieldStop() throws TException {
+    writeByteDirect(TType.STOP);
+  }
+
+  /**
+   * Write a map header. If the map is empty, omit the key and value type 
+   * headers, as we don't need any additional information to skip it.
+   */
+  public void writeMapBegin(TMap map) throws TException {
+    if (map.size == 0) {
+      writeByteDirect(0);
+    } else {
+      writeVarint32(map.size);
+      writeByteDirect(getCompactType(map.keyType) << 4 | getCompactType(map.valueType));
+    }
+  }
+  
+  /** 
+   * Write a list header.
+   */
+  public void writeListBegin(TList list) throws TException {
+    writeCollectionBegin(list.elemType, list.size);
+  }
+
+  /**
+   * Write a set header.
+   */
+  public void writeSetBegin(TSet set) throws TException {
+    writeCollectionBegin(set.elemType, set.size);
+  }
+
+  /**
+   * Write a boolean value. Potentially, this could be a boolean field, in 
+   * which case the field header info isn't written yet. If so, decide what the
+   * right type header is for the value and then write the field header. 
+   * Otherwise, write a single byte.
+   */
+  public void writeBool(boolean b) throws TException {
+    if (booleanField_ != null) {
+      // we haven't written the field header yet
+      writeFieldBeginInternal(booleanField_, b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
+      booleanField_ = null;
+    } else {
+      // we're not part of a field, so just write the value.
+      writeByteDirect(b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
+    }
+  }
+
+  /** 
+   * Write a byte. Nothing to see here!
+   */
+  public void writeByte(byte b) throws TException {
+    writeByteDirect(b);
+  }
+
+  /**
+   * Write an I16 as a zigzag varint.
+   */
+  public void writeI16(short i16) throws TException {
+    writeVarint32(intToZigZag(i16));
+  }
+
+  /**
+   * Write an i32 as a zigzag varint.
+   */
+  public void writeI32(int i32) throws TException {
+    writeVarint32(intToZigZag(i32));
+  }
+
+  /**
+   * Write an i64 as a zigzag varint.
+   */
+  public void writeI64(long i64) throws TException {
+    writeVarint64(longToZigzag(i64));
+  }
+
+  /**
+   * Write a double to the wire as 8 bytes.
+   */ 
+  public void writeDouble(double dub) throws TException {
+    byte[] data = new byte[]{0, 0, 0, 0, 0, 0, 0, 0};
+    fixedLongToBytes(Double.doubleToLongBits(dub), data, 0);
+    trans_.write(data);
+  }
+
+  /**
+   * Write a string to the wire with a varint size preceding.
+   */
+  public void writeString(String str) throws TException {
+    try {
+      byte[] bytes = str.getBytes("UTF-8");
+      writeBinary(bytes, 0, bytes.length);
+    } catch (UnsupportedEncodingException e) {
+      throw new TException("UTF-8 not supported!");
+    }
+  }
+
+  /**
+   * Write a byte array, using a varint for the size. 
+   */
+  public void writeBinary(ByteBuffer bin) throws TException {
+    int length = bin.limit() - bin.position();
+    writeBinary(bin.array(), bin.position() + bin.arrayOffset(), length);
+  }
+
+  private void writeBinary(byte[] buf, int offset, int length) throws TException {
+    writeVarint32(length);
+    trans_.write(buf, offset, length);
+  }
+
+  //
+  // These methods are called by structs, but don't actually have any wire 
+  // output or purpose.
+  // 
+
+  public void writeMessageEnd() throws TException {}
+  public void writeMapEnd() throws TException {}
+  public void writeListEnd() throws TException {}
+  public void writeSetEnd() throws TException {}
+  public void writeFieldEnd() throws TException {}
+
+  //
+  // Internal writing methods
+  //
+
+  /**
+   * Abstract method for writing the start of lists and sets. List and sets on 
+   * the wire differ only by the type indicator.
+   */
+  protected void writeCollectionBegin(byte elemType, int size) throws TException {
+    if (size <= 14) {
+      writeByteDirect(size << 4 | getCompactType(elemType));
+    } else {
+      writeByteDirect(0xf0 | getCompactType(elemType));
+      writeVarint32(size);
+    }
+  }
+
+  /**
+   * Write an i32 as a varint. Results in 1-5 bytes on the wire.
+   * TODO: make a permanent buffer like writeVarint64?
+   */
+  byte[] i32buf = new byte[5];
+  private void writeVarint32(int n) throws TException {
+    int idx = 0;
+    while (true) {
+      if ((n & ~0x7F) == 0) {
+        i32buf[idx++] = (byte)n;
+        // writeByteDirect((byte)n);
+        break;
+        // return;
+      } else {
+        i32buf[idx++] = (byte)((n & 0x7F) | 0x80);
+        // writeByteDirect((byte)((n & 0x7F) | 0x80));
+        n >>>= 7;
+      }
+    }
+    trans_.write(i32buf, 0, idx);
+  }
+
+  /**
+   * Write an i64 as a varint. Results in 1-10 bytes on the wire.
+   */
+  byte[] varint64out = new byte[10];
+  private void writeVarint64(long n) throws TException {
+    int idx = 0;
+    while (true) {
+      if ((n & ~0x7FL) == 0) {
+        varint64out[idx++] = (byte)n;
+        break;
+      } else {
+        varint64out[idx++] = ((byte)((n & 0x7F) | 0x80));
+        n >>>= 7;
+      }
+    }
+    trans_.write(varint64out, 0, idx);
+  }
+
+  /**
+   * Convert l into a zigzag long. This allows negative numbers to be 
+   * represented compactly as a varint.
+   */
+  private long longToZigzag(long l) {
+    return (l << 1) ^ (l >> 63);
+  }
+
+  /**
+   * Convert n into a zigzag int. This allows negative numbers to be 
+   * represented compactly as a varint.
+   */
+  private int intToZigZag(int n) {
+    return (n << 1) ^ (n >> 31);
+  }
+
+  /**
+   * Convert a long into little-endian bytes in buf starting at off and going 
+   * until off+7.
+   */
+  private void fixedLongToBytes(long n, byte[] buf, int off) {
+    buf[off+0] = (byte)( n        & 0xff);
+    buf[off+1] = (byte)((n >> 8 ) & 0xff);
+    buf[off+2] = (byte)((n >> 16) & 0xff);
+    buf[off+3] = (byte)((n >> 24) & 0xff);
+    buf[off+4] = (byte)((n >> 32) & 0xff);
+    buf[off+5] = (byte)((n >> 40) & 0xff);
+    buf[off+6] = (byte)((n >> 48) & 0xff);
+    buf[off+7] = (byte)((n >> 56) & 0xff);
+  }
+
+  /** 
+   * Writes a byte without any possibility of all that field header nonsense. 
+   * Used internally by other writing methods that know they need to write a byte.
+   */
+  private byte[] byteDirectBuffer = new byte[1];
+  private void writeByteDirect(byte b) throws TException {
+    byteDirectBuffer[0] = b;
+    trans_.write(byteDirectBuffer);
+  }
+
+  /** 
+   * Writes a byte without any possibility of all that field header nonsense.
+   */
+  private void writeByteDirect(int n) throws TException {
+    writeByteDirect((byte)n);
+  }
+
+
+  // 
+  // Reading methods.
+  // 
+
+  /**
+   * Read a message header. 
+   */
+  public TMessage readMessageBegin() throws TException {
+    byte protocolId = readByte();
+    if (protocolId != PROTOCOL_ID) {
+      throw new TProtocolException("Expected protocol id " + Integer.toHexString(PROTOCOL_ID) + " but got " + Integer.toHexString(protocolId));
+    }
+    byte versionAndType = readByte();
+    byte version = (byte)(versionAndType & VERSION_MASK);
+    if (version != VERSION) {
+      throw new TProtocolException("Expected version " + VERSION + " but got " + version);
+    }
+    byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+    int seqid = readVarint32();
+    String messageName = readString();
+    return new TMessage(messageName, type, seqid);
+  }
+
+  /**
+   * Read a struct begin. There's nothing on the wire for this, but it is our
+   * opportunity to push a new struct begin marker onto the field stack.
+   */
+  public TStruct readStructBegin() throws TException {
+    lastField_.push(lastFieldId_);
+    lastFieldId_ = 0;
+    return ANONYMOUS_STRUCT;
+  }
+
+  /**
+   * Doesn't actually consume any wire data, just removes the last field for 
+   * this struct from the field stack.
+   */
+  public void readStructEnd() throws TException {
+    // consume the last field we read off the wire.
+    lastFieldId_ = lastField_.pop();
+  }
+  
+  /**
+   * Read a field header off the wire. 
+   */
+  public TField readFieldBegin() throws TException {
+    byte type = readByte();
+
+    // if it's a stop, then we can return immediately, as the struct is over.
+    if (type == TType.STOP) {
+      return TSTOP;
+    }
+
+    short fieldId;
+
+    // mask off the 4 MSB of the type header. it could contain a field id delta.
+    short modifier = (short)((type & 0xf0) >> 4);
+    if (modifier == 0) {
+      // not a delta. look ahead for the zigzag varint field id.
+      fieldId = readI16();
+    } else {
+      // has a delta. add the delta to the last read field id.
+      fieldId = (short)(lastFieldId_ + modifier);
+    }
+
+    TField field = new TField("", getTType((byte)(type & 0x0f)), fieldId);
+
+    // if this happens to be a boolean field, the value is encoded in the type
+    if (isBoolType(type)) {
+      // save the boolean value in a special instance variable.
+      boolValue_ = (byte)(type & 0x0f) == Types.BOOLEAN_TRUE ? Boolean.TRUE : Boolean.FALSE;
+    } 
+
+    // push the new field onto the field stack so we can keep the deltas going.
+    lastFieldId_ = field.id;
+    return field;
+  }
+
+  /** 
+   * Read a map header off the wire. If the size is zero, skip reading the key
+   * and value type. This means that 0-length maps will yield TMaps without the
+   * "correct" types.
+   */
+  public TMap readMapBegin() throws TException {
+    int size = readVarint32();
+    byte keyAndValueType = size == 0 ? 0 : readByte();
+    return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
+  }
+
+  /**
+   * Read a list header off the wire. If the list size is 0-14, the size will 
+   * be packed into the element type header. If it's a longer list, the 4 MSB
+   * of the element type header will be 0xF, and a varint will follow with the
+   * true size.
+   */
+  public TList readListBegin() throws TException {
+    byte size_and_type = readByte();
+    int size = (size_and_type >> 4) & 0x0f;
+    if (size == 15) {
+      size = readVarint32();
+    }
+    byte type = getTType(size_and_type);
+    return new TList(type, size);
+  }
+
+  /**
+   * Read a set header off the wire. If the set size is 0-14, the size will 
+   * be packed into the element type header. If it's a longer set, the 4 MSB
+   * of the element type header will be 0xF, and a varint will follow with the
+   * true size.
+   */
+  public TSet readSetBegin() throws TException {
+    return new TSet(readListBegin());
+  }
+
+  /**
+   * Read a boolean off the wire. If this is a boolean field, the value should
+   * already have been read during readFieldBegin, so we'll just consume the
+   * pre-stored value. Otherwise, read a byte.
+   */
+  public boolean readBool() throws TException {
+    if (boolValue_ != null) {
+      boolean result = boolValue_.booleanValue();
+      boolValue_ = null;
+      return result;
+    }
+    return readByte() == Types.BOOLEAN_TRUE;
+  }
+
+  byte[] byteRawBuf = new byte[1];
+  /**
+   * Read a single byte off the wire. Nothing interesting here.
+   */
+  public byte readByte() throws TException {
+    byte b;
+    if (trans_.getBytesRemainingInBuffer() > 0) {
+      b = trans_.getBuffer()[trans_.getBufferPosition()];
+      trans_.consumeBuffer(1);
+    } else {
+      trans_.readAll(byteRawBuf, 0, 1);
+      b = byteRawBuf[0];
+    }
+    return b;
+  }
+
+  /**
+   * Read an i16 from the wire as a zigzag varint.
+   */
+  public short readI16() throws TException {
+    return (short)zigzagToInt(readVarint32());
+  }
+
+  /**
+   * Read an i32 from the wire as a zigzag varint.
+   */
+  public int readI32() throws TException {
+    return zigzagToInt(readVarint32());
+  }
+
+  /**
+   * Read an i64 from the wire as a zigzag varint.
+   */
+  public long readI64() throws TException {
+    return zigzagToLong(readVarint64());
+  }
+
+  /**
+   * No magic here - just read a double off the wire.
+   */
+  public double readDouble() throws TException {
+    byte[] longBits = new byte[8];
+    trans_.readAll(longBits, 0, 8);
+    return Double.longBitsToDouble(bytesToLong(longBits));
+  }
+
+  /**
+   * Reads a byte[] (via readBinary), and then UTF-8 decodes it.
+   */
+  public String readString() throws TException {
+    int length = readVarint32();
+    checkReadLength(length);
+
+    if (length == 0) {
+      return "";
+    }
+
+    try {
+      if (trans_.getBytesRemainingInBuffer() >= length) {
+        String str = new String(trans_.getBuffer(), trans_.getBufferPosition(), length, "UTF-8");
+        trans_.consumeBuffer(length);
+        return str;
+      } else {
+        return new String(readBinary(length), "UTF-8");
+      }
+    } catch (UnsupportedEncodingException e) {
+      throw new TException("UTF-8 not supported!");
+    }
+  }
+
+  /**
+   * Read a byte[] from the wire. 
+   */
+  public ByteBuffer readBinary() throws TException {
+    int length = readVarint32();
+    checkReadLength(length);
+    if (length == 0) return ByteBuffer.wrap(new byte[0]);
+
+    byte[] buf = new byte[length];
+    trans_.readAll(buf, 0, length);
+    return ByteBuffer.wrap(buf);
+  }
+
+  /**
+   * Read a byte[] of a known length from the wire. 
+   */
+  private byte[] readBinary(int length) throws TException {
+    if (length == 0) return new byte[0];
+
+    byte[] buf = new byte[length];
+    trans_.readAll(buf, 0, length);
+    return buf;
+  }
+
+  private void checkReadLength(int length) throws TProtocolException {
+    if (length < 0) {
+      throw new TProtocolException("Negative length: " + length);
+    }
+    if (maxNetworkBytes_ != -1 && length > maxNetworkBytes_) {
+      throw new TProtocolException("Length exceeded max allowed: " + length);
+    }
+  }
+
+  //
+  // These methods are here for the struct to call, but don't have any wire 
+  // encoding.
+  //
+  public void readMessageEnd() throws TException {}
+  public void readFieldEnd() throws TException {}
+  public void readMapEnd() throws TException {}
+  public void readListEnd() throws TException {}
+  public void readSetEnd() throws TException {}
+
+  //
+  // Internal reading methods
+  //
+
+  /**
+   * Read an i32 from the wire as a varint. The MSB of each byte is set
+   * if there is another byte to follow. This can read up to 5 bytes.
+   */
+  private int readVarint32() throws TException {
+    int result = 0;
+    int shift = 0;
+    if (trans_.getBytesRemainingInBuffer() >= 5) {
+      byte[] buf = trans_.getBuffer();
+      int pos = trans_.getBufferPosition();
+      int off = 0;
+      while (true) {
+        byte b = buf[pos+off];
+        result |= (int) (b & 0x7f) << shift;
+        if ((b & 0x80) != 0x80) break;
+        shift += 7;
+        off++;
+      }
+      trans_.consumeBuffer(off+1);
+    } else {
+      while (true) {
+        byte b = readByte();
+        result |= (int) (b & 0x7f) << shift;
+        if ((b & 0x80) != 0x80) break;
+        shift += 7;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Read an i64 from the wire as a proper varint. The MSB of each byte is set 
+   * if there is another byte to follow. This can read up to 10 bytes.
+   */
+  private long readVarint64() throws TException {
+    int shift = 0;
+    long result = 0;
+    if (trans_.getBytesRemainingInBuffer() >= 10) {
+      byte[] buf = trans_.getBuffer();
+      int pos = trans_.getBufferPosition();
+      int off = 0;
+      while (true) {
+        byte b = buf[pos+off];
+        result |= (long) (b & 0x7f) << shift;
+        if ((b & 0x80) != 0x80) break;
+        shift += 7;
+        off++;
+      }
+      trans_.consumeBuffer(off+1);
+    } else {
+      while (true) {
+        byte b = readByte();
+        result |= (long) (b & 0x7f) << shift;
+        if ((b & 0x80) != 0x80) break;
+        shift +=7;
+      }
+    }
+    return result;
+  }
+
+  //
+  // encoding helpers
+  //
+
+  /**
+   * Convert from zigzag int to int.
+   */
+  private int zigzagToInt(int n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  /** 
+   * Convert from zigzag long to long.
+   */
+  private long zigzagToLong(long n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  /**
+   * Note that it's important that the mask bytes are long literals, 
+   * otherwise they'll default to ints, and when you shift an int left 56 bits,
+   * you just get a messed up int.
+   */
+  private long bytesToLong(byte[] bytes) {
+    return
+      ((bytes[7] & 0xffL) << 56) |
+      ((bytes[6] & 0xffL) << 48) |
+      ((bytes[5] & 0xffL) << 40) |
+      ((bytes[4] & 0xffL) << 32) |
+      ((bytes[3] & 0xffL) << 24) |
+      ((bytes[2] & 0xffL) << 16) |
+      ((bytes[1] & 0xffL) <<  8) |
+      ((bytes[0] & 0xffL));
+  }
+
+  //
+  // type testing and converting
+  //
+
+  private boolean isBoolType(byte b) {
+    int lowerNibble = b & 0x0f;
+    return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
+  }
+
+  /**
+   * Given a TCompactProtocol.Types constant, convert it to its corresponding 
+   * TType value.
+   */
+  private byte getTType(byte type) throws TProtocolException {
+    switch ((byte)(type & 0x0f)) {
+      case TType.STOP:
+        return TType.STOP;
+      case Types.BOOLEAN_FALSE:
+      case Types.BOOLEAN_TRUE:
+        return TType.BOOL;
+      case Types.BYTE:
+        return TType.BYTE;
+      case Types.I16:
+        return TType.I16;
+      case Types.I32:
+        return TType.I32;
+      case Types.I64:
+        return TType.I64;
+      case Types.DOUBLE:
+        return TType.DOUBLE;
+      case Types.BINARY:
+        return TType.STRING;
+      case Types.LIST:
+        return TType.LIST;
+      case Types.SET:
+        return TType.SET;
+      case Types.MAP:
+        return TType.MAP;
+      case Types.STRUCT:
+        return TType.STRUCT;
+      default:
+        throw new TProtocolException("don't know what type: " + (byte)(type & 0x0f));
+    }
+  }
+
+  /**
+   * Given a TType value, find the appropriate TCompactProtocol.Types constant.
+   */
+  private byte getCompactType(byte ttype) {
+    return ttypeToCompactType[ttype];
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TField.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TField.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TField.java
new file mode 100644
index 0000000..d76c988
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TField.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+/**
+ * Helper class that encapsulates field metadata.
+ *
+ */
+public class TField {
+  public TField() {
+    this("", TType.STOP, (short)0);
+  }
+
+  public TField(String n, byte t, short i) {
+    name = n;
+    type = t;
+    id = i;
+  }
+
+  public final String name;
+  public final byte   type;
+  public final short  id;
+
+  public String toString() {
+    return "<TField name:'" + name + "' type:" + type + " field-id:" + id + ">";
+  }
+
+  public boolean equals(TField otherField) {
+    return type == otherField.type && id == otherField.id;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TJSONProtocol.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TJSONProtocol.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TJSONProtocol.java
new file mode 100644
index 0000000..2878a7b
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TJSONProtocol.java
@@ -0,0 +1,936 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Stack;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.TByteArrayOutputStream;
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+import org.apache.blur.thirdparty.thrift_0_9_0.transport.TTransport;
+
+/**
+ * JSON protocol implementation for thrift.
+ *
+ * This is a full-featured protocol supporting write and read.
+ *
+ * Please see the C++ class header for a detailed description of the
+ * protocol's wire format.
+ *
+ */
+public class TJSONProtocol extends TProtocol {
+
+  /**
+   * Factory for JSON protocol objects
+   */
+  public static class Factory implements TProtocolFactory {
+
+    public TProtocol getProtocol(TTransport trans) {
+      return new TJSONProtocol(trans);
+    }
+
+  }
+
+  private static final byte[] COMMA = new byte[] {','};
+  private static final byte[] COLON = new byte[] {':'};
+  private static final byte[] LBRACE = new byte[] {'{'};
+  private static final byte[] RBRACE = new byte[] {'}'};
+  private static final byte[] LBRACKET = new byte[] {'['};
+  private static final byte[] RBRACKET = new byte[] {']'};
+  private static final byte[] QUOTE = new byte[] {'"'};
+  private static final byte[] BACKSLASH = new byte[] {'\\'};
+  private static final byte[] ZERO = new byte[] {'0'};
+
+  private static final byte[] ESCSEQ = new byte[] {'\\','u','0','0'};
+
+  private static final long  VERSION = 1;
+
+  private static final byte[] JSON_CHAR_TABLE = {
+    /*  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
+    0,  0,  0,  0,  0,  0,  0,  0,'b','t','n',  0,'f','r',  0,  0, // 0
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 1
+    1,  1,'"',  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, // 2
+  };
+
+  private static final String ESCAPE_CHARS = "\"\\bfnrt";
+
+  private static final byte[] ESCAPE_CHAR_VALS = {
+    '"', '\\', '\b', '\f', '\n', '\r', '\t',
+  };
+
+  private static final int  DEF_STRING_SIZE = 16;
+
+  private static final byte[] NAME_BOOL = new byte[] {'t', 'f'};
+  private static final byte[] NAME_BYTE = new byte[] {'i','8'};
+  private static final byte[] NAME_I16 = new byte[] {'i','1','6'};
+  private static final byte[] NAME_I32 = new byte[] {'i','3','2'};
+  private static final byte[] NAME_I64 = new byte[] {'i','6','4'};
+  private static final byte[] NAME_DOUBLE = new byte[] {'d','b','l'};
+  private static final byte[] NAME_STRUCT = new byte[] {'r','e','c'};
+  private static final byte[] NAME_STRING = new byte[] {'s','t','r'};
+  private static final byte[] NAME_MAP = new byte[] {'m','a','p'};
+  private static final byte[] NAME_LIST = new byte[] {'l','s','t'};
+  private static final byte[] NAME_SET = new byte[] {'s','e','t'};
+
+  private static final TStruct ANONYMOUS_STRUCT = new TStruct();
+
+  private static final byte[] getTypeNameForTypeID(byte typeID)
+    throws TException {
+    switch (typeID) {
+    case TType.BOOL:
+      return NAME_BOOL;
+    case TType.BYTE:
+      return NAME_BYTE;
+    case TType.I16:
+      return NAME_I16;
+    case TType.I32:
+      return NAME_I32;
+    case TType.I64:
+      return NAME_I64;
+    case TType.DOUBLE:
+      return NAME_DOUBLE;
+    case TType.STRING:
+      return NAME_STRING;
+    case TType.STRUCT:
+      return NAME_STRUCT;
+    case TType.MAP:
+      return NAME_MAP;
+    case TType.SET:
+      return NAME_SET;
+    case TType.LIST:
+      return NAME_LIST;
+    default:
+      throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+                                   "Unrecognized type");
+    }
+  }
+
+  private static final byte getTypeIDForTypeName(byte[] name)
+    throws TException {
+    byte result = TType.STOP;
+    if (name.length > 1) {
+      switch (name[0]) {
+      case 'd':
+        result = TType.DOUBLE;
+        break;
+      case 'i':
+        switch (name[1]) {
+        case '8':
+          result = TType.BYTE;
+          break;
+        case '1':
+          result = TType.I16;
+          break;
+        case '3':
+          result = TType.I32;
+          break;
+        case '6':
+          result = TType.I64;
+          break;
+        }
+        break;
+      case 'l':
+        result = TType.LIST;
+        break;
+      case 'm':
+        result = TType.MAP;
+        break;
+      case 'r':
+        result = TType.STRUCT;
+        break;
+      case 's':
+        if (name[1] == 't') {
+          result = TType.STRING;
+        }
+        else if (name[1] == 'e') {
+          result = TType.SET;
+        }
+        break;
+      case 't':
+        result = TType.BOOL;
+        break;
+      }
+    }
+    if (result == TType.STOP) {
+      throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+                                   "Unrecognized type");
+    }
+    return result;
+  }
+
+  // Base class for tracking JSON contexts that may require inserting/reading
+  // additional JSON syntax characters
+  // This base context does nothing.
+  protected class JSONBaseContext {
+    protected void write() throws TException {}
+
+    protected void read() throws TException {}
+
+    protected boolean escapeNum() { return false; }
+  }
+
+  // Context for JSON lists. Will insert/read commas before each item except
+  // for the first one
+  protected class JSONListContext extends JSONBaseContext {
+    private boolean first_ = true;
+
+    @Override
+    protected void write() throws TException {
+      if (first_) {
+        first_ = false;
+      } else {
+        trans_.write(COMMA);
+      }
+    }
+
+    @Override
+    protected void read() throws TException {
+      if (first_) {
+        first_ = false;
+      } else {
+        readJSONSyntaxChar(COMMA);
+      }
+    }
+  }
+
+  // Context for JSON records. Will insert/read colons before the value portion
+  // of each record pair, and commas before each key except the first. In
+  // addition, will indicate that numbers in the key position need to be
+  // escaped in quotes (since JSON keys must be strings).
+  protected class JSONPairContext extends JSONBaseContext {
+    private boolean first_ = true;
+    private boolean colon_ = true;
+
+    @Override
+    protected void write() throws TException {
+      if (first_) {
+        first_ = false;
+        colon_ = true;
+      } else {
+        trans_.write(colon_ ? COLON : COMMA);
+        colon_ = !colon_;
+      }
+    }
+
+    @Override
+    protected void read() throws TException {
+      if (first_) {
+        first_ = false;
+        colon_ = true;
+      } else {
+        readJSONSyntaxChar(colon_ ? COLON : COMMA);
+        colon_ = !colon_;
+      }
+    }
+
+    @Override
+    protected boolean escapeNum() {
+      return colon_;
+    }
+  }
+
+  // Holds up to one byte from the transport
+  protected class LookaheadReader {
+
+    private boolean hasData_;
+    private byte[] data_ = new byte[1];
+
+    // Return and consume the next byte to be read, either taking it from the
+    // data buffer if present or getting it from the transport otherwise.
+    protected byte read() throws TException {
+      if (hasData_) {
+        hasData_ = false;
+      }
+      else {
+        trans_.readAll(data_, 0, 1);
+      }
+      return data_[0];
+    }
+
+    // Return the next byte to be read without consuming, filling the data
+    // buffer if it has not been filled already.
+    protected byte peek() throws TException {
+      if (!hasData_) {
+        trans_.readAll(data_, 0, 1);
+      }
+      hasData_ = true;
+      return data_[0];
+    }
+  }
+
+  // Stack of nested contexts that we may be in
+  private Stack<JSONBaseContext> contextStack_ = new Stack<JSONBaseContext>();
+
+  // Current context that we are in
+  private JSONBaseContext context_ = new JSONBaseContext();
+
+  // Reader that manages a 1-byte buffer
+  private LookaheadReader reader_ = new LookaheadReader();
+
+  // Push a new JSON context onto the stack.
+  private void pushContext(JSONBaseContext c) {
+    contextStack_.push(context_);
+    context_ = c;
+  }
+
+  // Pop the last JSON context off the stack
+  private void popContext() {
+    context_ = contextStack_.pop();
+  }
+
+  /**
+   * Constructor
+   */
+  public TJSONProtocol(TTransport trans) {
+    super(trans);
+  }
+
+  @Override
+  public void reset() {
+    contextStack_.clear();
+    context_ = new JSONBaseContext();
+    reader_ = new LookaheadReader();
+  }
+
+  // Temporary buffer used by several methods
+  private byte[] tmpbuf_ = new byte[4];
+
+  // Read a byte that must match b[0]; otherwise an exception is thrown.
+  // Marked protected to avoid synthetic accessor in JSONListContext.read
+  // and JSONPairContext.read
+  protected void readJSONSyntaxChar(byte[] b) throws TException {
+    byte ch = reader_.read();
+    if (ch != b[0]) {
+      throw new TProtocolException(TProtocolException.INVALID_DATA,
+                                   "Unexpected character:" + (char)ch);
+    }
+  }
+
+  // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its
+  // corresponding hex value
+  private static final byte hexVal(byte ch) throws TException {
+    if ((ch >= '0') && (ch <= '9')) {
+      return (byte)((char)ch - '0');
+    }
+    else if ((ch >= 'a') && (ch <= 'f')) {
+      return (byte)((char)ch - 'a' + 10);
+    }
+    else {
+      throw new TProtocolException(TProtocolException.INVALID_DATA,
+                                   "Expected hex character");
+    }
+  }
+
+  // Convert a byte containing a hex value to its corresponding hex character
+  private static final byte hexChar(byte val) {
+    val &= 0x0F;
+    if (val < 10) {
+      return (byte)((char)val + '0');
+    }
+    else {
+      return (byte)((char)(val - 10) + 'a');
+    }
+  }
+
+  // Write the bytes in array buf as a JSON characters, escaping as needed
+  private void writeJSONString(byte[] b) throws TException {
+    context_.write();
+    trans_.write(QUOTE);
+    int len = b.length;
+    for (int i = 0; i < len; i++) {
+      if ((b[i] & 0x00FF) >= 0x30) {
+        if (b[i] == BACKSLASH[0]) {
+          trans_.write(BACKSLASH);
+          trans_.write(BACKSLASH);
+        }
+        else {
+          trans_.write(b, i, 1);
+        }
+      }
+      else {
+        tmpbuf_[0] = JSON_CHAR_TABLE[b[i]];
+        if (tmpbuf_[0] == 1) {
+          trans_.write(b, i, 1);
+        }
+        else if (tmpbuf_[0] > 1) {
+          trans_.write(BACKSLASH);
+          trans_.write(tmpbuf_, 0, 1);
+        }
+        else {
+          trans_.write(ESCSEQ);
+          tmpbuf_[0] = hexChar((byte)(b[i] >> 4));
+          tmpbuf_[1] = hexChar(b[i]);
+          trans_.write(tmpbuf_, 0, 2);
+        }
+      }
+    }
+    trans_.write(QUOTE);
+  }
+
+  // Write out number as a JSON value. If the context dictates so, it will be
+  // wrapped in quotes to output as a JSON string.
+  private void writeJSONInteger(long num) throws TException {
+    context_.write();
+    String str = Long.toString(num);
+    boolean escapeNum = context_.escapeNum();
+    if (escapeNum) {
+      trans_.write(QUOTE);
+    }
+    try {
+      byte[] buf = str.getBytes("UTF-8");
+      trans_.write(buf);
+    } catch (UnsupportedEncodingException uex) {
+      throw new TException("JVM DOES NOT SUPPORT UTF-8");
+    }
+    if (escapeNum) {
+      trans_.write(QUOTE);
+    }
+  }
+
+  // Write out a double as a JSON value. If it is NaN or infinity or if the
+  // context dictates escaping, write out as JSON string.
+  private void writeJSONDouble(double num) throws TException {
+    context_.write();
+    String str = Double.toString(num);
+    boolean special = false;
+    switch (str.charAt(0)) {
+    case 'N': // NaN
+    case 'I': // Infinity
+      special = true;
+      break;
+    case '-':
+      if (str.charAt(1) == 'I') { // -Infinity
+        special = true;
+      }
+      break;
+    }
+
+    boolean escapeNum = special || context_.escapeNum();
+    if (escapeNum) {
+      trans_.write(QUOTE);
+    }
+    try {
+      byte[] b = str.getBytes("UTF-8");
+      trans_.write(b, 0, b.length);
+    } catch (UnsupportedEncodingException uex) {
+      throw new TException("JVM DOES NOT SUPPORT UTF-8");
+    }
+    if (escapeNum) {
+      trans_.write(QUOTE);
+    }
+  }
+
+  // Write out contents of byte array b as a JSON string with base-64 encoded
+  // data
+  private void writeJSONBase64(byte[] b, int offset, int length) throws TException {
+    context_.write();
+    trans_.write(QUOTE);
+    int len = length;
+    int off = offset;
+    while (len >= 3) {
+      // Encode 3 bytes at a time
+      TBase64Utils.encode(b, off, 3, tmpbuf_, 0);
+      trans_.write(tmpbuf_, 0, 4);
+      off += 3;
+      len -= 3;
+    }
+    if (len > 0) {
+      // Encode remainder
+      TBase64Utils.encode(b, off, len, tmpbuf_, 0);
+      trans_.write(tmpbuf_, 0, len + 1);
+    }
+    trans_.write(QUOTE);
+  }
+
+  private void writeJSONObjectStart() throws TException {
+    context_.write();
+    trans_.write(LBRACE);
+    pushContext(new JSONPairContext());
+  }
+
+  private void writeJSONObjectEnd() throws TException {
+    popContext();
+    trans_.write(RBRACE);
+  }
+
+  private void writeJSONArrayStart() throws TException {
+    context_.write();
+    trans_.write(LBRACKET);
+    pushContext(new JSONListContext());
+  }
+
+  private void writeJSONArrayEnd() throws TException {
+    popContext();
+    trans_.write(RBRACKET);
+  }
+
+  @Override
+  public void writeMessageBegin(TMessage message) throws TException {
+    writeJSONArrayStart();
+    writeJSONInteger(VERSION);
+    try {
+      byte[] b = message.name.getBytes("UTF-8");
+      writeJSONString(b);
+    } catch (UnsupportedEncodingException uex) {
+      throw new TException("JVM DOES NOT SUPPORT UTF-8");
+    }
+    writeJSONInteger(message.type);
+    writeJSONInteger(message.seqid);
+  }
+
+  @Override
+  public void writeMessageEnd() throws TException {
+    writeJSONArrayEnd();
+  }
+
+  @Override
+  public void writeStructBegin(TStruct struct) throws TException {
+    writeJSONObjectStart();
+  }
+
+  @Override
+  public void writeStructEnd() throws TException {
+    writeJSONObjectEnd();
+  }
+
+  @Override
+  public void writeFieldBegin(TField field) throws TException {
+    writeJSONInteger(field.id);
+    writeJSONObjectStart();
+    writeJSONString(getTypeNameForTypeID(field.type));
+  }
+
+  @Override
+  public void writeFieldEnd() throws TException {
+    writeJSONObjectEnd();
+  }
+
+  @Override
+  public void writeFieldStop() {}
+
+  @Override
+  public void writeMapBegin(TMap map) throws TException {
+    writeJSONArrayStart();
+    writeJSONString(getTypeNameForTypeID(map.keyType));
+    writeJSONString(getTypeNameForTypeID(map.valueType));
+    writeJSONInteger(map.size);
+    writeJSONObjectStart();
+  }
+
+  @Override
+  public void writeMapEnd() throws TException {
+    writeJSONObjectEnd();
+    writeJSONArrayEnd();
+  }
+
+  @Override
+  public void writeListBegin(TList list) throws TException {
+    writeJSONArrayStart();
+    writeJSONString(getTypeNameForTypeID(list.elemType));
+    writeJSONInteger(list.size);
+  }
+
+  @Override
+  public void writeListEnd() throws TException {
+    writeJSONArrayEnd();
+  }
+
+  @Override
+  public void writeSetBegin(TSet set) throws TException {
+    writeJSONArrayStart();
+    writeJSONString(getTypeNameForTypeID(set.elemType));
+    writeJSONInteger(set.size);
+  }
+
+  @Override
+  public void writeSetEnd() throws TException {
+    writeJSONArrayEnd();
+  }
+
+  @Override
+  public void writeBool(boolean b) throws TException {
+    writeJSONInteger(b ? (long)1 : (long)0);
+  }
+
+  @Override
+  public void writeByte(byte b) throws TException {
+    writeJSONInteger((long)b);
+  }
+
+  @Override
+  public void writeI16(short i16) throws TException {
+    writeJSONInteger((long)i16);
+  }
+
+  @Override
+  public void writeI32(int i32) throws TException {
+    writeJSONInteger((long)i32);
+  }
+
+  @Override
+  public void writeI64(long i64) throws TException {
+    writeJSONInteger(i64);
+  }
+
+  @Override
+  public void writeDouble(double dub) throws TException {
+    writeJSONDouble(dub);
+  }
+
+  @Override
+  public void writeString(String str) throws TException {
+    try {
+      byte[] b = str.getBytes("UTF-8");
+      writeJSONString(b);
+    } catch (UnsupportedEncodingException uex) {
+      throw new TException("JVM DOES NOT SUPPORT UTF-8");
+    }
+  }
+
+  @Override
+  public void writeBinary(ByteBuffer bin) throws TException {
+    writeJSONBase64(bin.array(), bin.position() + bin.arrayOffset(), bin.limit() - bin.position() - bin.arrayOffset());
+  }
+
+  /**
+   * Reading methods.
+   */
+
+  // Read in a JSON string, unescaping as appropriate.. Skip reading from the
+  // context if skipContext is true.
+  private TByteArrayOutputStream readJSONString(boolean skipContext)
+    throws TException {
+    TByteArrayOutputStream arr = new TByteArrayOutputStream(DEF_STRING_SIZE);
+    if (!skipContext) {
+      context_.read();
+    }
+    readJSONSyntaxChar(QUOTE);
+    while (true) {
+      byte ch = reader_.read();
+      if (ch == QUOTE[0]) {
+        break;
+      }
+      if (ch == ESCSEQ[0]) {
+        ch = reader_.read();
+        if (ch == ESCSEQ[1]) {
+          readJSONSyntaxChar(ZERO);
+          readJSONSyntaxChar(ZERO);
+          trans_.readAll(tmpbuf_, 0, 2);
+          ch = (byte)((hexVal((byte)tmpbuf_[0]) << 4) + hexVal(tmpbuf_[1]));
+        }
+        else {
+          int off = ESCAPE_CHARS.indexOf(ch);
+          if (off == -1) {
+            throw new TProtocolException(TProtocolException.INVALID_DATA,
+                                         "Expected control char");
+          }
+          ch = ESCAPE_CHAR_VALS[off];
+        }
+      }
+      arr.write(ch);
+    }
+    return arr;
+  }
+
+  // Return true if the given byte could be a valid part of a JSON number.
+  private boolean isJSONNumeric(byte b) {
+    switch (b) {
+    case '+':
+    case '-':
+    case '.':
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+    case 'E':
+    case 'e':
+      return true;
+    }
+    return false;
+  }
+
+  // Read in a sequence of characters that are all valid in JSON numbers. Does
+  // not do a complete regex check to validate that this is actually a number.
+  private String readJSONNumericChars() throws TException {
+    StringBuilder strbld = new StringBuilder();
+    while (true) {
+      byte ch = reader_.peek();
+      if (!isJSONNumeric(ch)) {
+        break;
+      }
+      strbld.append((char)reader_.read());
+    }
+    return strbld.toString();
+  }
+
+  // Read in a JSON number. If the context dictates, read in enclosing quotes.
+  private long readJSONInteger() throws TException {
+    context_.read();
+    if (context_.escapeNum()) {
+      readJSONSyntaxChar(QUOTE);
+    }
+    String str = readJSONNumericChars();
+    if (context_.escapeNum()) {
+      readJSONSyntaxChar(QUOTE);
+    }
+    try {
+      return Long.valueOf(str);
+    }
+    catch (NumberFormatException ex) {
+      throw new TProtocolException(TProtocolException.INVALID_DATA,
+                                   "Bad data encounted in numeric data");
+    }
+  }
+
+  // Read in a JSON double value. Throw if the value is not wrapped in quotes
+  // when expected or if wrapped in quotes when not expected.
+  private double readJSONDouble() throws TException {
+    context_.read();
+    if (reader_.peek() == QUOTE[0]) {
+      TByteArrayOutputStream arr = readJSONString(true);
+      try {
+        double dub = Double.valueOf(arr.toString("UTF-8"));
+        if (!context_.escapeNum() && !Double.isNaN(dub) &&
+            !Double.isInfinite(dub)) {
+          // Throw exception -- we should not be in a string in this case
+          throw new TProtocolException(TProtocolException.INVALID_DATA,
+                                       "Numeric data unexpectedly quoted");
+        }
+        return dub;
+      }
+      catch (UnsupportedEncodingException ex) {
+        throw new TException("JVM DOES NOT SUPPORT UTF-8");
+      }
+    }
+    else {
+      if (context_.escapeNum()) {
+        // This will throw - we should have had a quote if escapeNum == true
+        readJSONSyntaxChar(QUOTE);
+      }
+      try {
+        return Double.valueOf(readJSONNumericChars());
+      }
+      catch (NumberFormatException ex) {
+        throw new TProtocolException(TProtocolException.INVALID_DATA,
+                                     "Bad data encounted in numeric data");
+      }
+    }
+  }
+
+  // Read in a JSON string containing base-64 encoded data and decode it.
+  private byte[] readJSONBase64() throws TException {
+    TByteArrayOutputStream arr = readJSONString(false);
+    byte[] b = arr.get();
+    int len = arr.len();
+    int off = 0;
+    int size = 0;
+    while (len >= 4) {
+      // Decode 4 bytes at a time
+      TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place
+      off += 4;
+      len -= 4;
+      size += 3;
+    }
+    // Don't decode if we hit the end or got a single leftover byte (invalid
+    // base64 but legal for skip of regular string type)
+    if (len > 1) {
+      // Decode remainder
+      TBase64Utils.decode(b, off, len, b, size); // NB: decoded in place
+      size += len - 1;
+    }
+    // Sadly we must copy the byte[] (any way around this?)
+    byte [] result = new byte[size];
+    System.arraycopy(b, 0, result, 0, size);
+    return result;
+  }
+
+  private void readJSONObjectStart() throws TException {
+    context_.read();
+    readJSONSyntaxChar(LBRACE);
+    pushContext(new JSONPairContext());
+  }
+
+  private void readJSONObjectEnd() throws TException {
+    readJSONSyntaxChar(RBRACE);
+    popContext();
+  }
+
+  private void readJSONArrayStart() throws TException {
+    context_.read();
+    readJSONSyntaxChar(LBRACKET);
+    pushContext(new JSONListContext());
+  }
+
+  private void readJSONArrayEnd() throws TException {
+    readJSONSyntaxChar(RBRACKET);
+    popContext();
+  }
+
+  @Override
+  public TMessage readMessageBegin() throws TException {
+    readJSONArrayStart();
+    if (readJSONInteger() != VERSION) {
+      throw new TProtocolException(TProtocolException.BAD_VERSION,
+                                   "Message contained bad version.");
+    }
+    String name;
+    try {
+      name = readJSONString(false).toString("UTF-8");
+    }
+    catch (UnsupportedEncodingException ex) {
+      throw new TException("JVM DOES NOT SUPPORT UTF-8");
+    }
+    byte type = (byte) readJSONInteger();
+    int seqid = (int) readJSONInteger();
+    return new TMessage(name, type, seqid);
+  }
+
+  @Override
+  public void readMessageEnd() throws TException {
+    readJSONArrayEnd();
+  }
+
+  @Override
+  public TStruct readStructBegin() throws TException {
+    readJSONObjectStart();
+    return ANONYMOUS_STRUCT;
+  }
+
+  @Override
+  public void readStructEnd() throws TException {
+    readJSONObjectEnd();
+  }
+
+  @Override
+  public TField readFieldBegin() throws TException {
+    byte ch = reader_.peek();
+    byte type;
+    short id = 0;
+    if (ch == RBRACE[0]) {
+      type = TType.STOP;
+    }
+    else {
+      id = (short) readJSONInteger();
+      readJSONObjectStart();
+      type = getTypeIDForTypeName(readJSONString(false).get());
+    }
+    return new TField("", type, id);
+  }
+
+  @Override
+  public void readFieldEnd() throws TException {
+    readJSONObjectEnd();
+  }
+
+  @Override
+  public TMap readMapBegin() throws TException {
+    readJSONArrayStart();
+    byte keyType = getTypeIDForTypeName(readJSONString(false).get());
+    byte valueType = getTypeIDForTypeName(readJSONString(false).get());
+    int size = (int)readJSONInteger();
+    readJSONObjectStart();
+    return new TMap(keyType, valueType, size);
+  }
+
+  @Override
+  public void readMapEnd() throws TException {
+    readJSONObjectEnd();
+    readJSONArrayEnd();
+  }
+
+  @Override
+  public TList readListBegin() throws TException {
+    readJSONArrayStart();
+    byte elemType = getTypeIDForTypeName(readJSONString(false).get());
+    int size = (int)readJSONInteger();
+    return new TList(elemType, size);
+  }
+
+  @Override
+  public void readListEnd() throws TException {
+    readJSONArrayEnd();
+  }
+
+  @Override
+  public TSet readSetBegin() throws TException {
+    readJSONArrayStart();
+    byte elemType = getTypeIDForTypeName(readJSONString(false).get());
+    int size = (int)readJSONInteger();
+    return new TSet(elemType, size);
+  }
+
+  @Override
+  public void readSetEnd() throws TException {
+    readJSONArrayEnd();
+  }
+
+  @Override
+  public boolean readBool() throws TException {
+    return (readJSONInteger() == 0 ? false : true);
+  }
+
+  @Override
+  public byte readByte() throws TException {
+    return (byte) readJSONInteger();
+  }
+
+  @Override
+  public short readI16() throws TException {
+    return (short) readJSONInteger();
+  }
+
+  @Override
+  public int readI32() throws TException {
+    return (int) readJSONInteger();
+  }
+
+  @Override
+  public long readI64() throws TException {
+    return (long) readJSONInteger();
+  }
+
+  @Override
+  public double readDouble() throws TException {
+    return readJSONDouble();
+  }
+
+  @Override
+  public String readString() throws TException {
+    try {
+      return readJSONString(false).toString("UTF-8");
+    }
+    catch (UnsupportedEncodingException ex) {
+      throw new TException("JVM DOES NOT SUPPORT UTF-8");
+    }
+  }
+
+  @Override
+  public ByteBuffer readBinary() throws TException {
+    return ByteBuffer.wrap(readJSONBase64());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TList.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TList.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TList.java
new file mode 100644
index 0000000..f986187
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TList.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+/**
+ * Helper class that encapsulates list metadata.
+ *
+ */
+public final class TList {
+  public TList() {
+    this(TType.STOP, 0);
+  }
+
+  public TList(byte t, int s) {
+    elemType = t;
+    size = s;
+  }
+
+  public final byte elemType;
+  public final int  size;
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMap.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMap.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMap.java
new file mode 100644
index 0000000..9a22bd2
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMap.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+/**
+ * Helper class that encapsulates map metadata.
+ *
+ */
+public final class TMap {
+  public TMap() {
+    this(TType.STOP, TType.STOP, 0);
+  }
+
+  public TMap(byte k, byte v, int s) {
+    keyType = k;
+    valueType = v;
+    size = s;
+  }
+
+  public final byte  keyType;
+  public final byte  valueType;
+  public final int   size;
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessage.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessage.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessage.java
new file mode 100644
index 0000000..cc94af7
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessage.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+/**
+ * Helper class that encapsulates struct metadata.
+ *
+ */
+public final class TMessage {
+  public TMessage() {
+    this("", TType.STOP, 0);
+  }
+
+  public TMessage(String n, byte t, int s) {
+    name = n;
+    type = t;
+    seqid = s;
+  }
+
+  public final String name;
+  public final byte type;
+  public final int seqid;
+
+  @Override
+  public String toString() {
+    return "<TMessage name:'" + name + "' type: " + type + " seqid:" + seqid + ">";
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (other instanceof TMessage) {
+      return equals((TMessage) other);
+    }
+    return false;
+  }
+
+  public boolean equals(TMessage other) {
+    return name.equals(other.name) && type == other.type && seqid == other.seqid;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessageType.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessageType.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessageType.java
new file mode 100644
index 0000000..be4ebd8
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TMessageType.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+/**
+ * Message type constants in the Thrift protocol.
+ *
+ */
+public final class TMessageType {
+  public static final byte CALL  = 1;
+  public static final byte REPLY = 2;
+  public static final byte EXCEPTION = 3;
+  public static final byte ONEWAY = 4;
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocol.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocol.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocol.java
new file mode 100644
index 0000000..41531f5
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocol.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+import java.nio.ByteBuffer;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+import org.apache.blur.thirdparty.thrift_0_9_0.scheme.IScheme;
+import org.apache.blur.thirdparty.thrift_0_9_0.scheme.StandardScheme;
+import org.apache.blur.thirdparty.thrift_0_9_0.transport.TTransport;
+
+/**
+ * Protocol interface definition.
+ *
+ */
+public abstract class TProtocol {
+
+  /**
+   * Prevent direct instantiation
+   */
+  @SuppressWarnings("unused")
+  private TProtocol() {}
+
+  /**
+   * Transport
+   */
+  protected TTransport trans_;
+
+  /**
+   * Constructor
+   */
+  protected TProtocol(TTransport trans) {
+    trans_ = trans;
+  }
+
+  /**
+   * Transport accessor
+   */
+  public TTransport getTransport() {
+    return trans_;
+  }
+
+  /**
+   * Writing methods.
+   */
+
+  public abstract void writeMessageBegin(TMessage message) throws TException;
+
+  public abstract void writeMessageEnd() throws TException;
+
+  public abstract void writeStructBegin(TStruct struct) throws TException;
+
+  public abstract void writeStructEnd() throws TException;
+
+  public abstract void writeFieldBegin(TField field) throws TException;
+
+  public abstract void writeFieldEnd() throws TException;
+
+  public abstract void writeFieldStop() throws TException;
+
+  public abstract void writeMapBegin(TMap map) throws TException;
+
+  public abstract void writeMapEnd() throws TException;
+
+  public abstract void writeListBegin(TList list) throws TException;
+
+  public abstract void writeListEnd() throws TException;
+
+  public abstract void writeSetBegin(TSet set) throws TException;
+
+  public abstract void writeSetEnd() throws TException;
+
+  public abstract void writeBool(boolean b) throws TException;
+
+  public abstract void writeByte(byte b) throws TException;
+
+  public abstract void writeI16(short i16) throws TException;
+
+  public abstract void writeI32(int i32) throws TException;
+
+  public abstract void writeI64(long i64) throws TException;
+
+  public abstract void writeDouble(double dub) throws TException;
+
+  public abstract void writeString(String str) throws TException;
+
+  public abstract void writeBinary(ByteBuffer buf) throws TException;
+
+  /**
+   * Reading methods.
+   */
+
+  public abstract TMessage readMessageBegin() throws TException;
+
+  public abstract void readMessageEnd() throws TException;
+
+  public abstract TStruct readStructBegin() throws TException;
+
+  public abstract void readStructEnd() throws TException;
+
+  public abstract TField readFieldBegin() throws TException;
+
+  public abstract void readFieldEnd() throws TException;
+
+  public abstract TMap readMapBegin() throws TException;
+
+  public abstract void readMapEnd() throws TException;
+
+  public abstract TList readListBegin() throws TException;
+
+  public abstract void readListEnd() throws TException;
+
+  public abstract TSet readSetBegin() throws TException;
+
+  public abstract void readSetEnd() throws TException;
+
+  public abstract boolean readBool() throws TException;
+
+  public abstract byte readByte() throws TException;
+
+  public abstract short readI16() throws TException;
+
+  public abstract int readI32() throws TException;
+
+  public abstract long readI64() throws TException;
+
+  public abstract double readDouble() throws TException;
+
+  public abstract String readString() throws TException;
+
+  public abstract ByteBuffer readBinary() throws TException;
+
+  /**
+   * Reset any internal state back to a blank slate. This method only needs to
+   * be implemented for stateful protocols.
+   */
+  public void reset() {}
+  
+  /**
+   * Scheme accessor
+   */
+  public Class<? extends IScheme> getScheme() {
+    return StandardScheme.class;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolException.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolException.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolException.java
new file mode 100644
index 0000000..3163b19
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolException.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+
+/**
+ * Protocol exceptions.
+ *
+ */
+public class TProtocolException extends TException {
+
+
+  private static final long serialVersionUID = 1L;
+  public static final int UNKNOWN = 0;
+  public static final int INVALID_DATA = 1;
+  public static final int NEGATIVE_SIZE = 2;
+  public static final int SIZE_LIMIT = 3;
+  public static final int BAD_VERSION = 4;
+  public static final int NOT_IMPLEMENTED = 5;
+
+  protected int type_ = UNKNOWN;
+
+  public TProtocolException() {
+    super();
+  }
+
+  public TProtocolException(int type) {
+    super();
+    type_ = type;
+  }
+
+  public TProtocolException(int type, String message) {
+    super(message);
+    type_ = type;
+  }
+
+  public TProtocolException(String message) {
+    super(message);
+  }
+
+  public TProtocolException(int type, Throwable cause) {
+    super(cause);
+    type_ = type;
+  }
+
+  public TProtocolException(Throwable cause) {
+    super(cause);
+  }
+
+  public TProtocolException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public TProtocolException(int type, String message, Throwable cause) {
+    super(message, cause);
+    type_ = type;
+  }
+
+  public int getType() {
+    return type_;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolFactory.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolFactory.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolFactory.java
new file mode 100644
index 0000000..52a7dd8
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+import java.io.Serializable;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.transport.TTransport;
+
+/**
+ * Factory interface for constructing protocol instances.
+ */
+public interface TProtocolFactory extends Serializable {
+  public TProtocol getProtocol(TTransport trans);
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolUtil.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolUtil.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolUtil.java
new file mode 100644
index 0000000..335818d
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TProtocolUtil.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+
+/**
+ * Utility class with static methods for interacting with protocol data
+ * streams.
+ *
+ */
+public class TProtocolUtil {
+
+  /**
+   * The maximum recursive depth the skip() function will traverse before
+   * throwing a TException.
+   */
+  private static int maxSkipDepth = Integer.MAX_VALUE;
+
+  /**
+   * Specifies the maximum recursive depth that the skip function will
+   * traverse before throwing a TException.  This is a global setting, so
+   * any call to skip in this JVM will enforce this value.
+   *
+   * @param depth  the maximum recursive depth.  A value of 2 would allow
+   *    the skip function to skip a structure or collection with basic children,
+   *    but it would not permit skipping a struct that had a field containing
+   *    a child struct.  A value of 1 would only allow skipping of simple
+   *    types and empty structs/collections.
+   */
+  public static void setMaxSkipDepth(int depth) {
+    maxSkipDepth = depth;
+  }
+
+  /**
+   * Skips over the next data element from the provided input TProtocol object.
+   *
+   * @param prot  the protocol object to read from
+   * @param type  the next value will be interpreted as this TType value.
+   */
+  public static void skip(TProtocol prot, byte type)
+    throws TException {
+    skip(prot, type, maxSkipDepth);
+  }
+
+  /**
+   * Skips over the next data element from the provided input TProtocol object.
+   *
+   * @param prot  the protocol object to read from
+   * @param type  the next value will be interpreted as this TType value.
+   * @param maxDepth  this function will only skip complex objects to this
+   *   recursive depth, to prevent Java stack overflow.
+   */
+  public static void skip(TProtocol prot, byte type, int maxDepth)
+  throws TException {
+    if (maxDepth <= 0) {
+      throw new TException("Maximum skip depth exceeded");
+    }
+    switch (type) {
+      case TType.BOOL:
+        prot.readBool();
+        break;
+
+      case TType.BYTE:
+        prot.readByte();
+        break;
+
+      case TType.I16:
+        prot.readI16();
+        break;
+
+      case TType.I32:
+        prot.readI32();
+        break;
+
+      case TType.I64:
+        prot.readI64();
+        break;
+
+      case TType.DOUBLE:
+        prot.readDouble();
+        break;
+
+      case TType.STRING:
+        prot.readBinary();
+        break;
+
+      case TType.STRUCT:
+        prot.readStructBegin();
+        while (true) {
+          TField field = prot.readFieldBegin();
+          if (field.type == TType.STOP) {
+            break;
+          }
+          skip(prot, field.type, maxDepth - 1);
+          prot.readFieldEnd();
+        }
+        prot.readStructEnd();
+        break;
+
+      case TType.MAP:
+        TMap map = prot.readMapBegin();
+        for (int i = 0; i < map.size; i++) {
+          skip(prot, map.keyType, maxDepth - 1);
+          skip(prot, map.valueType, maxDepth - 1);
+        }
+        prot.readMapEnd();
+        break;
+
+      case TType.SET:
+        TSet set = prot.readSetBegin();
+        for (int i = 0; i < set.size; i++) {
+          skip(prot, set.elemType, maxDepth - 1);
+        }
+        prot.readSetEnd();
+        break;
+
+      case TType.LIST:
+        TList list = prot.readListBegin();
+        for (int i = 0; i < list.size; i++) {
+          skip(prot, list.elemType, maxDepth - 1);
+        }
+        prot.readListEnd();
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  /**
+   * Attempt to determine the protocol used to serialize some data.
+   *
+   * The guess is based on known specificities of supported protocols.
+   * In some cases, no guess can be done, in that case we return the
+   * fallback TProtocolFactory.
+   * To be certain to correctly detect the protocol, the first encoded
+   * field should have a field id < 256
+   *
+   * @param data The serialized data to guess the protocol for.
+   * @param fallback The TProtocol to return if no guess can be made.
+   * @return a Class implementing TProtocolFactory which can be used to create a deserializer.
+   */
+  public static TProtocolFactory guessProtocolFactory(byte[] data, TProtocolFactory fallback) {
+    //
+    // If the first and last bytes are opening/closing curly braces we guess the protocol as
+    // being TJSONProtocol.
+    // It could not be a TCompactBinary encoding for a field of type 0xb (Map)
+    // with delta id 7 as the last byte for TCompactBinary is always 0.
+    //
+
+    if ('{' == data[0] && '}' == data[data.length - 1]) {
+      return new TJSONProtocol.Factory();
+    }
+
+    //
+    // If the last byte is not 0, then it cannot be TCompactProtocol, it must be
+    // TBinaryProtocol.
+    //
+
+    if (data[data.length - 1] != 0) {
+      return new TBinaryProtocol.Factory();
+    }
+
+    //
+    // A first byte of value > 16 indicates TCompactProtocol was used, and the first byte
+    // encodes a delta field id (id <= 15) and a field type.
+    //
+
+    if (data[0] > 0x10) {
+      return new TCompactProtocol.Factory();
+    }
+
+    //
+    // If the second byte is 0 then it is a field id < 256 encoded by TBinaryProtocol.
+    // It cannot possibly be TCompactProtocol since a value of 0 would imply a field id
+    // of 0 as the zig zag varint encoding would end.
+    //
+
+    if (data.length > 1 && 0 == data[1]) {
+      return new TBinaryProtocol.Factory();
+    }
+
+    //
+    // If bit 7 of the first byte of the field id is set then we have two choices:
+    // 1. A field id > 63 was encoded with TCompactProtocol.
+    // 2. A field id > 0x7fff (32767) was encoded with TBinaryProtocol and the last byte of the
+    //    serialized data is 0.
+    // Option 2 is impossible since field ids are short and thus limited to 32767.
+    //
+
+    if (data.length > 1 && (data[1] & 0x80) != 0) {
+      return new TCompactProtocol.Factory();
+    }
+
+    //
+    // The remaining case is either a field id <= 63 encoded as TCompactProtocol,
+    // one >= 256 encoded with TBinaryProtocol with a last byte at 0, or an empty structure.
+    // As we cannot really decide, we return the fallback protocol.
+    //
+    return fallback;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0e26648/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TSet.java
----------------------------------------------------------------------
diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TSet.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TSet.java
new file mode 100644
index 0000000..116887d
--- /dev/null
+++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/protocol/TSet.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.blur.thirdparty.thrift_0_9_0.protocol;
+
+/**
+ * Helper class that encapsulates set metadata.
+ *
+ */
+public final class TSet {
+  public TSet() {
+    this(TType.STOP, 0);
+  }
+
+  public TSet(byte t, int s) {
+    elemType = t;
+    size = s;
+  }
+
+  public TSet(TList list) {
+    this(list.elemType, list.size);
+  }
+
+  public final byte elemType;
+  public final int  size;
+}


Mime
View raw message