/******************************************************************************

 FUSE binding for C++ (see http://fuse.sourceforge.net)

 Darryl Cain (darryl@cain.com.au) 
 May '07

*******************************************************************************/

#ifndef _FUSE_BINDING_H_
#define _FUSE_BINDING_H_

// based on fuse-2.6.4-r1
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <strings.h>

namespace DC { namespace Fuse
{
  typedef int   (*getattr)     (const char*, struct stat*);
  typedef int   (*readlink)    (const char*, char*, size_t);
  typedef int   (*mknod)       (const char*, mode_t, dev_t);
  typedef int   (*mkdir)       (const char*, mode_t);
  typedef int   (*unlink)      (const char*);
  typedef int   (*rmdir)       (const char*);
  typedef int   (*symlink)     (const char*, const char*);
  typedef int   (*rename)      (const char*, const char*);
  typedef int   (*link)        (const char*, const char*);
  typedef int   (*chmod)       (const char*, mode_t);
  typedef int   (*chown)       (const char*, uid_t, gid_t);
  typedef int   (*truncate)    (const char*, off_t);
  typedef int   (*open)        (const char*, struct fuse_file_info*);
  typedef int   (*read)        (const char*, char *, size_t, off_t, struct fuse_file_info*);
  typedef int   (*write)       (const char*, const char*, size_t, off_t, struct fuse_file_info*);
  typedef int   (*statfs)      (const char*, struct statvfs*);
  typedef int   (*flush)       (const char*, struct fuse_file_info*);
  typedef int   (*release)     (const char*, struct fuse_file_info*);
  typedef int   (*fsync)       (const char*, int, struct fuse_file_info*);
  typedef int   (*setxattr)    (const char*, const char*, const char*, size_t, int);
  typedef int   (*getxattr)    (const char*, const char*, char*, size_t);
  typedef int   (*listxattr)   (const char*, char*, size_t);
  typedef int   (*removexattr) (const char*, const char*);
  typedef int   (*opendir)     (const char*, struct fuse_file_info*);
  typedef int   (*readdir)     (const char*, void*, fuse_fill_dir_t, off_t, struct fuse_file_info*);
  typedef int   (*releasedir)  (const char*, struct fuse_file_info*);
  typedef int   (*fsyncdir)    (const char*, int, struct fuse_file_info*);
  typedef void* (*init)        (struct fuse_conn_info *conn);
  typedef void  (*destroy)     (void*);
  typedef int   (*access)      (const char*, int);
  typedef int   (*create)      (const char*, mode_t, struct fuse_file_info*);
  typedef int   (*ftruncate)   (const char*, off_t, struct fuse_file_info*);
  typedef int   (*fgetattr)    (const char*, struct stat*, struct fuse_file_info*);
  typedef int   (*lock)        (const char*, struct fuse_file_info*, int cmd, struct flock*);
  typedef int   (*utimens)     (const char*, const struct timespec tv[2]);
  typedef int   (*bmap)        (const char*, size_t blocksize, uint64_t *idx);

  typedef struct fuse_operations fuse_ops;

  class FuseBinding
  {
    public:
      // constructor
      FuseBinding()                              { bzero(&m_operations, sizeof(fuse_ops)); }

      // accessors
      fuse_ops*   get_operations()               { return &m_operations; }

      getattr     get_getattr()                  { return m_operations.getattr;}
      readlink    get_readlink()                 { return m_operations.readlink;}
      mknod       get_mknod()                    { return m_operations.mknod;}
      mkdir       get_mkdir()                    { return m_operations.mkdir;}
      unlink      get_unlink()                   { return m_operations.unlink;}
      rmdir       get_rmdir()                    { return m_operations.rmdir;}
      symlink     get_symlink()                  { return m_operations.symlink;}
      rename      get_rename()                   { return m_operations.rename;}
      link        get_link()                     { return m_operations.link;}
      chmod       get_chmod()                    { return m_operations.chmod;}
      chown       get_chown()                    { return m_operations.chown;}
      truncate    get_truncate()                 { return m_operations.truncate;}
      open        get_open()                     { return m_operations.open;}
      read        get_read()                     { return m_operations.read;}
      write       get_write()                    { return m_operations.write;}
      statfs      get_statfs()                   { return m_operations.statfs;}
      flush       get_flush()                    { return m_operations.flush;}
      release     get_release()                  { return m_operations.release;}
      fsync       get_fsync()                    { return m_operations.fsync;}
      setxattr    get_setxattr()                 { return m_operations.setxattr;}
      getxattr    get_getxattr()                 { return m_operations.getxattr;}
      listxattr   get_listxattr()                { return m_operations.listxattr;}
      removexattr get_removexattr()              { return m_operations.removexattr;}
      opendir     get_opendir()                  { return m_operations.opendir;}
      readdir     get_readdir()                  { return m_operations.readdir;}
      releasedir  get_releasedir()               { return m_operations.releasedir;}
      fsyncdir    get_fsyncdir()                 { return m_operations.fsyncdir;}
      init        get_init()                     { return m_operations.init;}
      destroy     get_destroy()                  { return m_operations.destroy;}
      access      get_access()                   { return m_operations.access;}
      create      get_create()                   { return m_operations.create;}
      ftruncate   get_ftruncate()                { return m_operations.ftruncate;}
      fgetattr    get_fgetattr()                 { return m_operations.fgetattr;}
      lock        get_lock()                     { return m_operations.lock;}
      utimens     get_utimens()                  { return m_operations.utimens;}
      bmap        get_bmap()                     { return m_operations.bmap;}

      // mutators
      void        set_getattr(getattr f)         { m_operations.getattr = f;}
      void        set_readlink(readlink f)       { m_operations.readlink = f;}
      void        set_mknod(mknod f)             { m_operations.mknod = f;}
      void        set_mkdir(mkdir f)             { m_operations.mkdir = f;}
      void        set_unlink(unlink f)           { m_operations.unlink = f;}
      void        set_rmdir(rmdir f)             { m_operations.rmdir = f;}
      void        set_symlink(symlink f)         { m_operations.symlink = f;}
      void        set_rename(rename f)           { m_operations.rename = f;}
      void        set_link(link f)               { m_operations.link = f;}
      void        set_chmod(chmod f)             { m_operations.chmod = f;}
      void        set_chown(chown f)             { m_operations.chown = f;}
      void        set_truncate(truncate f)       { m_operations.truncate = f;}
      void        set_open(open f)               { m_operations.open = f;}
      void        set_read(read f)               { m_operations.read = f;}
      void        set_write(write f)             { m_operations.write = f;}
      void        set_statfs(statfs f)           { m_operations.statfs = f;}
      void        set_flush(flush f)             { m_operations.flush = f;}
      void        set_release(release f)         { m_operations.release = f;}
      void        set_fsync(fsync f)             { m_operations.fsync = f;}
      void        set_setxattr(setxattr f)       { m_operations.setxattr = f;}
      void        set_getxattr(getxattr f)       { m_operations.getxattr = f;}
      void        set_listxattr(listxattr f)     { m_operations.listxattr = f;}
      void        set_removexattr(removexattr f) { m_operations.removexattr = f;}
      void        set_opendir(opendir f)         { m_operations.opendir = f;}
      void        set_readdir(readdir f)         { m_operations.readdir = f;}
      void        set_releasedir(releasedir f)   { m_operations.releasedir = f;}
      void        set_fsyncdir(fsyncdir f)       { m_operations.fsyncdir = f;}
      void        set_init(init f)               { m_operations.init = f;}
      void        set_destroy(destroy f)         { m_operations.destroy = f;}
      void        set_access(access f)           { m_operations.access = f;}
      void        set_create(create f)           { m_operations.create = f;}
      void        set_ftruncate(ftruncate f)     { m_operations.ftruncate = f;}
      void        set_fgetattr(fgetattr f)       { m_operations.fgetattr = f;}
      void        set_lock(lock f)               { m_operations.lock = f;}
      void        set_utimens(utimens f)         { m_operations.utimens = f;}
      void        set_bmap(bmap f)               { m_operations.bmap = f;}

    private:
      fuse_ops m_operations;
  };
}}

#endif
