/**
 * Autogenerated by Thrift
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 */
#ifndef ThriftHadoopFileSystem_H
#define ThriftHadoopFileSystem_H

#include <TProcessor.h>
#include "hadoopfs_types.h"



class ThriftHadoopFileSystemIf {
 public:
  virtual ~ThriftHadoopFileSystemIf() {}
  virtual void setInactivityTimeoutPeriod(const int64_t periodInSeconds) = 0;
  virtual void shutdown(const int32_t status) = 0;
  virtual void create(ThriftHandle& _return, const Pathname& path) = 0;
  virtual void createFile(ThriftHandle& _return, const Pathname& path, const int16_t mode, const bool overwrite, const int32_t bufferSize, const int16_t block_replication, const int64_t blocksize) = 0;
  virtual void open(ThriftHandle& _return, const Pathname& path) = 0;
  virtual void append(ThriftHandle& _return, const Pathname& path) = 0;
  virtual bool write(const ThriftHandle& handle, const std::string& data) = 0;
  virtual void read(std::string& _return, const ThriftHandle& handle, const int64_t offset, const int32_t size) = 0;
  virtual bool close(const ThriftHandle& out) = 0;
  virtual bool rm(const Pathname& path, const bool recursive) = 0;
  virtual bool rename(const Pathname& path, const Pathname& dest) = 0;
  virtual bool mkdirs(const Pathname& path) = 0;
  virtual bool exists(const Pathname& path) = 0;
  virtual void stat(FileStatus& _return, const Pathname& path) = 0;
  virtual void listStatus(std::vector<FileStatus> & _return, const Pathname& path) = 0;
  virtual void chmod(const Pathname& path, const int16_t mode) = 0;
  virtual void chown(const Pathname& path, const std::string& owner, const std::string& group) = 0;
  virtual void setReplication(const Pathname& path, const int16_t replication) = 0;
  virtual void getFileBlockLocations(std::vector<BlockLocation> & _return, const Pathname& path, const int64_t start, const int64_t length) = 0;
};

class ThriftHadoopFileSystemNull : virtual public ThriftHadoopFileSystemIf {
 public:
  virtual ~ThriftHadoopFileSystemNull() {}
  void setInactivityTimeoutPeriod(const int64_t /* periodInSeconds */) {
    return;
  }
  void shutdown(const int32_t /* status */) {
    return;
  }
  void create(ThriftHandle& /* _return */, const Pathname& /* path */) {
    return;
  }
  void createFile(ThriftHandle& /* _return */, const Pathname& /* path */, const int16_t /* mode */, const bool /* overwrite */, const int32_t /* bufferSize */, const int16_t /* block_replication */, const int64_t /* blocksize */) {
    return;
  }
  void open(ThriftHandle& /* _return */, const Pathname& /* path */) {
    return;
  }
  void append(ThriftHandle& /* _return */, const Pathname& /* path */) {
    return;
  }
  bool write(const ThriftHandle& /* handle */, const std::string& /* data */) {
    bool _return = false;
    return _return;
  }
  void read(std::string& /* _return */, const ThriftHandle& /* handle */, const int64_t /* offset */, const int32_t /* size */) {
    return;
  }
  bool close(const ThriftHandle& /* out */) {
    bool _return = false;
    return _return;
  }
  bool rm(const Pathname& /* path */, const bool /* recursive */) {
    bool _return = false;
    return _return;
  }
  bool rename(const Pathname& /* path */, const Pathname& /* dest */) {
    bool _return = false;
    return _return;
  }
  bool mkdirs(const Pathname& /* path */) {
    bool _return = false;
    return _return;
  }
  bool exists(const Pathname& /* path */) {
    bool _return = false;
    return _return;
  }
  void stat(FileStatus& /* _return */, const Pathname& /* path */) {
    return;
  }
  void listStatus(std::vector<FileStatus> & /* _return */, const Pathname& /* path */) {
    return;
  }
  void chmod(const Pathname& /* path */, const int16_t /* mode */) {
    return;
  }
  void chown(const Pathname& /* path */, const std::string& /* owner */, const std::string& /* group */) {
    return;
  }
  void setReplication(const Pathname& /* path */, const int16_t /* replication */) {
    return;
  }
  void getFileBlockLocations(std::vector<BlockLocation> & /* _return */, const Pathname& /* path */, const int64_t /* start */, const int64_t /* length */) {
    return;
  }
};

class ThriftHadoopFileSystem_setInactivityTimeoutPeriod_args {
 public:

  ThriftHadoopFileSystem_setInactivityTimeoutPeriod_args() : periodInSeconds(0) {
  }

  virtual ~ThriftHadoopFileSystem_setInactivityTimeoutPeriod_args() throw() {}

  int64_t periodInSeconds;

  struct __isset {
    __isset() : periodInSeconds(false) {}
    bool periodInSeconds;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_setInactivityTimeoutPeriod_args & rhs) const
  {
    if (!(periodInSeconds == rhs.periodInSeconds))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_setInactivityTimeoutPeriod_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_setInactivityTimeoutPeriod_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_setInactivityTimeoutPeriod_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_setInactivityTimeoutPeriod_pargs() throw() {}

  const int64_t* periodInSeconds;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_setInactivityTimeoutPeriod_result {
 public:

  ThriftHadoopFileSystem_setInactivityTimeoutPeriod_result() {
  }

  virtual ~ThriftHadoopFileSystem_setInactivityTimeoutPeriod_result() throw() {}


  bool operator == (const ThriftHadoopFileSystem_setInactivityTimeoutPeriod_result & /* rhs */) const
  {
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_setInactivityTimeoutPeriod_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_setInactivityTimeoutPeriod_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_setInactivityTimeoutPeriod_presult {
 public:


  virtual ~ThriftHadoopFileSystem_setInactivityTimeoutPeriod_presult() throw() {}


  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_shutdown_args {
 public:

  ThriftHadoopFileSystem_shutdown_args() : status(0) {
  }

  virtual ~ThriftHadoopFileSystem_shutdown_args() throw() {}

  int32_t status;

  struct __isset {
    __isset() : status(false) {}
    bool status;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_shutdown_args & rhs) const
  {
    if (!(status == rhs.status))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_shutdown_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_shutdown_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_shutdown_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_shutdown_pargs() throw() {}

  const int32_t* status;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_shutdown_result {
 public:

  ThriftHadoopFileSystem_shutdown_result() {
  }

  virtual ~ThriftHadoopFileSystem_shutdown_result() throw() {}


  bool operator == (const ThriftHadoopFileSystem_shutdown_result & /* rhs */) const
  {
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_shutdown_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_shutdown_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_shutdown_presult {
 public:


  virtual ~ThriftHadoopFileSystem_shutdown_presult() throw() {}


  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_create_args {
 public:

  ThriftHadoopFileSystem_create_args() {
  }

  virtual ~ThriftHadoopFileSystem_create_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_create_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_create_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_create_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_create_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_create_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_create_result {
 public:

  ThriftHadoopFileSystem_create_result() {
  }

  virtual ~ThriftHadoopFileSystem_create_result() throw() {}

  ThriftHandle success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_create_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_create_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_create_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_create_presult {
 public:


  virtual ~ThriftHadoopFileSystem_create_presult() throw() {}

  ThriftHandle* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_createFile_args {
 public:

  ThriftHadoopFileSystem_createFile_args() : mode(0), overwrite(0), bufferSize(0), block_replication(0), blocksize(0) {
  }

  virtual ~ThriftHadoopFileSystem_createFile_args() throw() {}

  Pathname path;
  int16_t mode;
  bool overwrite;
  int32_t bufferSize;
  int16_t block_replication;
  int64_t blocksize;

  struct __isset {
    __isset() : path(false), mode(false), overwrite(false), bufferSize(false), block_replication(false), blocksize(false) {}
    bool path;
    bool mode;
    bool overwrite;
    bool bufferSize;
    bool block_replication;
    bool blocksize;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_createFile_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(mode == rhs.mode))
      return false;
    if (!(overwrite == rhs.overwrite))
      return false;
    if (!(bufferSize == rhs.bufferSize))
      return false;
    if (!(block_replication == rhs.block_replication))
      return false;
    if (!(blocksize == rhs.blocksize))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_createFile_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_createFile_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_createFile_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_createFile_pargs() throw() {}

  const Pathname* path;
  const int16_t* mode;
  const bool* overwrite;
  const int32_t* bufferSize;
  const int16_t* block_replication;
  const int64_t* blocksize;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_createFile_result {
 public:

  ThriftHadoopFileSystem_createFile_result() {
  }

  virtual ~ThriftHadoopFileSystem_createFile_result() throw() {}

  ThriftHandle success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_createFile_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_createFile_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_createFile_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_createFile_presult {
 public:


  virtual ~ThriftHadoopFileSystem_createFile_presult() throw() {}

  ThriftHandle* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_open_args {
 public:

  ThriftHadoopFileSystem_open_args() {
  }

  virtual ~ThriftHadoopFileSystem_open_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_open_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_open_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_open_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_open_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_open_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_open_result {
 public:

  ThriftHadoopFileSystem_open_result() {
  }

  virtual ~ThriftHadoopFileSystem_open_result() throw() {}

  ThriftHandle success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_open_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_open_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_open_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_open_presult {
 public:


  virtual ~ThriftHadoopFileSystem_open_presult() throw() {}

  ThriftHandle* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_append_args {
 public:

  ThriftHadoopFileSystem_append_args() {
  }

  virtual ~ThriftHadoopFileSystem_append_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_append_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_append_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_append_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_append_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_append_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_append_result {
 public:

  ThriftHadoopFileSystem_append_result() {
  }

  virtual ~ThriftHadoopFileSystem_append_result() throw() {}

  ThriftHandle success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_append_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_append_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_append_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_append_presult {
 public:


  virtual ~ThriftHadoopFileSystem_append_presult() throw() {}

  ThriftHandle* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_write_args {
 public:

  ThriftHadoopFileSystem_write_args() : data("") {
  }

  virtual ~ThriftHadoopFileSystem_write_args() throw() {}

  ThriftHandle handle;
  std::string data;

  struct __isset {
    __isset() : handle(false), data(false) {}
    bool handle;
    bool data;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_write_args & rhs) const
  {
    if (!(handle == rhs.handle))
      return false;
    if (!(data == rhs.data))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_write_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_write_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_write_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_write_pargs() throw() {}

  const ThriftHandle* handle;
  const std::string* data;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_write_result {
 public:

  ThriftHadoopFileSystem_write_result() : success(0) {
  }

  virtual ~ThriftHadoopFileSystem_write_result() throw() {}

  bool success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_write_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_write_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_write_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_write_presult {
 public:


  virtual ~ThriftHadoopFileSystem_write_presult() throw() {}

  bool* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_read_args {
 public:

  ThriftHadoopFileSystem_read_args() : offset(0), size(0) {
  }

  virtual ~ThriftHadoopFileSystem_read_args() throw() {}

  ThriftHandle handle;
  int64_t offset;
  int32_t size;

  struct __isset {
    __isset() : handle(false), offset(false), size(false) {}
    bool handle;
    bool offset;
    bool size;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_read_args & rhs) const
  {
    if (!(handle == rhs.handle))
      return false;
    if (!(offset == rhs.offset))
      return false;
    if (!(size == rhs.size))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_read_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_read_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_read_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_read_pargs() throw() {}

  const ThriftHandle* handle;
  const int64_t* offset;
  const int32_t* size;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_read_result {
 public:

  ThriftHadoopFileSystem_read_result() : success("") {
  }

  virtual ~ThriftHadoopFileSystem_read_result() throw() {}

  std::string success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_read_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_read_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_read_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_read_presult {
 public:


  virtual ~ThriftHadoopFileSystem_read_presult() throw() {}

  std::string* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_close_args {
 public:

  ThriftHadoopFileSystem_close_args() {
  }

  virtual ~ThriftHadoopFileSystem_close_args() throw() {}

  ThriftHandle out;

  struct __isset {
    __isset() : out(false) {}
    bool out;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_close_args & rhs) const
  {
    if (!(out == rhs.out))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_close_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_close_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_close_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_close_pargs() throw() {}

  const ThriftHandle* out;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_close_result {
 public:

  ThriftHadoopFileSystem_close_result() : success(0) {
  }

  virtual ~ThriftHadoopFileSystem_close_result() throw() {}

  bool success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_close_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_close_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_close_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_close_presult {
 public:


  virtual ~ThriftHadoopFileSystem_close_presult() throw() {}

  bool* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_rm_args {
 public:

  ThriftHadoopFileSystem_rm_args() : recursive(0) {
  }

  virtual ~ThriftHadoopFileSystem_rm_args() throw() {}

  Pathname path;
  bool recursive;

  struct __isset {
    __isset() : path(false), recursive(false) {}
    bool path;
    bool recursive;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_rm_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(recursive == rhs.recursive))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_rm_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_rm_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_rm_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_rm_pargs() throw() {}

  const Pathname* path;
  const bool* recursive;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_rm_result {
 public:

  ThriftHadoopFileSystem_rm_result() : success(0) {
  }

  virtual ~ThriftHadoopFileSystem_rm_result() throw() {}

  bool success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_rm_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_rm_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_rm_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_rm_presult {
 public:


  virtual ~ThriftHadoopFileSystem_rm_presult() throw() {}

  bool* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_rename_args {
 public:

  ThriftHadoopFileSystem_rename_args() {
  }

  virtual ~ThriftHadoopFileSystem_rename_args() throw() {}

  Pathname path;
  Pathname dest;

  struct __isset {
    __isset() : path(false), dest(false) {}
    bool path;
    bool dest;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_rename_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(dest == rhs.dest))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_rename_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_rename_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_rename_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_rename_pargs() throw() {}

  const Pathname* path;
  const Pathname* dest;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_rename_result {
 public:

  ThriftHadoopFileSystem_rename_result() : success(0) {
  }

  virtual ~ThriftHadoopFileSystem_rename_result() throw() {}

  bool success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_rename_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_rename_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_rename_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_rename_presult {
 public:


  virtual ~ThriftHadoopFileSystem_rename_presult() throw() {}

  bool* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_mkdirs_args {
 public:

  ThriftHadoopFileSystem_mkdirs_args() {
  }

  virtual ~ThriftHadoopFileSystem_mkdirs_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_mkdirs_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_mkdirs_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_mkdirs_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_mkdirs_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_mkdirs_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_mkdirs_result {
 public:

  ThriftHadoopFileSystem_mkdirs_result() : success(0) {
  }

  virtual ~ThriftHadoopFileSystem_mkdirs_result() throw() {}

  bool success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_mkdirs_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_mkdirs_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_mkdirs_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_mkdirs_presult {
 public:


  virtual ~ThriftHadoopFileSystem_mkdirs_presult() throw() {}

  bool* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_exists_args {
 public:

  ThriftHadoopFileSystem_exists_args() {
  }

  virtual ~ThriftHadoopFileSystem_exists_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_exists_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_exists_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_exists_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_exists_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_exists_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_exists_result {
 public:

  ThriftHadoopFileSystem_exists_result() : success(0) {
  }

  virtual ~ThriftHadoopFileSystem_exists_result() throw() {}

  bool success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_exists_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_exists_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_exists_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_exists_presult {
 public:


  virtual ~ThriftHadoopFileSystem_exists_presult() throw() {}

  bool* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_stat_args {
 public:

  ThriftHadoopFileSystem_stat_args() {
  }

  virtual ~ThriftHadoopFileSystem_stat_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_stat_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_stat_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_stat_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_stat_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_stat_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_stat_result {
 public:

  ThriftHadoopFileSystem_stat_result() {
  }

  virtual ~ThriftHadoopFileSystem_stat_result() throw() {}

  FileStatus success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_stat_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_stat_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_stat_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_stat_presult {
 public:


  virtual ~ThriftHadoopFileSystem_stat_presult() throw() {}

  FileStatus* success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_listStatus_args {
 public:

  ThriftHadoopFileSystem_listStatus_args() {
  }

  virtual ~ThriftHadoopFileSystem_listStatus_args() throw() {}

  Pathname path;

  struct __isset {
    __isset() : path(false) {}
    bool path;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_listStatus_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_listStatus_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_listStatus_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_listStatus_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_listStatus_pargs() throw() {}

  const Pathname* path;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_listStatus_result {
 public:

  ThriftHadoopFileSystem_listStatus_result() {
  }

  virtual ~ThriftHadoopFileSystem_listStatus_result() throw() {}

  std::vector<FileStatus>  success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_listStatus_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_listStatus_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_listStatus_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_listStatus_presult {
 public:


  virtual ~ThriftHadoopFileSystem_listStatus_presult() throw() {}

  std::vector<FileStatus> * success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_chmod_args {
 public:

  ThriftHadoopFileSystem_chmod_args() : mode(0) {
  }

  virtual ~ThriftHadoopFileSystem_chmod_args() throw() {}

  Pathname path;
  int16_t mode;

  struct __isset {
    __isset() : path(false), mode(false) {}
    bool path;
    bool mode;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_chmod_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(mode == rhs.mode))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_chmod_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_chmod_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_chmod_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_chmod_pargs() throw() {}

  const Pathname* path;
  const int16_t* mode;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_chmod_result {
 public:

  ThriftHadoopFileSystem_chmod_result() {
  }

  virtual ~ThriftHadoopFileSystem_chmod_result() throw() {}

  ThriftIOException ouch;

  struct __isset {
    __isset() : ouch(false) {}
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_chmod_result & rhs) const
  {
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_chmod_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_chmod_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_chmod_presult {
 public:


  virtual ~ThriftHadoopFileSystem_chmod_presult() throw() {}

  ThriftIOException ouch;

  struct __isset {
    __isset() : ouch(false) {}
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_chown_args {
 public:

  ThriftHadoopFileSystem_chown_args() : owner(""), group("") {
  }

  virtual ~ThriftHadoopFileSystem_chown_args() throw() {}

  Pathname path;
  std::string owner;
  std::string group;

  struct __isset {
    __isset() : path(false), owner(false), group(false) {}
    bool path;
    bool owner;
    bool group;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_chown_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(owner == rhs.owner))
      return false;
    if (!(group == rhs.group))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_chown_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_chown_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_chown_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_chown_pargs() throw() {}

  const Pathname* path;
  const std::string* owner;
  const std::string* group;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_chown_result {
 public:

  ThriftHadoopFileSystem_chown_result() {
  }

  virtual ~ThriftHadoopFileSystem_chown_result() throw() {}

  ThriftIOException ouch;

  struct __isset {
    __isset() : ouch(false) {}
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_chown_result & rhs) const
  {
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_chown_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_chown_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_chown_presult {
 public:


  virtual ~ThriftHadoopFileSystem_chown_presult() throw() {}

  ThriftIOException ouch;

  struct __isset {
    __isset() : ouch(false) {}
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_setReplication_args {
 public:

  ThriftHadoopFileSystem_setReplication_args() : replication(0) {
  }

  virtual ~ThriftHadoopFileSystem_setReplication_args() throw() {}

  Pathname path;
  int16_t replication;

  struct __isset {
    __isset() : path(false), replication(false) {}
    bool path;
    bool replication;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_setReplication_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(replication == rhs.replication))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_setReplication_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_setReplication_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_setReplication_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_setReplication_pargs() throw() {}

  const Pathname* path;
  const int16_t* replication;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_setReplication_result {
 public:

  ThriftHadoopFileSystem_setReplication_result() {
  }

  virtual ~ThriftHadoopFileSystem_setReplication_result() throw() {}

  ThriftIOException ouch;

  struct __isset {
    __isset() : ouch(false) {}
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_setReplication_result & rhs) const
  {
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_setReplication_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_setReplication_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_setReplication_presult {
 public:


  virtual ~ThriftHadoopFileSystem_setReplication_presult() throw() {}

  ThriftIOException ouch;

  struct __isset {
    __isset() : ouch(false) {}
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystem_getFileBlockLocations_args {
 public:

  ThriftHadoopFileSystem_getFileBlockLocations_args() : start(0), length(0) {
  }

  virtual ~ThriftHadoopFileSystem_getFileBlockLocations_args() throw() {}

  Pathname path;
  int64_t start;
  int64_t length;

  struct __isset {
    __isset() : path(false), start(false), length(false) {}
    bool path;
    bool start;
    bool length;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_getFileBlockLocations_args & rhs) const
  {
    if (!(path == rhs.path))
      return false;
    if (!(start == rhs.start))
      return false;
    if (!(length == rhs.length))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_getFileBlockLocations_args &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_getFileBlockLocations_args & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_getFileBlockLocations_pargs {
 public:


  virtual ~ThriftHadoopFileSystem_getFileBlockLocations_pargs() throw() {}

  const Pathname* path;
  const int64_t* start;
  const int64_t* length;

  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_getFileBlockLocations_result {
 public:

  ThriftHadoopFileSystem_getFileBlockLocations_result() {
  }

  virtual ~ThriftHadoopFileSystem_getFileBlockLocations_result() throw() {}

  std::vector<BlockLocation>  success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  bool operator == (const ThriftHadoopFileSystem_getFileBlockLocations_result & rhs) const
  {
    if (!(success == rhs.success))
      return false;
    if (!(ouch == rhs.ouch))
      return false;
    return true;
  }
  bool operator != (const ThriftHadoopFileSystem_getFileBlockLocations_result &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ThriftHadoopFileSystem_getFileBlockLocations_result & ) const;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);
  uint32_t write(facebook::thrift::protocol::TProtocol* oprot) const;

};

class ThriftHadoopFileSystem_getFileBlockLocations_presult {
 public:


  virtual ~ThriftHadoopFileSystem_getFileBlockLocations_presult() throw() {}

  std::vector<BlockLocation> * success;
  ThriftIOException ouch;

  struct __isset {
    __isset() : success(false), ouch(false) {}
    bool success;
    bool ouch;
  } __isset;

  uint32_t read(facebook::thrift::protocol::TProtocol* iprot);

};

class ThriftHadoopFileSystemClient : virtual public ThriftHadoopFileSystemIf {
 public:
  ThriftHadoopFileSystemClient(boost::shared_ptr<facebook::thrift::protocol::TProtocol> prot) :
    piprot_(prot),
    poprot_(prot) {
    iprot_ = prot.get();
    oprot_ = prot.get();
  }
  ThriftHadoopFileSystemClient(boost::shared_ptr<facebook::thrift::protocol::TProtocol> iprot, boost::shared_ptr<facebook::thrift::protocol::TProtocol> oprot) :
    piprot_(iprot),
    poprot_(oprot) {
    iprot_ = iprot.get();
    oprot_ = oprot.get();
  }
  boost::shared_ptr<facebook::thrift::protocol::TProtocol> getInputProtocol() {
    return piprot_;
  }
  boost::shared_ptr<facebook::thrift::protocol::TProtocol> getOutputProtocol() {
    return poprot_;
  }
  void setInactivityTimeoutPeriod(const int64_t periodInSeconds);
  void send_setInactivityTimeoutPeriod(const int64_t periodInSeconds);
  void recv_setInactivityTimeoutPeriod();
  void shutdown(const int32_t status);
  void send_shutdown(const int32_t status);
  void recv_shutdown();
  void create(ThriftHandle& _return, const Pathname& path);
  void send_create(const Pathname& path);
  void recv_create(ThriftHandle& _return);
  void createFile(ThriftHandle& _return, const Pathname& path, const int16_t mode, const bool overwrite, const int32_t bufferSize, const int16_t block_replication, const int64_t blocksize);
  void send_createFile(const Pathname& path, const int16_t mode, const bool overwrite, const int32_t bufferSize, const int16_t block_replication, const int64_t blocksize);
  void recv_createFile(ThriftHandle& _return);
  void open(ThriftHandle& _return, const Pathname& path);
  void send_open(const Pathname& path);
  void recv_open(ThriftHandle& _return);
  void append(ThriftHandle& _return, const Pathname& path);
  void send_append(const Pathname& path);
  void recv_append(ThriftHandle& _return);
  bool write(const ThriftHandle& handle, const std::string& data);
  void send_write(const ThriftHandle& handle, const std::string& data);
  bool recv_write();
  void read(std::string& _return, const ThriftHandle& handle, const int64_t offset, const int32_t size);
  void send_read(const ThriftHandle& handle, const int64_t offset, const int32_t size);
  void recv_read(std::string& _return);
  bool close(const ThriftHandle& out);
  void send_close(const ThriftHandle& out);
  bool recv_close();
  bool rm(const Pathname& path, const bool recursive);
  void send_rm(const Pathname& path, const bool recursive);
  bool recv_rm();
  bool rename(const Pathname& path, const Pathname& dest);
  void send_rename(const Pathname& path, const Pathname& dest);
  bool recv_rename();
  bool mkdirs(const Pathname& path);
  void send_mkdirs(const Pathname& path);
  bool recv_mkdirs();
  bool exists(const Pathname& path);
  void send_exists(const Pathname& path);
  bool recv_exists();
  void stat(FileStatus& _return, const Pathname& path);
  void send_stat(const Pathname& path);
  void recv_stat(FileStatus& _return);
  void listStatus(std::vector<FileStatus> & _return, const Pathname& path);
  void send_listStatus(const Pathname& path);
  void recv_listStatus(std::vector<FileStatus> & _return);
  void chmod(const Pathname& path, const int16_t mode);
  void send_chmod(const Pathname& path, const int16_t mode);
  void recv_chmod();
  void chown(const Pathname& path, const std::string& owner, const std::string& group);
  void send_chown(const Pathname& path, const std::string& owner, const std::string& group);
  void recv_chown();
  void setReplication(const Pathname& path, const int16_t replication);
  void send_setReplication(const Pathname& path, const int16_t replication);
  void recv_setReplication();
  void getFileBlockLocations(std::vector<BlockLocation> & _return, const Pathname& path, const int64_t start, const int64_t length);
  void send_getFileBlockLocations(const Pathname& path, const int64_t start, const int64_t length);
  void recv_getFileBlockLocations(std::vector<BlockLocation> & _return);
 protected:
  boost::shared_ptr<facebook::thrift::protocol::TProtocol> piprot_;
  boost::shared_ptr<facebook::thrift::protocol::TProtocol> poprot_;
  facebook::thrift::protocol::TProtocol* iprot_;
  facebook::thrift::protocol::TProtocol* oprot_;
};

class ThriftHadoopFileSystemProcessor : virtual public facebook::thrift::TProcessor {
 protected:
  boost::shared_ptr<ThriftHadoopFileSystemIf> iface_;
  virtual bool process_fn(facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid);
 private:
  std::map<std::string, void (ThriftHadoopFileSystemProcessor::*)(int32_t, facebook::thrift::protocol::TProtocol*, facebook::thrift::protocol::TProtocol*)> processMap_;
  void process_setInactivityTimeoutPeriod(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_shutdown(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_create(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_createFile(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_open(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_append(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_write(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_read(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_close(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_rm(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_rename(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_mkdirs(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_exists(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_stat(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_listStatus(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_chmod(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_chown(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_setReplication(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
  void process_getFileBlockLocations(int32_t seqid, facebook::thrift::protocol::TProtocol* iprot, facebook::thrift::protocol::TProtocol* oprot);
 public:
  ThriftHadoopFileSystemProcessor(boost::shared_ptr<ThriftHadoopFileSystemIf> iface) :
    iface_(iface) {
    processMap_["setInactivityTimeoutPeriod"] = &ThriftHadoopFileSystemProcessor::process_setInactivityTimeoutPeriod;
    processMap_["shutdown"] = &ThriftHadoopFileSystemProcessor::process_shutdown;
    processMap_["create"] = &ThriftHadoopFileSystemProcessor::process_create;
    processMap_["createFile"] = &ThriftHadoopFileSystemProcessor::process_createFile;
    processMap_["open"] = &ThriftHadoopFileSystemProcessor::process_open;
    processMap_["append"] = &ThriftHadoopFileSystemProcessor::process_append;
    processMap_["write"] = &ThriftHadoopFileSystemProcessor::process_write;
    processMap_["read"] = &ThriftHadoopFileSystemProcessor::process_read;
    processMap_["close"] = &ThriftHadoopFileSystemProcessor::process_close;
    processMap_["rm"] = &ThriftHadoopFileSystemProcessor::process_rm;
    processMap_["rename"] = &ThriftHadoopFileSystemProcessor::process_rename;
    processMap_["mkdirs"] = &ThriftHadoopFileSystemProcessor::process_mkdirs;
    processMap_["exists"] = &ThriftHadoopFileSystemProcessor::process_exists;
    processMap_["stat"] = &ThriftHadoopFileSystemProcessor::process_stat;
    processMap_["listStatus"] = &ThriftHadoopFileSystemProcessor::process_listStatus;
    processMap_["chmod"] = &ThriftHadoopFileSystemProcessor::process_chmod;
    processMap_["chown"] = &ThriftHadoopFileSystemProcessor::process_chown;
    processMap_["setReplication"] = &ThriftHadoopFileSystemProcessor::process_setReplication;
    processMap_["getFileBlockLocations"] = &ThriftHadoopFileSystemProcessor::process_getFileBlockLocations;
  }

  virtual bool process(boost::shared_ptr<facebook::thrift::protocol::TProtocol> piprot, boost::shared_ptr<facebook::thrift::protocol::TProtocol> poprot);
  virtual ~ThriftHadoopFileSystemProcessor() {}
};

class ThriftHadoopFileSystemMultiface : virtual public ThriftHadoopFileSystemIf {
 public:
  ThriftHadoopFileSystemMultiface(std::vector<boost::shared_ptr<ThriftHadoopFileSystemIf> >& ifaces) : ifaces_(ifaces) {
  }
  virtual ~ThriftHadoopFileSystemMultiface() {}
 protected:
  std::vector<boost::shared_ptr<ThriftHadoopFileSystemIf> > ifaces_;
  ThriftHadoopFileSystemMultiface() {}
  void add(boost::shared_ptr<ThriftHadoopFileSystemIf> iface) {
    ifaces_.push_back(iface);
  }
 public:
  void setInactivityTimeoutPeriod(const int64_t periodInSeconds) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      ifaces_[i]->setInactivityTimeoutPeriod(periodInSeconds);
    }
  }

  void shutdown(const int32_t status) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      ifaces_[i]->shutdown(status);
    }
  }

  void create(ThriftHandle& _return, const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->create(_return, path);
        return;
      } else {
        ifaces_[i]->create(_return, path);
      }
    }
  }

  void createFile(ThriftHandle& _return, const Pathname& path, const int16_t mode, const bool overwrite, const int32_t bufferSize, const int16_t block_replication, const int64_t blocksize) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->createFile(_return, path, mode, overwrite, bufferSize, block_replication, blocksize);
        return;
      } else {
        ifaces_[i]->createFile(_return, path, mode, overwrite, bufferSize, block_replication, blocksize);
      }
    }
  }

  void open(ThriftHandle& _return, const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->open(_return, path);
        return;
      } else {
        ifaces_[i]->open(_return, path);
      }
    }
  }

  void append(ThriftHandle& _return, const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->append(_return, path);
        return;
      } else {
        ifaces_[i]->append(_return, path);
      }
    }
  }

  bool write(const ThriftHandle& handle, const std::string& data) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        return ifaces_[i]->write(handle, data);
      } else {
        ifaces_[i]->write(handle, data);
      }
    }
  }

  void read(std::string& _return, const ThriftHandle& handle, const int64_t offset, const int32_t size) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->read(_return, handle, offset, size);
        return;
      } else {
        ifaces_[i]->read(_return, handle, offset, size);
      }
    }
  }

  bool close(const ThriftHandle& out) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        return ifaces_[i]->close(out);
      } else {
        ifaces_[i]->close(out);
      }
    }
  }

  bool rm(const Pathname& path, const bool recursive) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        return ifaces_[i]->rm(path, recursive);
      } else {
        ifaces_[i]->rm(path, recursive);
      }
    }
  }

  bool rename(const Pathname& path, const Pathname& dest) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        return ifaces_[i]->rename(path, dest);
      } else {
        ifaces_[i]->rename(path, dest);
      }
    }
  }

  bool mkdirs(const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        return ifaces_[i]->mkdirs(path);
      } else {
        ifaces_[i]->mkdirs(path);
      }
    }
  }

  bool exists(const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        return ifaces_[i]->exists(path);
      } else {
        ifaces_[i]->exists(path);
      }
    }
  }

  void stat(FileStatus& _return, const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->stat(_return, path);
        return;
      } else {
        ifaces_[i]->stat(_return, path);
      }
    }
  }

  void listStatus(std::vector<FileStatus> & _return, const Pathname& path) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->listStatus(_return, path);
        return;
      } else {
        ifaces_[i]->listStatus(_return, path);
      }
    }
  }

  void chmod(const Pathname& path, const int16_t mode) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      ifaces_[i]->chmod(path, mode);
    }
  }

  void chown(const Pathname& path, const std::string& owner, const std::string& group) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      ifaces_[i]->chown(path, owner, group);
    }
  }

  void setReplication(const Pathname& path, const int16_t replication) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      ifaces_[i]->setReplication(path, replication);
    }
  }

  void getFileBlockLocations(std::vector<BlockLocation> & _return, const Pathname& path, const int64_t start, const int64_t length) {
    uint32_t sz = ifaces_.size();
    for (uint32_t i = 0; i < sz; ++i) {
      if (i == sz - 1) {
        ifaces_[i]->getFileBlockLocations(_return, path, start, length);
        return;
      } else {
        ifaces_[i]->getFileBlockLocations(_return, path, start, length);
      }
    }
  }

};



#endif
