vdr  2.6.1
tools.h
Go to the documentation of this file.
1 /*
2  * tools.h: Various tools
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: tools.h 5.6 2021/05/26 13:37:53 kls Exp $
8  */
9 
10 #ifndef __TOOLS_H
11 #define __TOOLS_H
12 
13 #include <dirent.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <float.h>
17 #include <iconv.h>
18 #include <math.h>
19 #include <poll.h>
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <syslog.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include "thread.h"
30 
31 typedef unsigned char uchar;
32 
33 extern int SysLogLevel;
34 
35 #define esyslog(a...) void( (SysLogLevel > 0) ? syslog_with_tid(LOG_ERR, a) : void() )
36 #define isyslog(a...) void( (SysLogLevel > 1) ? syslog_with_tid(LOG_INFO, a) : void() )
37 #define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(LOG_DEBUG, a) : void() )
38 
39 #define LOG_ERROR esyslog("ERROR (%s,%d): %m", __FILE__, __LINE__)
40 #define LOG_ERROR_STR(s) esyslog("ERROR (%s,%d): %s: %m", __FILE__, __LINE__, s)
41 
42 #define SECSINDAY 86400
43 
44 #define KILOBYTE(n) ((n) * 1024)
45 #define MEGABYTE(n) ((n) * 1024LL * 1024LL)
46 
47 #define MALLOC(type, size) (type *)malloc(sizeof(type) * (size))
48 
49 template<class T> inline void DELETENULL(T *&p) { T *q = p; p = NULL; delete q; }
50 
51 #define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
52 #define FATALERRNO (errno && errno != EAGAIN && errno != EINTR)
53 
54 #if __cplusplus >= 201103L
55 // any gcc >= 4.8.1; we have swap, min, max
56 #include <algorithm> // std::min, std::max, (c++98: also swap)
57 #include <utility> // std::swap (since c++11)
58 using std::min;
59 using std::max;
60 using std::swap;
61 #else
62 // no c++11 and old compiler, let's include our own templates
63 template<class T> inline T min(T a, T b) { return a <= b ? a : b; }
64 template<class T> inline T max(T a, T b) { return a >= b ? a : b; }
65 template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
66 #endif
67 
68 template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }
69 
70 template<class T> inline T constrain(T v, T l, T h) { return v < l ? l : v > h ? h : v; }
71 
72 void syslog_with_tid(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
73 
74 #define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
75 int BCD2INT(int x);
76 
77 #define IsBitSet(v, b) ((v) & (1 << (b))) // checks if the bit at index b is set in v, where the least significant bit has index 0
78 
79 // Unfortunately there are no platform independent macros for unaligned
80 // access, so we do it this way:
81 
82 template<class T> inline T get_unaligned(T *p)
83 {
84  struct s { T v; } __attribute__((packed));
85  return ((s *)p)->v;
86 }
87 
88 template<class T> inline void put_unaligned(unsigned int v, T* p)
89 {
90  struct s { T v; } __attribute__((packed));
91  ((s *)p)->v = v;
92 }
93 
94 // Comparing doubles for equality is unsafe, but unfortunately we can't
95 // overwrite operator==(double, double), so this will have to do:
96 
97 inline bool DoubleEqual(double a, double b)
98 {
99  return fabs(a - b) <= DBL_EPSILON;
100 }
101 
102 // When handling strings that might contain UTF-8 characters, it may be necessary
103 // to process a "symbol" that consists of several actual character bytes. The
104 // following functions allow transparently accessing a "char *" string without
105 // having to worry about what character set is actually used.
106 
107 int Utf8CharLen(const char *s);
110 uint Utf8CharGet(const char *s, int Length = 0);
114 int Utf8CharSet(uint c, char *s = NULL);
118 int Utf8SymChars(const char *s, int Symbols);
121 int Utf8StrLen(const char *s);
124 char *Utf8Strn0Cpy(char *Dest, const char *Src, int n);
129 int Utf8ToArray(const char *s, uint *a, int Size);
133 int Utf8FromArray(const uint *a, char *s, int Size, int Max = -1);
139 
140 // When allocating buffer space, make sure we reserve enough space to hold
141 // a string in UTF-8 representation:
142 
143 #define Utf8BufSize(s) ((s) * 4)
144 
145 // The following macros automatically use the correct versions of the character
146 // class functions:
147 
148 #define Utf8to(conv, c) (cCharSetConv::SystemCharacterTable() ? to##conv(c) : tow##conv(c))
149 #define Utf8is(ccls, c) (cCharSetConv::SystemCharacterTable() ? is##ccls(c) : isw##ccls(c))
150 
152 private:
153  iconv_t cd;
154  char *result;
155  size_t length;
156  static char *systemCharacterTable;
157 public:
158  cCharSetConv(const char *FromCode = NULL, const char *ToCode = NULL);
163  ~cCharSetConv();
164  const char *Convert(const char *From, char *To = NULL, size_t ToLength = 0);
174  static const char *SystemCharacterTable(void) { return systemCharacterTable; }
175  static void SetSystemCharacterTable(const char *CharacterTable);
176  };
177 
178 class cString {
179 private:
180  char *s;
181 public:
182  cString(const char *S = NULL, bool TakePointer = false);
183  cString(const char *S, const char *To);
184  cString(const cString &String);
185  virtual ~cString();
186  operator const void * () const { return s; } // to catch cases where operator*() should be used
187  operator const char * () const { return s; } // for use in (const char *) context
188  const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
189  cString &operator=(const cString &String);
190  cString &operator=(const char *String);
191  cString &Append(const char *String);
192  cString &Truncate(int Index);
193  cString &CompactChars(char c);
194  static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
195  static cString vsprintf(const char *fmt, va_list &ap);
196  };
197 
199 private:
200  char *p;
201  char c;
202 public:
204  p = NULL;
205  c = 0;
206  }
207  cNullTerminate(char *s) {
208  Set(s);
209  }
211  if (p)
212  *p = c;
213  }
214  void Set(char *s) {
215  if (s) {
216  p = s;
217  c = *s;
218  *s = 0;
219  }
220  else
221  p = NULL;
222  }
223  };
224 
225 ssize_t safe_read(int filedes, void *buffer, size_t size);
226 ssize_t safe_write(int filedes, const void *buffer, size_t size);
227 void writechar(int filedes, char c);
228 int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs = 0, int RetryMs = 0);
232 char *strcpyrealloc(char *dest, const char *src);
233 char *strn0cpy(char *dest, const char *src, size_t n);
234 char *strreplace(char *s, char c1, char c2);
235 char *strreplace(char *s, const char *s1, const char *s2);
236 const char *strchrn(const char *s, char c, size_t n);
237 int strcountchr(const char *s, char c);
238 cString strgetbefore(const char *s, char c, int n = 1); // returns the part of 's' before (and excluding) the n'th occurrence of 'c' from the right, or an empty string if there is no such 'c'.
239 const char *strgetlast(const char *s, char c); // returns the part of 's' after the last occurrence of 'c', or 's' if there is no 'c'.
240 inline char *strgetlast(char *s, char c) { return const_cast<char *>(strgetlast(static_cast<const char *>(s), c)); } // returns the part of 's' after the last occurrence of 'c', or 's' if there is no 'c'.
241 inline char *skipspace(const char *s)
242 {
243  if ((uchar)*s > ' ') // most strings don't have any leading space, so handle this case as fast as possible
244  return (char *)s;
245  while (*s && (uchar)*s <= ' ') // avoiding isspace() here, because it is much slower
246  s++;
247  return (char *)s;
248 }
249 char *stripspace(char *s);
250 char *compactspace(char *s);
251 char *compactchars(char *s, char c);
252 cString strescape(const char *s, const char *chars);
253 cString strgetval(const char *s, const char *name, char d = '=');
261 char *strshift(char *s, int n);
267 bool startswith(const char *s, const char *p);
268 bool endswith(const char *s, const char *p);
269 bool isempty(const char *s);
270 int numdigits(int n);
271 bool isnumber(const char *s);
272 int64_t StrToNum(const char *s);
278 bool StrInArray(const char *a[], const char *s);
281 double atod(const char *s);
285 cString dtoa(double d, const char *Format = "%f");
289 cString itoa(int n);
290 inline uint16_t Peek13(const uchar *p)
291 {
292  uint16_t v = uint16_t(*p++ & 0x1F) << 8;
293  return v + (*p & 0xFF);
294 }
295 inline void Poke13(uchar *p, uint16_t v)
296 {
297  v |= uint16_t(*p & ~0x1F) << 8;
298  *p++ = v >> 8;
299  *p = v & 0xFF;
300 }
301 cString AddDirectory(const char *DirName, const char *FileName);
302 bool EntriesOnSameFileSystem(const char *File1, const char *File2);
306 int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
307 bool DirectoryOk(const char *DirName, bool LogErrors = false);
308 bool MakeDirs(const char *FileName, bool IsDirectory = false);
309 bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false);
310 bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false, const char *IgnoreFiles[] = NULL);
316 int DirSizeMB(const char *DirName);
317 char *ReadLink(const char *FileName);
318 bool SpinUpDisk(const char *FileName);
319 void TouchFile(const char *FileName);
320 time_t LastModifiedTime(const char *FileName);
321 off_t FileSize(const char *FileName);
322 cString WeekDayName(int WeekDay);
325 cString WeekDayName(time_t t);
327 cString WeekDayNameFull(int WeekDay);
330 cString WeekDayNameFull(time_t t);
332 cString DayDateTime(time_t t = 0);
335 cString TimeToString(time_t t);
337 cString DateString(time_t t);
339 cString ShortDateString(time_t t);
341 cString TimeString(time_t t);
343 uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality = 100);
352 const char *GetHostName(void);
354 
356 private:
357  const uchar *data;
358  int length;
360  int i;
361  char *result;
362  static const char *b64;
363 public:
364  cBase64Encoder(const uchar *Data, int Length, int MaxResult = 64);
370  ~cBase64Encoder();
371  const char *NextLine(void);
377  };
378 
379 class cBitStream {
380 private:
381  const uint8_t *data;
382  int length; // in bits
383  int index; // in bits
384 public:
385  cBitStream(const uint8_t *Data, int Length) : data(Data), length(Length), index(0) {}
387  int GetBit(void);
388  uint32_t GetBits(int n);
389  void ByteAlign(void);
390  void WordAlign(void);
391  bool SetLength(int Length);
392  void SkipBits(int n) { index += n; }
393  void SkipBit(void) { SkipBits(1); }
394  bool IsEOF(void) const { return index >= length; }
395  void Reset(void) { index = 0; }
396  int Length(void) const { return length; }
397  int Index(void) const { return (IsEOF() ? length : index); }
398  const uint8_t *GetData(void) const { return (IsEOF() ? NULL : data + (index / 8)); }
399  };
400 
401 class cTimeMs {
402 private:
403  uint64_t begin;
404 public:
405  cTimeMs(int Ms = 0);
409  static uint64_t Now(void);
410  void Set(int Ms = 0);
417  bool TimedOut(void) const;
418  uint64_t Elapsed(void) const;
419  };
420 
421 class cReadLine {
422 private:
423  size_t size;
424  char *buffer;
425 public:
426  cReadLine(void);
427  ~cReadLine();
428  char *Read(FILE *f);
429  };
430 
431 class cPoller {
432 private:
433  enum { MaxPollFiles = 64 };
434  pollfd pfd[MaxPollFiles];
436 public:
437  cPoller(int FileHandle = -1, bool Out = false);
438  bool Add(int FileHandle, bool Out);
439  void Del(int FileHandle, bool Out);
440  bool Poll(int TimeoutMs = 0);
441  };
442 
443 class cReadDir {
444 private:
445  DIR *directory;
446  struct dirent *result;
447 #if !__GLIBC_PREREQ(2, 24) // readdir_r() is deprecated as of GLIBC 2.24
448  union { // according to "The GNU C Library Reference Manual"
449  struct dirent d;
450  char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
451  } u;
452 #endif
453 public:
454  cReadDir(const char *Directory);
455  ~cReadDir();
456  bool Ok(void) { return directory != NULL; }
457  struct dirent *Next(void);
458  };
459 
460 #ifndef DEPRECATED_CFILE
461 #define DEPRECATED_CFILE 0
462 #endif
463 class cFile {
464 private:
465 #if DEPRECATED_CFILE
466  static bool files[];
467  static int maxFiles;
468 #endif
469  int f;
470 public:
471  cFile(void);
472  ~cFile();
473  operator int () { return f; }
474  bool Open(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
475  bool Open(int FileDes);
476  void Close(void);
477  bool IsOpen(void) { return f >= 0; }
478  bool Ready(bool Wait = true);
479 #if DEPRECATED_CFILE
480  static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
481 #endif
482  static bool FileReady(int FileDes, int TimeoutMs = 1000);
483 #if DEPRECATED_CFILE
484  static bool FileReadyForWriting(int FileDes, int TimeoutMs = 1000);
485 #endif
486  };
487 
488 class cSafeFile {
489 private:
490  FILE *f;
491  char *fileName;
492  char *tempName;
493 public:
494  cSafeFile(const char *FileName);
495  ~cSafeFile();
496  operator FILE* () { return f; }
497  bool Open(void);
498  bool Close(void);
499  };
500 
503 
505 private:
506  int fd;
507  off_t curpos;
508  off_t cachedstart;
509  off_t cachedend;
510  off_t begin;
511  off_t lastpos;
512  off_t ahead;
513  size_t readahead;
514  size_t written;
515  size_t totwritten;
516  int FadviseDrop(off_t Offset, off_t Len);
517 public:
518  cUnbufferedFile(void);
519  ~cUnbufferedFile();
520  int Open(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
521  int Close(void);
522  void SetReadAhead(size_t ra);
523  off_t Seek(off_t Offset, int Whence);
524  ssize_t Read(void *Data, size_t Size);
525  ssize_t Write(const void *Data, size_t Size);
526  static cUnbufferedFile *Create(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE);
527  };
528 
529 class cLockFile {
530 private:
531  char *fileName;
532  int f;
533 public:
534  cLockFile(const char *Directory);
535  ~cLockFile();
536  bool Lock(int WaitSeconds = 0);
537  void Unlock(void);
538  };
539 
540 class cListObject {
541  friend class cListGarbageCollector;
542 private:
543  cListObject *prev, *next;
544  cListObject(const cListObject &ListObject) { abort(); } // no copy constructor!
545  cListObject& operator= (const cListObject &ListObject) { abort(); return *this; } // no assignment operator!
546 public:
547  cListObject(void);
548  virtual ~cListObject();
549  virtual int Compare(const cListObject &ListObject) const { return 0; }
552  void Append(cListObject *Object);
553  void Insert(cListObject *Object);
554  void Unlink(void);
555  int Index(void) const;
556  cListObject *Prev(void) const { return prev; }
557  cListObject *Next(void) const { return next; }
558  };
559 
561 private:
564  time_t lastPut;
565 public:
566  cListGarbageCollector(void);
568  void Put(cListObject *Object);
569  void Purge(bool Force = false);
570  };
571 
573 
574 class cListBase {
575 protected:
577  int count;
579  const char *needsLocking;
581  cListBase(const char *NeedsLocking = NULL);
582 public:
583  virtual ~cListBase();
584  bool Lock(cStateKey &StateKey, bool Write = false, int TimeoutMs = 0) const;
609  void SetSyncStateKey(cStateKey &StateKey) { stateLock.SetSyncStateKey(StateKey); }
614  void SetUseGarbageCollector(void) { useGarbageCollector = true; }
615  void SetExplicitModify(void);
620  void SetModified(void);
622  void Add(cListObject *Object, cListObject *After = NULL);
623  void Ins(cListObject *Object, cListObject *Before = NULL);
624  void Del(cListObject *Object, bool DeleteObject = true);
625  virtual void Move(int From, int To);
626  void Move(cListObject *From, cListObject *To);
627  virtual void Clear(void);
628  bool Contains(const cListObject *Object) const;
635  const cListObject *Get(int Index) const;
636  cListObject *Get(int Index) { return const_cast<cListObject *>(static_cast<const cListBase *>(this)->Get(Index)); }
637  int Count(void) const { return count; }
638  void Sort(void);
639  };
640 
641 template<class T> class cList : public cListBase {
642 public:
643  cList(const char *NeedsLocking = NULL): cListBase(NeedsLocking) {}
650  const T *Get(int Index) const { return (T *)cListBase::Get(Index); }
653  const T *First(void) const { return (T *)objects; }
655  const T *Last(void) const { return (T *)lastObject; }
657  const T *Prev(const T *Object) const { return (T *)Object->cListObject::Prev(); } // need to call cListObject's members to
660  const T *Next(const T *Object) const { return (T *)Object->cListObject::Next(); } // avoid ambiguities in case of a "list of lists"
663  T *Get(int Index) { return const_cast<T *>(static_cast<const cList<T> *>(this)->Get(Index)); }
665  T *First(void) { return const_cast<T *>(static_cast<const cList<T> *>(this)->First()); }
667  T *Last(void) { return const_cast<T *>(static_cast<const cList<T> *>(this)->Last()); }
669  T *Prev(const T *Object) { return const_cast<T *>(static_cast<const cList<T> *>(this)->Prev(Object)); }
671  T *Next(const T *Object) { return const_cast<T *>(static_cast<const cList<T> *>(this)->Next(Object)); }
673  };
674 
675 // The DEF_LIST_LOCK macro defines a convenience class that can be used to obtain
676 // a lock on a cList and make sure the lock is released when the current scope
677 // is left:
678 
679 #define DEF_LIST_LOCK2(Class, Name) \
680 class c##Name##_Lock { \
681 private: \
682  cStateKey stateKey; \
683  const c##Class *list; \
684 public: \
685  c##Name##_Lock(bool Write = false) \
686  { \
687  if (Write) \
688  list = c##Class::Get##Name##Write(stateKey); \
689  else \
690  list = c##Class::Get##Name##Read(stateKey); \
691  } \
692  ~c##Name##_Lock() { if (list) stateKey.Remove(); } \
693  const c##Class *Name(void) const { return list; } \
694  c##Class *Name(void) { return const_cast<c##Class *>(list); } \
695  }
696 #define DEF_LIST_LOCK(Class) DEF_LIST_LOCK2(Class, Class)
697 
698 // The USE_LIST_LOCK macro sets up a local variable of a class defined by
699 // a suitable DEF_LIST_LOCK, and also a pointer to the provided list:
700 
701 #define USE_LIST_LOCK_READ2(Class, Name) \
702 c##Name##_Lock Name##_Lock(false); \
703 const c##Class *Name __attribute__((unused)) = Name##_Lock.Name();
704 #define USE_LIST_LOCK_READ(Class) USE_LIST_LOCK_READ2(Class, Class)
705 
706 #define USE_LIST_LOCK_WRITE2(Class, Name) \
707 c##Name##_Lock Name##_Lock(true); \
708 c##Class *Name __attribute__((unused)) = Name##_Lock.Name();
709 #define USE_LIST_LOCK_WRITE(Class) USE_LIST_LOCK_WRITE2(Class, Class)
710 
711 template<class T> class cVector {
713 private:
714  mutable int allocated;
715  mutable int size;
716  mutable T *data;
717  cVector(const cVector &Vector) {} // don't copy...
718  cVector &operator=(const cVector &Vector) { return *this; } // ...or assign this!
719  void Realloc(int Index) const
720  {
721  if (++Index > allocated) {
722  data = (T *)realloc(data, Index * sizeof(T));
723  if (!data) {
724  esyslog("ERROR: out of memory - abort!");
725  abort();
726  }
727  for (int i = allocated; i < Index; i++)
728  data[i] = T(0);
729  allocated = Index;
730  }
731  }
732 public:
733  cVector(int Allocated = 10)
734  {
735  allocated = 0;
736  size = 0;
737  data = NULL;
738  Realloc(Allocated);
739  }
740  virtual ~cVector() { free(data); }
741  T& At(int Index) const
742  {
743  Realloc(Index);
744  if (Index >= size)
745  size = Index + 1;
746  return data[Index];
747  }
748  const T& operator[](int Index) const
749  {
750  return At(Index);
751  }
752  T& operator[](int Index)
753  {
754  return At(Index);
755  }
756  int IndexOf(const T &Data) // returns the index of Data, or -1 if not found
757  {
758  for (int i = 0; i < size; i++) {
759  if (data[i] == Data)
760  return i;
761  }
762  return -1;
763  }
764  int Size(void) const { return size; }
765  virtual void Insert(T Data, int Before = 0)
766  {
767  if (Before < size) {
768  Realloc(size);
769  memmove(&data[Before + 1], &data[Before], (size - Before) * sizeof(T));
770  size++;
771  data[Before] = Data;
772  }
773  else
774  Append(Data);
775  }
776  bool InsertUnique(T Data, int Before = 0)
777  {
778  if (IndexOf(Data) < 0) {
779  Insert(Data, Before);
780  return true;
781  }
782  return false;
783  }
784  virtual void Append(T Data)
785  {
786  if (size >= allocated)
787  Realloc(allocated * 3 / 2); // increase size by 50%
788  data[size++] = Data;
789  }
790  bool AppendUnique(T Data)
791  {
792  if (IndexOf(Data) < 0) {
793  Append(Data);
794  return true;
795  }
796  return false;
797  }
798  virtual void Remove(int Index)
799  {
800  if (Index < 0)
801  return; // prevents out-of-bounds access
802  if (Index < size - 1)
803  memmove(&data[Index], &data[Index + 1], (size - Index) * sizeof(T));
804  size--;
805  }
806  bool RemoveElement(const T &Data)
807  {
808  int i = IndexOf(Data);
809  if (i >= 0) {
810  Remove(i);
811  return true;
812  }
813  return false;
814  }
815  virtual void Clear(void)
816  {
817  for (int i = 0; i < size; i++)
818  data[i] = T(0);
819  size = 0;
820  }
821  void Sort(__compar_fn_t Compare)
822  {
823  qsort(data, size, sizeof(T), Compare);
824  }
825  };
826 
827 inline int CompareInts(const void *a, const void *b)
828 {
829  return *(const int *)a - *(const int *)b;
830 }
831 
832 inline int CompareStrings(const void *a, const void *b)
833 {
834  return strcmp(*(const char **)a, *(const char **)b);
835 }
836 
837 inline int CompareStringsIgnoreCase(const void *a, const void *b)
838 {
839  return strcasecmp(*(const char **)a, *(const char **)b);
840 }
841 
842 inline int CompareStringsNumerically(const void *a, const void *b)
843 {
844  int d = atoi(*(const char **)a) - atoi(*(const char **)b);
845  return d ? d : CompareStrings(a, b);
846 }
847 
848 class cStringList : public cVector<char *> {
849 public:
850  cStringList(int Allocated = 10): cVector<char *>(Allocated) {}
851  virtual ~cStringList();
852  int Find(const char *s) const;
853  void Sort(bool IgnoreCase = false)
854  {
855  if (IgnoreCase)
857  else
859  }
860  void SortNumerically(void)
861  {
863  }
864  virtual void Clear(void);
865  };
866 
867 class cFileNameList : public cStringList {
868 public:
869  cFileNameList(const char *Directory = NULL, bool DirsOnly = false);
870  bool Load(const char *Directory, bool DirsOnly = false);
871  };
872 
874 private:
877  int size; // the total size of the buffer (bytes in memory)
878  int used; // the number of used bytes, starting at the beginning of the buffer
879  bool Realloc(int NewSize);
880  bool Assert(int NewSize) { return size < NewSize ? Realloc(NewSize) : true; } // inline for performance!
881 public:
882  cDynamicBuffer(int InitialSize = 1024);
883  ~cDynamicBuffer();
884  void Append(const uchar *Data, int Length);
885  void Append(uchar Data) { if (Assert(used + 1)) buffer[used++] = Data; }
886  void Set(int Index, uchar Data) { if (Assert(Index + 1)) buffer[Index] = Data; }
887  uchar Get(int Index) { return Index < used ? buffer[Index] : 0; }
888  void Clear(void) { used = 0; }
889  uchar *Data(void) { return buffer; }
890  int Length(void) { return used; }
891  };
892 
893 class cHashObject : public cListObject {
894  friend class cHashBase;
895 private:
896  unsigned int id;
898 public:
899  cHashObject(cListObject *Object, unsigned int Id) { object = Object; id = Id; }
900  cListObject *Object(void) { return object; }
901  };
902 
903 class cHashBase {
904 private:
906  int size;
908  unsigned int hashfn(unsigned int Id) const { return Id % size; }
909 protected:
910  cHashBase(int Size, bool OwnObjects);
915 public:
916  virtual ~cHashBase();
917  void Add(cListObject *Object, unsigned int Id);
918  void Del(cListObject *Object, unsigned int Id);
919  void Clear(void);
920  cListObject *Get(unsigned int Id) const;
921  cList<cHashObject> *GetList(unsigned int Id) const;
922  };
923 
924 #define HASHSIZE 512
925 
926 template<class T> class cHash : public cHashBase {
927 public:
928  cHash(int Size = HASHSIZE, bool OwnObjects = false) : cHashBase(Size, OwnObjects) {}
929  T *Get(unsigned int Id) const { return (T *)cHashBase::Get(Id); }
930 };
931 
932 #endif //__TOOLS_H
static uint8_t * SetLength(uint8_t *Data, int Length)
Definition: ci.c:57
char * result
Definition: tools.h:361
int length
Definition: tools.h:358
const uchar * data
Definition: tools.h:357
int maxResult
Definition: tools.h:359
static const char * b64
Definition: tools.h:362
void SkipBit(void)
Definition: tools.h:393
const uint8_t * GetData(void) const
Definition: tools.h:398
int Index(void) const
Definition: tools.h:397
cBitStream(const uint8_t *Data, int Length)
Definition: tools.h:385
int length
Definition: tools.h:382
const uint8_t * data
Definition: tools.h:381
int index
Definition: tools.h:383
int Length(void) const
Definition: tools.h:396
bool IsEOF(void) const
Definition: tools.h:394
void SkipBits(int n)
Definition: tools.h:392
~cBitStream()
Definition: tools.h:386
void Reset(void)
Definition: tools.h:395
cCharSetConv(const char *FromCode=NULL, const char *ToCode=NULL)
Sets up a character set converter to convert from FromCode to ToCode.
Definition: tools.c:968
static void SetSystemCharacterTable(const char *CharacterTable)
Definition: tools.c:986
char * result
Definition: tools.h:154
size_t length
Definition: tools.h:155
iconv_t cd
Definition: tools.h:153
static char * systemCharacterTable
Definition: tools.h:156
~cCharSetConv()
Definition: tools.c:979
static const char * SystemCharacterTable(void)
Definition: tools.h:174
const char * Convert(const char *From, char *To=NULL, size_t ToLength=0)
Converts the given Text from FromCode to ToCode (as set in the constructor).
Definition: tools.c:1009
void Set(int Index, uchar Data)
Definition: tools.h:886
uchar Get(int Index)
Definition: tools.h:887
int Length(void)
Definition: tools.h:890
uchar * Data(void)
Definition: tools.h:889
uchar * buffer
Definition: tools.h:875
void Clear(void)
Definition: tools.h:888
bool Assert(int NewSize)
Definition: tools.h:880
void Append(uchar Data)
Definition: tools.h:885
int initialSize
Definition: tools.h:876
Definition: tools.h:463
bool IsOpen(void)
Definition: tools.h:477
int f
Definition: tools.h:469
cListObject * Get(unsigned int Id) const
Definition: tools.c:2419
cList< cHashObject > ** hashTable
Definition: tools.h:905
int size
Definition: tools.h:906
bool ownObjects
Definition: tools.h:907
unsigned int hashfn(unsigned int Id) const
Definition: tools.h:908
cListObject * Object(void)
Definition: tools.h:900
unsigned int id
Definition: tools.h:896
cListObject * object
Definition: tools.h:897
cHashObject(cListObject *Object, unsigned int Id)
Definition: tools.h:899
Definition: tools.h:926
T * Get(unsigned int Id) const
Definition: tools.h:929
cHash(int Size=HASHSIZE, bool OwnObjects=false)
Definition: tools.h:928
cListObject * Get(int Index)
Definition: tools.h:636
cListObject * lastObject
Definition: tools.h:576
cStateLock stateLock
Definition: tools.h:578
bool useGarbageCollector
Definition: tools.h:580
void SetSyncStateKey(cStateKey &StateKey)
When making changes to this list (while holding a write lock) that shall not affect some other code t...
Definition: tools.h:609
void SetUseGarbageCollector(void)
Definition: tools.h:614
int count
Definition: tools.h:577
const char * needsLocking
Definition: tools.h:579
const cListObject * Get(int Index) const
Definition: tools.c:2291
int Count(void) const
Definition: tools.h:637
cListObject * objects
Definition: tools.h:563
cListObject(const cListObject &ListObject)
Definition: tools.h:544
cListObject * next
Definition: tools.h:543
cListObject * Prev(void) const
Definition: tools.h:556
virtual int Compare(const cListObject &ListObject) const
Must return 0 if this object is equal to ListObject, a positive value if it is "greater",...
Definition: tools.h:549
cListObject * Next(void) const
Definition: tools.h:557
Definition: tools.h:641
T * Prev(const T *Object)
Non-const version of Prev().
Definition: tools.h:669
T * Next(const T *Object)
Non-const version of Next().
Definition: tools.h:671
T * Last(void)
Non-const version of Last().
Definition: tools.h:667
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
Definition: tools.h:660
const T * Last(void) const
Returns the last element in this list, or NULL if the list is empty.
Definition: tools.h:655
T * First(void)
Non-const version of First().
Definition: tools.h:665
T * Get(int Index)
< Returns the element immediately following Object in this list, or NULL if Object is the last elemen...
Definition: tools.h:663
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition: tools.h:653
cList(const char *NeedsLocking=NULL)
Sets up a new cList of the given type T.
Definition: tools.h:643
const T * Get(int Index) const
Returns the list element at the given Index, or NULL if no such element exists.
Definition: tools.h:650
const T * Prev(const T *Object) const
Definition: tools.h:657
char * fileName
Definition: tools.h:531
int f
Definition: tools.h:532
Definition: thread.h:67
char * p
Definition: tools.h:200
void Set(char *s)
Definition: tools.h:214
cNullTerminate(char *s)
Definition: tools.h:207
cNullTerminate(void)
Definition: tools.h:203
~cNullTerminate()
Definition: tools.h:210
Definition: tools.h:431
int numFileHandles
Definition: tools.h:435
struct dirent * result
Definition: tools.h:446
DIR * directory
Definition: tools.h:445
bool Ok(void)
Definition: tools.h:456
char * buffer
Definition: tools.h:424
size_t size
Definition: tools.h:423
char * tempName
Definition: tools.h:492
char * fileName
Definition: tools.h:491
FILE * f
Definition: tools.h:490
void SetSyncStateKey(cStateKey &StateKey)
Sets the given StateKey to be synchronized to the state of this lock.
Definition: thread.c:789
cStringList(int Allocated=10)
Definition: tools.h:850
void Sort(bool IgnoreCase=false)
Definition: tools.h:853
void SortNumerically(void)
Definition: tools.h:860
Definition: tools.h:178
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
Definition: tools.c:1143
static cString static cString vsprintf(const char *fmt, va_list &ap)
Definition: tools.c:1162
virtual ~cString()
Definition: tools.c:1095
cString(const char *S=NULL, bool TakePointer=false)
Definition: tools.c:1071
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition: tools.c:1149
cString & operator=(const cString &String)
Definition: tools.c:1100
const char * operator*() const
Definition: tools.h:188
char * s
Definition: tools.h:180
cString & Append(const char *String)
Definition: tools.c:1118
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
Definition: tools.c:1133
Definition: tools.h:401
uint64_t begin
Definition: tools.h:403
cUnbufferedFile is used for large files that are mainly written or read in a streaming manner,...
Definition: tools.h:504
off_t ahead
Definition: tools.h:512
off_t begin
Definition: tools.h:510
size_t readahead
Definition: tools.h:513
size_t totwritten
Definition: tools.h:515
off_t lastpos
Definition: tools.h:511
off_t cachedstart
Definition: tools.h:508
off_t cachedend
Definition: tools.h:509
size_t written
Definition: tools.h:514
off_t curpos
Definition: tools.h:507
Definition: tools.h:711
int Size(void) const
Definition: tools.h:764
cVector(int Allocated=10)
Definition: tools.h:733
bool AppendUnique(T Data)
Definition: tools.h:790
void Realloc(int Index) const
Definition: tools.h:719
void Sort(__compar_fn_t Compare)
Definition: tools.h:821
int IndexOf(const T &Data)
Definition: tools.h:756
int allocated
< cVector may only be used for simple types, like int or pointers - not for class objects that alloca...
Definition: tools.h:714
virtual void Clear(void)
Definition: tools.h:815
cVector & operator=(const cVector &Vector)
Definition: tools.h:718
virtual ~cVector()
Definition: tools.h:740
virtual void Insert(T Data, int Before=0)
Definition: tools.h:765
T * data
Definition: tools.h:716
virtual void Append(T Data)
Definition: tools.h:784
bool InsertUnique(T Data, int Before=0)
Definition: tools.h:776
T & operator[](int Index)
Definition: tools.h:752
int size
Definition: tools.h:715
const T & operator[](int Index) const
Definition: tools.h:748
virtual void Remove(int Index)
Definition: tools.h:798
T & At(int Index) const
Definition: tools.h:741
bool RemoveElement(const T &Data)
Definition: tools.h:806
cVector(const cVector &Vector)
Definition: tools.h:717
struct __attribute__((packed))
Definition: recording.c:2534
cString TimeString(time_t t)
Converts the given time to a string of the form "hh:mm".
Definition: tools.c:1255
const char * strgetlast(const char *s, char c)
Definition: tools.c:213
void TouchFile(const char *FileName)
Definition: tools.c:717
cString WeekDayNameFull(int WeekDay)
Converts the given WeekDay (0=Sunday, 1=Monday, ...) to a full day name.
Definition: tools.c:1193
char * strcpyrealloc(char *dest, const char *src)
Definition: tools.c:114
T get_unaligned(T *p)
Definition: tools.h:82
T constrain(T v, T l, T h)
Definition: tools.h:70
char * skipspace(const char *s)
Definition: tools.h:241
bool isempty(const char *s)
Definition: tools.c:349
int Utf8ToArray(const char *s, uint *a, int Size)
Converts the given character bytes (including the terminating 0) into an array of UTF-8 symbols of th...
Definition: tools.c:918
#define HASHSIZE
Definition: tools.h:924
cString strescape(const char *s, const char *chars)
Definition: tools.c:272
int strcountchr(const char *s, char c)
returns the number of occurrences of 'c' in 's'.
Definition: tools.c:191
cString TimeToString(time_t t)
Converts the given time to a string of the form "www mmm dd hh:mm:ss yyyy".
Definition: tools.c:1225
char * Utf8Strn0Cpy(char *Dest, const char *Src, int n)
Copies at most n character bytes from Src to Dest, making sure that the resulting copy ends with a co...
Definition: tools.c:899
bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis=false, const char *IgnoreFiles[]=NULL)
Removes all empty directories under the given directory DirName.
Definition: tools.c:585
bool SpinUpDisk(const char *FileName)
Definition: tools.c:685
int Utf8StrLen(const char *s)
Returns the number of UTF-8 symbols formed by the given string of character bytes.
Definition: tools.c:887
int Utf8CharSet(uint c, char *s=NULL)
Converts the given UTF-8 symbol to a sequence of character bytes and copies them to the given string.
Definition: tools.c:840
cString strgetbefore(const char *s, char c, int n=1)
Definition: tools.c:203
uint16_t Peek13(const uchar *p)
Definition: tools.h:290
cString WeekDayName(int WeekDay)
Converts the given WeekDay (0=Sunday, 1=Monday, ...) to a three letter day name.
Definition: tools.c:1172
bool MakeDirs(const char *FileName, bool IsDirectory=false)
Definition: tools.c:499
bool startswith(const char *s, const char *p)
Definition: tools.c:329
unsigned char uchar
Definition: tools.h:31
char * compactchars(char *s, char c)
removes all occurrences of 'c' from the beginning an end of 's' and replaces sequences of multiple 'c...
Definition: tools.c:248
cString strgetval(const char *s, const char *name, char d='=')
Returns the value part of a 'name=value' pair in s.
Definition: tools.c:295
int CompareStrings(const void *a, const void *b)
Definition: tools.h:832
int CompareInts(const void *a, const void *b)
Definition: tools.h:827
int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs=0, int RetryMs=0)
Writes either all Data to the given file descriptor, or nothing at all.
Definition: tools.c:90
time_t LastModifiedTime(const char *FileName)
Definition: tools.c:723
uint Utf8CharGet(const char *s, int Length=0)
Returns the UTF-8 symbol at the beginning of the given string.
Definition: tools.c:825
int sgn(T a)
Definition: tools.h:68
double atod(const char *s)
Converts the given string, which is a floating point number using a '.
Definition: tools.c:411
cString ShortDateString(time_t t)
Converts the given time to a string of the form "dd.mm.yy".
Definition: tools.c:1246
char * strreplace(char *s, char c1, char c2)
Definition: tools.c:139
ssize_t safe_read(int filedes, void *buffer, size_t size)
Definition: tools.c:53
void Poke13(uchar *p, uint16_t v)
Definition: tools.h:295
bool StrInArray(const char *a[], const char *s)
Returns true if the string s is equal to one of the strings pointed to by the (NULL terminated) array...
Definition: tools.c:390
const char * GetHostName(void)
Gets the host name of this machine.
Definition: tools.c:1363
void DELETENULL(T *&p)
Definition: tools.h:49
int FreeDiskSpaceMB(const char *Directory, int *UsedMB=NULL)
Definition: tools.c:464
bool DoubleEqual(double a, double b)
Definition: tools.h:97
char * stripspace(char *s)
Definition: tools.c:219
ssize_t safe_write(int filedes, const void *buffer, size_t size)
Definition: tools.c:65
int numdigits(int n)
Definition: tools.c:354
int Utf8SymChars(const char *s, int Symbols)
Returns the number of character bytes at the beginning of the given string that form at most the give...
Definition: tools.c:874
cString DayDateTime(time_t t=0)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition: tools.c:1214
int CompareStringsIgnoreCase(const void *a, const void *b)
Definition: tools.h:837
char * ReadLink(const char *FileName)
returns a new string allocated on the heap, which the caller must delete (or NULL in case of an error...
Definition: tools.c:671
bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks=false)
Definition: tools.c:527
int DirSizeMB(const char *DirName)
returns the total size of the files in the given directory, or -1 in case of an error
Definition: tools.c:639
cString DateString(time_t t)
Converts the given time to a string of the form "www dd.mm.yyyy".
Definition: tools.c:1235
int SysLogLevel
Definition: tools.c:31
cString dtoa(double d, const char *Format="%f")
Converts the given double value to a string, making sure it uses a '.
Definition: tools.c:432
bool DirectoryOk(const char *DirName, bool LogErrors=false)
Definition: tools.c:481
T min(T a, T b)
Definition: tools.h:63
char * strn0cpy(char *dest, const char *src, size_t n)
Definition: tools.c:131
void swap(T &a, T &b)
Definition: tools.h:65
int Utf8CharLen(const char *s)
Returns the number of character bytes at the beginning of the given string that form a UTF-8 symbol.
Definition: tools.c:811
T max(T a, T b)
Definition: tools.h:64
void syslog_with_tid(int priority, const char *format,...) __attribute__((format(printf
#define esyslog(a...)
Definition: tools.h:35
char * strshift(char *s, int n)
Shifts the given string to the left by the given number of bytes, thus removing the first n bytes fro...
Definition: tools.c:317
char * compactspace(char *s)
Definition: tools.c:231
off_t FileSize(const char *FileName)
returns the size of the given file, or -1 in case of an error (e.g. if the file doesn't exist)
Definition: tools.c:731
int CompareStringsNumerically(const void *a, const void *b)
Definition: tools.h:842
bool EntriesOnSameFileSystem(const char *File1, const char *File2)
Checks whether the given files are on the same file system.
Definition: tools.c:449
const char * strchrn(const char *s, char c, size_t n)
returns a pointer to the n'th occurrence (counting from 1) of c in s, or NULL if no such character wa...
Definition: tools.c:178
uchar * RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality=100)
Converts the given Memory to a JPEG image and returns a pointer to the resulting image.
Definition: tools.c:1320
void put_unaligned(unsigned int v, T *p)
Definition: tools.h:88
int Utf8FromArray(const uint *a, char *s, int Size, int Max=-1)
Converts the given array of UTF-8 symbols (including the terminating 0) into a sequence of character ...
Definition: tools.c:936
int BCD2INT(int x)
Definition: tools.c:45
bool endswith(const char *s, const char *p)
Definition: tools.c:338
cString itoa(int n)
Definition: tools.c:442
bool isnumber(const char *s)
Definition: tools.c:364
cString AddDirectory(const char *DirName, const char *FileName)
Definition: tools.c:402
void writechar(int filedes, char c)
Definition: tools.c:85
cListGarbageCollector ListGarbageCollector
Definition: tools.c:2120
int64_t StrToNum(const char *s)
Converts the given string to a number.
Definition: tools.c:375