lux/util.h

00001 #ifndef LUX_UTIL_H
00002 #define LUX_UTIL_H
00003 
00004 //#define _XOPEN_SOURCE 50
00005 
00006 #include "luxconfig.h"
00007 #include "types.h"
00008 #include <sys/stat.h>
00009 #include <fcntl.h>
00010 #include <sys/mman.h>
00011 #include <errno.h>
00012 #include <string>
00013 #include <iostream>
00014 #include <unistd.h>
00015 
00016 #ifdef USE_ZLIB
00017 #include <zlib.h>
00018 #endif
00019 
00020 #define MIN_COMPRESS_LENGTH 50
00021 
00022 #ifdef DEBUG
00023 #define error_log(msg) \
00024   std::cerr << "[error] " << msg \
00025             << " in " << __FILE__ << ":" << __LINE__ \
00026             << std::endl; 
00027 #else
00028 #define error_log(msg)
00029 #endif
00030 
00031 // for verbose info logging
00032 #ifdef DEBUG_VINFO
00033 #define vinfo_log(msg) \
00034   std::cerr << "[info] " << msg \
00035             << std::endl; 
00036 #else
00037 #define vinfo_log(msg)
00038 #endif
00039 
00040 namespace Lux {
00041 
00042   static inline void _mkdir(const char *str)
00043   {
00044     std::string str_(str); 
00045     std::size_t n = 0;
00046     while (1) {
00047       n = str_.find_first_of('/', n+1);
00048       if (n == std::string::npos) {
00049         break;  
00050       }
00051       std::string dir = str_.substr(0, n);
00052       // [TODO] error handling
00053       ::mkdir(dir.c_str(), 0755);
00054     }
00055   }
00056 
00057   static inline int _open(const char *pathname, int flags, mode_t mode)
00058   {
00059     int oflags = O_RDONLY;
00060 
00061     if (flags & DB_RDWR) {
00062       oflags |= O_RDWR;
00063     }
00064     if (flags & DB_CREAT) {
00065       oflags |= O_CREAT | O_RDWR;
00066       _mkdir(pathname);
00067     }
00068     if (flags & DB_TRUNC) {
00069       oflags |= O_TRUNC;
00070     }
00071     return ::open(pathname, oflags, mode);
00072   }
00073   
00074   static inline ssize_t _read(int fd, void *buf, size_t count)
00075   {
00076     char *p = reinterpret_cast<char *>(buf);
00077     const char * const end_p = p + count;
00078 
00079     while (p < end_p) {
00080       const int num_bytes = read(fd, p, end_p - p);
00081       if (num_bytes < 0) {
00082         if (errno == EINTR) {
00083           continue;
00084         }
00085         perror("read failed");
00086         break;
00087       }
00088       p += num_bytes;
00089     }
00090 
00091     if (p != end_p) {
00092       return -1;
00093     }
00094     return count;
00095   }
00096 
00097   static inline ssize_t _write(int fd, const void *buf, size_t count)
00098   {
00099     const char *p = reinterpret_cast<const char *>(buf);
00100     const char * const end_p = p + count;
00101 
00102     while (p < end_p) {
00103       const int num_bytes = write(fd, p, end_p - p);
00104       if (num_bytes < 0) {
00105         if (errno == EINTR) continue;
00106         perror("write failed");
00107         break;
00108       }
00109       p += num_bytes;
00110     }
00111 
00112     if (p != end_p) {
00113       return -1;
00114     }
00115     return count;
00116   }
00117 
00118   static inline bool _pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
00119   {
00120     if (pwrite(fd, buf, nbyte, offset) < 0) {
00121       perror("pwrite failed");
00122       return false;
00123     }
00124     /*
00125     if (lseek(fd, offset, SEEK_SET) < 0) {
00126       return false;
00127     }
00128     if (_write(fd, buf, nbyte) < 0) {
00129       return false; 
00130     }
00131     */
00132     return true;
00133   }
00134 
00135   static inline bool _pread(int fd, void *buf, size_t nbyte, off_t offset)
00136   {
00137     if (pread(fd, buf, nbyte, offset) < 0) {
00138       perror("pread failed");
00139       return false;
00140     }
00141     /*
00142     if (lseek(fd, offset, SEEK_SET) < 0) {
00143       return false;
00144     }
00145     if (_read(fd, buf, nbyte) < 0) {
00146       return false; 
00147     } 
00148     */
00149     return true;
00150   }
00151 
00152   static inline void *_mmap(int fd, size_t size, int flags)
00153   {
00154     int prot = PROT_READ;
00155     if (flags & DB_RDWR || flags & DB_CREAT) {
00156       prot |= PROT_WRITE;
00157     }
00158 
00159     void *p = mmap(0, size, prot, MAP_SHARED, fd, 0);  
00160     if (p == MAP_FAILED) {
00161       perror("mmap failed.");
00162       return NULL;
00163     }
00164     return p;
00165   }
00166 
00167 #ifdef USE_ZLIB
00168   static inline
00169   char *_compress(char *src, uint32_t slen, uint32_t *dlen)
00170   {
00171     *dlen = slen * 120 / 100 + 12;
00172     char *dest = new char[*dlen];
00173     int res = ::compress((Bytef *) dest, (uLongf *) dlen,
00174                          (const Bytef *) src, (uLong) slen);
00175     if (res != Z_OK) { 
00176       delete [] dest;
00177       if (res == Z_MEM_ERROR) {
00178         error_log("out of memory");
00179       } else if (res == Z_BUF_ERROR) {
00180         error_log("no enough buffer");
00181       }
00182       return NULL;
00183     }
00184     if (*dlen > slen) {
00185       *dlen = 0;
00186       delete [] dest;
00187       return NULL; // no compression
00188     }
00189     return dest;
00190   }
00191 
00192   static inline
00193   char *compress(char *src, uint32_t slen, uint32_t *dlen)
00194   {
00195     if (slen < MIN_COMPRESS_LENGTH) {
00196       *dlen = 0;
00197       return NULL;
00198     }
00199     return _compress(src, slen, dlen);
00200   }
00201 
00202   static inline
00203   char *uncompress(char *src, uint32_t slen, uint32_t *dlen)
00204   {
00205     char *dest = new char[*dlen+1]; // must be smaller than slen
00206     memset(dest, 0, *dlen+1);
00207     int res = ::uncompress((Bytef *) dest, (uLongf *) dlen,
00208                            (const Bytef *) src, (uLong) slen);
00209     if (res != Z_OK) { 
00210       delete [] dest;
00211       if (res == Z_MEM_ERROR) {
00212         error_log("out of memory");
00213       } else if (res == Z_BUF_ERROR) {
00214         error_log("no enough buffer");
00215       }
00216       return NULL;
00217     }
00218     return dest;
00219   }
00220 #endif
00221 
00222 }
00223 
00224 #endif

Generated on Fri Feb 5 15:50:30 2010 for Lux by  doxygen 1.4.7