//
// Autogenerated by Thrift Compiler (0.19.0)
//
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
//
"use strict";

var thrift = require('thrift');
var Thrift = thrift.Thrift;
var Q = thrift.Q;
var Int64 = require('node-int64');

var common_ttypes = require('./common_types');


var ttypes = require('./client_types');
//HELPER FUNCTIONS AND STRUCTURES

var IClientRPCService_executeQueryStatementV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteStatementReq(args.req);
    }
  }
};
IClientRPCService_executeQueryStatementV2_args.prototype = {};
IClientRPCService_executeQueryStatementV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeQueryStatementV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeQueryStatementV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeQueryStatementV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeQueryStatementV2_result.prototype = {};
IClientRPCService_executeQueryStatementV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeQueryStatementV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeQueryStatementV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeUpdateStatementV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteStatementReq(args.req);
    }
  }
};
IClientRPCService_executeUpdateStatementV2_args.prototype = {};
IClientRPCService_executeUpdateStatementV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeUpdateStatementV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeUpdateStatementV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeUpdateStatementV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeUpdateStatementV2_result.prototype = {};
IClientRPCService_executeUpdateStatementV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeUpdateStatementV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeUpdateStatementV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeStatementV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteStatementReq(args.req);
    }
  }
};
IClientRPCService_executeStatementV2_args.prototype = {};
IClientRPCService_executeStatementV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeStatementV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeStatementV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeStatementV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeStatementV2_result.prototype = {};
IClientRPCService_executeStatementV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeStatementV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeStatementV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeRawDataQueryV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSRawDataQueryReq(args.req);
    }
  }
};
IClientRPCService_executeRawDataQueryV2_args.prototype = {};
IClientRPCService_executeRawDataQueryV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSRawDataQueryReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeRawDataQueryV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeRawDataQueryV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeRawDataQueryV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeRawDataQueryV2_result.prototype = {};
IClientRPCService_executeRawDataQueryV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeRawDataQueryV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeRawDataQueryV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeLastDataQueryV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSLastDataQueryReq(args.req);
    }
  }
};
IClientRPCService_executeLastDataQueryV2_args.prototype = {};
IClientRPCService_executeLastDataQueryV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSLastDataQueryReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeLastDataQueryV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeLastDataQueryV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeLastDataQueryV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeLastDataQueryV2_result.prototype = {};
IClientRPCService_executeLastDataQueryV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeLastDataQueryV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeLastDataQueryV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSFastLastDataQueryForOnePrefixPathReq(args.req);
    }
  }
};
IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args.prototype = {};
IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSFastLastDataQueryForOnePrefixPathReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result.prototype = {};
IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSFastLastDataQueryForOneDeviceReq(args.req);
    }
  }
};
IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args.prototype = {};
IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSFastLastDataQueryForOneDeviceReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result.prototype = {};
IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeAggregationQueryV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSAggregationQueryReq(args.req);
    }
  }
};
IClientRPCService_executeAggregationQueryV2_args.prototype = {};
IClientRPCService_executeAggregationQueryV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSAggregationQueryReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeAggregationQueryV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeAggregationQueryV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeAggregationQueryV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeAggregationQueryV2_result.prototype = {};
IClientRPCService_executeAggregationQueryV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeAggregationQueryV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeAggregationQueryV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchResultsV2_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSFetchResultsReq(args.req);
    }
  }
};
IClientRPCService_fetchResultsV2_args.prototype = {};
IClientRPCService_fetchResultsV2_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSFetchResultsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchResultsV2_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchResultsV2_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchResultsV2_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSFetchResultsResp(args.success);
    }
  }
};
IClientRPCService_fetchResultsV2_result.prototype = {};
IClientRPCService_fetchResultsV2_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSFetchResultsResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchResultsV2_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchResultsV2_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_openSession_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSOpenSessionReq(args.req);
    }
  }
};
IClientRPCService_openSession_args.prototype = {};
IClientRPCService_openSession_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSOpenSessionReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_openSession_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_openSession_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_openSession_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSOpenSessionResp(args.success);
    }
  }
};
IClientRPCService_openSession_result.prototype = {};
IClientRPCService_openSession_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSOpenSessionResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_openSession_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_openSession_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_closeSession_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCloseSessionReq(args.req);
    }
  }
};
IClientRPCService_closeSession_args.prototype = {};
IClientRPCService_closeSession_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCloseSessionReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_closeSession_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_closeSession_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_closeSession_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_closeSession_result.prototype = {};
IClientRPCService_closeSession_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_closeSession_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_closeSession_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeStatement_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteStatementReq(args.req);
    }
  }
};
IClientRPCService_executeStatement_args.prototype = {};
IClientRPCService_executeStatement_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeStatement_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeStatement_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeStatement_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeStatement_result.prototype = {};
IClientRPCService_executeStatement_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeStatement_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeStatement_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeBatchStatement_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteBatchStatementReq(args.req);
    }
  }
};
IClientRPCService_executeBatchStatement_args.prototype = {};
IClientRPCService_executeBatchStatement_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteBatchStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeBatchStatement_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeBatchStatement_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeBatchStatement_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_executeBatchStatement_result.prototype = {};
IClientRPCService_executeBatchStatement_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeBatchStatement_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeBatchStatement_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeQueryStatement_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteStatementReq(args.req);
    }
  }
};
IClientRPCService_executeQueryStatement_args.prototype = {};
IClientRPCService_executeQueryStatement_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeQueryStatement_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeQueryStatement_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeQueryStatement_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeQueryStatement_result.prototype = {};
IClientRPCService_executeQueryStatement_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeQueryStatement_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeQueryStatement_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeUpdateStatement_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSExecuteStatementReq(args.req);
    }
  }
};
IClientRPCService_executeUpdateStatement_args.prototype = {};
IClientRPCService_executeUpdateStatement_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSExecuteStatementReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeUpdateStatement_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeUpdateStatement_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeUpdateStatement_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeUpdateStatement_result.prototype = {};
IClientRPCService_executeUpdateStatement_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeUpdateStatement_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeUpdateStatement_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchResults_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSFetchResultsReq(args.req);
    }
  }
};
IClientRPCService_fetchResults_args.prototype = {};
IClientRPCService_fetchResults_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSFetchResultsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchResults_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchResults_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchResults_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSFetchResultsResp(args.success);
    }
  }
};
IClientRPCService_fetchResults_result.prototype = {};
IClientRPCService_fetchResults_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSFetchResultsResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchResults_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchResults_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchMetadata_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSFetchMetadataReq(args.req);
    }
  }
};
IClientRPCService_fetchMetadata_args.prototype = {};
IClientRPCService_fetchMetadata_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSFetchMetadataReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchMetadata_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchMetadata_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchMetadata_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSFetchMetadataResp(args.success);
    }
  }
};
IClientRPCService_fetchMetadata_result.prototype = {};
IClientRPCService_fetchMetadata_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSFetchMetadataResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchMetadata_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchMetadata_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_cancelOperation_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCancelOperationReq(args.req);
    }
  }
};
IClientRPCService_cancelOperation_args.prototype = {};
IClientRPCService_cancelOperation_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCancelOperationReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_cancelOperation_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_cancelOperation_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_cancelOperation_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_cancelOperation_result.prototype = {};
IClientRPCService_cancelOperation_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_cancelOperation_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_cancelOperation_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_closeOperation_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCloseOperationReq(args.req);
    }
  }
};
IClientRPCService_closeOperation_args.prototype = {};
IClientRPCService_closeOperation_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCloseOperationReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_closeOperation_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_closeOperation_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_closeOperation_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_closeOperation_result.prototype = {};
IClientRPCService_closeOperation_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_closeOperation_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_closeOperation_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_getTimeZone_args = function(args) {
  this.sessionId = null;
  if (args) {
    if (args.sessionId !== undefined && args.sessionId !== null) {
      this.sessionId = args.sessionId;
    }
  }
};
IClientRPCService_getTimeZone_args.prototype = {};
IClientRPCService_getTimeZone_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.I64) {
        this.sessionId = input.readI64();
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_getTimeZone_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_getTimeZone_args');
  if (this.sessionId !== null && this.sessionId !== undefined) {
    output.writeFieldBegin('sessionId', Thrift.Type.I64, 1);
    output.writeI64(this.sessionId);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_getTimeZone_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSGetTimeZoneResp(args.success);
    }
  }
};
IClientRPCService_getTimeZone_result.prototype = {};
IClientRPCService_getTimeZone_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSGetTimeZoneResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_getTimeZone_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_getTimeZone_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_setTimeZone_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSSetTimeZoneReq(args.req);
    }
  }
};
IClientRPCService_setTimeZone_args.prototype = {};
IClientRPCService_setTimeZone_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSSetTimeZoneReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_setTimeZone_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_setTimeZone_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_setTimeZone_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_setTimeZone_result.prototype = {};
IClientRPCService_setTimeZone_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_setTimeZone_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_setTimeZone_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_getProperties_args = function(args) {
};
IClientRPCService_getProperties_args.prototype = {};
IClientRPCService_getProperties_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    input.skip(ftype);
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_getProperties_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_getProperties_args');
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_getProperties_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.ServerProperties(args.success);
    }
  }
};
IClientRPCService_getProperties_result.prototype = {};
IClientRPCService_getProperties_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.ServerProperties();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_getProperties_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_getProperties_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_setStorageGroup_args = function(args) {
  this.sessionId = null;
  this.storageGroup = null;
  if (args) {
    if (args.sessionId !== undefined && args.sessionId !== null) {
      this.sessionId = args.sessionId;
    }
    if (args.storageGroup !== undefined && args.storageGroup !== null) {
      this.storageGroup = args.storageGroup;
    }
  }
};
IClientRPCService_setStorageGroup_args.prototype = {};
IClientRPCService_setStorageGroup_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.I64) {
        this.sessionId = input.readI64();
      } else {
        input.skip(ftype);
      }
      break;
      case 2:
      if (ftype == Thrift.Type.STRING) {
        this.storageGroup = input.readString();
      } else {
        input.skip(ftype);
      }
      break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_setStorageGroup_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_setStorageGroup_args');
  if (this.sessionId !== null && this.sessionId !== undefined) {
    output.writeFieldBegin('sessionId', Thrift.Type.I64, 1);
    output.writeI64(this.sessionId);
    output.writeFieldEnd();
  }
  if (this.storageGroup !== null && this.storageGroup !== undefined) {
    output.writeFieldBegin('storageGroup', Thrift.Type.STRING, 2);
    output.writeString(this.storageGroup);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_setStorageGroup_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_setStorageGroup_result.prototype = {};
IClientRPCService_setStorageGroup_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_setStorageGroup_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_setStorageGroup_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createTimeseries_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCreateTimeseriesReq(args.req);
    }
  }
};
IClientRPCService_createTimeseries_args.prototype = {};
IClientRPCService_createTimeseries_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCreateTimeseriesReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createTimeseries_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createTimeseries_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createTimeseries_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_createTimeseries_result.prototype = {};
IClientRPCService_createTimeseries_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createTimeseries_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createTimeseries_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createAlignedTimeseries_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCreateAlignedTimeseriesReq(args.req);
    }
  }
};
IClientRPCService_createAlignedTimeseries_args.prototype = {};
IClientRPCService_createAlignedTimeseries_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCreateAlignedTimeseriesReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createAlignedTimeseries_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createAlignedTimeseries_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createAlignedTimeseries_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_createAlignedTimeseries_result.prototype = {};
IClientRPCService_createAlignedTimeseries_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createAlignedTimeseries_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createAlignedTimeseries_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createMultiTimeseries_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCreateMultiTimeseriesReq(args.req);
    }
  }
};
IClientRPCService_createMultiTimeseries_args.prototype = {};
IClientRPCService_createMultiTimeseries_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCreateMultiTimeseriesReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createMultiTimeseries_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createMultiTimeseries_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createMultiTimeseries_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_createMultiTimeseries_result.prototype = {};
IClientRPCService_createMultiTimeseries_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createMultiTimeseries_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createMultiTimeseries_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_deleteTimeseries_args = function(args) {
  this.sessionId = null;
  this.path = null;
  if (args) {
    if (args.sessionId !== undefined && args.sessionId !== null) {
      this.sessionId = args.sessionId;
    }
    if (args.path !== undefined && args.path !== null) {
      this.path = Thrift.copyList(args.path, [null]);
    }
  }
};
IClientRPCService_deleteTimeseries_args.prototype = {};
IClientRPCService_deleteTimeseries_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.I64) {
        this.sessionId = input.readI64();
      } else {
        input.skip(ftype);
      }
      break;
      case 2:
      if (ftype == Thrift.Type.LIST) {
        this.path = [];
        var _rtmp3488 = input.readListBegin();
        var _size487 = _rtmp3488.size || 0;
        for (var _i489 = 0; _i489 < _size487; ++_i489) {
          var elem490 = null;
          elem490 = input.readString();
          this.path.push(elem490);
        }
        input.readListEnd();
      } else {
        input.skip(ftype);
      }
      break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_deleteTimeseries_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_deleteTimeseries_args');
  if (this.sessionId !== null && this.sessionId !== undefined) {
    output.writeFieldBegin('sessionId', Thrift.Type.I64, 1);
    output.writeI64(this.sessionId);
    output.writeFieldEnd();
  }
  if (this.path !== null && this.path !== undefined) {
    output.writeFieldBegin('path', Thrift.Type.LIST, 2);
    output.writeListBegin(Thrift.Type.STRING, this.path.length);
    for (var iter491 in this.path) {
      if (this.path.hasOwnProperty(iter491)) {
        iter491 = this.path[iter491];
        output.writeString(iter491);
      }
    }
    output.writeListEnd();
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_deleteTimeseries_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_deleteTimeseries_result.prototype = {};
IClientRPCService_deleteTimeseries_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_deleteTimeseries_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_deleteTimeseries_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_deleteStorageGroups_args = function(args) {
  this.sessionId = null;
  this.storageGroup = null;
  if (args) {
    if (args.sessionId !== undefined && args.sessionId !== null) {
      this.sessionId = args.sessionId;
    }
    if (args.storageGroup !== undefined && args.storageGroup !== null) {
      this.storageGroup = Thrift.copyList(args.storageGroup, [null]);
    }
  }
};
IClientRPCService_deleteStorageGroups_args.prototype = {};
IClientRPCService_deleteStorageGroups_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.I64) {
        this.sessionId = input.readI64();
      } else {
        input.skip(ftype);
      }
      break;
      case 2:
      if (ftype == Thrift.Type.LIST) {
        this.storageGroup = [];
        var _rtmp3493 = input.readListBegin();
        var _size492 = _rtmp3493.size || 0;
        for (var _i494 = 0; _i494 < _size492; ++_i494) {
          var elem495 = null;
          elem495 = input.readString();
          this.storageGroup.push(elem495);
        }
        input.readListEnd();
      } else {
        input.skip(ftype);
      }
      break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_deleteStorageGroups_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_deleteStorageGroups_args');
  if (this.sessionId !== null && this.sessionId !== undefined) {
    output.writeFieldBegin('sessionId', Thrift.Type.I64, 1);
    output.writeI64(this.sessionId);
    output.writeFieldEnd();
  }
  if (this.storageGroup !== null && this.storageGroup !== undefined) {
    output.writeFieldBegin('storageGroup', Thrift.Type.LIST, 2);
    output.writeListBegin(Thrift.Type.STRING, this.storageGroup.length);
    for (var iter496 in this.storageGroup) {
      if (this.storageGroup.hasOwnProperty(iter496)) {
        iter496 = this.storageGroup[iter496];
        output.writeString(iter496);
      }
    }
    output.writeListEnd();
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_deleteStorageGroups_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_deleteStorageGroups_result.prototype = {};
IClientRPCService_deleteStorageGroups_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_deleteStorageGroups_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_deleteStorageGroups_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertRecord_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertRecordReq(args.req);
    }
  }
};
IClientRPCService_insertRecord_args.prototype = {};
IClientRPCService_insertRecord_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertRecordReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertRecord_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertRecord_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertRecord_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertRecord_result.prototype = {};
IClientRPCService_insertRecord_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertRecord_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertRecord_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertStringRecord_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertStringRecordReq(args.req);
    }
  }
};
IClientRPCService_insertStringRecord_args.prototype = {};
IClientRPCService_insertStringRecord_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertStringRecordReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertStringRecord_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertStringRecord_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertStringRecord_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertStringRecord_result.prototype = {};
IClientRPCService_insertStringRecord_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertStringRecord_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertStringRecord_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertTablet_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertTabletReq(args.req);
    }
  }
};
IClientRPCService_insertTablet_args.prototype = {};
IClientRPCService_insertTablet_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertTabletReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertTablet_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertTablet_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertTablet_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertTablet_result.prototype = {};
IClientRPCService_insertTablet_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertTablet_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertTablet_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertTablets_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertTabletsReq(args.req);
    }
  }
};
IClientRPCService_insertTablets_args.prototype = {};
IClientRPCService_insertTablets_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertTabletsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertTablets_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertTablets_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertTablets_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertTablets_result.prototype = {};
IClientRPCService_insertTablets_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertTablets_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertTablets_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertRecords_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertRecordsReq(args.req);
    }
  }
};
IClientRPCService_insertRecords_args.prototype = {};
IClientRPCService_insertRecords_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertRecordsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertRecords_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertRecords_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertRecords_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertRecords_result.prototype = {};
IClientRPCService_insertRecords_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertRecords_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertRecords_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertRecordsOfOneDevice_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertRecordsOfOneDeviceReq(args.req);
    }
  }
};
IClientRPCService_insertRecordsOfOneDevice_args.prototype = {};
IClientRPCService_insertRecordsOfOneDevice_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertRecordsOfOneDeviceReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertRecordsOfOneDevice_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertRecordsOfOneDevice_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertRecordsOfOneDevice_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertRecordsOfOneDevice_result.prototype = {};
IClientRPCService_insertRecordsOfOneDevice_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertRecordsOfOneDevice_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertRecordsOfOneDevice_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertStringRecordsOfOneDevice_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertStringRecordsOfOneDeviceReq(args.req);
    }
  }
};
IClientRPCService_insertStringRecordsOfOneDevice_args.prototype = {};
IClientRPCService_insertStringRecordsOfOneDevice_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertStringRecordsOfOneDeviceReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertStringRecordsOfOneDevice_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertStringRecordsOfOneDevice_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertStringRecordsOfOneDevice_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertStringRecordsOfOneDevice_result.prototype = {};
IClientRPCService_insertStringRecordsOfOneDevice_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertStringRecordsOfOneDevice_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertStringRecordsOfOneDevice_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertStringRecords_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertStringRecordsReq(args.req);
    }
  }
};
IClientRPCService_insertStringRecords_args.prototype = {};
IClientRPCService_insertStringRecords_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertStringRecordsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertStringRecords_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertStringRecords_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_insertStringRecords_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_insertStringRecords_result.prototype = {};
IClientRPCService_insertStringRecords_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_insertStringRecords_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_insertStringRecords_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertTablet_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertTabletReq(args.req);
    }
  }
};
IClientRPCService_testInsertTablet_args.prototype = {};
IClientRPCService_testInsertTablet_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertTabletReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertTablet_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertTablet_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertTablet_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertTablet_result.prototype = {};
IClientRPCService_testInsertTablet_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertTablet_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertTablet_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertTablets_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertTabletsReq(args.req);
    }
  }
};
IClientRPCService_testInsertTablets_args.prototype = {};
IClientRPCService_testInsertTablets_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertTabletsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertTablets_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertTablets_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertTablets_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertTablets_result.prototype = {};
IClientRPCService_testInsertTablets_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertTablets_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertTablets_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertRecord_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertRecordReq(args.req);
    }
  }
};
IClientRPCService_testInsertRecord_args.prototype = {};
IClientRPCService_testInsertRecord_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertRecordReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertRecord_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertRecord_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertRecord_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertRecord_result.prototype = {};
IClientRPCService_testInsertRecord_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertRecord_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertRecord_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertStringRecord_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertStringRecordReq(args.req);
    }
  }
};
IClientRPCService_testInsertStringRecord_args.prototype = {};
IClientRPCService_testInsertStringRecord_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertStringRecordReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertStringRecord_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertStringRecord_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertStringRecord_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertStringRecord_result.prototype = {};
IClientRPCService_testInsertStringRecord_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertStringRecord_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertStringRecord_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertRecords_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertRecordsReq(args.req);
    }
  }
};
IClientRPCService_testInsertRecords_args.prototype = {};
IClientRPCService_testInsertRecords_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertRecordsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertRecords_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertRecords_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertRecords_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertRecords_result.prototype = {};
IClientRPCService_testInsertRecords_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertRecords_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertRecords_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertRecordsOfOneDevice_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertRecordsOfOneDeviceReq(args.req);
    }
  }
};
IClientRPCService_testInsertRecordsOfOneDevice_args.prototype = {};
IClientRPCService_testInsertRecordsOfOneDevice_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertRecordsOfOneDeviceReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertRecordsOfOneDevice_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertRecordsOfOneDevice_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertRecordsOfOneDevice_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertRecordsOfOneDevice_result.prototype = {};
IClientRPCService_testInsertRecordsOfOneDevice_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertRecordsOfOneDevice_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertRecordsOfOneDevice_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertStringRecords_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSInsertStringRecordsReq(args.req);
    }
  }
};
IClientRPCService_testInsertStringRecords_args.prototype = {};
IClientRPCService_testInsertStringRecords_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSInsertStringRecordsReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertStringRecords_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertStringRecords_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testInsertStringRecords_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testInsertStringRecords_result.prototype = {};
IClientRPCService_testInsertStringRecords_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testInsertStringRecords_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testInsertStringRecords_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_deleteData_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSDeleteDataReq(args.req);
    }
  }
};
IClientRPCService_deleteData_args.prototype = {};
IClientRPCService_deleteData_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSDeleteDataReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_deleteData_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_deleteData_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_deleteData_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_deleteData_result.prototype = {};
IClientRPCService_deleteData_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_deleteData_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_deleteData_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeRawDataQuery_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSRawDataQueryReq(args.req);
    }
  }
};
IClientRPCService_executeRawDataQuery_args.prototype = {};
IClientRPCService_executeRawDataQuery_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSRawDataQueryReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeRawDataQuery_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeRawDataQuery_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeRawDataQuery_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeRawDataQuery_result.prototype = {};
IClientRPCService_executeRawDataQuery_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeRawDataQuery_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeRawDataQuery_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeLastDataQuery_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSLastDataQueryReq(args.req);
    }
  }
};
IClientRPCService_executeLastDataQuery_args.prototype = {};
IClientRPCService_executeLastDataQuery_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSLastDataQueryReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeLastDataQuery_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeLastDataQuery_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeLastDataQuery_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeLastDataQuery_result.prototype = {};
IClientRPCService_executeLastDataQuery_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeLastDataQuery_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeLastDataQuery_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeAggregationQuery_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSAggregationQueryReq(args.req);
    }
  }
};
IClientRPCService_executeAggregationQuery_args.prototype = {};
IClientRPCService_executeAggregationQuery_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSAggregationQueryReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeAggregationQuery_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeAggregationQuery_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_executeAggregationQuery_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSExecuteStatementResp(args.success);
    }
  }
};
IClientRPCService_executeAggregationQuery_result.prototype = {};
IClientRPCService_executeAggregationQuery_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSExecuteStatementResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_executeAggregationQuery_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_executeAggregationQuery_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_requestStatementId_args = function(args) {
  this.sessionId = null;
  if (args) {
    if (args.sessionId !== undefined && args.sessionId !== null) {
      this.sessionId = args.sessionId;
    }
  }
};
IClientRPCService_requestStatementId_args.prototype = {};
IClientRPCService_requestStatementId_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.I64) {
        this.sessionId = input.readI64();
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_requestStatementId_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_requestStatementId_args');
  if (this.sessionId !== null && this.sessionId !== undefined) {
    output.writeFieldBegin('sessionId', Thrift.Type.I64, 1);
    output.writeI64(this.sessionId);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_requestStatementId_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = args.success;
    }
  }
};
IClientRPCService_requestStatementId_result.prototype = {};
IClientRPCService_requestStatementId_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.I64) {
        this.success = input.readI64();
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_requestStatementId_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_requestStatementId_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.I64, 0);
    output.writeI64(this.success);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSCreateSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_createSchemaTemplate_args.prototype = {};
IClientRPCService_createSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSCreateSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_createSchemaTemplate_result.prototype = {};
IClientRPCService_createSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_appendSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSAppendSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_appendSchemaTemplate_args.prototype = {};
IClientRPCService_appendSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSAppendSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_appendSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_appendSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_appendSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_appendSchemaTemplate_result.prototype = {};
IClientRPCService_appendSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_appendSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_appendSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_pruneSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSPruneSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_pruneSchemaTemplate_args.prototype = {};
IClientRPCService_pruneSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSPruneSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_pruneSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_pruneSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_pruneSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_pruneSchemaTemplate_result.prototype = {};
IClientRPCService_pruneSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_pruneSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_pruneSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_querySchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSQueryTemplateReq(args.req);
    }
  }
};
IClientRPCService_querySchemaTemplate_args.prototype = {};
IClientRPCService_querySchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSQueryTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_querySchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_querySchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_querySchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSQueryTemplateResp(args.success);
    }
  }
};
IClientRPCService_querySchemaTemplate_result.prototype = {};
IClientRPCService_querySchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSQueryTemplateResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_querySchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_querySchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_showConfigurationTemplate_args = function(args) {
};
IClientRPCService_showConfigurationTemplate_args.prototype = {};
IClientRPCService_showConfigurationTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    input.skip(ftype);
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_showConfigurationTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_showConfigurationTemplate_args');
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_showConfigurationTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TShowConfigurationTemplateResp(args.success);
    }
  }
};
IClientRPCService_showConfigurationTemplate_result.prototype = {};
IClientRPCService_showConfigurationTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TShowConfigurationTemplateResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_showConfigurationTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_showConfigurationTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_showConfiguration_args = function(args) {
  this.nodeId = null;
  if (args) {
    if (args.nodeId !== undefined && args.nodeId !== null) {
      this.nodeId = args.nodeId;
    }
  }
};
IClientRPCService_showConfiguration_args.prototype = {};
IClientRPCService_showConfiguration_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.I32) {
        this.nodeId = input.readI32();
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_showConfiguration_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_showConfiguration_args');
  if (this.nodeId !== null && this.nodeId !== undefined) {
    output.writeFieldBegin('nodeId', Thrift.Type.I32, 1);
    output.writeI32(this.nodeId);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_showConfiguration_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TShowConfigurationResp(args.success);
    }
  }
};
IClientRPCService_showConfiguration_result.prototype = {};
IClientRPCService_showConfiguration_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TShowConfigurationResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_showConfiguration_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_showConfiguration_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_setSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSSetSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_setSchemaTemplate_args.prototype = {};
IClientRPCService_setSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSSetSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_setSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_setSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_setSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_setSchemaTemplate_result.prototype = {};
IClientRPCService_setSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_setSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_setSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_unsetSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSUnsetSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_unsetSchemaTemplate_args.prototype = {};
IClientRPCService_unsetSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSUnsetSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_unsetSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_unsetSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_unsetSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_unsetSchemaTemplate_result.prototype = {};
IClientRPCService_unsetSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_unsetSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_unsetSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_dropSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TSDropSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_dropSchemaTemplate_args.prototype = {};
IClientRPCService_dropSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TSDropSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_dropSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_dropSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_dropSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_dropSchemaTemplate_result.prototype = {};
IClientRPCService_dropSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_dropSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_dropSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createTimeseriesUsingSchemaTemplate_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TCreateTimeseriesUsingSchemaTemplateReq(args.req);
    }
  }
};
IClientRPCService_createTimeseriesUsingSchemaTemplate_args.prototype = {};
IClientRPCService_createTimeseriesUsingSchemaTemplate_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TCreateTimeseriesUsingSchemaTemplateReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createTimeseriesUsingSchemaTemplate_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createTimeseriesUsingSchemaTemplate_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, 1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_createTimeseriesUsingSchemaTemplate_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_createTimeseriesUsingSchemaTemplate_result.prototype = {};
IClientRPCService_createTimeseriesUsingSchemaTemplate_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_createTimeseriesUsingSchemaTemplate_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_createTimeseriesUsingSchemaTemplate_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_handshake_args = function(args) {
  this.info = null;
  if (args) {
    if (args.info !== undefined && args.info !== null) {
      this.info = new ttypes.TSyncIdentityInfo(args.info);
    }
  }
};
IClientRPCService_handshake_args.prototype = {};
IClientRPCService_handshake_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case -1:
      if (ftype == Thrift.Type.STRUCT) {
        this.info = new ttypes.TSyncIdentityInfo();
        this.info.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_handshake_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_handshake_args');
  if (this.info !== null && this.info !== undefined) {
    output.writeFieldBegin('info', Thrift.Type.STRUCT, -1);
    this.info.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_handshake_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_handshake_result.prototype = {};
IClientRPCService_handshake_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_handshake_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_handshake_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_sendPipeData_args = function(args) {
  this.buff = null;
  if (args) {
    if (args.buff !== undefined && args.buff !== null) {
      this.buff = args.buff;
    }
  }
};
IClientRPCService_sendPipeData_args.prototype = {};
IClientRPCService_sendPipeData_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRING) {
        this.buff = input.readBinary();
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_sendPipeData_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_sendPipeData_args');
  if (this.buff !== null && this.buff !== undefined) {
    output.writeFieldBegin('buff', Thrift.Type.STRING, 1);
    output.writeBinary(this.buff);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_sendPipeData_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_sendPipeData_result.prototype = {};
IClientRPCService_sendPipeData_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_sendPipeData_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_sendPipeData_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_sendFile_args = function(args) {
  this.metaInfo = null;
  this.buff = null;
  if (args) {
    if (args.metaInfo !== undefined && args.metaInfo !== null) {
      this.metaInfo = new ttypes.TSyncTransportMetaInfo(args.metaInfo);
    }
    if (args.buff !== undefined && args.buff !== null) {
      this.buff = args.buff;
    }
  }
};
IClientRPCService_sendFile_args.prototype = {};
IClientRPCService_sendFile_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 1:
      if (ftype == Thrift.Type.STRUCT) {
        this.metaInfo = new ttypes.TSyncTransportMetaInfo();
        this.metaInfo.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 2:
      if (ftype == Thrift.Type.STRING) {
        this.buff = input.readBinary();
      } else {
        input.skip(ftype);
      }
      break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_sendFile_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_sendFile_args');
  if (this.metaInfo !== null && this.metaInfo !== undefined) {
    output.writeFieldBegin('metaInfo', Thrift.Type.STRUCT, 1);
    this.metaInfo.write(output);
    output.writeFieldEnd();
  }
  if (this.buff !== null && this.buff !== undefined) {
    output.writeFieldBegin('buff', Thrift.Type.STRING, 2);
    output.writeBinary(this.buff);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_sendFile_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_sendFile_result.prototype = {};
IClientRPCService_sendFile_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_sendFile_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_sendFile_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_pipeTransfer_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TPipeTransferReq(args.req);
    }
  }
};
IClientRPCService_pipeTransfer_args.prototype = {};
IClientRPCService_pipeTransfer_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case -1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TPipeTransferReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_pipeTransfer_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_pipeTransfer_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, -1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_pipeTransfer_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TPipeTransferResp(args.success);
    }
  }
};
IClientRPCService_pipeTransfer_result.prototype = {};
IClientRPCService_pipeTransfer_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TPipeTransferResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_pipeTransfer_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_pipeTransfer_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_pipeSubscribe_args = function(args) {
  this.req = null;
  if (args) {
    if (args.req !== undefined && args.req !== null) {
      this.req = new ttypes.TPipeSubscribeReq(args.req);
    }
  }
};
IClientRPCService_pipeSubscribe_args.prototype = {};
IClientRPCService_pipeSubscribe_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case -1:
      if (ftype == Thrift.Type.STRUCT) {
        this.req = new ttypes.TPipeSubscribeReq();
        this.req.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_pipeSubscribe_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_pipeSubscribe_args');
  if (this.req !== null && this.req !== undefined) {
    output.writeFieldBegin('req', Thrift.Type.STRUCT, -1);
    this.req.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_pipeSubscribe_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TPipeSubscribeResp(args.success);
    }
  }
};
IClientRPCService_pipeSubscribe_result.prototype = {};
IClientRPCService_pipeSubscribe_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TPipeSubscribeResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_pipeSubscribe_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_pipeSubscribe_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_getBackupConfiguration_args = function(args) {
};
IClientRPCService_getBackupConfiguration_args.prototype = {};
IClientRPCService_getBackupConfiguration_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    input.skip(ftype);
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_getBackupConfiguration_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_getBackupConfiguration_args');
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_getBackupConfiguration_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSBackupConfigurationResp(args.success);
    }
  }
};
IClientRPCService_getBackupConfiguration_result.prototype = {};
IClientRPCService_getBackupConfiguration_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSBackupConfigurationResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_getBackupConfiguration_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_getBackupConfiguration_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchAllConnectionsInfo_args = function(args) {
};
IClientRPCService_fetchAllConnectionsInfo_args.prototype = {};
IClientRPCService_fetchAllConnectionsInfo_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    input.skip(ftype);
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchAllConnectionsInfo_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchAllConnectionsInfo_args');
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_fetchAllConnectionsInfo_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new ttypes.TSConnectionInfoResp(args.success);
    }
  }
};
IClientRPCService_fetchAllConnectionsInfo_result.prototype = {};
IClientRPCService_fetchAllConnectionsInfo_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new ttypes.TSConnectionInfoResp();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_fetchAllConnectionsInfo_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_fetchAllConnectionsInfo_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testConnectionEmptyRPC_args = function(args) {
};
IClientRPCService_testConnectionEmptyRPC_args.prototype = {};
IClientRPCService_testConnectionEmptyRPC_args.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    input.skip(ftype);
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testConnectionEmptyRPC_args.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testConnectionEmptyRPC_args');
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCService_testConnectionEmptyRPC_result = function(args) {
  this.success = null;
  if (args) {
    if (args.success !== undefined && args.success !== null) {
      this.success = new common_ttypes.TSStatus(args.success);
    }
  }
};
IClientRPCService_testConnectionEmptyRPC_result.prototype = {};
IClientRPCService_testConnectionEmptyRPC_result.prototype.read = function(input) {
  input.readStructBegin();
  while (true) {
    var ret = input.readFieldBegin();
    var ftype = ret.ftype;
    var fid = ret.fid;
    if (ftype == Thrift.Type.STOP) {
      break;
    }
    switch (fid) {
      case 0:
      if (ftype == Thrift.Type.STRUCT) {
        this.success = new common_ttypes.TSStatus();
        this.success.read(input);
      } else {
        input.skip(ftype);
      }
      break;
      case 0:
        input.skip(ftype);
        break;
      default:
        input.skip(ftype);
    }
    input.readFieldEnd();
  }
  input.readStructEnd();
  return;
};

IClientRPCService_testConnectionEmptyRPC_result.prototype.write = function(output) {
  output.writeStructBegin('IClientRPCService_testConnectionEmptyRPC_result');
  if (this.success !== null && this.success !== undefined) {
    output.writeFieldBegin('success', Thrift.Type.STRUCT, 0);
    this.success.write(output);
    output.writeFieldEnd();
  }
  output.writeFieldStop();
  output.writeStructEnd();
  return;
};

var IClientRPCServiceClient = exports.Client = function(output, pClass) {
  this.output = output;
  this.pClass = pClass;
  this._seqid = 0;
  this._reqs = {};
};
IClientRPCServiceClient.prototype = {};
IClientRPCServiceClient.prototype.seqid = function() { return this._seqid; };
IClientRPCServiceClient.prototype.new_seqid = function() { return this._seqid += 1; };

IClientRPCServiceClient.prototype.executeQueryStatementV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeQueryStatementV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeQueryStatementV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeQueryStatementV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeQueryStatementV2_args(params);
  try {
    output.writeMessageBegin('executeQueryStatementV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeQueryStatementV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeQueryStatementV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeQueryStatementV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.executeUpdateStatementV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeUpdateStatementV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeUpdateStatementV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeUpdateStatementV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeUpdateStatementV2_args(params);
  try {
    output.writeMessageBegin('executeUpdateStatementV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeUpdateStatementV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeUpdateStatementV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeUpdateStatementV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.executeStatementV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeStatementV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeStatementV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeStatementV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeStatementV2_args(params);
  try {
    output.writeMessageBegin('executeStatementV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeStatementV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeStatementV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeStatementV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.executeRawDataQueryV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeRawDataQueryV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeRawDataQueryV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeRawDataQueryV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeRawDataQueryV2_args(params);
  try {
    output.writeMessageBegin('executeRawDataQueryV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeRawDataQueryV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeRawDataQueryV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeRawDataQueryV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.executeLastDataQueryV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeLastDataQueryV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeLastDataQueryV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeLastDataQueryV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeLastDataQueryV2_args(params);
  try {
    output.writeMessageBegin('executeLastDataQueryV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeLastDataQueryV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeLastDataQueryV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeLastDataQueryV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.executeFastLastDataQueryForOnePrefixPath = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeFastLastDataQueryForOnePrefixPath(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeFastLastDataQueryForOnePrefixPath(req);
  }
};

IClientRPCServiceClient.prototype.send_executeFastLastDataQueryForOnePrefixPath = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args(params);
  try {
    output.writeMessageBegin('executeFastLastDataQueryForOnePrefixPath', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeFastLastDataQueryForOnePrefixPath = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeFastLastDataQueryForOnePrefixPath failed: unknown result');
};

IClientRPCServiceClient.prototype.executeFastLastDataQueryForOneDeviceV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeFastLastDataQueryForOneDeviceV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeFastLastDataQueryForOneDeviceV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeFastLastDataQueryForOneDeviceV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args(params);
  try {
    output.writeMessageBegin('executeFastLastDataQueryForOneDeviceV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeFastLastDataQueryForOneDeviceV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeFastLastDataQueryForOneDeviceV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.executeAggregationQueryV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeAggregationQueryV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeAggregationQueryV2(req);
  }
};

IClientRPCServiceClient.prototype.send_executeAggregationQueryV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeAggregationQueryV2_args(params);
  try {
    output.writeMessageBegin('executeAggregationQueryV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeAggregationQueryV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeAggregationQueryV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeAggregationQueryV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.fetchResultsV2 = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_fetchResultsV2(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_fetchResultsV2(req);
  }
};

IClientRPCServiceClient.prototype.send_fetchResultsV2 = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_fetchResultsV2_args(params);
  try {
    output.writeMessageBegin('fetchResultsV2', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_fetchResultsV2 = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_fetchResultsV2_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('fetchResultsV2 failed: unknown result');
};

IClientRPCServiceClient.prototype.openSession = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_openSession(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_openSession(req);
  }
};

IClientRPCServiceClient.prototype.send_openSession = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_openSession_args(params);
  try {
    output.writeMessageBegin('openSession', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_openSession = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_openSession_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('openSession failed: unknown result');
};

IClientRPCServiceClient.prototype.closeSession = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_closeSession(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_closeSession(req);
  }
};

IClientRPCServiceClient.prototype.send_closeSession = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_closeSession_args(params);
  try {
    output.writeMessageBegin('closeSession', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_closeSession = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_closeSession_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('closeSession failed: unknown result');
};

IClientRPCServiceClient.prototype.executeStatement = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeStatement(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeStatement(req);
  }
};

IClientRPCServiceClient.prototype.send_executeStatement = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeStatement_args(params);
  try {
    output.writeMessageBegin('executeStatement', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeStatement = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeStatement_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeStatement failed: unknown result');
};

IClientRPCServiceClient.prototype.executeBatchStatement = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeBatchStatement(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeBatchStatement(req);
  }
};

IClientRPCServiceClient.prototype.send_executeBatchStatement = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeBatchStatement_args(params);
  try {
    output.writeMessageBegin('executeBatchStatement', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeBatchStatement = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeBatchStatement_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeBatchStatement failed: unknown result');
};

IClientRPCServiceClient.prototype.executeQueryStatement = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeQueryStatement(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeQueryStatement(req);
  }
};

IClientRPCServiceClient.prototype.send_executeQueryStatement = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeQueryStatement_args(params);
  try {
    output.writeMessageBegin('executeQueryStatement', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeQueryStatement = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeQueryStatement_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeQueryStatement failed: unknown result');
};

IClientRPCServiceClient.prototype.executeUpdateStatement = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeUpdateStatement(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeUpdateStatement(req);
  }
};

IClientRPCServiceClient.prototype.send_executeUpdateStatement = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeUpdateStatement_args(params);
  try {
    output.writeMessageBegin('executeUpdateStatement', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeUpdateStatement = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeUpdateStatement_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeUpdateStatement failed: unknown result');
};

IClientRPCServiceClient.prototype.fetchResults = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_fetchResults(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_fetchResults(req);
  }
};

IClientRPCServiceClient.prototype.send_fetchResults = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_fetchResults_args(params);
  try {
    output.writeMessageBegin('fetchResults', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_fetchResults = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_fetchResults_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('fetchResults failed: unknown result');
};

IClientRPCServiceClient.prototype.fetchMetadata = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_fetchMetadata(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_fetchMetadata(req);
  }
};

IClientRPCServiceClient.prototype.send_fetchMetadata = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_fetchMetadata_args(params);
  try {
    output.writeMessageBegin('fetchMetadata', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_fetchMetadata = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_fetchMetadata_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('fetchMetadata failed: unknown result');
};

IClientRPCServiceClient.prototype.cancelOperation = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_cancelOperation(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_cancelOperation(req);
  }
};

IClientRPCServiceClient.prototype.send_cancelOperation = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_cancelOperation_args(params);
  try {
    output.writeMessageBegin('cancelOperation', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_cancelOperation = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_cancelOperation_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('cancelOperation failed: unknown result');
};

IClientRPCServiceClient.prototype.closeOperation = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_closeOperation(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_closeOperation(req);
  }
};

IClientRPCServiceClient.prototype.send_closeOperation = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_closeOperation_args(params);
  try {
    output.writeMessageBegin('closeOperation', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_closeOperation = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_closeOperation_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('closeOperation failed: unknown result');
};

IClientRPCServiceClient.prototype.getTimeZone = function(sessionId, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_getTimeZone(sessionId);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_getTimeZone(sessionId);
  }
};

IClientRPCServiceClient.prototype.send_getTimeZone = function(sessionId) {
  var output = new this.pClass(this.output);
  var params = {
    sessionId: sessionId
  };
  var args = new IClientRPCService_getTimeZone_args(params);
  try {
    output.writeMessageBegin('getTimeZone', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_getTimeZone = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_getTimeZone_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('getTimeZone failed: unknown result');
};

IClientRPCServiceClient.prototype.setTimeZone = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_setTimeZone(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_setTimeZone(req);
  }
};

IClientRPCServiceClient.prototype.send_setTimeZone = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_setTimeZone_args(params);
  try {
    output.writeMessageBegin('setTimeZone', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_setTimeZone = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_setTimeZone_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('setTimeZone failed: unknown result');
};

IClientRPCServiceClient.prototype.getProperties = function(callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_getProperties();
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_getProperties();
  }
};

IClientRPCServiceClient.prototype.send_getProperties = function() {
  var output = new this.pClass(this.output);
  var args = new IClientRPCService_getProperties_args();
  try {
    output.writeMessageBegin('getProperties', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_getProperties = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_getProperties_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('getProperties failed: unknown result');
};

IClientRPCServiceClient.prototype.setStorageGroup = function(sessionId, storageGroup, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_setStorageGroup(sessionId, storageGroup);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_setStorageGroup(sessionId, storageGroup);
  }
};

IClientRPCServiceClient.prototype.send_setStorageGroup = function(sessionId, storageGroup) {
  var output = new this.pClass(this.output);
  var params = {
    sessionId: sessionId,
    storageGroup: storageGroup
  };
  var args = new IClientRPCService_setStorageGroup_args(params);
  try {
    output.writeMessageBegin('setStorageGroup', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_setStorageGroup = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_setStorageGroup_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('setStorageGroup failed: unknown result');
};

IClientRPCServiceClient.prototype.createTimeseries = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_createTimeseries(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_createTimeseries(req);
  }
};

IClientRPCServiceClient.prototype.send_createTimeseries = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_createTimeseries_args(params);
  try {
    output.writeMessageBegin('createTimeseries', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_createTimeseries = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_createTimeseries_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('createTimeseries failed: unknown result');
};

IClientRPCServiceClient.prototype.createAlignedTimeseries = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_createAlignedTimeseries(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_createAlignedTimeseries(req);
  }
};

IClientRPCServiceClient.prototype.send_createAlignedTimeseries = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_createAlignedTimeseries_args(params);
  try {
    output.writeMessageBegin('createAlignedTimeseries', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_createAlignedTimeseries = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_createAlignedTimeseries_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('createAlignedTimeseries failed: unknown result');
};

IClientRPCServiceClient.prototype.createMultiTimeseries = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_createMultiTimeseries(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_createMultiTimeseries(req);
  }
};

IClientRPCServiceClient.prototype.send_createMultiTimeseries = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_createMultiTimeseries_args(params);
  try {
    output.writeMessageBegin('createMultiTimeseries', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_createMultiTimeseries = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_createMultiTimeseries_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('createMultiTimeseries failed: unknown result');
};

IClientRPCServiceClient.prototype.deleteTimeseries = function(sessionId, path, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_deleteTimeseries(sessionId, path);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_deleteTimeseries(sessionId, path);
  }
};

IClientRPCServiceClient.prototype.send_deleteTimeseries = function(sessionId, path) {
  var output = new this.pClass(this.output);
  var params = {
    sessionId: sessionId,
    path: path
  };
  var args = new IClientRPCService_deleteTimeseries_args(params);
  try {
    output.writeMessageBegin('deleteTimeseries', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_deleteTimeseries = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_deleteTimeseries_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('deleteTimeseries failed: unknown result');
};

IClientRPCServiceClient.prototype.deleteStorageGroups = function(sessionId, storageGroup, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_deleteStorageGroups(sessionId, storageGroup);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_deleteStorageGroups(sessionId, storageGroup);
  }
};

IClientRPCServiceClient.prototype.send_deleteStorageGroups = function(sessionId, storageGroup) {
  var output = new this.pClass(this.output);
  var params = {
    sessionId: sessionId,
    storageGroup: storageGroup
  };
  var args = new IClientRPCService_deleteStorageGroups_args(params);
  try {
    output.writeMessageBegin('deleteStorageGroups', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_deleteStorageGroups = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_deleteStorageGroups_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('deleteStorageGroups failed: unknown result');
};

IClientRPCServiceClient.prototype.insertRecord = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertRecord(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertRecord(req);
  }
};

IClientRPCServiceClient.prototype.send_insertRecord = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertRecord_args(params);
  try {
    output.writeMessageBegin('insertRecord', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertRecord = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertRecord_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertRecord failed: unknown result');
};

IClientRPCServiceClient.prototype.insertStringRecord = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertStringRecord(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertStringRecord(req);
  }
};

IClientRPCServiceClient.prototype.send_insertStringRecord = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertStringRecord_args(params);
  try {
    output.writeMessageBegin('insertStringRecord', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertStringRecord = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertStringRecord_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertStringRecord failed: unknown result');
};

IClientRPCServiceClient.prototype.insertTablet = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertTablet(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertTablet(req);
  }
};

IClientRPCServiceClient.prototype.send_insertTablet = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertTablet_args(params);
  try {
    output.writeMessageBegin('insertTablet', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertTablet = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertTablet_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertTablet failed: unknown result');
};

IClientRPCServiceClient.prototype.insertTablets = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertTablets(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertTablets(req);
  }
};

IClientRPCServiceClient.prototype.send_insertTablets = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertTablets_args(params);
  try {
    output.writeMessageBegin('insertTablets', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertTablets = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertTablets_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertTablets failed: unknown result');
};

IClientRPCServiceClient.prototype.insertRecords = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertRecords(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertRecords(req);
  }
};

IClientRPCServiceClient.prototype.send_insertRecords = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertRecords_args(params);
  try {
    output.writeMessageBegin('insertRecords', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertRecords = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertRecords_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertRecords failed: unknown result');
};

IClientRPCServiceClient.prototype.insertRecordsOfOneDevice = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertRecordsOfOneDevice(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertRecordsOfOneDevice(req);
  }
};

IClientRPCServiceClient.prototype.send_insertRecordsOfOneDevice = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertRecordsOfOneDevice_args(params);
  try {
    output.writeMessageBegin('insertRecordsOfOneDevice', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertRecordsOfOneDevice = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertRecordsOfOneDevice_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertRecordsOfOneDevice failed: unknown result');
};

IClientRPCServiceClient.prototype.insertStringRecordsOfOneDevice = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertStringRecordsOfOneDevice(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertStringRecordsOfOneDevice(req);
  }
};

IClientRPCServiceClient.prototype.send_insertStringRecordsOfOneDevice = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertStringRecordsOfOneDevice_args(params);
  try {
    output.writeMessageBegin('insertStringRecordsOfOneDevice', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertStringRecordsOfOneDevice = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertStringRecordsOfOneDevice_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertStringRecordsOfOneDevice failed: unknown result');
};

IClientRPCServiceClient.prototype.insertStringRecords = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_insertStringRecords(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_insertStringRecords(req);
  }
};

IClientRPCServiceClient.prototype.send_insertStringRecords = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_insertStringRecords_args(params);
  try {
    output.writeMessageBegin('insertStringRecords', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_insertStringRecords = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_insertStringRecords_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('insertStringRecords failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertTablet = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertTablet(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertTablet(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertTablet = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertTablet_args(params);
  try {
    output.writeMessageBegin('testInsertTablet', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertTablet = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertTablet_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertTablet failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertTablets = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertTablets(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertTablets(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertTablets = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertTablets_args(params);
  try {
    output.writeMessageBegin('testInsertTablets', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertTablets = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertTablets_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertTablets failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertRecord = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertRecord(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertRecord(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertRecord = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertRecord_args(params);
  try {
    output.writeMessageBegin('testInsertRecord', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertRecord = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertRecord_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertRecord failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertStringRecord = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertStringRecord(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertStringRecord(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertStringRecord = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertStringRecord_args(params);
  try {
    output.writeMessageBegin('testInsertStringRecord', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertStringRecord = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertStringRecord_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertStringRecord failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertRecords = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertRecords(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertRecords(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertRecords = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertRecords_args(params);
  try {
    output.writeMessageBegin('testInsertRecords', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertRecords = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertRecords_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertRecords failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertRecordsOfOneDevice = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertRecordsOfOneDevice(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertRecordsOfOneDevice(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertRecordsOfOneDevice = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertRecordsOfOneDevice_args(params);
  try {
    output.writeMessageBegin('testInsertRecordsOfOneDevice', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertRecordsOfOneDevice = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertRecordsOfOneDevice_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertRecordsOfOneDevice failed: unknown result');
};

IClientRPCServiceClient.prototype.testInsertStringRecords = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testInsertStringRecords(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testInsertStringRecords(req);
  }
};

IClientRPCServiceClient.prototype.send_testInsertStringRecords = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_testInsertStringRecords_args(params);
  try {
    output.writeMessageBegin('testInsertStringRecords', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testInsertStringRecords = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testInsertStringRecords_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testInsertStringRecords failed: unknown result');
};

IClientRPCServiceClient.prototype.deleteData = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_deleteData(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_deleteData(req);
  }
};

IClientRPCServiceClient.prototype.send_deleteData = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_deleteData_args(params);
  try {
    output.writeMessageBegin('deleteData', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_deleteData = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_deleteData_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('deleteData failed: unknown result');
};

IClientRPCServiceClient.prototype.executeRawDataQuery = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeRawDataQuery(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeRawDataQuery(req);
  }
};

IClientRPCServiceClient.prototype.send_executeRawDataQuery = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeRawDataQuery_args(params);
  try {
    output.writeMessageBegin('executeRawDataQuery', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeRawDataQuery = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeRawDataQuery_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeRawDataQuery failed: unknown result');
};

IClientRPCServiceClient.prototype.executeLastDataQuery = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeLastDataQuery(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeLastDataQuery(req);
  }
};

IClientRPCServiceClient.prototype.send_executeLastDataQuery = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeLastDataQuery_args(params);
  try {
    output.writeMessageBegin('executeLastDataQuery', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeLastDataQuery = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeLastDataQuery_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeLastDataQuery failed: unknown result');
};

IClientRPCServiceClient.prototype.executeAggregationQuery = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_executeAggregationQuery(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_executeAggregationQuery(req);
  }
};

IClientRPCServiceClient.prototype.send_executeAggregationQuery = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_executeAggregationQuery_args(params);
  try {
    output.writeMessageBegin('executeAggregationQuery', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_executeAggregationQuery = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_executeAggregationQuery_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('executeAggregationQuery failed: unknown result');
};

IClientRPCServiceClient.prototype.requestStatementId = function(sessionId, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_requestStatementId(sessionId);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_requestStatementId(sessionId);
  }
};

IClientRPCServiceClient.prototype.send_requestStatementId = function(sessionId) {
  var output = new this.pClass(this.output);
  var params = {
    sessionId: sessionId
  };
  var args = new IClientRPCService_requestStatementId_args(params);
  try {
    output.writeMessageBegin('requestStatementId', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_requestStatementId = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_requestStatementId_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('requestStatementId failed: unknown result');
};

IClientRPCServiceClient.prototype.createSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_createSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_createSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_createSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_createSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('createSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_createSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_createSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('createSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.appendSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_appendSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_appendSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_appendSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_appendSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('appendSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_appendSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_appendSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('appendSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.pruneSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_pruneSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_pruneSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_pruneSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_pruneSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('pruneSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_pruneSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_pruneSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('pruneSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.querySchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_querySchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_querySchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_querySchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_querySchemaTemplate_args(params);
  try {
    output.writeMessageBegin('querySchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_querySchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_querySchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('querySchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.showConfigurationTemplate = function(callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_showConfigurationTemplate();
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_showConfigurationTemplate();
  }
};

IClientRPCServiceClient.prototype.send_showConfigurationTemplate = function() {
  var output = new this.pClass(this.output);
  var args = new IClientRPCService_showConfigurationTemplate_args();
  try {
    output.writeMessageBegin('showConfigurationTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_showConfigurationTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_showConfigurationTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('showConfigurationTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.showConfiguration = function(nodeId, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_showConfiguration(nodeId);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_showConfiguration(nodeId);
  }
};

IClientRPCServiceClient.prototype.send_showConfiguration = function(nodeId) {
  var output = new this.pClass(this.output);
  var params = {
    nodeId: nodeId
  };
  var args = new IClientRPCService_showConfiguration_args(params);
  try {
    output.writeMessageBegin('showConfiguration', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_showConfiguration = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_showConfiguration_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('showConfiguration failed: unknown result');
};

IClientRPCServiceClient.prototype.setSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_setSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_setSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_setSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_setSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('setSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_setSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_setSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('setSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.unsetSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_unsetSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_unsetSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_unsetSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_unsetSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('unsetSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_unsetSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_unsetSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('unsetSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.dropSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_dropSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_dropSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_dropSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_dropSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('dropSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_dropSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_dropSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('dropSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.createTimeseriesUsingSchemaTemplate = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_createTimeseriesUsingSchemaTemplate(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_createTimeseriesUsingSchemaTemplate(req);
  }
};

IClientRPCServiceClient.prototype.send_createTimeseriesUsingSchemaTemplate = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_createTimeseriesUsingSchemaTemplate_args(params);
  try {
    output.writeMessageBegin('createTimeseriesUsingSchemaTemplate', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_createTimeseriesUsingSchemaTemplate = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_createTimeseriesUsingSchemaTemplate_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('createTimeseriesUsingSchemaTemplate failed: unknown result');
};

IClientRPCServiceClient.prototype.handshake = function(info, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_handshake(info);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_handshake(info);
  }
};

IClientRPCServiceClient.prototype.send_handshake = function(info) {
  var output = new this.pClass(this.output);
  var params = {
    info: info
  };
  var args = new IClientRPCService_handshake_args(params);
  try {
    output.writeMessageBegin('handshake', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_handshake = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_handshake_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('handshake failed: unknown result');
};

IClientRPCServiceClient.prototype.sendPipeData = function(buff, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_sendPipeData(buff);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_sendPipeData(buff);
  }
};

IClientRPCServiceClient.prototype.send_sendPipeData = function(buff) {
  var output = new this.pClass(this.output);
  var params = {
    buff: buff
  };
  var args = new IClientRPCService_sendPipeData_args(params);
  try {
    output.writeMessageBegin('sendPipeData', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_sendPipeData = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_sendPipeData_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('sendPipeData failed: unknown result');
};

IClientRPCServiceClient.prototype.sendFile = function(metaInfo, buff, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_sendFile(metaInfo, buff);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_sendFile(metaInfo, buff);
  }
};

IClientRPCServiceClient.prototype.send_sendFile = function(metaInfo, buff) {
  var output = new this.pClass(this.output);
  var params = {
    metaInfo: metaInfo,
    buff: buff
  };
  var args = new IClientRPCService_sendFile_args(params);
  try {
    output.writeMessageBegin('sendFile', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_sendFile = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_sendFile_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('sendFile failed: unknown result');
};

IClientRPCServiceClient.prototype.pipeTransfer = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_pipeTransfer(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_pipeTransfer(req);
  }
};

IClientRPCServiceClient.prototype.send_pipeTransfer = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_pipeTransfer_args(params);
  try {
    output.writeMessageBegin('pipeTransfer', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_pipeTransfer = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_pipeTransfer_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('pipeTransfer failed: unknown result');
};

IClientRPCServiceClient.prototype.pipeSubscribe = function(req, callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_pipeSubscribe(req);
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_pipeSubscribe(req);
  }
};

IClientRPCServiceClient.prototype.send_pipeSubscribe = function(req) {
  var output = new this.pClass(this.output);
  var params = {
    req: req
  };
  var args = new IClientRPCService_pipeSubscribe_args(params);
  try {
    output.writeMessageBegin('pipeSubscribe', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_pipeSubscribe = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_pipeSubscribe_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('pipeSubscribe failed: unknown result');
};

IClientRPCServiceClient.prototype.getBackupConfiguration = function(callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_getBackupConfiguration();
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_getBackupConfiguration();
  }
};

IClientRPCServiceClient.prototype.send_getBackupConfiguration = function() {
  var output = new this.pClass(this.output);
  var args = new IClientRPCService_getBackupConfiguration_args();
  try {
    output.writeMessageBegin('getBackupConfiguration', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_getBackupConfiguration = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_getBackupConfiguration_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('getBackupConfiguration failed: unknown result');
};

IClientRPCServiceClient.prototype.fetchAllConnectionsInfo = function(callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_fetchAllConnectionsInfo();
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_fetchAllConnectionsInfo();
  }
};

IClientRPCServiceClient.prototype.send_fetchAllConnectionsInfo = function() {
  var output = new this.pClass(this.output);
  var args = new IClientRPCService_fetchAllConnectionsInfo_args();
  try {
    output.writeMessageBegin('fetchAllConnectionsInfo', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_fetchAllConnectionsInfo = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_fetchAllConnectionsInfo_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('fetchAllConnectionsInfo failed: unknown result');
};

IClientRPCServiceClient.prototype.testConnectionEmptyRPC = function(callback) {
  this._seqid = this.new_seqid();
  if (callback === undefined) {
    var _defer = Q.defer();
    this._reqs[this.seqid()] = function(error, result) {
      if (error) {
        _defer.reject(error);
      } else {
        _defer.resolve(result);
      }
    };
    this.send_testConnectionEmptyRPC();
    return _defer.promise;
  } else {
    this._reqs[this.seqid()] = callback;
    this.send_testConnectionEmptyRPC();
  }
};

IClientRPCServiceClient.prototype.send_testConnectionEmptyRPC = function() {
  var output = new this.pClass(this.output);
  var args = new IClientRPCService_testConnectionEmptyRPC_args();
  try {
    output.writeMessageBegin('testConnectionEmptyRPC', Thrift.MessageType.CALL, this.seqid());
    args.write(output);
    output.writeMessageEnd();
    return this.output.flush();
  }
  catch (e) {
    delete this._reqs[this.seqid()];
    if (typeof output.reset === 'function') {
      output.reset();
    }
    throw e;
  }
};

IClientRPCServiceClient.prototype.recv_testConnectionEmptyRPC = function(input,mtype,rseqid) {
  var callback = this._reqs[rseqid] || function() {};
  delete this._reqs[rseqid];
  if (mtype == Thrift.MessageType.EXCEPTION) {
    var x = new Thrift.TApplicationException();
    x.read(input);
    input.readMessageEnd();
    return callback(x);
  }
  var result = new IClientRPCService_testConnectionEmptyRPC_result();
  result.read(input);
  input.readMessageEnd();

  if (null !== result.success) {
    return callback(null, result.success);
  }
  return callback('testConnectionEmptyRPC failed: unknown result');
};
var IClientRPCServiceProcessor = exports.Processor = function(handler) {
  this._handler = handler;
};
IClientRPCServiceProcessor.prototype.process = function(input, output) {
  var r = input.readMessageBegin();
  if (this['process_' + r.fname]) {
    return this['process_' + r.fname].call(this, r.rseqid, input, output);
  } else {
    input.skip(Thrift.Type.STRUCT);
    input.readMessageEnd();
    var x = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN_METHOD, 'Unknown function ' + r.fname);
    output.writeMessageBegin(r.fname, Thrift.MessageType.EXCEPTION, r.rseqid);
    x.write(output);
    output.writeMessageEnd();
    output.flush();
  }
};
IClientRPCServiceProcessor.prototype.process_executeQueryStatementV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeQueryStatementV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeQueryStatementV2.length === 1) {
    Q.fcall(this._handler.executeQueryStatementV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeQueryStatementV2_result({success: result});
      output.writeMessageBegin("executeQueryStatementV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeQueryStatementV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeQueryStatementV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeQueryStatementV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeQueryStatementV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeQueryStatementV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeUpdateStatementV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeUpdateStatementV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeUpdateStatementV2.length === 1) {
    Q.fcall(this._handler.executeUpdateStatementV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeUpdateStatementV2_result({success: result});
      output.writeMessageBegin("executeUpdateStatementV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeUpdateStatementV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeUpdateStatementV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeUpdateStatementV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeUpdateStatementV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeUpdateStatementV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeStatementV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeStatementV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeStatementV2.length === 1) {
    Q.fcall(this._handler.executeStatementV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeStatementV2_result({success: result});
      output.writeMessageBegin("executeStatementV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeStatementV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeStatementV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeStatementV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeStatementV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeStatementV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeRawDataQueryV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeRawDataQueryV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeRawDataQueryV2.length === 1) {
    Q.fcall(this._handler.executeRawDataQueryV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeRawDataQueryV2_result({success: result});
      output.writeMessageBegin("executeRawDataQueryV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeRawDataQueryV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeRawDataQueryV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeRawDataQueryV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeRawDataQueryV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeRawDataQueryV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeLastDataQueryV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeLastDataQueryV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeLastDataQueryV2.length === 1) {
    Q.fcall(this._handler.executeLastDataQueryV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeLastDataQueryV2_result({success: result});
      output.writeMessageBegin("executeLastDataQueryV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeLastDataQueryV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeLastDataQueryV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeLastDataQueryV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeLastDataQueryV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeLastDataQueryV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeFastLastDataQueryForOnePrefixPath = function(seqid, input, output) {
  var args = new IClientRPCService_executeFastLastDataQueryForOnePrefixPath_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeFastLastDataQueryForOnePrefixPath.length === 1) {
    Q.fcall(this._handler.executeFastLastDataQueryForOnePrefixPath.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result({success: result});
      output.writeMessageBegin("executeFastLastDataQueryForOnePrefixPath", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeFastLastDataQueryForOnePrefixPath", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeFastLastDataQueryForOnePrefixPath(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeFastLastDataQueryForOnePrefixPath_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeFastLastDataQueryForOnePrefixPath", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeFastLastDataQueryForOnePrefixPath", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeFastLastDataQueryForOneDeviceV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeFastLastDataQueryForOneDeviceV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeFastLastDataQueryForOneDeviceV2.length === 1) {
    Q.fcall(this._handler.executeFastLastDataQueryForOneDeviceV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result({success: result});
      output.writeMessageBegin("executeFastLastDataQueryForOneDeviceV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeFastLastDataQueryForOneDeviceV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeFastLastDataQueryForOneDeviceV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeFastLastDataQueryForOneDeviceV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeFastLastDataQueryForOneDeviceV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeFastLastDataQueryForOneDeviceV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeAggregationQueryV2 = function(seqid, input, output) {
  var args = new IClientRPCService_executeAggregationQueryV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeAggregationQueryV2.length === 1) {
    Q.fcall(this._handler.executeAggregationQueryV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeAggregationQueryV2_result({success: result});
      output.writeMessageBegin("executeAggregationQueryV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeAggregationQueryV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeAggregationQueryV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeAggregationQueryV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeAggregationQueryV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeAggregationQueryV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_fetchResultsV2 = function(seqid, input, output) {
  var args = new IClientRPCService_fetchResultsV2_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.fetchResultsV2.length === 1) {
    Q.fcall(this._handler.fetchResultsV2.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_fetchResultsV2_result({success: result});
      output.writeMessageBegin("fetchResultsV2", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("fetchResultsV2", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.fetchResultsV2(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_fetchResultsV2_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("fetchResultsV2", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("fetchResultsV2", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_openSession = function(seqid, input, output) {
  var args = new IClientRPCService_openSession_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.openSession.length === 1) {
    Q.fcall(this._handler.openSession.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_openSession_result({success: result});
      output.writeMessageBegin("openSession", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("openSession", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.openSession(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_openSession_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("openSession", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("openSession", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_closeSession = function(seqid, input, output) {
  var args = new IClientRPCService_closeSession_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.closeSession.length === 1) {
    Q.fcall(this._handler.closeSession.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_closeSession_result({success: result});
      output.writeMessageBegin("closeSession", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("closeSession", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.closeSession(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_closeSession_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("closeSession", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("closeSession", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeStatement = function(seqid, input, output) {
  var args = new IClientRPCService_executeStatement_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeStatement.length === 1) {
    Q.fcall(this._handler.executeStatement.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeStatement_result({success: result});
      output.writeMessageBegin("executeStatement", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeStatement", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeStatement(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeStatement_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeStatement", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeStatement", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeBatchStatement = function(seqid, input, output) {
  var args = new IClientRPCService_executeBatchStatement_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeBatchStatement.length === 1) {
    Q.fcall(this._handler.executeBatchStatement.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeBatchStatement_result({success: result});
      output.writeMessageBegin("executeBatchStatement", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeBatchStatement", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeBatchStatement(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeBatchStatement_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeBatchStatement", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeBatchStatement", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeQueryStatement = function(seqid, input, output) {
  var args = new IClientRPCService_executeQueryStatement_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeQueryStatement.length === 1) {
    Q.fcall(this._handler.executeQueryStatement.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeQueryStatement_result({success: result});
      output.writeMessageBegin("executeQueryStatement", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeQueryStatement", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeQueryStatement(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeQueryStatement_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeQueryStatement", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeQueryStatement", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeUpdateStatement = function(seqid, input, output) {
  var args = new IClientRPCService_executeUpdateStatement_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeUpdateStatement.length === 1) {
    Q.fcall(this._handler.executeUpdateStatement.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeUpdateStatement_result({success: result});
      output.writeMessageBegin("executeUpdateStatement", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeUpdateStatement", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeUpdateStatement(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeUpdateStatement_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeUpdateStatement", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeUpdateStatement", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_fetchResults = function(seqid, input, output) {
  var args = new IClientRPCService_fetchResults_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.fetchResults.length === 1) {
    Q.fcall(this._handler.fetchResults.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_fetchResults_result({success: result});
      output.writeMessageBegin("fetchResults", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("fetchResults", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.fetchResults(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_fetchResults_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("fetchResults", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("fetchResults", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_fetchMetadata = function(seqid, input, output) {
  var args = new IClientRPCService_fetchMetadata_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.fetchMetadata.length === 1) {
    Q.fcall(this._handler.fetchMetadata.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_fetchMetadata_result({success: result});
      output.writeMessageBegin("fetchMetadata", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("fetchMetadata", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.fetchMetadata(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_fetchMetadata_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("fetchMetadata", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("fetchMetadata", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_cancelOperation = function(seqid, input, output) {
  var args = new IClientRPCService_cancelOperation_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.cancelOperation.length === 1) {
    Q.fcall(this._handler.cancelOperation.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_cancelOperation_result({success: result});
      output.writeMessageBegin("cancelOperation", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("cancelOperation", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.cancelOperation(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_cancelOperation_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("cancelOperation", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("cancelOperation", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_closeOperation = function(seqid, input, output) {
  var args = new IClientRPCService_closeOperation_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.closeOperation.length === 1) {
    Q.fcall(this._handler.closeOperation.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_closeOperation_result({success: result});
      output.writeMessageBegin("closeOperation", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("closeOperation", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.closeOperation(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_closeOperation_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("closeOperation", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("closeOperation", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_getTimeZone = function(seqid, input, output) {
  var args = new IClientRPCService_getTimeZone_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.getTimeZone.length === 1) {
    Q.fcall(this._handler.getTimeZone.bind(this._handler),
      args.sessionId
    ).then(function(result) {
      var result_obj = new IClientRPCService_getTimeZone_result({success: result});
      output.writeMessageBegin("getTimeZone", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("getTimeZone", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.getTimeZone(args.sessionId, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_getTimeZone_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("getTimeZone", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("getTimeZone", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_setTimeZone = function(seqid, input, output) {
  var args = new IClientRPCService_setTimeZone_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.setTimeZone.length === 1) {
    Q.fcall(this._handler.setTimeZone.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_setTimeZone_result({success: result});
      output.writeMessageBegin("setTimeZone", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("setTimeZone", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.setTimeZone(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_setTimeZone_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("setTimeZone", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("setTimeZone", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_getProperties = function(seqid, input, output) {
  var args = new IClientRPCService_getProperties_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.getProperties.length === 0) {
    Q.fcall(this._handler.getProperties.bind(this._handler)
    ).then(function(result) {
      var result_obj = new IClientRPCService_getProperties_result({success: result});
      output.writeMessageBegin("getProperties", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("getProperties", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.getProperties(function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_getProperties_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("getProperties", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("getProperties", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_setStorageGroup = function(seqid, input, output) {
  var args = new IClientRPCService_setStorageGroup_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.setStorageGroup.length === 2) {
    Q.fcall(this._handler.setStorageGroup.bind(this._handler),
      args.sessionId,
      args.storageGroup
    ).then(function(result) {
      var result_obj = new IClientRPCService_setStorageGroup_result({success: result});
      output.writeMessageBegin("setStorageGroup", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("setStorageGroup", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.setStorageGroup(args.sessionId, args.storageGroup, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_setStorageGroup_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("setStorageGroup", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("setStorageGroup", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_createTimeseries = function(seqid, input, output) {
  var args = new IClientRPCService_createTimeseries_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.createTimeseries.length === 1) {
    Q.fcall(this._handler.createTimeseries.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_createTimeseries_result({success: result});
      output.writeMessageBegin("createTimeseries", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("createTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.createTimeseries(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_createTimeseries_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("createTimeseries", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("createTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_createAlignedTimeseries = function(seqid, input, output) {
  var args = new IClientRPCService_createAlignedTimeseries_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.createAlignedTimeseries.length === 1) {
    Q.fcall(this._handler.createAlignedTimeseries.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_createAlignedTimeseries_result({success: result});
      output.writeMessageBegin("createAlignedTimeseries", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("createAlignedTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.createAlignedTimeseries(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_createAlignedTimeseries_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("createAlignedTimeseries", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("createAlignedTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_createMultiTimeseries = function(seqid, input, output) {
  var args = new IClientRPCService_createMultiTimeseries_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.createMultiTimeseries.length === 1) {
    Q.fcall(this._handler.createMultiTimeseries.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_createMultiTimeseries_result({success: result});
      output.writeMessageBegin("createMultiTimeseries", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("createMultiTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.createMultiTimeseries(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_createMultiTimeseries_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("createMultiTimeseries", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("createMultiTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_deleteTimeseries = function(seqid, input, output) {
  var args = new IClientRPCService_deleteTimeseries_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.deleteTimeseries.length === 2) {
    Q.fcall(this._handler.deleteTimeseries.bind(this._handler),
      args.sessionId,
      args.path
    ).then(function(result) {
      var result_obj = new IClientRPCService_deleteTimeseries_result({success: result});
      output.writeMessageBegin("deleteTimeseries", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("deleteTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.deleteTimeseries(args.sessionId, args.path, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_deleteTimeseries_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("deleteTimeseries", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("deleteTimeseries", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_deleteStorageGroups = function(seqid, input, output) {
  var args = new IClientRPCService_deleteStorageGroups_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.deleteStorageGroups.length === 2) {
    Q.fcall(this._handler.deleteStorageGroups.bind(this._handler),
      args.sessionId,
      args.storageGroup
    ).then(function(result) {
      var result_obj = new IClientRPCService_deleteStorageGroups_result({success: result});
      output.writeMessageBegin("deleteStorageGroups", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("deleteStorageGroups", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.deleteStorageGroups(args.sessionId, args.storageGroup, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_deleteStorageGroups_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("deleteStorageGroups", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("deleteStorageGroups", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertRecord = function(seqid, input, output) {
  var args = new IClientRPCService_insertRecord_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertRecord.length === 1) {
    Q.fcall(this._handler.insertRecord.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertRecord_result({success: result});
      output.writeMessageBegin("insertRecord", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertRecord", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertRecord(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertRecord_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertRecord", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertRecord", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertStringRecord = function(seqid, input, output) {
  var args = new IClientRPCService_insertStringRecord_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertStringRecord.length === 1) {
    Q.fcall(this._handler.insertStringRecord.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertStringRecord_result({success: result});
      output.writeMessageBegin("insertStringRecord", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertStringRecord", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertStringRecord(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertStringRecord_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertStringRecord", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertStringRecord", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertTablet = function(seqid, input, output) {
  var args = new IClientRPCService_insertTablet_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertTablet.length === 1) {
    Q.fcall(this._handler.insertTablet.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertTablet_result({success: result});
      output.writeMessageBegin("insertTablet", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertTablet", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertTablet(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertTablet_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertTablet", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertTablet", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertTablets = function(seqid, input, output) {
  var args = new IClientRPCService_insertTablets_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertTablets.length === 1) {
    Q.fcall(this._handler.insertTablets.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertTablets_result({success: result});
      output.writeMessageBegin("insertTablets", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertTablets", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertTablets(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertTablets_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertTablets", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertTablets", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertRecords = function(seqid, input, output) {
  var args = new IClientRPCService_insertRecords_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertRecords.length === 1) {
    Q.fcall(this._handler.insertRecords.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertRecords_result({success: result});
      output.writeMessageBegin("insertRecords", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertRecords", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertRecords(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertRecords_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertRecords", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertRecords", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertRecordsOfOneDevice = function(seqid, input, output) {
  var args = new IClientRPCService_insertRecordsOfOneDevice_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertRecordsOfOneDevice.length === 1) {
    Q.fcall(this._handler.insertRecordsOfOneDevice.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertRecordsOfOneDevice_result({success: result});
      output.writeMessageBegin("insertRecordsOfOneDevice", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertRecordsOfOneDevice", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertRecordsOfOneDevice(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertRecordsOfOneDevice_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertRecordsOfOneDevice", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertRecordsOfOneDevice", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertStringRecordsOfOneDevice = function(seqid, input, output) {
  var args = new IClientRPCService_insertStringRecordsOfOneDevice_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertStringRecordsOfOneDevice.length === 1) {
    Q.fcall(this._handler.insertStringRecordsOfOneDevice.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertStringRecordsOfOneDevice_result({success: result});
      output.writeMessageBegin("insertStringRecordsOfOneDevice", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertStringRecordsOfOneDevice", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertStringRecordsOfOneDevice(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertStringRecordsOfOneDevice_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertStringRecordsOfOneDevice", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertStringRecordsOfOneDevice", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_insertStringRecords = function(seqid, input, output) {
  var args = new IClientRPCService_insertStringRecords_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.insertStringRecords.length === 1) {
    Q.fcall(this._handler.insertStringRecords.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_insertStringRecords_result({success: result});
      output.writeMessageBegin("insertStringRecords", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("insertStringRecords", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.insertStringRecords(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_insertStringRecords_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("insertStringRecords", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("insertStringRecords", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertTablet = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertTablet_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertTablet.length === 1) {
    Q.fcall(this._handler.testInsertTablet.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertTablet_result({success: result});
      output.writeMessageBegin("testInsertTablet", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertTablet", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertTablet(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertTablet_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertTablet", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertTablet", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertTablets = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertTablets_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertTablets.length === 1) {
    Q.fcall(this._handler.testInsertTablets.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertTablets_result({success: result});
      output.writeMessageBegin("testInsertTablets", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertTablets", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertTablets(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertTablets_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertTablets", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertTablets", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertRecord = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertRecord_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertRecord.length === 1) {
    Q.fcall(this._handler.testInsertRecord.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertRecord_result({success: result});
      output.writeMessageBegin("testInsertRecord", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertRecord", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertRecord(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertRecord_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertRecord", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertRecord", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertStringRecord = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertStringRecord_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertStringRecord.length === 1) {
    Q.fcall(this._handler.testInsertStringRecord.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertStringRecord_result({success: result});
      output.writeMessageBegin("testInsertStringRecord", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertStringRecord", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertStringRecord(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertStringRecord_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertStringRecord", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertStringRecord", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertRecords = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertRecords_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertRecords.length === 1) {
    Q.fcall(this._handler.testInsertRecords.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertRecords_result({success: result});
      output.writeMessageBegin("testInsertRecords", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertRecords", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertRecords(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertRecords_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertRecords", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertRecords", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertRecordsOfOneDevice = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertRecordsOfOneDevice_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertRecordsOfOneDevice.length === 1) {
    Q.fcall(this._handler.testInsertRecordsOfOneDevice.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertRecordsOfOneDevice_result({success: result});
      output.writeMessageBegin("testInsertRecordsOfOneDevice", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertRecordsOfOneDevice", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertRecordsOfOneDevice(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertRecordsOfOneDevice_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertRecordsOfOneDevice", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertRecordsOfOneDevice", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testInsertStringRecords = function(seqid, input, output) {
  var args = new IClientRPCService_testInsertStringRecords_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testInsertStringRecords.length === 1) {
    Q.fcall(this._handler.testInsertStringRecords.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_testInsertStringRecords_result({success: result});
      output.writeMessageBegin("testInsertStringRecords", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testInsertStringRecords", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testInsertStringRecords(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testInsertStringRecords_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testInsertStringRecords", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testInsertStringRecords", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_deleteData = function(seqid, input, output) {
  var args = new IClientRPCService_deleteData_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.deleteData.length === 1) {
    Q.fcall(this._handler.deleteData.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_deleteData_result({success: result});
      output.writeMessageBegin("deleteData", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("deleteData", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.deleteData(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_deleteData_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("deleteData", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("deleteData", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeRawDataQuery = function(seqid, input, output) {
  var args = new IClientRPCService_executeRawDataQuery_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeRawDataQuery.length === 1) {
    Q.fcall(this._handler.executeRawDataQuery.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeRawDataQuery_result({success: result});
      output.writeMessageBegin("executeRawDataQuery", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeRawDataQuery", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeRawDataQuery(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeRawDataQuery_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeRawDataQuery", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeRawDataQuery", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeLastDataQuery = function(seqid, input, output) {
  var args = new IClientRPCService_executeLastDataQuery_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeLastDataQuery.length === 1) {
    Q.fcall(this._handler.executeLastDataQuery.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeLastDataQuery_result({success: result});
      output.writeMessageBegin("executeLastDataQuery", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeLastDataQuery", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeLastDataQuery(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeLastDataQuery_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeLastDataQuery", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeLastDataQuery", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_executeAggregationQuery = function(seqid, input, output) {
  var args = new IClientRPCService_executeAggregationQuery_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.executeAggregationQuery.length === 1) {
    Q.fcall(this._handler.executeAggregationQuery.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_executeAggregationQuery_result({success: result});
      output.writeMessageBegin("executeAggregationQuery", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("executeAggregationQuery", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.executeAggregationQuery(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_executeAggregationQuery_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("executeAggregationQuery", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("executeAggregationQuery", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_requestStatementId = function(seqid, input, output) {
  var args = new IClientRPCService_requestStatementId_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.requestStatementId.length === 1) {
    Q.fcall(this._handler.requestStatementId.bind(this._handler),
      args.sessionId
    ).then(function(result) {
      var result_obj = new IClientRPCService_requestStatementId_result({success: result});
      output.writeMessageBegin("requestStatementId", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("requestStatementId", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.requestStatementId(args.sessionId, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_requestStatementId_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("requestStatementId", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("requestStatementId", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_createSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_createSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.createSchemaTemplate.length === 1) {
    Q.fcall(this._handler.createSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_createSchemaTemplate_result({success: result});
      output.writeMessageBegin("createSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("createSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.createSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_createSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("createSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("createSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_appendSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_appendSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.appendSchemaTemplate.length === 1) {
    Q.fcall(this._handler.appendSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_appendSchemaTemplate_result({success: result});
      output.writeMessageBegin("appendSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("appendSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.appendSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_appendSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("appendSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("appendSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_pruneSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_pruneSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.pruneSchemaTemplate.length === 1) {
    Q.fcall(this._handler.pruneSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_pruneSchemaTemplate_result({success: result});
      output.writeMessageBegin("pruneSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("pruneSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.pruneSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_pruneSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("pruneSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("pruneSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_querySchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_querySchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.querySchemaTemplate.length === 1) {
    Q.fcall(this._handler.querySchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_querySchemaTemplate_result({success: result});
      output.writeMessageBegin("querySchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("querySchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.querySchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_querySchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("querySchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("querySchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_showConfigurationTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_showConfigurationTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.showConfigurationTemplate.length === 0) {
    Q.fcall(this._handler.showConfigurationTemplate.bind(this._handler)
    ).then(function(result) {
      var result_obj = new IClientRPCService_showConfigurationTemplate_result({success: result});
      output.writeMessageBegin("showConfigurationTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("showConfigurationTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.showConfigurationTemplate(function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_showConfigurationTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("showConfigurationTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("showConfigurationTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_showConfiguration = function(seqid, input, output) {
  var args = new IClientRPCService_showConfiguration_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.showConfiguration.length === 1) {
    Q.fcall(this._handler.showConfiguration.bind(this._handler),
      args.nodeId
    ).then(function(result) {
      var result_obj = new IClientRPCService_showConfiguration_result({success: result});
      output.writeMessageBegin("showConfiguration", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("showConfiguration", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.showConfiguration(args.nodeId, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_showConfiguration_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("showConfiguration", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("showConfiguration", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_setSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_setSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.setSchemaTemplate.length === 1) {
    Q.fcall(this._handler.setSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_setSchemaTemplate_result({success: result});
      output.writeMessageBegin("setSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("setSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.setSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_setSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("setSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("setSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_unsetSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_unsetSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.unsetSchemaTemplate.length === 1) {
    Q.fcall(this._handler.unsetSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_unsetSchemaTemplate_result({success: result});
      output.writeMessageBegin("unsetSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("unsetSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.unsetSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_unsetSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("unsetSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("unsetSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_dropSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_dropSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.dropSchemaTemplate.length === 1) {
    Q.fcall(this._handler.dropSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_dropSchemaTemplate_result({success: result});
      output.writeMessageBegin("dropSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("dropSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.dropSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_dropSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("dropSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("dropSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_createTimeseriesUsingSchemaTemplate = function(seqid, input, output) {
  var args = new IClientRPCService_createTimeseriesUsingSchemaTemplate_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.createTimeseriesUsingSchemaTemplate.length === 1) {
    Q.fcall(this._handler.createTimeseriesUsingSchemaTemplate.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_createTimeseriesUsingSchemaTemplate_result({success: result});
      output.writeMessageBegin("createTimeseriesUsingSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("createTimeseriesUsingSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.createTimeseriesUsingSchemaTemplate(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_createTimeseriesUsingSchemaTemplate_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("createTimeseriesUsingSchemaTemplate", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("createTimeseriesUsingSchemaTemplate", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_handshake = function(seqid, input, output) {
  var args = new IClientRPCService_handshake_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.handshake.length === 1) {
    Q.fcall(this._handler.handshake.bind(this._handler),
      args.info
    ).then(function(result) {
      var result_obj = new IClientRPCService_handshake_result({success: result});
      output.writeMessageBegin("handshake", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("handshake", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.handshake(args.info, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_handshake_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("handshake", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("handshake", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_sendPipeData = function(seqid, input, output) {
  var args = new IClientRPCService_sendPipeData_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.sendPipeData.length === 1) {
    Q.fcall(this._handler.sendPipeData.bind(this._handler),
      args.buff
    ).then(function(result) {
      var result_obj = new IClientRPCService_sendPipeData_result({success: result});
      output.writeMessageBegin("sendPipeData", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("sendPipeData", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.sendPipeData(args.buff, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_sendPipeData_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("sendPipeData", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("sendPipeData", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_sendFile = function(seqid, input, output) {
  var args = new IClientRPCService_sendFile_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.sendFile.length === 2) {
    Q.fcall(this._handler.sendFile.bind(this._handler),
      args.metaInfo,
      args.buff
    ).then(function(result) {
      var result_obj = new IClientRPCService_sendFile_result({success: result});
      output.writeMessageBegin("sendFile", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("sendFile", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.sendFile(args.metaInfo, args.buff, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_sendFile_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("sendFile", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("sendFile", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_pipeTransfer = function(seqid, input, output) {
  var args = new IClientRPCService_pipeTransfer_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.pipeTransfer.length === 1) {
    Q.fcall(this._handler.pipeTransfer.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_pipeTransfer_result({success: result});
      output.writeMessageBegin("pipeTransfer", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("pipeTransfer", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.pipeTransfer(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_pipeTransfer_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("pipeTransfer", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("pipeTransfer", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_pipeSubscribe = function(seqid, input, output) {
  var args = new IClientRPCService_pipeSubscribe_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.pipeSubscribe.length === 1) {
    Q.fcall(this._handler.pipeSubscribe.bind(this._handler),
      args.req
    ).then(function(result) {
      var result_obj = new IClientRPCService_pipeSubscribe_result({success: result});
      output.writeMessageBegin("pipeSubscribe", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("pipeSubscribe", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.pipeSubscribe(args.req, function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_pipeSubscribe_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("pipeSubscribe", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("pipeSubscribe", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_getBackupConfiguration = function(seqid, input, output) {
  var args = new IClientRPCService_getBackupConfiguration_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.getBackupConfiguration.length === 0) {
    Q.fcall(this._handler.getBackupConfiguration.bind(this._handler)
    ).then(function(result) {
      var result_obj = new IClientRPCService_getBackupConfiguration_result({success: result});
      output.writeMessageBegin("getBackupConfiguration", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("getBackupConfiguration", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.getBackupConfiguration(function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_getBackupConfiguration_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("getBackupConfiguration", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("getBackupConfiguration", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_fetchAllConnectionsInfo = function(seqid, input, output) {
  var args = new IClientRPCService_fetchAllConnectionsInfo_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.fetchAllConnectionsInfo.length === 0) {
    Q.fcall(this._handler.fetchAllConnectionsInfo.bind(this._handler)
    ).then(function(result) {
      var result_obj = new IClientRPCService_fetchAllConnectionsInfo_result({success: result});
      output.writeMessageBegin("fetchAllConnectionsInfo", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("fetchAllConnectionsInfo", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.fetchAllConnectionsInfo(function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_fetchAllConnectionsInfo_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("fetchAllConnectionsInfo", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("fetchAllConnectionsInfo", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
IClientRPCServiceProcessor.prototype.process_testConnectionEmptyRPC = function(seqid, input, output) {
  var args = new IClientRPCService_testConnectionEmptyRPC_args();
  args.read(input);
  input.readMessageEnd();
  if (this._handler.testConnectionEmptyRPC.length === 0) {
    Q.fcall(this._handler.testConnectionEmptyRPC.bind(this._handler)
    ).then(function(result) {
      var result_obj = new IClientRPCService_testConnectionEmptyRPC_result({success: result});
      output.writeMessageBegin("testConnectionEmptyRPC", Thrift.MessageType.REPLY, seqid);
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    }).catch(function (err) {
      var result;
      result = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
      output.writeMessageBegin("testConnectionEmptyRPC", Thrift.MessageType.EXCEPTION, seqid);
      result.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  } else {
    this._handler.testConnectionEmptyRPC(function (err, result) {
      var result_obj;
      if ((err === null || typeof err === 'undefined')) {
        result_obj = new IClientRPCService_testConnectionEmptyRPC_result((err !== null || typeof err === 'undefined') ? err : {success: result});
        output.writeMessageBegin("testConnectionEmptyRPC", Thrift.MessageType.REPLY, seqid);
      } else {
        result_obj = new Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN, err.message);
        output.writeMessageBegin("testConnectionEmptyRPC", Thrift.MessageType.EXCEPTION, seqid);
      }
      result_obj.write(output);
      output.writeMessageEnd();
      output.flush();
    });
  }
};
