#
# Autogenerated by Thrift
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#

from thrift.Thrift import *
from ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
try:
  from thrift.protocol import fastbinary
except:
  fastbinary = None


class Iface:
  def setInactivityTimeoutPeriod(self, periodInSeconds):
    pass

  def shutdown(self, status):
    pass

  def create(self, path):
    pass

  def createFile(self, path, mode, overwrite, bufferSize, block_replication, blocksize):
    pass

  def open(self, path):
    pass

  def append(self, path):
    pass

  def write(self, handle, data):
    pass

  def read(self, handle, offset, size):
    pass

  def close(self, out):
    pass

  def rm(self, path, recursive):
    pass

  def rename(self, path, dest):
    pass

  def mkdirs(self, path):
    pass

  def exists(self, path):
    pass

  def stat(self, path):
    pass

  def listStatus(self, path):
    pass

  def chmod(self, path, mode):
    pass

  def chown(self, path, owner, group):
    pass

  def setReplication(self, path, replication):
    pass

  def getFileBlockLocations(self, path, start, length):
    pass


class Client(Iface):
  def __init__(self, iprot, oprot=None):
    self._iprot = self._oprot = iprot
    if oprot != None:
      self._oprot = oprot
    self._seqid = 0

  def setInactivityTimeoutPeriod(self, periodInSeconds):
    self.send_setInactivityTimeoutPeriod(periodInSeconds)
    self.recv_setInactivityTimeoutPeriod()

  def send_setInactivityTimeoutPeriod(self, periodInSeconds):
    self._oprot.writeMessageBegin('setInactivityTimeoutPeriod', TMessageType.CALL, self._seqid)
    args = setInactivityTimeoutPeriod_args()
    args.periodInSeconds = periodInSeconds
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_setInactivityTimeoutPeriod(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = setInactivityTimeoutPeriod_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    return

  def shutdown(self, status):
    self.send_shutdown(status)
    self.recv_shutdown()

  def send_shutdown(self, status):
    self._oprot.writeMessageBegin('shutdown', TMessageType.CALL, self._seqid)
    args = shutdown_args()
    args.status = status
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_shutdown(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = shutdown_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    return

  def create(self, path):
    self.send_create(path)
    return self.recv_create()

  def send_create(self, path):
    self._oprot.writeMessageBegin('create', TMessageType.CALL, self._seqid)
    args = create_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_create(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = create_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "create failed: unknown result");

  def createFile(self, path, mode, overwrite, bufferSize, block_replication, blocksize):
    self.send_createFile(path, mode, overwrite, bufferSize, block_replication, blocksize)
    return self.recv_createFile()

  def send_createFile(self, path, mode, overwrite, bufferSize, block_replication, blocksize):
    self._oprot.writeMessageBegin('createFile', TMessageType.CALL, self._seqid)
    args = createFile_args()
    args.path = path
    args.mode = mode
    args.overwrite = overwrite
    args.bufferSize = bufferSize
    args.block_replication = block_replication
    args.blocksize = blocksize
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_createFile(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = createFile_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "createFile failed: unknown result");

  def open(self, path):
    self.send_open(path)
    return self.recv_open()

  def send_open(self, path):
    self._oprot.writeMessageBegin('open', TMessageType.CALL, self._seqid)
    args = open_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_open(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = open_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "open failed: unknown result");

  def append(self, path):
    self.send_append(path)
    return self.recv_append()

  def send_append(self, path):
    self._oprot.writeMessageBegin('append', TMessageType.CALL, self._seqid)
    args = append_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_append(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = append_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "append failed: unknown result");

  def write(self, handle, data):
    self.send_write(handle, data)
    return self.recv_write()

  def send_write(self, handle, data):
    self._oprot.writeMessageBegin('write', TMessageType.CALL, self._seqid)
    args = write_args()
    args.handle = handle
    args.data = data
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_write(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = write_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "write failed: unknown result");

  def read(self, handle, offset, size):
    self.send_read(handle, offset, size)
    return self.recv_read()

  def send_read(self, handle, offset, size):
    self._oprot.writeMessageBegin('read', TMessageType.CALL, self._seqid)
    args = read_args()
    args.handle = handle
    args.offset = offset
    args.size = size
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_read(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = read_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "read failed: unknown result");

  def close(self, out):
    self.send_close(out)
    return self.recv_close()

  def send_close(self, out):
    self._oprot.writeMessageBegin('close', TMessageType.CALL, self._seqid)
    args = close_args()
    args.out = out
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_close(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = close_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "close failed: unknown result");

  def rm(self, path, recursive):
    self.send_rm(path, recursive)
    return self.recv_rm()

  def send_rm(self, path, recursive):
    self._oprot.writeMessageBegin('rm', TMessageType.CALL, self._seqid)
    args = rm_args()
    args.path = path
    args.recursive = recursive
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_rm(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = rm_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "rm failed: unknown result");

  def rename(self, path, dest):
    self.send_rename(path, dest)
    return self.recv_rename()

  def send_rename(self, path, dest):
    self._oprot.writeMessageBegin('rename', TMessageType.CALL, self._seqid)
    args = rename_args()
    args.path = path
    args.dest = dest
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_rename(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = rename_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "rename failed: unknown result");

  def mkdirs(self, path):
    self.send_mkdirs(path)
    return self.recv_mkdirs()

  def send_mkdirs(self, path):
    self._oprot.writeMessageBegin('mkdirs', TMessageType.CALL, self._seqid)
    args = mkdirs_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_mkdirs(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = mkdirs_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "mkdirs failed: unknown result");

  def exists(self, path):
    self.send_exists(path)
    return self.recv_exists()

  def send_exists(self, path):
    self._oprot.writeMessageBegin('exists', TMessageType.CALL, self._seqid)
    args = exists_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_exists(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = exists_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "exists failed: unknown result");

  def stat(self, path):
    self.send_stat(path)
    return self.recv_stat()

  def send_stat(self, path):
    self._oprot.writeMessageBegin('stat', TMessageType.CALL, self._seqid)
    args = stat_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_stat(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = stat_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "stat failed: unknown result");

  def listStatus(self, path):
    self.send_listStatus(path)
    return self.recv_listStatus()

  def send_listStatus(self, path):
    self._oprot.writeMessageBegin('listStatus', TMessageType.CALL, self._seqid)
    args = listStatus_args()
    args.path = path
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_listStatus(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = listStatus_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "listStatus failed: unknown result");

  def chmod(self, path, mode):
    self.send_chmod(path, mode)
    self.recv_chmod()

  def send_chmod(self, path, mode):
    self._oprot.writeMessageBegin('chmod', TMessageType.CALL, self._seqid)
    args = chmod_args()
    args.path = path
    args.mode = mode
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_chmod(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = chmod_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ouch != None:
      raise result.ouch
    return

  def chown(self, path, owner, group):
    self.send_chown(path, owner, group)
    self.recv_chown()

  def send_chown(self, path, owner, group):
    self._oprot.writeMessageBegin('chown', TMessageType.CALL, self._seqid)
    args = chown_args()
    args.path = path
    args.owner = owner
    args.group = group
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_chown(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = chown_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ouch != None:
      raise result.ouch
    return

  def setReplication(self, path, replication):
    self.send_setReplication(path, replication)
    self.recv_setReplication()

  def send_setReplication(self, path, replication):
    self._oprot.writeMessageBegin('setReplication', TMessageType.CALL, self._seqid)
    args = setReplication_args()
    args.path = path
    args.replication = replication
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_setReplication(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = setReplication_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ouch != None:
      raise result.ouch
    return

  def getFileBlockLocations(self, path, start, length):
    self.send_getFileBlockLocations(path, start, length)
    return self.recv_getFileBlockLocations()

  def send_getFileBlockLocations(self, path, start, length):
    self._oprot.writeMessageBegin('getFileBlockLocations', TMessageType.CALL, self._seqid)
    args = getFileBlockLocations_args()
    args.path = path
    args.start = start
    args.length = length
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_getFileBlockLocations(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = getFileBlockLocations_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.ouch != None:
      raise result.ouch
    raise TApplicationException(TApplicationException.MISSING_RESULT, "getFileBlockLocations failed: unknown result");


class Processor(Iface, TProcessor):
  def __init__(self, handler):
    self._handler = handler
    self._processMap = {}
    self._processMap["setInactivityTimeoutPeriod"] = Processor.process_setInactivityTimeoutPeriod
    self._processMap["shutdown"] = Processor.process_shutdown
    self._processMap["create"] = Processor.process_create
    self._processMap["createFile"] = Processor.process_createFile
    self._processMap["open"] = Processor.process_open
    self._processMap["append"] = Processor.process_append
    self._processMap["write"] = Processor.process_write
    self._processMap["read"] = Processor.process_read
    self._processMap["close"] = Processor.process_close
    self._processMap["rm"] = Processor.process_rm
    self._processMap["rename"] = Processor.process_rename
    self._processMap["mkdirs"] = Processor.process_mkdirs
    self._processMap["exists"] = Processor.process_exists
    self._processMap["stat"] = Processor.process_stat
    self._processMap["listStatus"] = Processor.process_listStatus
    self._processMap["chmod"] = Processor.process_chmod
    self._processMap["chown"] = Processor.process_chown
    self._processMap["setReplication"] = Processor.process_setReplication
    self._processMap["getFileBlockLocations"] = Processor.process_getFileBlockLocations

  def process(self, iprot, oprot):
    (name, type, seqid) = iprot.readMessageBegin()
    if name not in self._processMap:
      iprot.skip(TType.STRUCT)
      iprot.readMessageEnd()
      x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
      oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
      x.write(oprot)
      oprot.writeMessageEnd()
      oprot.trans.flush()
      return
    else:
      self._processMap[name](self, seqid, iprot, oprot)
    return True

  def process_setInactivityTimeoutPeriod(self, seqid, iprot, oprot):
    args = setInactivityTimeoutPeriod_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = setInactivityTimeoutPeriod_result()
    self._handler.setInactivityTimeoutPeriod(args.periodInSeconds)
    oprot.writeMessageBegin("setInactivityTimeoutPeriod", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_shutdown(self, seqid, iprot, oprot):
    args = shutdown_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = shutdown_result()
    self._handler.shutdown(args.status)
    oprot.writeMessageBegin("shutdown", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_create(self, seqid, iprot, oprot):
    args = create_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = create_result()
    try:
      result.success = self._handler.create(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("create", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_createFile(self, seqid, iprot, oprot):
    args = createFile_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = createFile_result()
    try:
      result.success = self._handler.createFile(args.path, args.mode, args.overwrite, args.bufferSize, args.block_replication, args.blocksize)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("createFile", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_open(self, seqid, iprot, oprot):
    args = open_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = open_result()
    try:
      result.success = self._handler.open(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("open", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_append(self, seqid, iprot, oprot):
    args = append_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = append_result()
    try:
      result.success = self._handler.append(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("append", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_write(self, seqid, iprot, oprot):
    args = write_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = write_result()
    try:
      result.success = self._handler.write(args.handle, args.data)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("write", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_read(self, seqid, iprot, oprot):
    args = read_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = read_result()
    try:
      result.success = self._handler.read(args.handle, args.offset, args.size)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("read", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_close(self, seqid, iprot, oprot):
    args = close_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = close_result()
    try:
      result.success = self._handler.close(args.out)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("close", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_rm(self, seqid, iprot, oprot):
    args = rm_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = rm_result()
    try:
      result.success = self._handler.rm(args.path, args.recursive)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("rm", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_rename(self, seqid, iprot, oprot):
    args = rename_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = rename_result()
    try:
      result.success = self._handler.rename(args.path, args.dest)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("rename", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_mkdirs(self, seqid, iprot, oprot):
    args = mkdirs_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = mkdirs_result()
    try:
      result.success = self._handler.mkdirs(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("mkdirs", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_exists(self, seqid, iprot, oprot):
    args = exists_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = exists_result()
    try:
      result.success = self._handler.exists(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("exists", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_stat(self, seqid, iprot, oprot):
    args = stat_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = stat_result()
    try:
      result.success = self._handler.stat(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("stat", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_listStatus(self, seqid, iprot, oprot):
    args = listStatus_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = listStatus_result()
    try:
      result.success = self._handler.listStatus(args.path)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("listStatus", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_chmod(self, seqid, iprot, oprot):
    args = chmod_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = chmod_result()
    try:
      self._handler.chmod(args.path, args.mode)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("chmod", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_chown(self, seqid, iprot, oprot):
    args = chown_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = chown_result()
    try:
      self._handler.chown(args.path, args.owner, args.group)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("chown", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_setReplication(self, seqid, iprot, oprot):
    args = setReplication_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = setReplication_result()
    try:
      self._handler.setReplication(args.path, args.replication)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("setReplication", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_getFileBlockLocations(self, seqid, iprot, oprot):
    args = getFileBlockLocations_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = getFileBlockLocations_result()
    try:
      result.success = self._handler.getFileBlockLocations(args.path, args.start, args.length)
    except ThriftIOException, ouch:
      result.ouch = ouch
    oprot.writeMessageBegin("getFileBlockLocations", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()


# HELPER FUNCTIONS AND STRUCTURES

class setInactivityTimeoutPeriod_args:

  thrift_spec = (
    None, # 0
    (1, TType.I64, 'periodInSeconds', None, None, ), # 1
  )

  def __init__(self, d=None):
    self.periodInSeconds = None
    if isinstance(d, dict):
      if 'periodInSeconds' in d:
        self.periodInSeconds = d['periodInSeconds']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.I64:
          self.periodInSeconds = iprot.readI64();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('setInactivityTimeoutPeriod_args')
    if self.periodInSeconds != None:
      oprot.writeFieldBegin('periodInSeconds', TType.I64, 1)
      oprot.writeI64(self.periodInSeconds)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class setInactivityTimeoutPeriod_result:

  thrift_spec = (
  )

  def __init__(self, d=None):
    pass

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('setInactivityTimeoutPeriod_result')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class shutdown_args:

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'status', None, None, ), # 1
  )

  def __init__(self, d=None):
    self.status = None
    if isinstance(d, dict):
      if 'status' in d:
        self.status = d['status']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.I32:
          self.status = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('shutdown_args')
    if self.status != None:
      oprot.writeFieldBegin('status', TType.I32, 1)
      oprot.writeI32(self.status)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class shutdown_result:

  thrift_spec = (
  )

  def __init__(self, d=None):
    pass

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('shutdown_result')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class create_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('create_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class create_result:

  thrift_spec = (
    (0, TType.STRUCT, 'success', (ThriftHandle, ThriftHandle.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = ThriftHandle()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('create_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class createFile_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.I16, 'mode', None, None, ), # 2
    (3, TType.BOOL, 'overwrite', None, None, ), # 3
    (4, TType.I32, 'bufferSize', None, None, ), # 4
    (5, TType.I16, 'block_replication', None, None, ), # 5
    (6, TType.I64, 'blocksize', None, None, ), # 6
  )

  def __init__(self, d=None):
    self.path = None
    self.mode = None
    self.overwrite = None
    self.bufferSize = None
    self.block_replication = None
    self.blocksize = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'mode' in d:
        self.mode = d['mode']
      if 'overwrite' in d:
        self.overwrite = d['overwrite']
      if 'bufferSize' in d:
        self.bufferSize = d['bufferSize']
      if 'block_replication' in d:
        self.block_replication = d['block_replication']
      if 'blocksize' in d:
        self.blocksize = d['blocksize']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I16:
          self.mode = iprot.readI16();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.BOOL:
          self.overwrite = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.bufferSize = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I16:
          self.block_replication = iprot.readI16();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.I64:
          self.blocksize = iprot.readI64();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('createFile_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.mode != None:
      oprot.writeFieldBegin('mode', TType.I16, 2)
      oprot.writeI16(self.mode)
      oprot.writeFieldEnd()
    if self.overwrite != None:
      oprot.writeFieldBegin('overwrite', TType.BOOL, 3)
      oprot.writeBool(self.overwrite)
      oprot.writeFieldEnd()
    if self.bufferSize != None:
      oprot.writeFieldBegin('bufferSize', TType.I32, 4)
      oprot.writeI32(self.bufferSize)
      oprot.writeFieldEnd()
    if self.block_replication != None:
      oprot.writeFieldBegin('block_replication', TType.I16, 5)
      oprot.writeI16(self.block_replication)
      oprot.writeFieldEnd()
    if self.blocksize != None:
      oprot.writeFieldBegin('blocksize', TType.I64, 6)
      oprot.writeI64(self.blocksize)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class createFile_result:

  thrift_spec = (
    (0, TType.STRUCT, 'success', (ThriftHandle, ThriftHandle.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = ThriftHandle()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('createFile_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class open_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('open_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class open_result:

  thrift_spec = (
    (0, TType.STRUCT, 'success', (ThriftHandle, ThriftHandle.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = ThriftHandle()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('open_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class append_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('append_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class append_result:

  thrift_spec = (
    (0, TType.STRUCT, 'success', (ThriftHandle, ThriftHandle.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = ThriftHandle()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('append_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class write_args:

  thrift_spec = None
  def __init__(self, d=None):
    self.handle = None
    self.data = None
    if isinstance(d, dict):
      if 'handle' in d:
        self.handle = d['handle']
      if 'data' in d:
        self.data = d['data']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.handle = ThriftHandle()
          self.handle.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == -1:
        if ftype == TType.STRING:
          self.data = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('write_args')
    if self.handle != None:
      oprot.writeFieldBegin('handle', TType.STRUCT, 1)
      self.handle.write(oprot)
      oprot.writeFieldEnd()
    if self.data != None:
      oprot.writeFieldBegin('data', TType.STRING, -1)
      oprot.writeString(self.data)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class write_result:

  thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.BOOL:
          self.success = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('write_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.BOOL, 0)
      oprot.writeBool(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class read_args:

  thrift_spec = None
  def __init__(self, d=None):
    self.handle = None
    self.offset = None
    self.size = None
    if isinstance(d, dict):
      if 'handle' in d:
        self.handle = d['handle']
      if 'offset' in d:
        self.offset = d['offset']
      if 'size' in d:
        self.size = d['size']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.handle = ThriftHandle()
          self.handle.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == -1:
        if ftype == TType.I64:
          self.offset = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == -2:
        if ftype == TType.I32:
          self.size = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('read_args')
    if self.handle != None:
      oprot.writeFieldBegin('handle', TType.STRUCT, 1)
      self.handle.write(oprot)
      oprot.writeFieldEnd()
    if self.offset != None:
      oprot.writeFieldBegin('offset', TType.I64, -1)
      oprot.writeI64(self.offset)
      oprot.writeFieldEnd()
    if self.size != None:
      oprot.writeFieldBegin('size', TType.I32, -2)
      oprot.writeI32(self.size)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class read_result:

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('read_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class close_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'out', (ThriftHandle, ThriftHandle.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.out = None
    if isinstance(d, dict):
      if 'out' in d:
        self.out = d['out']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.out = ThriftHandle()
          self.out.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('close_args')
    if self.out != None:
      oprot.writeFieldBegin('out', TType.STRUCT, 1)
      self.out.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class close_result:

  thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.BOOL:
          self.success = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('close_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.BOOL, 0)
      oprot.writeBool(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class rm_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.BOOL, 'recursive', None, None, ), # 2
  )

  def __init__(self, d=None):
    self.path = None
    self.recursive = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'recursive' in d:
        self.recursive = d['recursive']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.BOOL:
          self.recursive = iprot.readBool();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('rm_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.recursive != None:
      oprot.writeFieldBegin('recursive', TType.BOOL, 2)
      oprot.writeBool(self.recursive)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class rm_result:

  thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.BOOL:
          self.success = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('rm_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.BOOL, 0)
      oprot.writeBool(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class rename_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'dest', (Pathname, Pathname.thrift_spec), None, ), # 2
  )

  def __init__(self, d=None):
    self.path = None
    self.dest = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'dest' in d:
        self.dest = d['dest']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.dest = Pathname()
          self.dest.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('rename_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.dest != None:
      oprot.writeFieldBegin('dest', TType.STRUCT, 2)
      self.dest.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class rename_result:

  thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.BOOL:
          self.success = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('rename_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.BOOL, 0)
      oprot.writeBool(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class mkdirs_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('mkdirs_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class mkdirs_result:

  thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.BOOL:
          self.success = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('mkdirs_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.BOOL, 0)
      oprot.writeBool(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class exists_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('exists_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class exists_result:

  thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.BOOL:
          self.success = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('exists_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.BOOL, 0)
      oprot.writeBool(self.success)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class stat_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('stat_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class stat_result:

  thrift_spec = (
    (0, TType.STRUCT, 'success', (FileStatus, FileStatus.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = FileStatus()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('stat_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class listStatus_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.path = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('listStatus_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class listStatus_result:

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(FileStatus, FileStatus.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype17, _size14) = iprot.readListBegin()
          for _i18 in xrange(_size14):
            _elem19 = FileStatus()
            _elem19.read(iprot)
            self.success.append(_elem19)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('listStatus_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter20 in self.success:
        iter20.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class chmod_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.I16, 'mode', None, None, ), # 2
  )

  def __init__(self, d=None):
    self.path = None
    self.mode = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'mode' in d:
        self.mode = d['mode']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I16:
          self.mode = iprot.readI16();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('chmod_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.mode != None:
      oprot.writeFieldBegin('mode', TType.I16, 2)
      oprot.writeI16(self.mode)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class chmod_result:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.ouch = None
    if isinstance(d, dict):
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('chmod_result')
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class chown_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.STRING, 'owner', None, None, ), # 2
    (3, TType.STRING, 'group', None, None, ), # 3
  )

  def __init__(self, d=None):
    self.path = None
    self.owner = None
    self.group = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'owner' in d:
        self.owner = d['owner']
      if 'group' in d:
        self.group = d['group']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.owner = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.group = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('chown_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.owner != None:
      oprot.writeFieldBegin('owner', TType.STRING, 2)
      oprot.writeString(self.owner)
      oprot.writeFieldEnd()
    if self.group != None:
      oprot.writeFieldBegin('group', TType.STRING, 3)
      oprot.writeString(self.group)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class chown_result:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.ouch = None
    if isinstance(d, dict):
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('chown_result')
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class setReplication_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.I16, 'replication', None, None, ), # 2
  )

  def __init__(self, d=None):
    self.path = None
    self.replication = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'replication' in d:
        self.replication = d['replication']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I16:
          self.replication = iprot.readI16();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('setReplication_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.replication != None:
      oprot.writeFieldBegin('replication', TType.I16, 2)
      oprot.writeI16(self.replication)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class setReplication_result:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.ouch = None
    if isinstance(d, dict):
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('setReplication_result')
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class getFileBlockLocations_args:

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'path', (Pathname, Pathname.thrift_spec), None, ), # 1
    (2, TType.I64, 'start', None, None, ), # 2
    (3, TType.I64, 'length', None, None, ), # 3
  )

  def __init__(self, d=None):
    self.path = None
    self.start = None
    self.length = None
    if isinstance(d, dict):
      if 'path' in d:
        self.path = d['path']
      if 'start' in d:
        self.start = d['start']
      if 'length' in d:
        self.length = d['length']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.path = Pathname()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.start = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I64:
          self.length = iprot.readI64();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('getFileBlockLocations_args')
    if self.path != None:
      oprot.writeFieldBegin('path', TType.STRUCT, 1)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.start != None:
      oprot.writeFieldBegin('start', TType.I64, 2)
      oprot.writeI64(self.start)
      oprot.writeFieldEnd()
    if self.length != None:
      oprot.writeFieldBegin('length', TType.I64, 3)
      oprot.writeI64(self.length)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class getFileBlockLocations_result:

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(BlockLocation, BlockLocation.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ouch', (ThriftIOException, ThriftIOException.thrift_spec), None, ), # 1
  )

  def __init__(self, d=None):
    self.success = None
    self.ouch = None
    if isinstance(d, dict):
      if 'success' in d:
        self.success = d['success']
      if 'ouch' in d:
        self.ouch = d['ouch']

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype24, _size21) = iprot.readListBegin()
          for _i25 in xrange(_size21):
            _elem26 = BlockLocation()
            _elem26.read(iprot)
            self.success.append(_elem26)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ouch = ThriftIOException()
          self.ouch.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('getFileBlockLocations_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter27 in self.success:
        iter27.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ouch != None:
      oprot.writeFieldBegin('ouch', TType.STRUCT, 1)
      self.ouch.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def __str__(self):
    return str(self.__dict__)

  def __repr__(self):
    return repr(self.__dict__)

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)


