28 #include <sys/types.h> 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() ) 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) 42 #define SECSINDAY 86400 44 #define KILOBYTE(n) ((n) * 1024) 45 #define MEGABYTE(n) ((n) * 1024LL * 1024LL) 47 #define MALLOC(type, size) (type *)malloc(sizeof(type) * (size)) 49 template<
class T>
inline void DELETENULL(T *&p) { T *q = p; p = NULL;
delete q; }
51 #define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls 52 #define FATALERRNO (errno && errno != EAGAIN && errno != EINTR) 57 #if !defined(__STL_CONFIG_H) // for old versions of the STL 58 #if !defined(DISABLE_TEMPLATES_COLLIDING_WITH_STL) && !defined(_STL_ALGOBASE_H) 59 template<
class T>
inline T
min(T a, T b) {
return a <= b ? a : b; }
60 template<
class T>
inline T
max(T a, T b) {
return a >= b ? a : b; }
62 template<
class T>
inline int sgn(T a) {
return a < 0 ? -1 : a > 0 ? 1 : 0; }
63 #if !defined(DISABLE_TEMPLATES_COLLIDING_WITH_STL) && !defined(_MOVE_H) 64 template<
class T>
inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
68 template<
class T>
inline T
constrain(T v, T l, T h) {
return v < l ? l : v > h ? h : v; }
70 void syslog_with_tid(
int priority,
const char *format, ...) __attribute__ ((format (printf, 2, 3)));
72 #define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF)) 75 #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 82 struct s { T v; } __attribute__((packed));
88 struct s { T v; } __attribute__((packed));
97 return fabs(a - b) <= DBL_EPSILON;
131 int Utf8FromArray(
const uint *a,
char *s,
int Size,
int Max = -1);
141 #define Utf8BufSize(s) ((s) * 4) 146 #define Utf8to(conv, c) (cCharSetConv::SystemCharacterTable() ? to##conv(c) : tow##conv(c)) 147 #define Utf8is(ccls, c) (cCharSetConv::SystemCharacterTable() ? is##ccls(c) : isw##ccls(c)) 156 cCharSetConv(
const char *FromCode = NULL,
const char *ToCode = NULL);
162 const char *
Convert(
const char *From,
char *To = NULL,
size_t ToLength = 0);
180 cString(
const char *S = NULL,
bool TakePointer =
false);
181 cString(
const char *S,
const char *To);
184 operator const void * ()
const {
return s; }
185 operator const char * ()
const {
return s; }
192 static cString sprintf(
const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
196 ssize_t
safe_read(
int filedes,
void *buffer,
size_t size);
197 ssize_t
safe_write(
int filedes, const
void *buffer,
size_t size);
204 char *
strn0cpy(
char *dest, const
char *src,
size_t n);
206 char *
strreplace(
char *
s, const
char *s1, const
char *s2);
207 const
char *
strchrn(const
char *
s,
char c,
size_t n);
236 bool endswith(
const char *
s,
const char *p);
249 double atod(
const char *
s);
260 uint16_t v = uint16_t(*p++ & 0x1F) << 8;
261 return v + (*p & 0xFF);
265 v |= uint16_t(*p & ~0x1F) << 8;
275 bool DirectoryOk(
const char *DirName,
bool LogErrors =
false);
276 bool MakeDirs(
const char *FileName,
bool IsDirectory =
false);
277 bool RemoveFileOrDir(
const char *FileName,
bool FollowSymlinks =
false);
278 bool RemoveEmptyDirectories(
const char *DirName,
bool RemoveThis =
false,
const char *IgnoreFiles[] = NULL);
285 char *
ReadLink(
const char *FileName);
289 off_t
FileSize(
const char *FileName);
339 const char *NextLine(
void);
353 cBitStream(
const uint8_t *Data,
int Length) : data(Data), length(Length), index(0) {}
356 uint32_t GetBits(
int n);
357 void ByteAlign(
void);
358 void WordAlign(
void);
362 bool IsEOF(
void)
const {
return index >= length; }
364 int Length(
void)
const {
return length; }
365 int Index(
void)
const {
return (IsEOF() ? length : index); }
366 const uint8_t *
GetData(
void)
const {
return (IsEOF() ? NULL : data + (index / 8)); }
377 static uint64_t Now(
void);
378 void Set(
int Ms = 0);
379 bool TimedOut(
void)
const;
380 uint64_t Elapsed(
void)
const;
395 enum { MaxPollFiles = 64 };
396 pollfd pfd[MaxPollFiles];
399 cPoller(
int FileHandle = -1,
bool Out =
false);
400 bool Add(
int FileHandle,
bool Out);
401 void Del(
int FileHandle,
bool Out);
402 bool Poll(
int TimeoutMs = 0);
409 #if !__GLIBC_PREREQ(2, 24) // readdir_r() is deprecated as of GLIBC 2.24 412 char b[offsetof(
struct dirent, d_name) + NAME_MAX + 1];
418 bool Ok(
void) {
return directory != NULL; }
419 struct dirent *Next(
void);
430 operator int () {
return f; }
431 bool Open(
const char *FileName,
int Flags, mode_t Mode = DEFFILEMODE);
432 bool Open(
int FileDes);
435 bool Ready(
bool Wait =
true);
436 static bool AnyFileReady(
int FileDes = -1,
int TimeoutMs = 1000);
437 static bool FileReady(
int FileDes,
int TimeoutMs = 1000);
438 static bool FileReadyForWriting(
int FileDes,
int TimeoutMs = 1000);
449 operator FILE* () {
return f; }
469 int FadviseDrop(off_t Offset, off_t Len);
473 int Open(
const char *FileName,
int Flags, mode_t Mode = DEFFILEMODE);
475 void SetReadAhead(
size_t ra);
476 off_t Seek(off_t Offset,
int Whence);
477 ssize_t Read(
void *Data,
size_t Size);
478 ssize_t Write(
const void *Data,
size_t Size);
479 static cUnbufferedFile *Create(
const char *FileName,
int Flags, mode_t Mode = DEFFILEMODE);
489 bool Lock(
int WaitSeconds = 0);
508 int Index(
void)
const;
522 void Purge(
bool Force =
false);
534 cListBase(
const char *NeedsLocking = NULL);
537 bool Lock(
cStateKey &StateKey,
bool Write =
false,
int TimeoutMs = 0)
const;
568 void SetExplicitModify(
void);
573 void SetModified(
void);
577 void Del(
cListObject *Object,
bool DeleteObject =
true);
578 virtual void Move(
int From,
int To);
580 virtual void Clear(
void);
590 int Count(
void)
const {
return count; }
606 const T *
First(
void)
const {
return (T *)objects; }
608 const T *
Last(
void)
const {
return (T *)lastObject; }
610 const T *
Prev(
const T *Object)
const {
return (T *)Object->cListObject::Prev(); }
613 const T *
Next(
const T *Object)
const {
return (T *)Object->cListObject::Next(); }
616 T *
Get(
int Index) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->
Get(Index)); }
622 T *
Prev(
const T *Object) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->
Prev(Object)); }
624 T *
Next(
const T *Object) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->
Next(Object)); }
632 #define DEF_LIST_LOCK2(Class, Name) \ 633 class c##Name##_Lock { \ 635 cStateKey stateKey; \ 636 const c##Class *list; \ 638 c##Name##_Lock(bool Write = false) \ 641 list = c##Class::Get##Name##Write(stateKey); \ 643 list = c##Class::Get##Name##Read(stateKey); \ 645 ~c##Name##_Lock() { if (list) stateKey.Remove(); } \ 646 const c##Class *Name(void) const { return list; } \ 647 c##Class *Name(void) { return const_cast<c##Class *>(list); } \ 649 #define DEF_LIST_LOCK(Class) DEF_LIST_LOCK2(Class, Class) 654 #define USE_LIST_LOCK_READ2(Class, Name) \ 655 c##Name##_Lock Name##_Lock(false); \ 656 const c##Class *Name __attribute__((unused)) = Name##_Lock.Name(); 657 #define USE_LIST_LOCK_READ(Class) USE_LIST_LOCK_READ2(Class, Class) 659 #define USE_LIST_LOCK_WRITE2(Class, Name) \ 660 c##Name##_Lock Name##_Lock(true); \ 661 c##Class *Name __attribute__((unused)) = Name##_Lock.Name(); 662 #define USE_LIST_LOCK_WRITE(Class) USE_LIST_LOCK_WRITE2(Class, Class) 674 if (++Index > allocated) {
675 data = (T *)realloc(data, Index *
sizeof(T));
677 esyslog(
"ERROR: out of memory - abort!");
680 for (
int i = allocated; i < Index; i++)
694 T&
At(
int Index)
const 711 for (
int i = 0; i < size; i++) {
717 int Size(
void)
const {
return size; }
718 virtual void Insert(T Data,
int Before = 0)
722 memmove(&data[Before + 1], &data[Before], (size - Before) *
sizeof(T));
731 if (IndexOf(Data) < 0) {
732 Insert(Data, Before);
739 if (size >= allocated)
740 Realloc(allocated * 3 / 2);
745 if (IndexOf(Data) < 0) {
755 if (Index < size - 1)
756 memmove(&data[Index], &data[Index + 1], (size - Index) *
sizeof(T));
761 int i = IndexOf(Data);
770 for (
int i = 0; i < size; i++)
774 void Sort(__compar_fn_t Compare)
776 qsort(data, size,
sizeof(T), Compare);
782 return *(
const int *)a - *(
const int *)b;
787 return strcmp(*(
const char **)a, *(
const char **)b);
792 return strcasecmp(*(
const char **)a, *(
const char **)b);
797 int d = atoi(*(
const char **)a) - atoi(*(
const char **)b);
805 int Find(
const char *
s)
const;
806 void Sort(
bool IgnoreCase =
false)
817 virtual void Clear(
void);
822 cFileNameList(
const char *Directory = NULL,
bool DirsOnly =
false);
823 bool Load(
const char *Directory,
bool DirsOnly =
false);
832 bool Realloc(
int NewSize);
833 bool Assert(
int NewSize) {
return size < NewSize ? Realloc(NewSize) :
true; }
838 void Append(
uchar Data) {
if (Assert(used + 1)) buffer[used++] = Data; }
839 void Set(
int Index,
uchar Data) {
if (Assert(Index + 1)) buffer[Index] = Data; }
840 uchar Get(
int Index) {
return Index < used ? buffer[Index] : 0; }
861 unsigned int hashfn(
unsigned int Id)
const {
return Id % size; }
const char * operator*() const
const T * Get(int Index) const
Returns the list element at the given Index, or NULL if no such element exists.
cListObject * Get(unsigned int Id) const
cString(const char *S=NULL, bool TakePointer=false)
bool RemoveElement(const T &Data)
cHash(int Size=HASHSIZE, bool OwnObjects=false)
static char * systemCharacterTable
static const char * SystemCharacterTable(void)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
virtual void Append(T Data)
int allocated
< cVector may only be used for simple types, like int or pointers - not for class objects that alloca...
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string)...
T * Prev(const T *Object)
Non-const version of Prev().
cHashObject(cListObject *Object, unsigned int Id)
T & operator[](int Index)
void Set(int Index, uchar Data)
cBitStream(const uint8_t *Data, int Length)
int IndexOf(const T &Data)
cUnbufferedFile is used for large files that are mainly written or read in a streaming manner...
cListObject * Get(int Index)
cVector & operator=(const cVector &Vector)
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).
cCharSetConv(const char *FromCode=NULL, const char *ToCode=NULL)
Sets up a character set converter to convert from FromCode to ToCode.
void SetSyncStateKey(cStateKey &StateKey)
When making changes to this list (while holding a write lock) that shall not affect some other code t...
cListObject(const cListObject &ListObject)
cList< cHashObject > ** hashTable
virtual void Remove(int Index)
static cString static cString vsprintf(const char *fmt, va_list &ap)
const T & operator[](int Index) const
bool AppendUnique(T Data)
virtual void Insert(T Data, int Before=0)
cListObject * Prev(void) const
T * First(void)
Non-const version of First().
cListObject * Object(void)
virtual int Compare(const cListObject &ListObject) const
Must return 0 if this object is equal to ListObject, a positive value if it is "greater", and a negative value if it is "smaller".
const uint8_t * GetData(void) const
const char * needsLocking
cVector(const cVector &Vector)
void SetSyncStateKey(cStateKey &StateKey)
Sets the given StateKey to be synchronized to the state of this lock.
const T * Last(void) const
Returns the last element in this list, or NULL if the list is empty.
static void SetSystemCharacterTable(const char *CharacterTable)
void Sort(__compar_fn_t Compare)
bool InsertUnique(T Data, int Before=0)
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
const T * Prev(const T *Object) const
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
static uint8_t * SetLength(uint8_t *Data, int Length)
unsigned int hashfn(unsigned int Id) const
T * Get(unsigned int Id) const
T * Next(const T *Object)
Non-const version of Next().
cListObject * Next(void) const
void Sort(bool IgnoreCase=false)
const cListObject * Get(int Index) const
cString & Append(const char *String)
T * Get(int Index)
< Returns the element immediately following Object in this list, or NULL if Object is the last elemen...
cString & operator=(const cString &String)
cList(const char *NeedsLocking=NULL)
Sets up a new cList of the given type T.
T * Last(void)
Non-const version of Last().
void SetUseGarbageCollector(void)
cStringList(int Allocated=10)
void Realloc(int Index) const
void SortNumerically(void)
cVector(int Allocated=10)
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...