SASC-NG
DVBSoftCAM

tools.h

Go to the documentation of this file.
00001 /*
00002  * tools.h: Various tools
00003  *
00004  * See the main source file 'vdr.c' for copyright information and
00005  * how to reach the author.
00006  *
00007  * $Id: tools.h 1.103 2007/06/23 13:34:28 kls Exp $
00008  */
00009 
00010 #ifndef __TOOLS_H
00011 #define __TOOLS_H
00012 
00013 #include <dirent.h>
00014 #include <errno.h>
00015 #include <fcntl.h>
00016 #include <iconv.h>
00017 #include <poll.h>
00018 #include <stddef.h>
00019 #include <stdint.h>
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <syslog.h>
00024 #include <sys/stat.h>
00025 #include <sys/types.h>
00026 
00027 typedef unsigned char uchar;
00028 
00029 extern int SysLogLevel;
00030 
00031 #define esyslog(a...) void( (SysLogLevel > 0) ? syslog_with_tid(LOG_ERR,   a) : void() )
00032 #define isyslog(a...) void( (SysLogLevel > 1) ? syslog_with_tid(LOG_INFO,  a) : void() )
00033 #define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(LOG_DEBUG, a) : void() )
00034 
00035 #define LOG_ERROR         esyslog("ERROR (%s,%d): %m", __FILE__, __LINE__)
00036 #define LOG_ERROR_STR(s)  esyslog("ERROR: %s: %m", s)
00037 
00038 #define SECSINDAY  86400
00039 
00040 #define KILOBYTE(n) ((n) * 1024)
00041 #define MEGABYTE(n) ((n) * 1024 * 1024)
00042 
00043 #define MALLOC(type, size)  (type *)malloc(sizeof(type) * (size))
00044 
00045 #define DELETENULL(p) (delete (p), p = NULL)
00046 
00047 #define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
00048 #define FATALERRNO (errno && errno != EAGAIN && errno != EINTR)
00049 
00050 #ifndef __STL_CONFIG_H // in case some plugin needs to use the STL
00051 template<class T> inline T min(T a, T b) { return a <= b ? a : b; }
00052 template<class T> inline T max(T a, T b) { return a >= b ? a : b; }
00053 template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }
00054 template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
00055 #endif
00056 
00057 void syslog_with_tid(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
00058 
00059 #define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
00060 int BCD2INT(int x);
00061 
00062 // Unfortunately there are no platform independent macros for unaligned
00063 // access. so we do it this way:
00064 
00065 template<class T> inline T get_unaligned(T *p)
00066 {
00067   struct s { T v; } __attribute__((packed));
00068   return ((s *)p)->v;
00069 }
00070 
00071 template<class T> inline void put_unaligned(unsigned int v, T* p)
00072 {
00073   struct s { T v; } __attribute__((packed));
00074   ((s *)p)->v = v;
00075 }
00076 
00077 // When handling strings that might contain UTF-8 characters, it may be necessary
00078 // to process a "symbol" that consists of several actual character bytes. The
00079 // following functions allow transparently accessing a "char *" string without
00080 // having to worry about what character set is actually used.
00081 
00082 int Utf8CharLen(const char *s);
00085 uint Utf8CharGet(const char *s, int Length = 0);
00089 int Utf8CharSet(uint c, char *s = NULL);
00093 int Utf8SymChars(const char *s, int Symbols);
00096 int Utf8StrLen(const char *s);
00099 char *Utf8Strn0Cpy(char *Dest, const char *Src, int n);
00104 int Utf8ToArray(const char *s, uint *a, int Size);
00108 int Utf8FromArray(const uint *a, char *s, int Size, int Max = -1);
00114 
00115 // When allocating buffer space, make sure we reserve enough space to hold
00116 // a string in UTF-8 representation:
00117 
00118 #define Utf8BufSize(s) ((s) * 4)
00119 
00120 // The following macros automatically use the correct versions of the character
00121 // class functions:
00122 
00123 #define Utf8to(conv, c) (cCharSetConv::SystemCharacterTable() ? to##conv(c) : tow##conv(c))
00124 #define Utf8is(ccls, c) (cCharSetConv::SystemCharacterTable() ? is##ccls(c) : isw##ccls(c))
00125 
00126 class cCharSetConv {
00127 private:
00128   iconv_t cd;
00129   char *result;
00130   size_t length;
00131   static char *systemCharacterTable;
00132 public:
00133   cCharSetConv(const char *FromCode = NULL, const char *ToCode = NULL);
00137   ~cCharSetConv();
00138   const char *Convert(const char *From, char *To = NULL, size_t ToLength = 0);
00148   static const char *SystemCharacterTable(void) { return systemCharacterTable; }
00149   static void SetSystemCharacterTable(const char *CharacterTable);
00150   };
00151 
00152 class cString {
00153 private:
00154   char *s;
00155 public:
00156   cString(const char *S = NULL, bool TakePointer = false);
00157   cString(const cString &String);
00158   virtual ~cString();
00159   operator const char * () const { return s; } // for use in (const char *) context
00160   const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
00161   cString &operator=(const cString &String);
00162   static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
00163   };
00164 
00165 ssize_t safe_read(int filedes, void *buffer, size_t size);
00166 ssize_t safe_write(int filedes, const void *buffer, size_t size);
00167 void writechar(int filedes, char c);
00168 int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs = 0, int RetryMs = 0);
00172 char *strcpyrealloc(char *dest, const char *src);
00173 char *strn0cpy(char *dest, const char *src, size_t n);
00174 char *strreplace(char *s, char c1, char c2);
00175 char *strreplace(char *s, const char *s1, const char *s2); 
00176 char *skipspace(const char *s);
00177 char *stripspace(char *s);
00178 char *compactspace(char *s);
00179 cString strescape(const char *s, const char *chars);
00180 bool startswith(const char *s, const char *p);
00181 bool endswith(const char *s, const char *p);
00182 bool isempty(const char *s);
00183 int numdigits(int n);
00184 bool isnumber(const char *s);
00185 cString itoa(int n);
00186 cString AddDirectory(const char *DirName, const char *FileName);
00187 int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
00188 bool DirectoryOk(const char *DirName, bool LogErrors = false);
00189 bool MakeDirs(const char *FileName, bool IsDirectory = false);
00190 bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false);
00191 bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false);
00192 int DirSizeMB(const char *DirName); 
00193 char *ReadLink(const char *FileName); 
00194 bool SpinUpDisk(const char *FileName);
00195 void TouchFile(const char *FileName);
00196 time_t LastModifiedTime(const char *FileName);
00197 cString WeekDayName(int WeekDay);
00198 cString WeekDayName(time_t t);
00199 cString WeekDayNameFull(int WeekDay);
00200 cString WeekDayNameFull(time_t t);
00201 cString DayDateTime(time_t t = 0);
00202 cString TimeToString(time_t t);
00203 cString DateString(time_t t);
00204 cString TimeString(time_t t);
00205 uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality = 100);
00214 
00215 class cBase64Encoder {
00216 private:
00217   const uchar *data;
00218   int length;
00219   int maxResult;
00220   int i;
00221   char *result;
00222   static const char *b64;
00223 public:
00224   cBase64Encoder(const uchar *Data, int Length, int MaxResult = 64);
00230   ~cBase64Encoder();
00231   const char *NextLine(void);
00237   };
00238 
00239 class cTimeMs {
00240 private:
00241   uint64_t begin;
00242 public:
00243   cTimeMs(int Ms = 0);
00245   static uint64_t Now(void);
00246   void Set(int Ms = 0);
00247   bool TimedOut(void);
00248   uint64_t Elapsed(void);
00249   };
00250 
00251 class cReadLine {
00252 private:
00253   size_t size;
00254   char *buffer;
00255 public:
00256   cReadLine(void);
00257   ~cReadLine();
00258   char *Read(FILE *f);
00259   };
00260 
00261 class cPoller {
00262 private:
00263   enum { MaxPollFiles = 16 };
00264   pollfd pfd[MaxPollFiles];
00265   int numFileHandles;
00266 public:
00267   cPoller(int FileHandle = -1, bool Out = false);
00268   bool Add(int FileHandle, bool Out);
00269   bool Poll(int TimeoutMs = 0);
00270   };
00271 
00272 class cReadDir {
00273 private:
00274   DIR *directory;
00275   struct dirent *result;
00276   union { // according to "The GNU C Library Reference Manual"
00277     struct dirent d;
00278     char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
00279     } u;
00280 public:
00281   cReadDir(const char *Directory);
00282   ~cReadDir();
00283   bool Ok(void) { return directory != NULL; }
00284   struct dirent *Next(void);
00285   };
00286 
00287 class cFile {
00288 private:
00289   static bool files[];
00290   static int maxFiles;
00291   int f;
00292 public:
00293   cFile(void);
00294   ~cFile();
00295   operator int () { return f; }
00296   bool Open(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
00297   bool Open(int FileDes);
00298   void Close(void);
00299   bool IsOpen(void) { return f >= 0; }
00300   bool Ready(bool Wait = true);
00301   static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
00302   static bool FileReady(int FileDes, int TimeoutMs = 1000);
00303   static bool FileReadyForWriting(int FileDes, int TimeoutMs = 1000);
00304   };
00305 
00306 class cSafeFile {
00307 private:
00308   FILE *f;
00309   char *fileName;
00310   char *tempName;
00311 public:
00312   cSafeFile(const char *FileName);
00313   ~cSafeFile();
00314   operator FILE* () { return f; }
00315   bool Open(void);
00316   bool Close(void);
00317   };
00318 
00321 
00322 class cUnbufferedFile {
00323 private:
00324   int fd;
00325   off_t curpos;
00326   off_t cachedstart;
00327   off_t cachedend;
00328   off_t begin;
00329   off_t lastpos;
00330   off_t ahead;
00331   size_t readahead;
00332   size_t written;
00333   size_t totwritten;
00334   int FadviseDrop(off_t Offset, off_t Len);
00335 public:
00336   cUnbufferedFile(void);
00337   ~cUnbufferedFile();
00338   int Open(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
00339   int Close(void);
00340   void SetReadAhead(size_t ra);
00341   off_t Seek(off_t Offset, int Whence);
00342   ssize_t Read(void *Data, size_t Size);
00343   ssize_t Write(const void *Data, size_t Size);
00344   static cUnbufferedFile *Create(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
00345   };
00346 
00347 class cLockFile {
00348 private:
00349   char *fileName;
00350   int f;
00351 public:
00352   cLockFile(const char *Directory);
00353   ~cLockFile();
00354   bool Lock(int WaitSeconds = 0);
00355   void Unlock(void);
00356   };
00357 
00358 class cListObject {
00359 private:
00360   cListObject *prev, *next;
00361 public:
00362   cListObject(void);
00363   virtual ~cListObject();
00364   virtual int Compare(const cListObject &ListObject) const { return 0; }
00367   void Append(cListObject *Object);
00368   void Insert(cListObject *Object);
00369   void Unlink(void);
00370   int Index(void) const;
00371   cListObject *Prev(void) const { return prev; }
00372   cListObject *Next(void) const { return next; }
00373   };
00374 
00375 class cListBase {
00376 protected:
00377   cListObject *objects, *lastObject;
00378   cListBase(void);
00379   int count;
00380 public:
00381   virtual ~cListBase();
00382   void Add(cListObject *Object, cListObject *After = NULL);
00383   void Ins(cListObject *Object, cListObject *Before = NULL);
00384   void Del(cListObject *Object, bool DeleteObject = true);
00385   virtual void Move(int From, int To);
00386   void Move(cListObject *From, cListObject *To);
00387   virtual void Clear(void);
00388   cListObject *Get(int Index) const;
00389   int Count(void) const { return count; }
00390   void Sort(void);
00391   };
00392 
00393 template<class T> class cList : public cListBase {
00394 public:
00395   T *Get(int Index) const { return (T *)cListBase::Get(Index); }
00396   T *First(void) const { return (T *)objects; }
00397   T *Last(void) const { return (T *)lastObject; }
00398   T *Prev(const T *object) const { return (T *)object->cListObject::Prev(); } // need to call cListObject's members to
00399   T *Next(const T *object) const { return (T *)object->cListObject::Next(); } // avoid ambiguities in case of a "list of lists"
00400   };
00401 
00402 template<class T> class cVector {
00403 private:
00404   mutable int allocated;
00405   mutable int size;
00406   mutable T *data;
00407   cVector(const cVector &Vector) {} // don't copy...
00408   cVector &operator=(const cVector &Vector) { return *this; } // ...or assign this!
00409   void Realloc(int Index) const
00410   {
00411     if (++Index > allocated) {
00412        data = (T *)realloc(data, Index * sizeof(T));
00413        for (int i = allocated; i < Index; i++)
00414            data[i] = T(0);
00415        allocated = Index;
00416        }
00417   }
00418 public:
00419   cVector(int Allocated = 10)
00420   {
00421     allocated = 0;
00422     size = 0;
00423     data = NULL;
00424     Realloc(Allocated);
00425   }
00426   virtual ~cVector() { free(data); }
00427   T& At(int Index) const
00428   {
00429     Realloc(Index);
00430     if (Index >= size)
00431        size = Index + 1;
00432     return data[Index];
00433   }
00434   const T& operator[](int Index) const
00435   {
00436     return At(Index);
00437   }
00438   T& operator[](int Index)
00439   {
00440     return At(Index);
00441   }
00442   int Size(void) const { return size; }
00443   virtual void Insert(T Data, int Before = 0)
00444   {
00445     if (Before < size) {
00446        Realloc(size);
00447        memmove(&data[Before + 1], &data[Before], (size - Before) * sizeof(T));
00448        size++;
00449        data[Before] = Data;
00450        }
00451     else
00452        Append(Data);
00453   }
00454   virtual void Append(T Data)
00455   {
00456     if (size >= allocated)
00457        Realloc(allocated * 4 / 2); // increase size by 50%
00458     data[size++] = Data;
00459   }
00460   virtual void Clear(void) {}
00461   void Sort(__compar_fn_t Compare)
00462   {
00463     qsort(data, size, sizeof(T), Compare);
00464   }
00465   };
00466 
00467 inline int CompareStrings(const void *a, const void *b)
00468 {
00469   return strcmp(*(const char **)a, *(const char **)b);
00470 }
00471 
00472 class cStringList : public cVector<char *> {
00473 public:
00474   cStringList(int Allocated = 10): cVector<char *>(Allocated) {}
00475   virtual ~cStringList();
00476   int Find(const char *s) const;
00477   void Sort(void) { cVector<char *>::Sort(CompareStrings); }
00478   virtual void Clear(void);
00479   };
00480 
00481 class cFileNameList : public cStringList {
00482 public:
00483   cFileNameList(const char *Directory = NULL);
00484   bool Load(const char *Directory);
00485   };
00486 
00487 class cHashObject : public cListObject {
00488   friend class cHashBase;
00489 private:
00490   unsigned int id;
00491   cListObject *object;
00492 public:
00493   cHashObject(cListObject *Object, unsigned int Id) { object = Object; id = Id; }
00494   cListObject *Object(void) { return object; }
00495   };
00496 
00497 class cHashBase {
00498 private:
00499   cList<cHashObject> **hashTable;
00500   int size;
00501   unsigned int hashfn(unsigned int Id) const { return Id % size; }
00502 protected:
00503   cHashBase(int Size);
00504 public:
00505   virtual ~cHashBase();
00506   void Add(cListObject *Object, unsigned int Id);
00507   void Del(cListObject *Object, unsigned int Id);
00508   void Clear(void);
00509   cListObject *Get(unsigned int Id) const;
00510   cList<cHashObject> *GetList(unsigned int Id) const;
00511   };
00512 
00513 #define HASHSIZE 512
00514 
00515 template<class T> class cHash : public cHashBase {
00516 public:
00517   cHash(int Size = HASHSIZE) : cHashBase(Size) {}
00518   T *Get(unsigned int Id) const { return (T *)cHashBase::Get(Id); }
00519 };
00520 
00521 #endif //__TOOLS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines