/*
 * 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.
 */

#include "TJSONProtocol.h"

#include <math.h>
#include <boost/lexical_cast.hpp>
#include "TBase64Utils.h"
#include <transport/TTransportException.h>

using namespace apache::thrift::transport;

namespace apache { namespace thrift { namespace protocol {


// Static data

static const uint8_t kJSONObjectStart = '{';
static const uint8_t kJSONObjectEnd = '}';
static const uint8_t kJSONArrayStart = '[';
static const uint8_t kJSONArrayEnd = ']';
static const uint8_t kJSONNewline = '\n';
static const uint8_t kJSONPairSeparator = ':';
static const uint8_t kJSONElemSeparator = ',';
static const uint8_t kJSONBackslash = '\\';
static const uint8_t kJSONStringDelimiter = '"';
static const uint8_t kJSONZeroChar = '0';
static const uint8_t kJSONEscapeChar = 'u';

static const std::string kJSONEscapePrefix("\\u00");

static const uint32_t kThriftVersion1 = 1;

static const std::string kThriftNan("NaN");
static const std::string kThriftInfinity("Infinity");
static const std::string kThriftNegativeInfinity("-Infinity");

static const std::string kTypeNameBool("tf");
static const std::string kTypeNameByte("i8");
static const std::string kTypeNameI16("i16");
static const std::string kTypeNameI32("i32");
static const std::string kTypeNameI64("i64");
static const std::string kTypeNameDouble("dbl");
static const std::string kTypeNameStruct("rec");
static const std::string kTypeNameString("str");
static const std::string kTypeNameMap("map");
static const std::string kTypeNameList("lst");
static const std::string kTypeNameSet("set");

static const std::string &getTypeNameForTypeID(TType typeID) {
  switch (typeID) {
  case T_BOOL:
    return kTypeNameBool;
  case T_BYTE:
    return kTypeNameByte;
  case T_I16:
    return kTypeNameI16;
  case T_I32:
    return kTypeNameI32;
  case T_I64:
    return kTypeNameI64;
  case T_DOUBLE:
    return kTypeNameDouble;
  case T_STRING:
    return kTypeNameString;
  case T_STRUCT:
    return kTypeNameStruct;
  case T_MAP:
    return kTypeNameMap;
  case T_SET:
    return kTypeNameSet;
  case T_LIST:
    return kTypeNameList;
  default:
    throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
                             "Unrecognized type");
  }
}

static TType getTypeIDForTypeName(const std::string &name) {
  TType result = T_STOP; // Sentinel value
  if (name.length() > 1) {
    switch (name[0]) {
    case 'd':
      result = T_DOUBLE;
      break;
    case 'i':
      switch (name[1]) {
      case '8':
        result = T_BYTE;
        break;
      case '1':
        result = T_I16;
        break;
      case '3':
        result = T_I32;
        break;
      case '6':
        result = T_I64;
        break;
      }
      break;
    case 'l':
      result = T_LIST;
      break;
    case 'm':
      result = T_MAP;
      break;
    case 'r':
      result = T_STRUCT;
      break;
    case 's':
      if (name[1] == 't') {
        result = T_STRING;
      }
      else if (name[1] == 'e') {
        result = T_SET;
      }
      break;
    case 't':
      result = T_BOOL;
      break;
    }
  }
  if (result == T_STOP) {
    throw TProtocolException(TProtocolException::NOT_IMPLEMENTED,
                             "Unrecognized type");
  }
  return result;
}


// This table describes the handling for the first 0x30 characters
//  0 : escape using "\u00xx" notation
//  1 : just output index
// <other> : escape using "\<other>" notation
static const uint8_t kJSONCharTable[0x30] = {
//  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
};


// This string's characters must match up with the elements in kEscapeCharVals.
// I don't have '/' on this list even though it appears on www.json.org --
// it is not in the RFC
const static std::string kEscapeChars("\"\\bfnrt");

// The elements of this array must match up with the sequence of characters in
// kEscapeChars
const static uint8_t kEscapeCharVals[7] = {
  '"', '\\', '\b', '\f', '\n', '\r', '\t',
};


// Static helper functions

// Read 1 character from the transport trans and verify that it is the
// expected character ch.
// Throw a protocol exception if it is not.
static uint32_t readSyntaxChar(TJSONProtocol::LookaheadReader &reader,
                               uint8_t ch) {
  uint8_t ch2 = reader.read();
  if (ch2 != ch) {
    throw TProtocolException(TProtocolException::INVALID_DATA,
                             "Expected \'" + std::string((char *)&ch, 1) +
                             "\'; got \'" + std::string((char *)&ch2, 1) +
                             "\'.");
  }
  return 1;
}

// Return the integer value of a hex character ch.
// Throw a protocol exception if the character is not [0-9a-f].
static uint8_t hexVal(uint8_t ch) {
  if ((ch >= '0') && (ch <= '9')) {
    return ch - '0';
  }
  else if ((ch >= 'a') && (ch <= 'f')) {
    return ch - 'a';
  }
  else {
    throw TProtocolException(TProtocolException::INVALID_DATA,
                             "Expected hex val ([0-9a-f]); got \'"
                               + std::string((char *)&ch, 1) + "\'.");
  }
}

// Return the hex character representing the integer val. The value is masked
// to make sure it is in the correct range.
static uint8_t hexChar(uint8_t val) {
  val &= 0x0F;
  if (val < 10) {
    return val + '0';
  }
  else {
    return val + 'a';
  }
}

// Return true if the character ch is in [-+0-9.Ee]; false otherwise
static bool isJSONNumeric(uint8_t ch) {
  switch (ch) {
  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;
}


/**
 * Class to serve as base JSON context and as base class for other context
 * implementations
 */
class TJSONContext {

 public:

  TJSONContext() {};

  virtual ~TJSONContext() {};

  /**
   * Write context data to the transport. Default is to do nothing.
   */
  virtual uint32_t write(TTransport &trans) {
    return 0;
  };

  /**
   * Read context data from the transport. Default is to do nothing.
   */
  virtual uint32_t read(TJSONProtocol::LookaheadReader &reader) {
    return 0;
  };

  /**
   * Return true if numbers need to be escaped as strings in this context.
   * Default behavior is to return false.
   */
  virtual bool escapeNum() {
    return false;
  }
};

// Context class for object member key-value pairs
class JSONPairContext : public TJSONContext {

public:

  JSONPairContext() :
    first_(true),
    colon_(true) {
  }

  uint32_t write(TTransport &trans) {
    if (first_) {
      first_ = false;
      colon_ = true;
      return 0;
    }
    else {
      trans.write(colon_ ? &kJSONPairSeparator : &kJSONElemSeparator, 1);
      colon_ = !colon_;
      return 1;
    }
  }

  uint32_t read(TJSONProtocol::LookaheadReader &reader) {
    if (first_) {
      first_ = false;
      colon_ = true;
      return 0;
    }
    else {
      uint8_t ch = (colon_ ? kJSONPairSeparator : kJSONElemSeparator);
      colon_ = !colon_;
      return readSyntaxChar(reader, ch);
    }
  }

  // Numbers must be turned into strings if they are the key part of a pair
  virtual bool escapeNum() {
    return colon_;
  }

  private:

    bool first_;
    bool colon_;
};

// Context class for lists
class JSONListContext : public TJSONContext {

public:

  JSONListContext() :
    first_(true) {
  }

  uint32_t write(TTransport &trans) {
    if (first_) {
      first_ = false;
      return 0;
    }
    else {
      trans.write(&kJSONElemSeparator, 1);
      return 1;
    }
  }

  uint32_t read(TJSONProtocol::LookaheadReader &reader) {
    if (first_) {
      first_ = false;
      return 0;
    }
    else {
      return readSyntaxChar(reader, kJSONElemSeparator);
    }
  }

  private:
    bool first_;
};


TJSONProtocol::TJSONProtocol(boost::shared_ptr<TTransport> ptrans) :
  TProtocol(ptrans),
  context_(new TJSONContext()),
  reader_(*ptrans) {
}

TJSONProtocol::~TJSONProtocol() {}

void TJSONProtocol::pushContext(boost::shared_ptr<TJSONContext> c) {
  contexts_.push(context_);
  context_ = c;
}

void TJSONProtocol::popContext() {
  context_ = contexts_.top();
  contexts_.pop();
}

// Write the character ch as a JSON escape sequence ("\u00xx")
uint32_t TJSONProtocol::writeJSONEscapeChar(uint8_t ch) {
  trans_->write((const uint8_t *)kJSONEscapePrefix.c_str(),
                kJSONEscapePrefix.length());
  uint8_t outCh = hexChar(ch >> 4);
  trans_->write(&outCh, 1);
  outCh = hexChar(ch);
  trans_->write(&outCh, 1);
  return 6;
}

// Write the character ch as part of a JSON string, escaping as appropriate.
uint32_t TJSONProtocol::writeJSONChar(uint8_t ch) {
  if (ch >= 0x30) {
    if (ch == kJSONBackslash) { // Only special character >= 0x30 is '\'
      trans_->write(&kJSONBackslash, 1);
      trans_->write(&kJSONBackslash, 1);
      return 2;
    }
    else {
      trans_->write(&ch, 1);
      return 1;
    }
  }
  else {
    uint8_t outCh = kJSONCharTable[ch];
    // Check if regular character, backslash escaped, or JSON escaped
    if (outCh == 1) {
      trans_->write(&ch, 1);
      return 1;
    }
    else if (outCh > 1) {
      trans_->write(&kJSONBackslash, 1);
      trans_->write(&outCh, 1);
      return 2;
    }
    else {
      return writeJSONEscapeChar(ch);
    }
  }
}

// Write out the contents of the string str as a JSON string, escaping
// characters as appropriate.
uint32_t TJSONProtocol::writeJSONString(const std::string &str) {
  uint32_t result = context_->write(*trans_);
  result += 2; // For quotes
  trans_->write(&kJSONStringDelimiter, 1);
  std::string::const_iterator iter(str.begin());
  std::string::const_iterator end(str.end());
  while (iter != end) {
    result += writeJSONChar(*iter++);
  }
  trans_->write(&kJSONStringDelimiter, 1);
  return result;
}

// Write out the contents of the string as JSON string, base64-encoding
// the string's contents, and escaping as appropriate
uint32_t TJSONProtocol::writeJSONBase64(const std::string &str) {
  uint32_t result = context_->write(*trans_);
  result += 2; // For quotes
  trans_->write(&kJSONStringDelimiter, 1);
  uint8_t b[4];
  const uint8_t *bytes = (const uint8_t *)str.c_str();
  uint32_t len = str.length();
  while (len >= 3) {
    // Encode 3 bytes at a time
    base64_encode(bytes, 3, b);
    trans_->write(b, 4);
    result += 4;
    bytes += 3;
    len -=3;
  }
  if (len) { // Handle remainder
    base64_encode(bytes, len, b);
    trans_->write(b, len + 1);
    result += len + 1;
  }
  trans_->write(&kJSONStringDelimiter, 1);
  return result;
}

// Convert the given integer type to a JSON number, or a string
// if the context requires it (eg: key in a map pair).
template <typename NumberType>
uint32_t TJSONProtocol::writeJSONInteger(NumberType num) {
  uint32_t result = context_->write(*trans_);
  std::string val(boost::lexical_cast<std::string>(num));
  bool escapeNum = context_->escapeNum();
  if (escapeNum) {
    trans_->write(&kJSONStringDelimiter, 1);
    result += 1;
  }
  trans_->write((const uint8_t *)val.c_str(), val.length());
  result += val.length();
  if (escapeNum) {
    trans_->write(&kJSONStringDelimiter, 1);
    result += 1;
  }
  return result;
}

// Convert the given double to a JSON string, which is either the number,
// "NaN" or "Infinity" or "-Infinity".
uint32_t TJSONProtocol::writeJSONDouble(double num) {
  uint32_t result = context_->write(*trans_);
  std::string val(boost::lexical_cast<std::string>(num));

  // Normalize output of boost::lexical_cast for NaNs and Infinities
  bool special = false;
  switch (val[0]) {
  case 'N':
  case 'n':
    val = kThriftNan;
    special = true;
    break;
  case 'I':
  case 'i':
    val = kThriftInfinity;
    special = true;
    break;
  case '-':
    if ((val[1] == 'I') || (val[1] == 'i')) {
      val = kThriftNegativeInfinity;
      special = true;
    }
    break;
  }

  bool escapeNum = special || context_->escapeNum();
  if (escapeNum) {
    trans_->write(&kJSONStringDelimiter, 1);
    result += 1;
  }
  trans_->write((const uint8_t *)val.c_str(), val.length());
  result += val.length();
  if (escapeNum) {
    trans_->write(&kJSONStringDelimiter, 1);
    result += 1;
  }
  return result;
}

uint32_t TJSONProtocol::writeJSONObjectStart() {
  uint32_t result = context_->write(*trans_);
  trans_->write(&kJSONObjectStart, 1);
  pushContext(boost::shared_ptr<TJSONContext>(new JSONPairContext()));
  return result + 1;
}

uint32_t TJSONProtocol::writeJSONObjectEnd() {
  popContext();
  trans_->write(&kJSONObjectEnd, 1);
  return 1;
}

uint32_t TJSONProtocol::writeJSONArrayStart() {
  uint32_t result = context_->write(*trans_);
  trans_->write(&kJSONArrayStart, 1);
  pushContext(boost::shared_ptr<TJSONContext>(new JSONListContext()));
  return result + 1;
}

uint32_t TJSONProtocol::writeJSONArrayEnd() {
  popContext();
  trans_->write(&kJSONArrayEnd, 1);
  return 1;
}

uint32_t TJSONProtocol::writeMessageBegin(const std::string& name,
                                          const TMessageType messageType,
                                          const int32_t seqid) {
  uint32_t result = writeJSONArrayStart();
  result += writeJSONInteger(kThriftVersion1);
  result += writeJSONString(name);
  result += writeJSONInteger(messageType);
  result += writeJSONInteger(seqid);
  return result;
}

uint32_t TJSONProtocol::writeMessageEnd() {
  return writeJSONArrayEnd();
}

uint32_t TJSONProtocol::writeStructBegin(const char* name) {
  return writeJSONObjectStart();
}

uint32_t TJSONProtocol::writeStructEnd() {
  return writeJSONObjectEnd();
}

uint32_t TJSONProtocol::writeFieldBegin(const char* name,
                                        const TType fieldType,
                                        const int16_t fieldId) {
  uint32_t result = writeJSONInteger(fieldId);
  result += writeJSONObjectStart();
  result += writeJSONString(getTypeNameForTypeID(fieldType));
  return result;
}

uint32_t TJSONProtocol::writeFieldEnd() {
  return writeJSONObjectEnd();
}

uint32_t TJSONProtocol::writeFieldStop() {
  return 0;
}

uint32_t TJSONProtocol::writeMapBegin(const TType keyType,
                                      const TType valType,
                                      const uint32_t size) {
  uint32_t result = writeJSONArrayStart();
  result += writeJSONString(getTypeNameForTypeID(keyType));
  result += writeJSONString(getTypeNameForTypeID(valType));
  result += writeJSONInteger((int64_t)size);
  result += writeJSONObjectStart();
  return result;
}

uint32_t TJSONProtocol::writeMapEnd() {
  return writeJSONObjectEnd() + writeJSONArrayEnd();
}

uint32_t TJSONProtocol::writeListBegin(const TType elemType,
                                       const uint32_t size) {
  uint32_t result = writeJSONArrayStart();
  result += writeJSONString(getTypeNameForTypeID(elemType));
  result += writeJSONInteger((int64_t)size);
  return result;
}

uint32_t TJSONProtocol::writeListEnd() {
  return writeJSONArrayEnd();
}

uint32_t TJSONProtocol::writeSetBegin(const TType elemType,
                                      const uint32_t size) {
  uint32_t result = writeJSONArrayStart();
  result += writeJSONString(getTypeNameForTypeID(elemType));
  result += writeJSONInteger((int64_t)size);
  return result;
}

uint32_t TJSONProtocol::writeSetEnd() {
  return writeJSONArrayEnd();
}

uint32_t TJSONProtocol::writeBool(const bool value) {
  return writeJSONInteger(value);
}

uint32_t TJSONProtocol::writeByte(const int8_t byte) {
  // writeByte() must be handled specially becuase boost::lexical cast sees
  // int8_t as a text type instead of an integer type
  return writeJSONInteger((int16_t)byte);
}

uint32_t TJSONProtocol::writeI16(const int16_t i16) {
  return writeJSONInteger(i16);
}

uint32_t TJSONProtocol::writeI32(const int32_t i32) {
  return writeJSONInteger(i32);
}

uint32_t TJSONProtocol::writeI64(const int64_t i64) {
  return writeJSONInteger(i64);
}

uint32_t TJSONProtocol::writeDouble(const double dub) {
  return writeJSONDouble(dub);
}

uint32_t TJSONProtocol::writeString(const std::string& str) {
  return writeJSONString(str);
}

uint32_t TJSONProtocol::writeBinary(const std::string& str) {
  return writeJSONBase64(str);
}

  /**
   * Reading functions
   */

// Reads 1 byte and verifies that it matches ch.
uint32_t TJSONProtocol::readJSONSyntaxChar(uint8_t ch) {
  return readSyntaxChar(reader_, ch);
}

// Decodes the four hex parts of a JSON escaped string character and returns
// the character via out. The first two characters must be "00".
uint32_t TJSONProtocol::readJSONEscapeChar(uint8_t *out) {
  uint8_t b[2];
  readJSONSyntaxChar(kJSONZeroChar);
  readJSONSyntaxChar(kJSONZeroChar);
  b[0] = reader_.read();
  b[1] = reader_.read();
  *out = (hexVal(b[0]) << 4) + hexVal(b[1]);
  return 4;
}

// Decodes a JSON string, including unescaping, and returns the string via str
uint32_t TJSONProtocol::readJSONString(std::string &str, bool skipContext) {
  uint32_t result = (skipContext ? 0 : context_->read(reader_));
  result += readJSONSyntaxChar(kJSONStringDelimiter);
  uint8_t ch;
  str.clear();
  while (true) {
    ch = reader_.read();
    ++result;
    if (ch == kJSONStringDelimiter) {
      break;
    }
    if (ch == kJSONBackslash) {
      ch = reader_.read();
      ++result;
      if (ch == kJSONEscapeChar) {
        result += readJSONEscapeChar(&ch);
      }
      else {
        size_t pos = kEscapeChars.find(ch);
        if (pos == std::string::npos) {
          throw TProtocolException(TProtocolException::INVALID_DATA,
                                   "Expected control char, got '" +
                                   std::string((const char *)&ch, 1)  + "'.");
        }
        ch = kEscapeCharVals[pos];
      }
    }
    str += ch;
  }
  return result;
}

// Reads a block of base64 characters, decoding it, and returns via str
uint32_t TJSONProtocol::readJSONBase64(std::string &str) {
  std::string tmp;
  uint32_t result = readJSONString(tmp);
  uint8_t *b = (uint8_t *)tmp.c_str();
  uint32_t len = tmp.length();
  str.clear();
  while (len >= 4) {
    base64_decode(b, 4);
    str.append((const char *)b, 3);
    b += 4;
    len -= 4;
  }
  // 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) {
    base64_decode(b, len);
    str.append((const char *)b, len - 1);
  }
  return result;
}

// Reads a sequence of characters, stopping at the first one that is not
// a valid JSON numeric character.
uint32_t TJSONProtocol::readJSONNumericChars(std::string &str) {
  uint32_t result = 0;
  str.clear();
  while (true) {
    uint8_t ch = reader_.peek();
    if (!isJSONNumeric(ch)) {
      break;
    }
    reader_.read();
    str += ch;
    ++result;
  }
  return result;
}

// Reads a sequence of characters and assembles them into a number,
// returning them via num
template <typename NumberType>
uint32_t TJSONProtocol::readJSONInteger(NumberType &num) {
  uint32_t result = context_->read(reader_);
  if (context_->escapeNum()) {
    result += readJSONSyntaxChar(kJSONStringDelimiter);
  }
  std::string str;
  result += readJSONNumericChars(str);
  try {
    num = boost::lexical_cast<NumberType>(str);
  }
  catch (boost::bad_lexical_cast e) {
    throw new TProtocolException(TProtocolException::INVALID_DATA,
                                 "Expected numeric value; got \"" + str +
                                  "\"");
  }
  if (context_->escapeNum()) {
    result += readJSONSyntaxChar(kJSONStringDelimiter);
  }
  return result;
}

// Reads a JSON number or string and interprets it as a double.
uint32_t TJSONProtocol::readJSONDouble(double &num) {
  uint32_t result = context_->read(reader_);
  std::string str;
  if (reader_.peek() == kJSONStringDelimiter) {
    result += readJSONString(str, true);
    // Check for NaN, Infinity and -Infinity
    if (str == kThriftNan) {
      num = HUGE_VAL/HUGE_VAL; // generates NaN
    }
    else if (str == kThriftInfinity) {
      num = HUGE_VAL;
    }
    else if (str == kThriftNegativeInfinity) {
      num = -HUGE_VAL;
    }
    else {
      if (!context_->escapeNum()) {
        // Throw exception -- we should not be in a string in this case
        throw new TProtocolException(TProtocolException::INVALID_DATA,
                                     "Numeric data unexpectedly quoted");
      }
      try {
        num = boost::lexical_cast<double>(str);
      }
      catch (boost::bad_lexical_cast e) {
        throw new TProtocolException(TProtocolException::INVALID_DATA,
                                     "Expected numeric value; got \"" + str +
                                     "\"");
      }
    }
  }
  else {
    if (context_->escapeNum()) {
      // This will throw - we should have had a quote if escapeNum == true
      readJSONSyntaxChar(kJSONStringDelimiter);
    }
    result += readJSONNumericChars(str);
    try {
      num = boost::lexical_cast<double>(str);
    }
    catch (boost::bad_lexical_cast e) {
      throw new TProtocolException(TProtocolException::INVALID_DATA,
                                   "Expected numeric value; got \"" + str +
                                   "\"");
    }
  }
  return result;
}

uint32_t TJSONProtocol::readJSONObjectStart() {
  uint32_t result = context_->read(reader_);
  result += readJSONSyntaxChar(kJSONObjectStart);
  pushContext(boost::shared_ptr<TJSONContext>(new JSONPairContext()));
  return result;
}

uint32_t TJSONProtocol::readJSONObjectEnd() {
  uint32_t result = readJSONSyntaxChar(kJSONObjectEnd);
  popContext();
  return result;
}

uint32_t TJSONProtocol::readJSONArrayStart() {
  uint32_t result = context_->read(reader_);
  result += readJSONSyntaxChar(kJSONArrayStart);
  pushContext(boost::shared_ptr<TJSONContext>(new JSONListContext()));
  return result;
}

uint32_t TJSONProtocol::readJSONArrayEnd() {
  uint32_t result = readJSONSyntaxChar(kJSONArrayEnd);
  popContext();
  return result;
}

uint32_t TJSONProtocol::readMessageBegin(std::string& name,
                                         TMessageType& messageType,
                                         int32_t& seqid) {
  uint32_t result = readJSONArrayStart();
  uint64_t tmpVal = 0;
  result += readJSONInteger(tmpVal);
  if (tmpVal != kThriftVersion1) {
    throw TProtocolException(TProtocolException::BAD_VERSION,
                             "Message contained bad version.");
  }
  result += readJSONString(name);
  result += readJSONInteger(tmpVal);
  messageType = (TMessageType)tmpVal;
  result += readJSONInteger(tmpVal);
  seqid = tmpVal;
  return result;
}

uint32_t TJSONProtocol::readMessageEnd() {
  return readJSONArrayEnd();
}

uint32_t TJSONProtocol::readStructBegin(std::string& name) {
  return readJSONObjectStart();
}

uint32_t TJSONProtocol::readStructEnd() {
  return readJSONObjectEnd();
}

uint32_t TJSONProtocol::readFieldBegin(std::string& name,
                                       TType& fieldType,
                                       int16_t& fieldId) {
  uint32_t result = 0;
  // Check if we hit the end of the list
  uint8_t ch = reader_.peek();
  if (ch == kJSONObjectEnd) {
    fieldType = apache::thrift::protocol::T_STOP;
  }
  else {
    uint64_t tmpVal = 0;
    std::string tmpStr;
    result += readJSONInteger(tmpVal);
    fieldId = tmpVal;
    result += readJSONObjectStart();
    result += readJSONString(tmpStr);
    fieldType = getTypeIDForTypeName(tmpStr);
  }
  return result;
}

uint32_t TJSONProtocol::readFieldEnd() {
  return readJSONObjectEnd();
}

uint32_t TJSONProtocol::readMapBegin(TType& keyType,
                                     TType& valType,
                                     uint32_t& size) {
  uint64_t tmpVal = 0;
  std::string tmpStr;
  uint32_t result = readJSONArrayStart();
  result += readJSONString(tmpStr);
  keyType = getTypeIDForTypeName(tmpStr);
  result += readJSONString(tmpStr);
  valType = getTypeIDForTypeName(tmpStr);
  result += readJSONInteger(tmpVal);
  size = tmpVal;
  result += readJSONObjectStart();
  return result;
}

uint32_t TJSONProtocol::readMapEnd() {
  return readJSONObjectEnd() + readJSONArrayEnd();
}

uint32_t TJSONProtocol::readListBegin(TType& elemType,
                                      uint32_t& size) {
  uint64_t tmpVal = 0;
  std::string tmpStr;
  uint32_t result = readJSONArrayStart();
  result += readJSONString(tmpStr);
  elemType = getTypeIDForTypeName(tmpStr);
  result += readJSONInteger(tmpVal);
  size = tmpVal;
  return result;
}

uint32_t TJSONProtocol::readListEnd() {
  return readJSONArrayEnd();
}

uint32_t TJSONProtocol::readSetBegin(TType& elemType,
                                     uint32_t& size) {
  uint64_t tmpVal = 0;
  std::string tmpStr;
  uint32_t result = readJSONArrayStart();
  result += readJSONString(tmpStr);
  elemType = getTypeIDForTypeName(tmpStr);
  result += readJSONInteger(tmpVal);
  size = tmpVal;
  return result;
}

uint32_t TJSONProtocol::readSetEnd() {
  return readJSONArrayEnd();
}

uint32_t TJSONProtocol::readBool(bool& value) {
  return readJSONInteger(value);
}

// readByte() must be handled properly becuase boost::lexical cast sees int8_t
// as a text type instead of an integer type
uint32_t TJSONProtocol::readByte(int8_t& byte) {
  int16_t tmp = (int16_t) byte;
  uint32_t result =  readJSONInteger(tmp);
  assert(tmp < 256);
  byte = (int8_t)tmp;
  return result;
}

uint32_t TJSONProtocol::readI16(int16_t& i16) {
  return readJSONInteger(i16);
}

uint32_t TJSONProtocol::readI32(int32_t& i32) {
  return readJSONInteger(i32);
}

uint32_t TJSONProtocol::readI64(int64_t& i64) {
  return readJSONInteger(i64);
}

uint32_t TJSONProtocol::readDouble(double& dub) {
  return readJSONDouble(dub);
}

uint32_t TJSONProtocol::readString(std::string &str) {
  return readJSONString(str);
}

uint32_t TJSONProtocol::readBinary(std::string &str) {
  return readJSONBase64(str);
}

}}} // apache::thrift::protocol
