Home2L - C/C++ API v1.4-0-g38cc (2024-05-25)
Smart Tools for a Private Home
base.H
Go to the documentation of this file.
1/*
2 * This file is part of the Home2L project.
3 *
4 * (C) 2015-2024 Gundolf Kiefer
5 *
6 * Home2L is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Home2L is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Home2L. If not, see <https://www.gnu.org/licenses/>.
18 *
19 */
20
21
22#ifndef _BASE_
23#define _BASE_
24
25
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <stdint.h>
38#include <limits.h>
39#include <unistd.h>
40#include <signal.h>
41#include <pthread.h>
42#include <regex.h>
43#include <stdarg.h>
44
45#include <config.H>
46
47
48
49
50
51// *************************** Configuration ***********************************
52
53
54#ifdef __ANDROID__
55#define ANDROID 1
56#else
57#define ANDROID 0
58#endif
59
60
61
62
63
64// ***************** Basic definitions and functions ***************************
65
66
74#define MIN(A, B) ((A) < (B) ? (A) : (B))
75#define MAX(A, B) ((A) > (B) ? (A) : (B))
76
77#define STR(X) #X
80#define OFFSET(type, field) ((unsigned) &(((type *) 0)->field))
82
83#define ENTRIES(ARRAY) ((int) (sizeof (ARRAY) / sizeof (ARRAY[0])))
85
86#define CLEAR(X) bzero (&(X), sizeof (X))
88
89
93#define ATOMIC_READ(OBJ) __atomic_load_n (&(OBJ), __ATOMIC_RELAXED)
94#define ATOMIC_WRITE(OBJ, VAL) __atomic_store_n (&(OBJ), VAL, __ATOMIC_RELAXED)
95#define ATOMIC_INC(OBJ, N) __atomic_exchange_n (&(OBJ), (OBJ) + (N), __ATOMIC_RELAXED)
97
98
101size_t Write (int fd, const void *buf, size_t count);
110
111size_t Read (int fd, void *buf, size_t count);
121
122bool MakeDir (const char *relOrAbsPath, bool setHome2lGroup = true);
131
132bool UnlinkTree (const char *relOrAbsPath, const char *skipPattern = NULL);
143
144bool ReadDir (const char *relOrAbsPath, class CKeySet *ret);
152
154
155
157
158
159
160
161
162// ********************** Logging and Debugging ********************************
163
164
172#if WITH_DEBUG == 1
173extern int envDebug;
174#else
175#define envDebug 0
176#endif
177
178
179typedef void FLogCbMessage (const char *title, const char *msg);
183typedef void FLogCbToast (const char *msg, bool showLonger);
188
189
190#if !ANDROID
191void LogToSyslog (const char *instanceName = NULL);
192void LogClose ();
193bool LoggingToSyslog ();
194void LogStack ();
195static inline void LogSetCbMessage (FLogCbMessage *_cbMessage) {}
196static inline void LogSetCallbacks (FLogCbMessage *_cbMessage, FLogCbToast *_cbToast) {}
197#else
198static inline void LogToSyslog () {}
199static inline void LogClose () {}
200static inline bool LoggingToSyslog () { return true; }
201static inline void LogStack () {}
202void LogSetCallbacks (FLogCbMessage *_cbMessage, FLogCbToast *_cbToast);
203#endif
204
205void LogPara (const char *_logHead, const char* _logFile, int _logLine); // Helper only; use the following macros instead
206void LogPrintf (const char *format, ...); // Helper only; use the following macros instead
207
208
209#if WITH_DEBUG == 1
210#define DEBUG(LEVEL, MSG) do { if (envDebug >= LEVEL) { LogPara ("DEBUG-" #LEVEL, __FILE__, __LINE__); LogPrintf (MSG); } } while (0)
221#define DEBUGF(LEVEL, FMT) do { if (envDebug >= LEVEL) { LogPara ("DEBUG-" #LEVEL, __FILE__, __LINE__); LogPrintf FMT; } } while (0)
226#else
227#define DEBUG(LEVEL, MSG) do {} while (0)
228#define DEBUGF(LEVEL, FMT) do {} while (0)
229#endif
230
231#define INFO(MSG) do { LogPara ("INFO", __FILE__, __LINE__); LogPrintf (MSG); } while (0)
233#define INFOF(FMT) do { LogPara ("INFO", __FILE__, __LINE__); LogPrintf FMT; } while (0)
235
236#define WARNING(MSG) do { LogPara ("WARNING", __FILE__, __LINE__); LogPrintf (MSG); } while (0)
238#define WARNINGF(FMT) do { LogPara ("WARNING", __FILE__, __LINE__); LogPrintf FMT; } while (0)
240
241#define SECURITY(MSG) do { LogPara ("SECURITY", __FILE__, __LINE__); LogPrintf (MSG); } while (0)
245#define SECURITYF(FMT) do { LogPara ("SECURITY", __FILE__, __LINE__); LogPrintf FMT; } while (0)
247
248#define ERROR(MSG) do { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf (MSG); _exit (3); } while (0)
250#define ERRORF(FMT) do { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf FMT; _exit (3); } while (0)
252
253#define ABORT(MSG) do { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf (MSG); abort (); } while (0)
257#define ABORTF(FMT) do { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf FMT; abort (); } while (0)
259
260#define ASSERT(COND) do { if (!(COND)) { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf ("Assertion failed"); LogStack (); abort (); } } while (0)
262#define ASSERTM(COND,MSG) do { if (!(COND)) { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf ("Assertion failed: %s", MSG); LogStack (); abort (); } } while (0)
264#define ASSERTF(COND,FMT) do { if (!(COND)) { LogPara ("ERROR", __FILE__, __LINE__); LogPrintf ("Assertion failed - explanation follows."); LogPrintf FMT; abort (); LogStack (); abort (); } } while (0)
266
267#define ASSERT_WARN(COND) do { if (!(COND)) WARNING("Weak assertion failed"); } while (0)
269
270
272
273// ***** Compile-time assertion *****
275
276#if __cplusplus >= 201103L
277#define STATIC_ASSERT(COND) static_assert (COND, "please check!")
281#else
282#define STATIC_ASSERT(COND) static inline void build_assert_##__LINE__() { (void) sizeof(char[(COND) - 1]); }
283#endif
285
287
289
290
291
292// *************************** Safe heap operations ****************************
293
294
304#define MALLOC(T, N) (T*) malloc (sizeof (T) * (N))
306#define REALLOC(T, P, N) (T*) realloc (P, sizeof (T) * (N))
308#define SETP(P, X) { if (P) free (P); P = (X); }
310#define FREEP(P) SETP(P, NULL)
313
314
317#define SETO(O, X) { if (O) delete O; O = (X); }
319#define FREEO(O) SETO(O, NULL)
321
322#define SETA(A, X) { if (A) delete [] A; A = (X); }
324#define FREEA(A) SETA(A, NULL)
327
328
330
331
333
334
335// *************************** Version Helpers *********************************
336
337
349static inline uint32_t VersionCompose (uint8_t major, uint8_t minor, uint16_t revision, bool dirty = false) {
355 return (((uint32_t) major) << 24) + (((uint32_t) minor) << 16) + (((uint32_t) revision) << 1) + ((uint32_t) dirty);
356}
357static inline int VersionMajor (uint32_t ver) { return (int) (ver >> 24); }
359static inline int VersionMinor (uint32_t ver) { return (int) ((ver >> 16) & 0xff); }
361static inline int VersionRevision (uint32_t ver) { return (int) ((ver >> 1) & 0x7fff); }
363static inline bool VersionDirty (uint32_t ver) { return (ver & 1) == 1; }
365
366uint32_t VersionFromStr (const char *str);
369const char *VersionToStr (class CString *ret, uint32_t ver);
373
374static inline const char *VersionGetOwnAsStr () { return buildVersion; }
376uint32_t VersionGetOwn ();
378
379
381
382
383
384
386// ********************** Localization and language ****************************
388
399// Select the 'gettext' implementation (GNU vs. internal)...
400#if ANDROID
401#define USE_GNU_GETTEXT 0 // Android does not have GNU gettext => use internal implementation
402#else
403#define USE_GNU_GETTEXT 0 // can be set to 1, presently set to 0 for debugging purposes
404#endif
405
406
407// Basic definitions...
408#if USE_GNU_GETTEXT // GNU gettext implementation ...
409
410#include <libintl.h>
411
412#else // Internal implementation ...
413
414const char *LangGetText (const char *msgId);
415
416#define gettext(STR) LangGetText (STR)
417
418#endif
419
420
421// Init/done...
422void LangInit (const char *localeDir, const char *locale);
423 // locale = "" or NULL: use environment setting LC_MESSAGES
424 // 'localeDir' is expected to be '$HOME2L_ROOT/locale'. The domain will be automatically set to "home2l",
425 // so that the translations for the complete Home2L suite are contained in a single file:
426 // '$HOME2L_ROOT/locale/<locale>/LC_MESSAGES/home2l.mo'
427void LangDone ();
428
429
430// Marking macros...
431#define _(STR) gettext(STR)
432#define gettext_noop(STR) STR
433#define N_(STR) gettext_noop(STR)
434
435
436// More helpers...
437void LangTranslateNumber (char *str);
439
440
442
443
444
445
446
447// *************************** Strings *****************************************
448
449
481#define WHITESPACE " \t\n\r\v"
482
483
484// ***** Misc. helpers *****
485
486
501
502#define TTS (GetThreadTempString ())
504
505const char *StringF (class CString *ret, const char *fmt, ...);
507
508bool BoolFromString (const char *str, bool *ret);
512bool ValidBoolFromString (const char *str, bool defaultVal);
514bool IntFromString (const char *str, int *ret, int radix = 0);
518int ValidIntFromString (const char *str, int defaultVal, int radix = 0);
520bool UnsignedFromString (const char *str, unsigned *ret, int radix = 0);
524unsigned ValidUnsignedFromString (const char *str, unsigned defaultVal, int radix = 0);
526bool FloatFromString (const char *str, float *ret);
530float ValidFloatFromString (const char *str, float defaultVal);
532
533void StringStrip (char *str, const char *sepChars = WHITESPACE);
535void StringTruncate (char *str, const char *sepChars = WHITESPACE, bool after = false);
537void StringSplit (const char *str, int *retArgc, char ***retArgv, int maxArgc = INT_MAX, const char *sepChars = NULL, char **retRef = NULL);
558void StringSplitFree (char ***argv);
562bool CharIsWhiteSpace (char c);
564
568void PathNormalize (char *str);
569void PathRemoveTrailingSlashes (char *str);
570const char *PathLeaf (const char *str);
571
572const char *GetAbsPath (class CString *ret, const char *relOrAbsPath, const char *defaultPath);
583
584
587const char *ToUtf8 (class CString *ret, const char *iso8859str);
590const char *ToIso8859 (class CString *ret, const char *str);
594
595
597// ***** CString *****
599
607class CString {
608 public:
609 CString () { size = 0; ptr = (char *) emptyStr; }
610 CString (const CString& str) { size = 0; Set (str.Get ()); }
611 CString (const char *str, int maxLen = INT_MAX) { size = 0; Set (str, maxLen); }
612 ~CString () { if (size) free (ptr); }
613
616 void Clear () { SetC (emptyStr); }
617 void Set (char c) { Clear (); Insert (0, c); }
618 void Set (const char *str, int maxLen = INT_MAX);
620 void SetF (const char *fmt, ...);
622 void SetFV (const char *fmt, va_list ap);
624
625 void SetC (const char *_ptr);
630
633 void SetO (const char *_ptr);
636 char *Disown ();
645
648 static const char * const emptyStr;
653 void SetFromIso8859 (const char *iso8859str);
654 bool SetAsIso8859 (const char *str);
656
659 char *Get () const { return ptr; }
660 int Len () { return strlen (ptr); }
661 bool IsEmpty () { return ptr[0] == '\0'; }
663
666 void Del (int n0, int dn = INT_MAX);
667
668 void Insert (int n0, int dn, int *retInsPos = NULL);
669 void Insert (int n0, char c);
670 void Insert (int n0, const char *str, int maxLen = INT_MAX);
671 void InsertF (int n0, const char *fmt, ...);
672 void InsertFV (int n0, const char *fmt, va_list ap);
673
674 void Append (char c) { Insert (INT_MAX, c); }
675 void Append (const char *str, int maxLen = INT_MAX) { Insert (INT_MAX, str, maxLen); }
676 void AppendF (const char *fmt, ...);
677 void AppendFV (const char *fmt, va_list ap) { InsertFV (INT_MAX, fmt, ap); }
679
682 int Compare (const char *str2);
683
684 void Strip (const char *sepChars = WHITESPACE);
685 void Truncate (const char *sepChars = WHITESPACE, bool after = false);
686
687 void Split (class CSplitString *args, int maxArgc = INT_MAX, const char *sepChars = WHITESPACE);
688 void Split (int *retArgc, char ***retArgv, int maxArgc = INT_MAX, const char *sepChars = WHITESPACE) { StringSplit (ptr, retArgc, retArgv, maxArgc, sepChars); }
690 void AppendFByLine (const char *fmt, const char *text);
692 void SetFByLine (const char *fmt, const char *text) { Clear (); AppendFByLine (fmt, text); }
695
696 void AppendEscaped (const char *s, const char *dontEscape = NULL);
698 void SetEscaped (const char *s, const char *dontEscape = NULL) { Clear (); AppendEscaped (s, dontEscape); }
711
712 bool AppendUnescaped (const char *s);
714 bool SetUnescaped (const char *s) { Clear (); return AppendUnescaped (s); }
724 void PathNormalize ();
725 void PathRemoveTrailingSlashes ();
726 const char *PathLeaf () { return ::PathLeaf (ptr); }
727 void PathGo (const char *where);
728 void PathGoUp ();
729
732 bool ReadFile (const char *relOrAbsPath);
735 bool AppendFromFile (int fd, const char *name = NULL);
740 bool ReadLine (CString *ret);
747
750 operator char * () { return ptr; }
751
752 CString& operator = (const CString &str) { Set (str.Get ()); return *this; }
753 CString& operator = (const char *str) { Set (str); return *this; }
754 char& operator [] (int n) { return n >= 0 ? ptr [n] : ptr [strlen (ptr) + n]; }
755 CString operator + (const char *str);
756 CString& operator += (char c) { Append (c); return *this; }
757 CString& operator += (const char *str) { Append (str); return *this; }
758
759 bool operator < (const char *str) { return Compare (str) < 0; }
760 bool operator > (const char *str) { return Compare (str) > 0; }
761 bool operator <= (const char *str) { return Compare (str) <= 0; }
762 bool operator >= (const char *str) { return Compare (str) >= 0; }
763 bool operator == (const char *str) { return Compare (str) == 0; }
764 bool operator != (const char *str) { return Compare (str) != 0; }
766
767 // Interfaces ...
768 const char *ToStr (CString *) { return Get (); } // (internal, for 'CDict')
769
770 protected:
771 void SetSize (int _size);
772 void MakeWriteable () { if (!size) SetSize (strlen (ptr) + 1); } // '+1' is just for the case that string was empty
773
774 char *ptr;
775 int size; // number of allocated bytes (including '\0`);
776 //'size' == 0: nothing allocated in heap ('ptr' may still point to some constant string
777
778};
779
780
781
782// ***** CSplitString *****
783
784
791class CSplitString {
792 public:
793 CSplitString () { argc = 0; argv = NULL; ref = NULL; }
794 CSplitString (const char *str, int maxArgc = INT_MAX, const char *sepChars = NULL) { StringSplit (str, &argc, &argv, maxArgc, sepChars, &ref); }
796 ~CSplitString () { Clear (); }
797
798 void Clear ();
800
801 void Set (const char *str, int maxArgc = INT_MAX, const char *sepChars = NULL) { Clear (); StringSplit (str, &argc, &argv, maxArgc, sepChars, &ref); }
810
811 int Entries () const { return argc; }
812 const char *Get (int idx) const { return argv[idx]; }
813 const char *operator [] (int n) const { return Get (n); }
814
815 int GetOffset (int argNo) { return (argv && ref) ? argv[argNo] - ref : 0; }
817 int GetOffset (const char *p) { return ref ? (p - ref) : 0; }
819 int GetIdx (int pos);
823
824 protected:
825 int argc;
826 char **argv, *ref;
827};
828
830
831// ***** Regexp *****
832
833
838class CRegex {
839 public:
840 CRegex () { reValid = false; lastError = 0; }
841 ~CRegex () { if (reValid) regfree (&re); }
842
843 bool SetPattern (const char *pattern, int cflags = REG_EXTENDED);
852 bool Match (const char *s, int eflags = 0, size_t maxMatches = 0, regmatch_t *retMatchList = NULL);
862
864 bool IsValid () { return reValid; }
865 const char *ErrorStr ();
867 private:
868 CString errorStr;
869 bool reValid;
870 int lastError;
871 regex_t re;
872};
873
874
876
877
878
879
881// ********************** Container Classes ************************************
882
883
891#define CONT_ALIGNMENT 4
892#define CONT_ALIGN(X) (((X) + CONT_ALIGNMENT - 1) & ~(CONT_ALIGNMENT - 1))
893
894
895
896// ***** Stringification of container values ****
897
898
899// Template for all classes, which must have a 'ToStr()' method ...
900template <typename T> const char *ToStr (CString *ret, T *obj) { return obj->ToStr (ret); }
901
902// Specializations for non-class types (more specializations may be added here as required) ...
903template <> const char *ToStr<int> (CString *ret, int *obj);
904
905
906
907// ***** CList... *****
908
909
915class CListRaw {
916 public:
917 CListRaw (int _recSize);
918 virtual ~CListRaw () { Clear (); }
919
922 int Entries () const { return entries; }
925
928 void Clear () { SetEntries (0); }
930 void Del (int idx);
933
936 virtual void Dump (const char *name);
938
939 protected:
940
941 // Methods to be overloaded by derived classes ...
942 virtual void RecInit (void *p);
943 // Initialize record in previously uninitialized memory.
944 // This method is also used to wipe entries that have been copied and are no longer owned.
945 virtual void RecClear (void *p);
946 // Clear (initialized) record such that no destructor call is necessary anymore.
947
948 virtual void ValueInit (void *p) {}
949 // Initialize value data in previously uninitialized memory
950 virtual void ValueClear (void *p) {}
951 // Clear (initialized) record such that no destructor call is necessary anymore
952 virtual void ValueSet (void *p, void *orig) {}
953 // Copy or move 'orig' to 'p' properly. Both are initialized objects.
954 // The derived class must specify whether 'orig' is copied or moved (= disowned) by this
955 // and document the behavior for
956 virtual const char *ValueToStr (CString *ret, void *p);
957 // return readable string for the 'Dump' method
959 // Helpers for derived classes ...
960 void SetEntries (int _entries);
961
962 uint8_t *GetRecAdr (int idx) const { return idx < 0 ? NULL : data + recSize * idx; }
963 // Get memory address of whole record (including eventual tag)
964 uint8_t *GetValueAdr (int idx) const { return idx < 0 ? NULL : data + recSize * idx + tagSize; }
965 // Get memory address of the value part of the record (for '...Compact' classes)
966 void *GetValuePtr (int idx) const { return idx < 0 ? NULL : * (void **) (GetValueAdr (idx)); }
967 // (for non-compact classes) Take the value part inside the record as a pointer to the real value and dereference it
968
969 void Copy (int idxDst, int idxSrc); // byte-copy entry
970 void Swap (void *rec0, void *rec1); // byte-swap two entries (potentially from different objects)
971
972 void SetRaw (int idx, void *value);
973 // Set a new entry. The entry must exist and 'idx' be valid.
974 // 'value' may either be copied or moved, see comment to 'ValueSet()'.
975 void InsertRaw (int idx, void *value);
976 // Insert a new entry in position 'idx'.
977 // 'value' may either be copied or moved, see comment to 'ValueSet()'.
978 void *DisownRaw (int idx);
979 // (for non-compact classes) Take the value part inside the record as a pointer to the real value,
980 // return it and set it to NULL in the record.
981
982 // Data ...
983 uint8_t *data;
984 int recSize, tagSize, entries, allocEntries;
985 // 'tagSize' is an offset inside a record. It can be used by derived classes,
986 // e.g. by 'CDictRaw' to reserve space for keys.
987};
988
989
999template <typename T> class CList: public CListRaw {
1000 public:
1001 CList (): CListRaw (sizeof (T *)) {}
1002
1005 T *Get (int idx) { return (T *) GetValuePtr (idx); }
1006 T *operator [] (int idx) { return Get (idx); }
1008
1014 void Set (int idx, T *value) { SetRaw (idx, value); }
1017 void Insert (int idx, T *value) { InsertRaw (idx, value); }
1020 void Append (T *value) { InsertRaw (INT_MAX, value); }
1023 T *Disown (int idx) { return (T *) DisownRaw (idx); }
1026
1027 protected:
1028 virtual void ValueInit (void *p) { * (T **) p = NULL; }
1029 virtual void ValueClear (void *p) { if (* (T**) p) { delete * (T **) p; * (T **) p = NULL; } }
1030 virtual void ValueSet (void *p, void *orig) { ValueClear (p); * (T**) p = (T*) orig; }
1031 virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, * (T**) p); }
1032};
1033
1034
1052template <typename T> class CListCompact: public CListRaw {
1053 public:
1054 CListCompact (): CListRaw (sizeof (T)) {}
1055 virtual ~CListCompact () { Clear (); }
1056
1059 T *Get (int idx) { return (T *) GetValueAdr (idx); }
1060 T *operator [] (int idx) { return Get (idx); }
1062
1066 void Set (int idx, T *value) { SetRaw (idx, value); }
1069 void Insert (int idx, T *value) { InsertRaw (idx, value); }
1072 void Append (T *value) { InsertRaw (INT_MAX, value); }
1076
1077 protected:
1078 virtual void ValueInit (void *p) { memcpy (p, &emptyObj, sizeof (emptyObj)); }
1079 virtual void ValueClear (void *p) { ValueSet (p, &emptyObj); }
1080 virtual void ValueSet (void *p, void *orig) { * (T *) p = * (T *) orig; }
1081 virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, (T*) p); }
1082
1083 T emptyObj; // Template for an initialized object
1084};
1085
1086
1092template <typename T> class CListRef: public CList<T> {
1093 protected:
1094 virtual void ValueClear (void *p) { * (T **) p = NULL; }
1095 virtual void ValueSet (void *p, void *orig) { * (T**) p = (T*) orig; }
1096};
1098
1099
1100// ***** CDict... *****
1101
1102
1103#define DICT_KEYSIZE CONT_ALIGN((int) sizeof (CString))
1104
1105
1111class CDictRaw: public CListRaw {
1112 public:
1113 CDictRaw (int _valueSize): CListRaw (_valueSize + DICT_KEYSIZE) { tagSize = DICT_KEYSIZE; }
1114
1117 void Del (int idx) { CListRaw::Del (idx); }
1123 void Del (const char *key) { Del (Find (key)); }
1126
1129 const char *GetKey (int idx) const { return ((CString *) GetRecAdr (idx))->Get (); }
1131 int Find (const char *key, int *retInsIdx = NULL);
1134 void PrefixSearch (const char *key, int *retIdx0, int *retIdx1);
1140
1143 virtual void Dump (const char *name);
1146 protected:
1147 virtual void RecInit (void *p);
1148 virtual void RecClear (void *p);
1149
1150 void SetRaw (int idx, void *value) { CListRaw::SetRaw (idx, value); }
1151 int SetRaw (const char *key, void *value); // add or replace the keyed entry; returns new index
1152
1153 void MergeRaw (CDictRaw *dict2); // merge 'dict2' into this one and clear 'dict2'
1154};
1155
1156
1167template <typename T> class CDict: public CDictRaw {
1168 public:
1169 CDict (): CDictRaw (sizeof (T *)) {}
1170
1173 T *Get (int idx) { return (T *) GetValuePtr (idx); }
1174 T *Get (const char *key) { return Get (Find (key)); }
1175 T *operator [] (int idx) { return Get (idx); }
1176 T *operator [] (const char *key) { return Get (key); }
1178
1184 int Set (const char *key, T *value) { return SetRaw (key, value); }
1187 void SetValue (int idx, T *value) { SetRaw (idx, value); }
1193 T *DisownValue (int idx) { return (T *) DisownRaw (idx); }
1195 T *DisownValue (const char *key) { return (T *) DisownRaw (Find (key)); }
1197
1198 void Merge (CDict<T> *dict2) { MergeRaw (dict2); }
1206
1207 protected:
1208 virtual void ValueInit (void *p) { * (T **) p = NULL; }
1209 virtual void ValueClear (void *p) { if (* (T**) p) { delete * (T **) p; * (T **) p = NULL; } }
1210 virtual void ValueSet (void *p, void *orig) { ValueClear (p); * (T**) p = (T*) orig; }
1211 virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, * (T**) p); }
1213
1214
1222template <typename T> class CDictCompact: public CDictRaw {
1223 public:
1224 CDictCompact (): CDictRaw (sizeof (T)) {}
1225
1228 T *Get (int idx) { return (T *) GetValueAdr (idx); }
1229 T *Get (const char *key) { return Get (Find (key)); }
1230 T *operator [] (int idx) { return Get (idx); }
1231 T *operator [] (const char *key) { return Get (key); }
1233
1236 int Set (const char *key, T *value) { return SetRaw (key, value); }
1239 void SetValue (int idx, T *value) { SetRaw (idx, value); }
1242 void Merge (CDictCompact<T> *dict2) { MergeRaw (dict2); }
1251 protected:
1252 virtual void ValueInit (void *p) { memcpy (p, (void *) &emptyObj, sizeof (emptyObj)); }
1253 virtual void ValueClear (void *p) { ValueSet (p, (void *) &emptyObj); }
1254 virtual void ValueSet (void *p, void *orig) { * (T *) p = * (T *) orig; }
1255 virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, (T*) p); }
1256
1257 T emptyObj; // Template for an initialized object
1258};
1259
1260
1266template <typename T> class CDictRef: public CDict<T> {
1267 protected:
1268 virtual void ValueClear (void *p) { * (T **) p = NULL; }
1269 virtual void ValueSet (void *p, void *orig) { * (T**) p = (T*) orig; }
1271
1272
1273
1274// ***** CKeySet *****
1275
1278class CKeySet: public CDictRaw {
1279 public:
1280 CKeySet (): CDictRaw (0) {}
1281
1284 const char *operator [] (int idx) { return GetKey (idx); }
1286
1289 int Set (const char *key) { return SetRaw (key, NULL); }
1290 void Merge (CKeySet *set2) { MergeRaw (set2); }
1298
1301 virtual void Dump (const char *name);
1303};
1304
1305
1307
1308
1309
1310
1311
1312// *************************** Date & Time *************************************
1313
1314
1349
1350typedef int64_t TTicks;
1352
1353#define ASAP ((TTicks) 0)
1355#define NEVER ((TTicks) INT64_MIN)
1359
1360
1361TTicks TicksNow ();
1367
1374
1375const char *TicksAbsToString (CString *ret, TTicks ticks, int fracDigits = INT_MAX, bool precise = false);
1384const char *TicksRelToString (CString *ret, TTicks ticks);
1393
1394bool TicksFromString (const char *str, TTicks *ret, bool absolute);
1415static inline bool TicksAbsFromString (const char *str, TTicks *ret) { return TicksFromString (str, ret, true); }
1417static inline bool TicksRelFromString (const char *str, TTicks *ret) { return TicksFromString (str, ret, false); }
1419
1420void TicksToStructTimeval (TTicks t, struct timeval *retTv);
1421
1422#define TICKS_FROM_SECONDS(S) (((TTicks) (S)) * 1000)
1423#define SECONDS_FROM_TICKS(T) (((TTicks) (T) + 500) / 1000)
1424#define TICKS_FROM_MILLIS(MS) ((TTicks) (MS))
1425#define MILLIS_FROM_TICKS(T) ((int) (T))
1426
1428
1429
1432
1433typedef int TDate; // Date encoded as bit fields
1434
1435#define DATE_OF(Y,M,D) ((TDate) (((Y) << 9) | ((M) << 5) | (D)))
1436#define YEAR_OF(DT) ((int) (DT) >> 9)
1437#define MONTH_OF(DT) (((int) (DT) >> 5) & 0xf) // range is 1..12 (different from 'struct tm' in <time.h>)
1438#define DAY_OF(DT) ((int) (DT) & 0x1f) // range is 1..31
1439
1440
1441typedef int TTime; // Time in seconds since midnight
1442
1443#define TIME_OF(H,M,S) ((TTime) ((H) * 3600 + (M) * 60 + (S)))
1444#define HOURS_OF(T) ((int) (T) / 3600)
1445#define MINUTES_OF(T) ((int) (T) / 60)
1446#define HOUR_OF(T) HOURS_OF(T)
1447#define MINUTE_OF(T) (MINUTES_OF(T) % 60)
1448#define SECOND_OF(T) ((int) (T) % 60)
1449
1455TTicks TicksOfDate (int dy, int dm, int dd); // range of 'dm' is 1..12
1456TTicks TicksOfDate (TDate d);
1457TTicks TicksOfTime (int th, int tm, int ts);
1458TTicks TicksOfTime (TTime t);
1459
1460TDate DateOfTicks (TTicks t);
1461TTime TimeOfTicks (TTicks t);
1462
1463TTicks DateTimeToTicks (TDate d, TTime t, struct tm *retTm = NULL);
1464#if !ANDROID
1465TTicks DateTimeToTicksUTC (TDate d, TTime t, struct tm *retTm = NULL);
1466#endif
1467void TicksToDateTime (TTicks t, TDate *retDate, TTime *retTime, struct tm *retTm = NULL);
1468void TicksToDateTimeUTC (TTicks t, TDate *retDate, TTime *retTime, struct tm *retTm = NULL);
1470
1471
1474static inline void DateTimeNow (TDate *d, TTime *t) { TicksToDateTime (TicksNow (), d, t, NULL); }
1476TDate Today ();
1477TTicks TicksToday ();
1479
1480
1483TDate DateIncByDays (TDate date, int dDays);
1484int DateDiffByDays (TDate d1, TDate d0); // returns "d1" - "d0" in days
1485
1486TDate DateIncByMonths (TDate date, int dMon);
1487
1488static inline TDate DateFirstOfMonth (TDate date) { return (date & ~0x1f) + 1; }
1489
1490int GetWeekDay (TDate date); // range is 0..6 (Mon..Sun)
1491int GetCalWeek (TDate date);
1493
1494
1497const char *MonthName (int dm);
1498const char *MonthNameShort (int dm);
1499const char *DayName (int wd);
1500const char *DayNameShort (int wd);
1503
1504
1506
1507
1508
1509
1510
1511// *************************** Timer *******************************************
1512
1513
1546typedef void FTimerCallback (class CTimer *timer, void *data);
1550
1551
1554class CTimer {
1555 public:
1556 CTimer ();
1557 CTimer (FTimerCallback *_func, void *_data = NULL, void *_creator = NULL) { Set (_func, _data, _creator); }
1559 CTimer (TTicks _time, TTicks _interval = 0, FTimerCallback *_func = NULL, void *_data = NULL, void *_creator = NULL) { Set (_time, _interval, _func, _data, _creator); }
1561 virtual ~CTimer () { Clear (); }
1562
1563 void Set (FTimerCallback *_func, void *_data = NULL, void *_creator = NULL);
1565 void Set (TTicks _time, TTicks _interval = 0, FTimerCallback *_func = NULL, void *_data = NULL, void *_creator = NULL);
1576
1577 void Reschedule (TTicks _time, TTicks _interval = 0);
1579 void Clear ();
1580 static void DelByCreator (void *_creator);
1581 void *GetCreator () { return creator; }
1583 bool Pending () { return isLinked; }
1589
1590 // Timer callback...
1591 virtual void OnTime () { if (func) func (this, data); }
1594 protected:
1595 friend bool TimerIterate ();
1596 friend TTicks TimerGetDelay ();
1597 friend void TimerRun ();
1598 friend void *TimerThreadRoutine (void *);
1599
1600 static bool ClassIterateAL ();
1601 static TTicks GetDelayTimeAL ();
1602
1603 void InsertAL ();
1604 void UnlinkAL ();
1606 static CTimer *first; // for chained list
1607 CTimer *next; // for chained list
1608 bool isLinked; // indicates, whether element is in the linked list
1609
1610 TTicks nextTicks, interval;
1611 void *creator; // this object is managed externally, the caller has a reference to it and must remove it
1612
1613 FTimerCallback *func;
1614 void *data;
1615};
1616
1617
1618
1621bool TimerIterate ();
1625
1626void TimerStart ();
1629int TimerRun (bool catchSignals = true);
1634void TimerStop ();
1638
1639
1641
1642
1643
1644
1645
1646// ********************** Threading and Synchronization ************************
1647
1648
1656typedef void *FThreadRoutine (void *data);
1659
1660
1671class CThread {
1672 public:
1673 CThread () { running = false; }
1674 virtual ~CThread () { if (running) Join (); }
1675
1676 void Start (FThreadRoutine *_routine, void *_data = NULL);
1678 void Start ();
1679 void *Join ();
1680
1681 bool IsRunning () { return running; }
1682
1683 protected:
1684 friend void *CThreadRoutine (void *);
1685
1686 virtual void *Run () { return NULL; }
1687
1688 bool running;
1689 pthread_t thread;
1690};
1691
1692
1695class CMutex {
1696 public:
1697 CMutex ();
1698 ~CMutex ();
1700 void Lock ();
1701 bool TryLock ();
1702 void Unlock ();
1703
1704 protected:
1705 friend class CCond;
1706 pthread_mutex_t mutex;
1708
1712class CCond {
1713 public:
1715 ~CCond ();
1716
1717 void Wait (CMutex *mutex);
1720 TTicks Wait (CMutex *mutex, TTicks maxTime);
1735 void Signal ();
1736 void Broadcast ();
1737
1738 protected:
1739 pthread_cond_t cond;
1741
1742
1749class CSleeper {
1750 public:
1751 CSleeper ();
1752 ~CSleeper () { Done (); }
1753 void Done ();
1754
1757 void EnableCmds (int _cmdRecSize);
1761
1766 void Prepare ();
1768 void AddReadable (int fd);
1770 void AddWritable (int fd);
1773
1776 void Sleep (TTicks maxTime = -1);
1782
1785 bool IsReadable (int fd);
1786 bool IsWritable (int fd);
1787 bool GetCmd (void *retCmdRec);
1791
1794 void PutCmd (const void *cmdRec, TTicks t = 0, TTicks _interval = 0);
1800 void ClearTimedCmds () { CTimer::DelByCreator (this); }
1805 protected:
1806 fd_set fdSetRead, fdSetWrite;
1807 int maxFd, cmdRecSize;
1808 int selfPipe[2];
1809};
1810
1811
1812
1813void Sleep (TTicks mSecs);
1816
1817
1819
1820
1821
1823
1824
1825
1826// *************************** CShell and variants *****************************
1827
1837// ***** Abstract base class and functions *****
1838
1839
1844class CShell {
1845 public:
1846 CShell () { exitCode = -1; }
1847 virtual ~CShell () {}
1848
1851 virtual bool Start (const char *cmd, bool readStdErr = false) = 0;
1864 virtual bool StartRestricted (const char *name, const char *args = NULL);
1873 virtual bool IsRunning () { return !ReadClosed (); }
1875 virtual void Wait () = 0;
1877 virtual void Kill (int sig = SIGTERM) { WriteClose (); }
1881 int ExitCode () { return exitCode; }
1884
1887 int Run (const char *cmd, const char *input = NULL, CString *output = NULL);
1895
1898 virtual void CheckIO (bool *canWrite, bool *canRead, TTicks maxTime = -1) = 0;
1915 bool WaitUntilReadable (TTicks maxTime = -1) { bool canRead; CheckIO (NULL, &canRead, maxTime); return canRead; }
1921 bool WaitUntilWritable (TTicks maxTime = -1) { bool canWrite; CheckIO (&canWrite, NULL, maxTime); return canWrite; }
1927
1928 bool Writable () { return WaitUntilWritable (0); }
1930 virtual void WriteLine (const char *line) = 0;
1933 void WriteLine (CString *str) { WriteLine (str->Get ()); }
1935 virtual void WriteClose () = 0;
1937
1938 bool Readable () { return WaitUntilReadable (0); }
1940 virtual bool ReadLine (CString *str) = 0;
1943 virtual bool ReadClosed () = 0;
1946
1947 protected:
1948 int exitCode;
1950
1951
1952
1953
1954// ***** CShellBare *****
1955
1961class CShellBare: public CShell {
1962 public:
1963 CShellBare () { host = NULL; newProcessGroup = false; fdToScript = fdFromScript = childPid = -1; }
1964 virtual ~CShellBare () { Done (); }
1965 void Done ();
1969 virtual bool Start (const char *cmd, bool readStdErr = false);
1971 virtual bool IsRunning ();
1972 virtual void Wait ();
1973 virtual void Kill (int sig = SIGTERM);
1975
1978 virtual void CheckIO (bool *canWrite, bool *canRead, TTicks maxTime = -1);
1980
1981 virtual void WriteLine (const char *line);
1982 virtual void WriteClose ();
1983
1984 virtual bool ReadLine (CString *str);
1985 virtual bool ReadClosed () { return fdFromScript < 0 && !readBufMayContainLine; }
1987
1993
1995 int ReadFd () { return fdFromScript; }
1996 int WriteFd () { return fdToScript; }
1998
2001 void SetHost (const char *_host);
2003 const char *Host () { return host; }
2004 bool HasHost () { return !host.IsEmpty (); }
2006 void SetNewProcessGroup (bool on = true) { newProcessGroup = on; }
2008 bool StartSession (bool readStdErr = false) { return Start (NULL, readStdErr); }
2011
2012 protected:
2013 CString id, host;
2014 bool newProcessGroup;
2015 CString readBuf;
2016 bool readBufMayContainLine;
2017 int fdToScript, fdFromScript;
2018 int childPid, killSig;
2019
2020 bool DoWaitPid (int options);
2021};
2022
2025// ***** CShellSession *****
2026
2027
2034class CShellSession: public CShell {
2035 public:
2036 CShellSession () { writeOpen = readOpen = false; }
2037 virtual ~CShellSession () { Done (); }
2038 void Done ();
2039
2042 void SetHost (const char *_host) { session.SetHost (_host); }
2044 const char *Host () { return session.Host (); }
2045 bool HasHost () { return session.HasHost (); }
2047
2050 virtual bool Start (const char *cmd, bool readStdErr = false);
2051 virtual void Wait ();
2053
2056 virtual void CheckIO (bool *canWrite, bool *canRead, TTicks maxTime = -1);
2057
2058 virtual void WriteLine (const char *line) { session.WriteLine (line); }
2059 virtual void WriteClose ();
2060
2061 virtual bool ReadLine (CString *str);
2062 virtual bool ReadClosed () { return !readOpen; }
2063
2064 int ReadFd () { return session.ReadFd (); }
2065 int WriteFd () { return session.WriteFd (); }
2067
2068 protected:
2069 CShellBare session;
2070 bool writeOpen, readOpen;
2071};
2072
2073
2075
2076
2077
2080// *************************** Service managing ********************************
2081
2082
2091// ***** CServiceKeeper *****
2108class CServiceKeeper {
2109 public:
2110
2113 CServiceKeeper () { isOpen = shouldBeOpen = false; tDShort = tDLong = tShortToLong = 0; }
2114 CServiceKeeper (TTicks _tDShort, TTicks _tDLong = NEVER, TTicks _tShortToLong = NEVER)
2115 { isOpen = shouldBeOpen = false; Setup (_tDShort, _tDLong, _tShortToLong); }
2116 ~CServiceKeeper () { Close (); }
2117
2118 void Setup (TTicks _tDShort, TTicks _tDLong = NEVER, TTicks _tShortToLong = NEVER) { tDShort = _tDShort; tDLong = _tDLong; tShortToLong = _tShortToLong; }
2124
2127 void Open () { shouldBeOpen = true; Refresh (); }
2132 void Close () { shouldBeOpen = false; }
2140
2141 void Refresh ();
2143
2144 void Iterate ();
2147 bool IsOpen () { return isOpen; }
2149 bool ShouldBeOpen () { return shouldBeOpen; }
2152
2158 virtual void DoOpen () {}
2162 virtual void DoClose () {}
2167
2170 bool OpenAttemptNow ();
2173 bool CloseNow ();
2180 void ReportLost ();
2182 void ReportOpenAttempt (bool success);
2186 void ReportClosed () { isOpen = false; }
2191
2192 protected:
2193 bool isOpen, shouldBeOpen;
2194 TTicks tLastOpen; // last time the service was known to be open (only valid if 'isOpen == false' and 'shouldBeOpen == true')
2195 TTicks tNextAttempt; // time of next open attempt (only valid if 'isOpen == false' and 'shouldBeOpen == true')
2196 TTicks tDShort, tDLong, tShortToLong;
2197};
2199
2202
2203
2204
2205
2206// *************************** Doxygen Hooks **********************************
2207//
2208// Declare groups for the other modules in "common".
2209
2212
2215
2216
2217
2219
2220
2221#endif
Class to wrap (POSIX) condition variables.
Definition: base.H:1740
void Signal()
Wakeup ONE waiting thread.
void Wait(CMutex *mutex)
Wait until woken up. The supplied mutex must be locked and will be atomically unlocked while waiting.
void Broadcast()
Wakeup ALL waiting threads.
Compact dictionary.
Definition: base.H:1250
void Merge(CDictCompact< T > *dict2)
Merge another map into this one. Complexity is O(n_this + n_dict2). 'dict2' will be empty afterwards.
Definition: base.H:1270
void SetValue(int idx, T *value)
Set (replace) a value. The entry must exist and 'idx' be valid. Complexity is O(1).
Definition: base.H:1267
int Set(const char *key, T *value)
Add or replace the keyed entry. Complexity is O(n).
Definition: base.H:1264
Raw dictionary (base class for other dictionary variants).
Definition: base.H:1139
int Find(const char *key, int *retInsIdx=NULL)
Make binary search and return index of entry found or -1 if the key does not exist....
virtual void Dump(const char *name)
Dump contents by means of INFO logs (for debugging)
const char * GetKey(int idx) const
Get key by index.
Definition: base.H:1157
void PrefixSearch(const char *key, int *retIdx0, int *retIdx1)
Determine all elements with keys starting with key.
void Del(int idx)
Delete entry; complexity is O(n).
Definition: base.H:1145
Dictionary of references.
Definition: base.H:1294
Dictionary.
Definition: base.H:1195
int Set(const char *key, T *value)
Add or replace the keyed entry. Complexity is O(n).
Definition: base.H:1212
T * DisownValue(int idx)
Disown a value and clear it in the dictionary.
Definition: base.H:1221
void SetValue(int idx, T *value)
Set (replace) a value.
Definition: base.H:1215
void Merge(CDict< T > *dict2)
Merge another dictionary into this one. Complexity is O(n_this + n_dict2). 'dict2' will be empty afte...
Definition: base.H:1226
Set of strings (keys).
Definition: base.H:1306
virtual void Dump(const char *name)
Dump contents by means of INFO logs (for debugging)
void Merge(CKeySet *set2)
Merge another map into this one. Complexity is O(n_this + n_set2). 'set2' will be empty afterwards.
Definition: base.H:1318
Compact list.
Definition: base.H:1080
void Set(int idx, T *value)
Set (replace) a value. The entry must exist and 'idx' be valid. Complexity is O(1).
Definition: base.H:1094
void Append(T *value)
Append a new value. Complexity is O(1) if no resizing is necessary, else O(1).
Definition: base.H:1100
void Insert(int idx, T *value)
Insert a new value. Complexity is O(n).
Definition: base.H:1097
Raw list (base class for other list variants).
Definition: base.H:943
void Clear()
Clear the list.
Definition: base.H:956
virtual void Dump(const char *name)
Dump contents by means of INFO logs (for debugging)
int Entries() const
Get number of entries.
Definition: base.H:950
void Del(int idx)
Delete entry; complexity is O(n).
Reference list.
Definition: base.H:1120
Dynamic list.
Definition: base.H:1027
void Append(T *value)
Append a new value. Complexity is O(1) if no resizing is necessary, else O(1).
Definition: base.H:1048
T * Disown(int idx)
Disown a value and clear it in the array.
Definition: base.H:1051
void Set(int idx, T *value)
Set (replace) a value. The entry must exist and 'idx' be valid. Complexity is O(1).
Definition: base.H:1042
void Insert(int idx, T *value)
Insert a new value. Complexity is O(n).
Definition: base.H:1045
Class to wrap (POSIX) mutex objects.
Definition: base.H:1723
Factory class for regular expression matching.
Definition: base.H:866
bool SetPattern(const char *pattern, int cflags=REG_EXTENDED)
Set and compile a search pattern.
bool Match(const char *s, int eflags=0, size_t maxMatches=0, regmatch_t *retMatchList=NULL)
Perform a regular expression search.
Service keeper: Helper class to keep an unreliable service running.
Definition: base.H:2136
void Close()
Request the service to close.
Definition: base.H:2160
void ReportLost()
Report that the service is no longer running.
virtual void DoOpen()
Attempt to open the service in callback use. If this method is overloaded it must call ReportOpenAtte...
Definition: base.H:2186
void Setup(TTicks _tDShort, TTicks _tDLong=NEVER, TTicks _tShortToLong=NEVER)
Setup the retry policy.
Definition: base.H:2146
void ReportOpenAttempt(bool success)
Report an open attempt (either successful or not). This must be called from DoOpen() or after OpenAtt...
bool OpenAttemptNow()
Query if the connection should be (re-)opened now. After the attempt, ReportOpenAttempt() must be cal...
void Open()
Request the service to open.
Definition: base.H:2155
void Iterate()
Iterate (callback use); perform all open/close actions as adequate. Not needed for polling use.
bool IsOpen()
check if the service is actually open.
Definition: base.H:2175
bool CloseNow()
Query if the connection should be closed now. Closing must not fail.
bool ShouldBeOpen()
check if the service has been requested to be open.
Definition: base.H:2177
void Refresh()
Force retry on next Iterate() and return to short retry intervals.
virtual void DoClose()
Actually close the service. If this method is overloaded it must call ReportClosed() to report that t...
Definition: base.H:2190
void ReportClosed()
Report that the service was actually closed. This must be calld from DoClose() or after CloseNow() ha...
Definition: base.H:2214
Normal shell: Commands are executed individually.
Definition: base.H:1989
int ReadFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2023
virtual void Kill(int sig=SIGTERM)
(not tested in shell mode!)
virtual bool Start(const char *cmd, bool readStdErr=false)
Start new command, optionally on a remote host (see below).
virtual void Wait()
Wait until current command completes.
void SetNewProcessGroup(bool on=true)
Create a new process group and let this process become the leader (for daemon to support job control)...
Definition: base.H:2034
bool HasHost()
Return whether this is a remote shell (including remote SSH to 'localhost').
Definition: base.H:2032
virtual bool ReadClosed()
Close the read channel.
Definition: base.H:2013
void SetHost(const char *_host)
Set host to run subsequent commands on; 'NULL' represents the local host.
virtual bool IsRunning()
Still running?
bool StartSession(bool readStdErr=false)
Start a commmand shell session.
Definition: base.H:2036
int WriteFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2024
virtual void WriteClose()
Close the write channel.
virtual void WriteLine(const char *line)
Blocking write, execution is guaranteed. To avoid blocking, run Writable() or CheckI() first.
virtual void CheckIO(bool *canWrite, bool *canRead, TTicks maxTime=-1)
Use select() to check whether the i/o channels can take/deliver data.
virtual bool ReadLine(CString *str)
Non-Blocking read, returns 'true' on success. str can be NULL, in which case the line is ignored,...
Session shell: Multiple commands are executed through one shell.
Definition: base.H:2062
virtual void CheckIO(bool *canWrite, bool *canRead, TTicks maxTime=-1)
Check whether the i/o channels can take/deliver data.
virtual bool ReadLine(CString *str)
Non-Blocking read, returns 'true' on success. str can be NULL, in which case the line is ignored,...
virtual bool Start(const char *cmd, bool readStdErr=false)
Start command.
virtual void WriteClose()
Close the write channel.
virtual void WriteLine(const char *line)
Blocking write, execution is guaranteed. To avoid blocking, run Writable() or CheckI() first.
Definition: base.H:2086
void SetHost(const char *_host)
Define a remote host; must be called before first Start() call.
Definition: base.H:2070
int WriteFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2093
virtual void Wait()
Wait until current command completes.
virtual bool ReadClosed()
Close the read channel.
Definition: base.H:2090
int ReadFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2092
Abstract base class for shells that can execute system commands.
Definition: base.H:1872
bool Writable()
Poll for writability (non-blocking).
Definition: base.H:1956
virtual bool IsRunning()
Still running?
Definition: base.H:1901
int ExitCode()
Get the exit code of last command.
Definition: base.H:1909
virtual bool Start(const char *cmd, bool readStdErr=false)=0
Start command.
int Run(const char *cmd, const char *input=NULL, CString *output=NULL)
Run command 'cmd' synchronously and return its exit code.
virtual void WriteLine(const char *line)=0
Blocking write, execution is guaranteed. To avoid blocking, run Writable() or CheckI() first.
virtual void Wait()=0
Wait until current command completes.
virtual bool StartRestricted(const char *name, const char *args=NULL)
Same as 'Start', but fetch the command from the environment.
virtual void Kill(int sig=SIGTERM)
Kill the current command nicely. This may not work for all types of shells. A Wait() invocation is re...
Definition: base.H:1905
bool Readable()
Poll for readability.
Definition: base.H:1966
bool WaitUntilReadable(TTicks maxTime=-1)
Wait until output of the external command is readable. Be aware of potential deadlocks....
Definition: base.H:1943
virtual bool ReadClosed()=0
Close the read channel.
bool WaitUntilWritable(TTicks maxTime=-1)
Wait until the external command can accept written input. Be aware of potential deadlocks....
Definition: base.H:1949
virtual void WriteClose()=0
Close the write channel.
virtual bool ReadLine(CString *str)=0
Non-Blocking read, returns 'true' on success. str can be NULL, in which case the line is ignored,...
virtual void CheckIO(bool *canWrite, bool *canRead, TTicks maxTime=-1)=0
Check whether the i/o channels can take/deliver data.
Class allowing to sleep until one out of multiple i/o operations becomes possible.
Definition: base.H:1777
void Prepare()
Prepare for sleeping, clear all file descriptors.
void AddWritable(int fd)
Add file descriptor fd to monitor for writability, descriptors < 0 are silently ignored.
void EnableCmds(int _cmdRecSize)
Enable sending commands by PutCmd(). To be called immediately after initialization and only if the co...
bool IsWritable(int fd)
Check if file descriptor is writable (flags are only updated in Sleep() ).
void AddReadable(int fd)
Add file descriptor fd to monitor for readability, descriptors < 0 are silently ignored.
void Sleep(TTicks maxTime=-1)
Sleep until one file descriptor is readable/writable or a new command was received.
bool GetCmd(void *retCmdRec)
Get and consume next command (non-blocking).
void PutCmd(const void *cmdRec, TTicks t=0, TTicks _interval=0)
Send message to sleeper.
void ClearTimedCmds()
Clear any scheduled commands which have not yet been put into the queue. Note: Respective commands ma...
Definition: base.H:1828
bool IsReadable(int fd)
Check if file descriptor is readable (flags are only updated in Sleep() ).
Factory class to split a string into substrings.
Definition: base.H:819
int GetOffset(int argNo)
Get offset of argument number arg in the original string.
Definition: base.H:843
const char * Get(int idx) const
Get one string.
Definition: base.H:840
void Set(const char *str, int maxArgc=INT_MAX, const char *sepChars=NULL)
Set and split a string.
Definition: base.H:829
int Entries() const
Get number of string after splitting.
Definition: base.H:839
const char * operator[](int n) const
Get one string.
Definition: base.H:841
int GetIdx(int pos)
Get the argument number of character number pos of the original string. On error, -1 is returned,...
void Clear()
Clear the object (only necessary if another string is to be split)
Dynamically allocated string.
Definition: base.H:635
bool SetAsIso8859(const char *str)
'this' will be ISO-8859-encoded string, the source is expected to be (normal) UTF-8
bool ReadFile(const char *relOrAbsPath)
Read a complete text file into a string. The path may be absolute or relative to HOME2L_ROOT.
static const char *const emptyStr
Use this whenever you need an empty string ("")
Definition: base.H:676
char * Disown()
Return current string as a dynamic object and clear 'this'.
void SetFromIso8859(const char *iso8859str)
'this' will be a (normal) UTF-8 string, the source is expected to be ISO-8859
void AppendEscaped(const char *s, const char *dontEscape=NULL)
Same as 'Set...', but appending the result to the current srtring.
void SetFByLine(const char *fmt, const char *text)
Split 'text' into lines and reassembles the text by processing each line through sprintf and 'fmt'....
Definition: base.H:720
bool ReadLine(CString *ret)
Consume and optionally return the first line from 'this'. On success, 'true' is returned....
void SetEscaped(const char *s, const char *dontEscape=NULL)
Set and escape all non-alphanumerical characters by "\...".
Definition: base.H:726
void SetFV(const char *fmt, va_list ap)
Set using vprintf() formatting.
void SetF(const char *fmt,...)
Set using printf() formatting.
bool SetUnescaped(const char *s)
Set and revers escapes. On error, 'false' is returned and the string remains unchanged....
Definition: base.H:742
void SetO(const char *_ptr)
Set content and take ownership of '_ptr'. '_ptr' must have been dynamically allocated,...
bool AppendUnescaped(const char *s)
Same as 'Set...', but appending the result to the current srtring.
int Len()
Get the length.
Definition: base.H:688
char * Get() const
Get the C string. Unless explicitely set by 'SetC', this will never return NULL or an invalid pointer...
Definition: base.H:687
void AppendFByLine(const char *fmt, const char *text)
Same as SetFByLine(), but appending the result to the current srtring.
void SetC(const char *_ptr)
Set without copying or taking ownership of '_ptr' (but "copy-on-write" semantics)....
bool AppendFromFile(int fd, const char *name=NULL)
Read as much as possible from 'fd' and append to buffer. If an end-of-file is encountered,...
bool IsEmpty()
Check, if empty.
Definition: base.H:689
Class to wrap (POSIX) threads.
Definition: base.H:1699
virtual void * Run()
Main thread routine (to be overloaded)
Definition: base.H:1714
void Start()
Run the virtual method Run() in the background.
void * Join()
Join with the background thread.
bool IsRunning()
(only for main thread)
Definition: base.H:1709
Timer class.
Definition: base.H:1582
void Clear()
Remove timer from the event list.
static void DelByCreator(void *_creator)
Remove all timers created by _creator from the event list.
void Reschedule(TTicks _time, TTicks _interval=0)
Change a timer (like 'Set'), but leave function and creator unchanged.
virtual void OnTime()
[T:timer] Virtual function called when the timer triggers.
Definition: base.H:1619
friend TTicks TimerGetDelay()
Returns number of milliseconds until next call to TimerIterate() is necessary, or -1 if no timer is p...
void Set(FTimerCallback *_func, void *_data=NULL, void *_creator=NULL)
Setup timer without (re-)scheduling it.
friend bool TimerIterate()
Returns false if nothing was done.
bool Pending()
Indicate whether the timer is pending and may be executed in the future.
Definition: base.H:1611
size_t Read(int fd, void *buf, size_t count)
Similar to POSIX read(), but reads all 'count' bytes as possible.
bool ReadDir(const char *relOrAbsPath, class CKeySet *ret)
Read a directory into a CKeySet object.
bool UnlinkTree(const char *relOrAbsPath, const char *skipPattern=NULL)
Unlink (remove) a directory with all its decendants.
size_t Write(int fd, const void *buf, size_t count)
Similar to POSIX write(), but writes all 'count' bytes as possible.
bool MakeDir(const char *relOrAbsPath, bool setHome2lGroup=true)
Create a directory (and all its parents as necessary).
const char * MonthName(int dm)
Get textual name. 1 = "January", ..., 12 = "December".
bool TicksFromString(const char *str, TTicks *ret, bool absolute)
Convert a string to a relative or absolute ticks value.
const char * DayName(int wd)
Get textual name. 0 = "Monday", ..., 6 = "Sunday".
static bool TicksAbsFromString(const char *str, TTicks *ret)
Convert a string to an absolute ticks value. See TicksFromString() for supported string formats.
Definition: base.H:1443
static void DateTimeNow(TDate *d, TTime *t)
Retrieve current date and time (both pointers may be NULL)
Definition: base.H:1502
TTicks TicksAbsFromMonotic(TTicks tm)
Get the approximated absolute (real) time for a monotonic time. Arguments <= 0 are returned unmodifie...
int64_t TTicks
Time value (relative, absolute, or monotonic).
Definition: base.H:1378
static bool TicksRelFromString(const char *str, TTicks *ret)
Convert a string to a relative ticks value. See TicksFromString() for supported string formats.
Definition: base.H:1445
TTicks TicksNowMonotonic()
Get the current monotonic time in milliseconds. This function never returns 0 or a negative value.
const char * TicksRelToString(CString *ret, TTicks ticks)
Get a string of the form "<integer>[<unit>]" for a relative time.
const char * TicksAbsToString(CString *ret, TTicks ticks, int fracDigits=INT_MAX, bool precise=false)
Get a string of the form "YYYY-MM-DD-hhmmss[.<millis>]" in local time.
#define NEVER
Special value that may represent "never" for absolute or monotonic times. Other application-specific ...
Definition: base.H:1383
TTicks TicksMonotonicFromAbs(TTicks ta)
Get the approximated monotonic time for an absolute time . Arguments <= 0 are returned unmodified.
const char * DayNameShort(int wd)
Get textual name. 0 = "Mon", ..., 6 = "Sun".
const char * MonthNameShort(int dm)
Get textual shortname. 1 = "Jan", ..., 12 = "Dec".
TTicks TicksNow()
Get the current absolute time in milliseconds. This function never returns 0 or a negative value.
void LangTranslateNumber(char *str)
Adapt numeric string by replacing all '.' by the locale's decimal point.
void FLogCbMessage(const char *title, const char *msg)
Callback to display a message box using OS mechanisms. This is mainly used if the program is aborted ...
Definition: base.H:183
int envDebug
Debug level (read-only; may also be mapped to a constant macro).
void LogToSyslog(const char *instanceName=NULL)
Redirect logging to syslog from now; instance name must be passed if this is called before EnvInit()
void FLogCbToast(const char *msg, bool showLonger)
Callback to display a short info popup using OS mechanisms. This is used if for messages printed usin...
Definition: base.H:187
void LogStack()
Log a stack trace (requires linker flag '-rdynamic' to print function names)
bool UnsignedFromString(const char *str, unsigned *ret, int radix=0)
Convert a string to an unsigned integer using 'strtoul'. On success, '*ret' is set accordingly and 't...
int ValidIntFromString(const char *str, int defaultVal, int radix=0)
Convert a string to an integer. On failure, 'defaultVal' is returned.
unsigned ValidUnsignedFromString(const char *str, unsigned defaultVal, int radix=0)
Convert a string to an unsigned integer. On failure, 'defaultVal' is returned.
void StringTruncate(char *str, const char *sepChars=WHITESPACE, bool after=false)
Cut away anything from or after the first occurence of any of the given seperator characters.
const char * GetAbsPath(class CString *ret, const char *relOrAbsPath, const char *defaultPath)
Get absolute path.
const char * ToUtf8(class CString *ret, const char *iso8859str)
Transcode an ISO8859-coded string to UTF-8. Result is valid until next call of this function.
void StringSplit(const char *str, int *retArgc, char ***retArgv, int maxArgc=INT_MAX, const char *sepChars=NULL, char **retRef=NULL)
Split a string into (whitespace-)separated arguments.
float ValidFloatFromString(const char *str, float defaultVal)
Convert a string to a float value. On failure, 'defaultVal' is returned.
bool BoolFromString(const char *str, bool *ret)
Convert a string to a Boolean value. On success, '*ret' is set accordingly and 'true' is returned....
void PathNormalize(char *str)
Treat string as a (full) pathname and normalize it.
void PathRemoveTrailingSlashes(char *str)
Treat string as a (full) pathname and remove trailing slash(es)
bool ValidBoolFromString(const char *str, bool defaultVal)
Convert a string to a Boolean value. On failure, 'defaultVal' is returned.
void StringSplitFree(char ***argv)
Free memory allocated by StringSplit().
const char * ToIso8859(class CString *ret, const char *str)
Transcode an ISO8859-coded string to UTF-8. Result is valid until next call of this function.
bool FloatFromString(const char *str, float *ret)
Convert a string to a floating-point value using 'strtof'. On success, '*ret' is set accordingly and ...
const char * StringF(class CString *ret, const char *fmt,...)
Return 'ret->Get ()'.
class CString * GetThreadTempString()
Get the thread-local temporary string (TTS) of the calling thread.
#define WHITESPACE
white space characters according to 'man 3 isspace'
Definition: base.H:509
bool CharIsWhiteSpace(char c)
Indicate whether the given character is white space (see WHITSPACE).
void StringStrip(char *str, const char *sepChars=WHITESPACE)
Remove seperator (whitespace) characters at the beginning and end of the string.
bool IntFromString(const char *str, int *ret, int radix=0)
Convert a string to an integer using 'strtol'. On success, '*ret' is set accordingly and 'true' is re...
const char * PathLeaf(const char *str)
Get leaf component of a path.
void * FThreadRoutine(void *data)
Function type for thread routines.
Definition: base.H:1684
void Sleep(TTicks mSecs)
Suspend for mSecs milliseconds using nanosleep().
int TimerRun(bool catchSignals=true)
Perform an endless loop calling timers until TimerStop() is called.
TTicks TimerGetDelay()
Returns number of milliseconds until next call to TimerIterate() is necessary, or -1 if no timer is p...
void TimerStart()
Start TimerRun() in a background thread, which is to be stopped using TimerStop()....
bool TimerIterate()
Returns false if nothing was done.
void FTimerCallback(class CTimer *timer, void *data)
Function type for timer callbacks.
Definition: base.H:1574
void TimerStop()
Request TimerRun() to return at next occasion (can be called from any thread). If a dedicated timer t...
static const char * VersionGetOwnAsStr()
Get my own build version as a string.
Definition: base.H:402
static bool VersionDirty(uint32_t ver)
Get the "dirty" component of the version.
Definition: base.H:391
static uint32_t VersionCompose(uint8_t major, uint8_t minor, uint16_t revision, bool dirty=false)
Definition: base.H:377
static int VersionMinor(uint32_t ver)
Get the minor component of the version.
Definition: base.H:387
static int VersionRevision(uint32_t ver)
Get the revision component of the version.
Definition: base.H:389
uint32_t VersionFromStr(const char *str)
Get a numeric representation of the version string. On syntax error, a warning is logged and 0 is ret...
const char * VersionToStr(class CString *ret, uint32_t ver)
Get a string representation of the version. This may be shorter than an eventual original string pass...
uint32_t VersionGetOwn()
Get my own build version.
static int VersionMajor(uint32_t ver)
Get the major component of the version.
Definition: base.H:385