file.cpp
Go to the documentation of this file.
00001 #include <imagezero/file.h>
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include "iz_config.h"
00005 #endif
00006 
00007 #if defined(HAVE_MMAP)
00008 
00010 
00011 #include <cstdlib>
00012 #include <fcntl.h>
00013 #include <unistd.h>
00014 #include <sys/mman.h>
00015 #include <sys/stat.h>
00016 
00017 namespace IZ
00018 {
00019   class InputFile::Private
00020   {
00021   public:
00022     Private() : addr(MAP_FAILED)
00023     {}
00024 
00025     void* addr;
00026     size_t size;
00027   };
00028 
00029   InputFile::InputFile(const char* filename)
00030       : d(new Private)
00031   {
00032       int fd = open(filename, O_RDONLY);
00033       if (fd != -1)
00034       {
00035           struct stat sb;
00036           fstat(fd, &sb);
00037           d->size = sb.st_size;
00038           d->addr = mmap(0, d->size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0);
00039           if (d->addr == MAP_FAILED)
00040           {
00041               d->addr = mmap(0, d->size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
00042               if (d->addr != MAP_FAILED)
00043               {
00044                   read(fd, d->addr, d->size);
00045               }
00046           }
00047           close(fd);
00048       }
00049   }
00050 
00051   InputFile::~InputFile()
00052   {
00053       if (d->addr != MAP_FAILED)
00054       {
00055           munmap(d->addr, d->size);
00056       }
00057       delete d;
00058   }
00059 
00060   bool InputFile::isReadable() const
00061   {
00062       return d->addr != MAP_FAILED;
00063   }
00064 
00065   const unsigned char* InputFile::data() const
00066   {
00067       return (const unsigned char*) d->addr;
00068   }
00069 
00070   size_t InputFile::dataSize() const
00071   {
00072       return d->size;
00073   }
00074 
00075 
00076   class OutputFile::Private
00077   {
00078   public:
00079     Private()
00080     {}
00081 
00082     int fd;
00083     size_t mapSize;
00084   };
00085 
00086   OutputFile::OutputFile(const char* filename)
00087       : d(new Private)
00088   {
00089       d->fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644);
00090   }
00091 
00092   OutputFile::~OutputFile()
00093   {
00094       if (d->fd != -1)
00095       {
00096           close(d->fd);
00097       }
00098       delete d;
00099   }
00100 
00101   bool OutputFile::isWritable() const
00102   {
00103       if (d->fd != -1)
00104       {
00105           return true;
00106       }
00107       return false;
00108   }
00109 
00110   unsigned char* OutputFile::prepareData(size_t maxSize)
00111   {
00112       if (d->fd != -1)
00113       {
00114           ftruncate(d->fd, maxSize);
00115           d->mapSize = maxSize;
00116           void* addr = mmap(0, d->mapSize, PROT_WRITE | PROT_READ, MAP_SHARED, d->fd, 0);
00117           if (addr != MAP_FAILED)
00118           {
00119               return (unsigned char*) addr;
00120           }
00121           ftruncate(d->fd, 0);
00122           d->mapSize = 0;
00123           return (unsigned char*) malloc(maxSize);
00124       }
00125       return 0;
00126   }
00127 
00128   void OutputFile::commitData(unsigned char* data, size_t size)
00129   {
00130       if (data)
00131       {
00132           if (d->mapSize)
00133           {
00134               munmap(data, d->mapSize);
00135               ftruncate(d->fd, size);
00136           }
00137           else
00138           {
00139               write(d->fd, data, size);
00140               free(data);
00141           }
00142       }
00143   }
00144 
00145 #else // defined(HAVE_MMAP)
00146 
00148 
00149 #include <cstdio>
00150 #include <cstdlib>
00151 
00152   class InputFile::Private
00153   {
00154   public:
00155       Private() : buffer(0), size(0) { }
00156 
00157       unsigned char *buffer;
00158       size_t size;
00159   };
00160 
00161   InputFile::InputFile(const char *filename)
00162       : d(new Private)
00163   {
00164       FILE *fp = fopen(filename, "rb");
00165       if (fp) {
00166           setbuf(fp, 0);
00167           fseek(fp, 0, SEEK_END);
00168           d->size = ftell(fp);
00169           fseek(fp, 0, SEEK_SET);
00170           if (d->size > 0) {
00171               d->buffer = (unsigned char *) malloc(d->size);
00172               if (d->buffer) {
00173                   d->size = fread(d->buffer, 1, d->size, fp);
00174               }
00175           }
00176           fclose(fp);
00177       }
00178   }
00179 
00180   InputFile::~InputFile()
00181   {
00182       if (d->buffer) {
00183           free(d->buffer);
00184       }
00185       delete d;
00186   }
00187 
00188   bool InputFile::isReadable() const
00189   {
00190       return d->buffer != 0;
00191   }
00192 
00193   const unsigned char *InputFile::data() const
00194   {
00195       return d->buffer;
00196   }
00197 
00198   size_t InputFile::dataSize() const
00199   {
00200       return d->size;
00201   }
00202 
00203 
00204   class OutputFile::Private
00205   {
00206   public:
00207       Private() { }
00208 
00209       FILE *fp;
00210   };
00211 
00212   OutputFile::OutputFile(const char *filename)
00213       : d(new Private)
00214   {
00215       d->fp = fopen(filename, "wb");
00216       if (d->fp) {
00217           setbuf(d->fp, 0);
00218       }
00219   }
00220 
00221   OutputFile::~OutputFile()
00222   {
00223       if (d->fp) {
00224           fclose(d->fp);
00225       }
00226       delete d;
00227   }
00228 
00229   bool OutputFile::isWritable() const
00230   {
00231       if (d->fp) {
00232           return true;
00233       }
00234       return false;
00235   }
00236 
00237   unsigned char *OutputFile::prepareData(size_t maxSize)
00238   {
00239       return (unsigned char *) malloc(maxSize);
00240   }
00241 
00242   void OutputFile::commitData(unsigned char *data, size_t size)
00243   {
00244       if (data) {
00245           if (d->fp) {
00246               fwrite(data, 1, size, d->fp);
00247           }
00248           free(data);
00249       }
00250   }
00251 
00252 #endif // defined(HAVE_MMAP)
00253 
00254 }


imagezero
Author(s):
autogenerated on Thu Jun 6 2019 21:34:51