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))
49template<
class T>
inline void DELETENULL(T *&p) { T *q = p; p = NULL;
delete q; }
51#define CHECK(s) { if ((s) < 0) LOG_ERROR; }
52#define FATALERRNO (errno && errno != EAGAIN && errno != EINTR)
54#if __cplusplus >= 201103L
63template<
class T>
inline T
min(T a, T b) {
return a <= b ? a : b; }
64template<
class T>
inline T
max(T a, T b) {
return a >= b ? a : b; }
65template<
class T>
inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
68template<
class T>
inline int sgn(T a) {
return a < 0 ? -1 : a > 0 ? 1 : 0; }
70template<
class T>
inline T
constrain(T v, T l, T h) {
return v < l ? l : v > h ? h : v; }
74#define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
77#define IsBitSet(v, b) ((v) & (1 << (b)))
99 return fabs(a - b) <= DBL_EPSILON;
133int Utf8FromArray(
const uint *a,
char *s,
int Size,
int Max = -1);
143#define Utf8BufSize(s) ((s) * 4 + 1)
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))
158 cCharSetConv(
const char *FromCode = NULL,
const char *ToCode = NULL);
164 const char *
Convert(
const char *From,
char *To = NULL,
size_t ToLength = 0);
182 cString(
const char *S = NULL,
bool TakePointer =
false);
183 cString(
const char *S,
const char *To);
187 operator const void * ()
const {
return s; }
188 operator const char * ()
const {
return s; }
228ssize_t
safe_read(
int filedes,
void *buffer,
size_t size);
229ssize_t
safe_write(
int filedes,
const void *buffer,
size_t size);
236char *
strn0cpy(
char *dest,
const char *src,
size_t n);
238char *
strreplace(
char *
s,
const char *s1,
const char *s2);
239const char *
strchrn(
const char *
s,
char c,
size_t n);
271bool endswith(
const char *
s,
const char *p);
284double atod(
const char *
s);
295 uint16_t v = uint16_t(*p++ & 0x1F) << 8;
296 return v + (*p & 0xFF);
300 v |= uint16_t(*p & ~0x1F) << 8;
312bool DirectoryOk(
const char *DirName,
bool LogErrors =
false);
313bool MakeDirs(
const char *FileName,
bool IsDirectory =
false);
314bool RemoveFileOrDir(
const char *FileName,
bool FollowSymlinks =
false);
315bool RemoveEmptyDirectories(
const char *DirName,
bool RemoveThis =
false,
const char *IgnoreFiles[] = NULL);
322char *
ReadLink(
const char *FileName);
324void TouchFile(
const char *FileName,
bool Create =
false);
326off_t
FileSize(
const char *FileName);
393 uint32_t GetBits(
int n);
394 void ByteAlign(
void);
395 void WordAlign(
void);
415 static uint64_t
Now(
void);
416 void Set(
int Ms = 0);
453 cPoller(
int FileHandle = -1,
bool Out =
false);
454 bool Add(
int FileHandle,
bool Out);
455 void Del(
int FileHandle,
bool Out);
456 bool Poll(
int TimeoutMs = 0);
463#if !__GLIBC_PREREQ(2, 24)
466 char b[offsetof(
struct dirent, d_name) + NAME_MAX + 1];
473 struct dirent *Next(
void);
482 operator int () {
return f; }
483 bool Open(
const char *FileName,
int Flags, mode_t Mode = DEFFILEMODE);
484 bool Open(
int FileDes);
487 bool Ready(
bool Wait =
true);
488 static bool FileReady(
int FileDes,
int TimeoutMs = 1000);
499 operator FILE* () {
return f; }
523 int Open(
const char *FileName,
int Flags, mode_t Mode = DEFFILEMODE);
526 off_t
Seek(off_t Offset,
int Whence);
527 ssize_t
Read(
void *Data,
size_t Size);
528 ssize_t
Write(
const void *Data,
size_t Size);
539 bool Lock(
int WaitSeconds = 0);
558 int Index(
void)
const;
572 void Purge(
bool Force =
false);
584 cListBase(
const char *NeedsLocking = NULL);
587 bool Lock(
cStateKey &StateKey,
bool Write =
false,
int TimeoutMs = 0)
const;
618 void SetExplicitModify(
void);
623 void SetModified(
void);
627 void Del(
cListObject *Object,
bool DeleteObject =
true);
628 virtual void Move(
int From,
int To);
630 virtual void Clear(
void);
660 const T *
Prev(
const T *Object)
const {
return (T *)Object->cListObject::Prev(); }
663 const T *
Next(
const T *Object)
const {
return (T *)Object->cListObject::Next(); }
666 T *
Get(
int Index) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->Get(Index)); }
668 T *
First(
void) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->First()); }
670 T *
Last(
void) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->Last()); }
672 T *
Prev(
const T *Object) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->Prev(Object)); }
674 T *
Next(
const T *Object) {
return const_cast<T *
>(
static_cast<const cList<T> *
>(
this)->Next(Object)); }
682#define DEF_LIST_LOCK2(Class, Name) \
683class c##Name##_Lock { \
685 cStateKey stateKey; \
686 const c##Class *list; \
688 c##Name##_Lock(bool Write = false) \
691 list = c##Class::Get##Name##Write(stateKey); \
693 list = c##Class::Get##Name##Read(stateKey); \
695 ~c##Name##_Lock() { if (list) stateKey.Remove(); } \
696 const c##Class *Name(void) const { return list; } \
697 c##Class *Name(void) { return const_cast<c##Class *>(list); } \
699#define DEF_LIST_LOCK(Class) DEF_LIST_LOCK2(Class, Class)
704#define USE_LIST_LOCK_READ2(Class, Name) \
705c##Name##_Lock Name##_Lock(false); \
706const c##Class *Name __attribute__((unused)) = Name##_Lock.Name();
707#define USE_LIST_LOCK_READ(Class) USE_LIST_LOCK_READ2(Class, Class)
709#define USE_LIST_LOCK_WRITE2(Class, Name) \
710c##Name##_Lock Name##_Lock(true); \
711c##Class *Name __attribute__((unused)) = Name##_Lock.Name();
712#define USE_LIST_LOCK_WRITE(Class) USE_LIST_LOCK_WRITE2(Class, Class)
725 data = (T *)realloc(
data, Index *
sizeof(T));
727 esyslog(
"ERROR: out of memory - abort!");
744 T&
At(
int Index)
const
761 for (
int i = 0; i <
size; i++) {
768 virtual void Insert(T Data,
int Before = 0)
772 memmove(&
data[Before + 1], &
data[Before], (
size - Before) *
sizeof(T));
801 virtual void Remove(
int Index,
int Count = 1)
803 if (Index < 0 || Index >=
size || Count < 1)
805 if (Index + Count >
size)
806 Count =
size - Index;
807 int Tail =
size - (Index + Count);
809 memmove(&
data[Index], &
data[Index + Count], Tail *
sizeof(T));
823 for (
int i = 0; i <
size; i++)
827 void Sort(__compar_fn_t Compare)
829 qsort(
data,
size,
sizeof(T), Compare);
835 return *(
const int *)a - *(
const int *)b;
840 return strcmp(*(
const char **)a, *(
const char **)b);
845 return strcasecmp(*(
const char **)a, *(
const char **)b);
850 int d = atoi(*(
const char **)a) - atoi(*(
const char **)b);
858 int Find(
const char *s)
const;
859 void Sort(
bool IgnoreCase =
false)
870 virtual void Clear(
void)
override;
875 cFileNameList(
const char *Directory = NULL,
bool DirsOnly =
false);
876 bool Load(
const char *Directory,
bool DirsOnly =
false);
890 void Append(
const uchar *Data,
int Length);
914 unsigned int hashfn(
unsigned int Id)
const {
return Id %
size; }
static uint8_t * SetLength(uint8_t *Data, int Length)
cBase64Encoder(const uchar *Data, int Length, int MaxResult=64)
Sets up a new base 64 encoder for the given Data, with the given Length.
const char * NextLine(void)
Returns the next line of encoded data (terminated by '\0'), or NULL if there is no more encoded data.
cBitStream(const uint8_t *Data, int Length)
const uint8_t * GetData(void) const
cCharSetConv(const char *FromCode=NULL, const char *ToCode=NULL)
Sets up a character set converter to convert from FromCode to ToCode.
static const char * SystemCharacterTable(void)
static void SetSystemCharacterTable(const char *CharacterTable)
static char * systemCharacterTable
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).
cDynamicBuffer(int InitialSize=1024)
void Set(int Index, uchar Data)
bool Realloc(int NewSize)
bool Load(const char *Directory, bool DirsOnly=false)
cFileNameList(const char *Directory=NULL, bool DirsOnly=false)
cListObject * Get(unsigned int Id) const
cList< cHashObject > ** hashTable
cHashBase(int Size, bool OwnObjects)
Creates a new hash of the given Size.
unsigned int hashfn(unsigned int Id) const
cListObject * Object(void)
cHashObject(cListObject *Object, unsigned int Id)
cHash(int Size=HASHSIZE, bool OwnObjects=false)
T * Get(unsigned int Id) const
cListObject * Get(int Index)
void SetSyncStateKey(cStateKey &StateKey)
When making changes to this list (while holding a write lock) that shall not affect some other code t...
void SetUseGarbageCollector(void)
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0) const
Tries to get a lock on this list and returns true if successful.
const char * needsLocking
cListBase(const char *NeedsLocking=NULL)
const cListObject * Get(int Index) const
void Purge(bool Force=false)
cListGarbageCollector(void)
void Put(cListObject *Object)
cListObject(const cListObject &ListObject)
cListObject * Prev(void) const
friend class cListGarbageCollector
virtual int Compare(const cListObject &ListObject) const
Must return 0 if this object is equal to ListObject, a positive value if it is "greater",...
cListObject * Next(void) const
T * Last(void)
Non-const version of Last().
T * Prev(const T *Object)
Non-const version of Prev().
T * First(void)
Non-const version of First().
const T * Prev(const T *Object) const
T * Get(int Index)
< Returns the element immediately following Object in this list, or NULL if Object is the last elemen...
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
T * Next(const T *Object)
Non-const version of Next().
cList(const char *NeedsLocking=NULL)
Sets up a new cList of the given type T.
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
const T * Last(void) const
Returns the last element in this list, or NULL if the list is empty.
const T * Get(int Index) const
Returns the list element at the given Index, or NULL if no such element exists.
bool Lock(int WaitSeconds=0)
cLockFile(const char *Directory)
cPoller(int FileHandle=-1, bool Out=false)
bool Add(int FileHandle, bool Out)
bool Poll(int TimeoutMs=0)
void Del(int FileHandle, bool Out)
cReadDir(const char *Directory)
char b[offsetof(struct dirent, d_name)+NAME_MAX+1]
cSafeFile(const char *FileName)
cStringList(int Allocated=10)
void Sort(bool IgnoreCase=false)
void SortNumerically(void)
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
static cString static cString vsprintf(const char *fmt, va_list &ap)
const char * operator*() const
cString(const char *S=NULL, bool TakePointer=false)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
cString & operator=(const cString &String)
cString(cString &&String)
cString & Append(const char *String)
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
uint64_t Elapsed(void) const
Returns the number of milliseconds that have elapsed since the last call to Set().
void Set(int Ms=0)
Sets the timer.
bool TimedOut(void) const
Returns true if the number of milliseconds given in the last call to Set() have passed.
cTimeMs(int Ms=0)
Creates a timer with ms resolution and an initial timeout of Ms.
void Reset(void)
Resets the timer to the same timeout as given in the last call to Set().
static uint64_t Now(void)
uint64_t Remaining(void) const
Returns the number of milliseconds remaining until the timer times out.
static cUnbufferedFile * Create(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
void SetReadAhead(size_t ra)
ssize_t Write(const void *Data, size_t Size)
int Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
ssize_t Read(void *Data, size_t Size)
int FadviseDrop(off_t Offset, off_t Len)
off_t Seek(off_t Offset, int Whence)
cVector(int Allocated=10)
bool AppendUnique(T Data)
void Realloc(int Index) const
void Sort(__compar_fn_t Compare)
int IndexOf(const T &Data)
T & operator[](int Index)
cVector & operator=(const cVector &Vector)
int allocated
< cVector may only be used for simple types, like int or pointers - not for class objects that alloca...
virtual void Insert(T Data, int Before=0)
virtual void Remove(int Index, int Count=1)
virtual void Append(T Data)
bool InsertUnique(T Data, int Before=0)
const T & operator[](int Index) const
bool RemoveElement(const T &Data)
cVector(const cVector &Vector)
struct __attribute__((packed))