Home2L - C/C++ API  v1.2-2-ga4fe (2023-04-15)
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-2021 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
79 
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 
101 size_t Write (int fd, const void *buf, size_t count);
110 
111 size_t Read (int fd, void *buf, size_t count);
121 
122 bool MakeDir (const char *relOrAbsPath, bool setHome2lGroup = true);
131 
132 bool UnlinkTree (const char *relOrAbsPath, const char *skipPattern = NULL);
143 
144 bool 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
173 extern int envDebug;
174 #else
175 #define envDebug 0
176 #endif
177 
178 
179 typedef void FLogCbMessage (const char *title, const char *msg);
183 typedef void FLogCbToast (const char *msg, bool showLonger);
188 
189 
190 #if !ANDROID
191 void LogToSyslog (const char *instanceName = NULL);
192 void LogClose ();
193 bool LoggingToSyslog ();
194 void LogStack ();
195 static inline void LogSetCbMessage (FLogCbMessage *_cbMessage) {}
196 static inline void LogSetCallbacks (FLogCbMessage *_cbMessage, FLogCbToast *_cbToast) {}
197 #else
198 static inline void LogToSyslog () {}
199 static inline void LogClose () {}
200 static inline bool LoggingToSyslog () { return true; }
201 static inline void LogStack () {}
202 void LogSetCallbacks (FLogCbMessage *_cbMessage, FLogCbToast *_cbToast);
203 #endif
204 
205 void LogPara (const char *_logHead, const char* _logFile, int _logLine); // Helper only; use the following macros instead
206 void 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 
271 
272 
273 // ***** Compile-time assertion *****
274 
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
284 
285 
287 
288 
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 
332 
333 
334 
335 // *************************** Version Helpers *********************************
336 
337 
349 static 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 }
357 static inline int VersionMajor (uint32_t ver) { return (int) (ver >> 24); }
359 static inline int VersionMinor (uint32_t ver) { return (int) ((ver >> 16) & 0xff); }
361 static inline int VersionRevision (uint32_t ver) { return (int) ((ver >> 1) & 0x7fff); }
363 static inline bool VersionDirty (uint32_t ver) { return (ver & 1) == 1; }
365 
366 uint32_t VersionFromStr (const char *str);
369 const char *VersionToStr (class CString *ret, uint32_t ver);
373 
374 static inline const char *VersionGetOwnAsStr () { return buildVersion; }
376 uint32_t VersionGetOwn ();
378 
379 
381 
382 
383 
384 
385 
386 // ********************** Localization and language ****************************
387 
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 
414 const char *LangGetText (const char *msgId);
415 
416 #define gettext(STR) LangGetText (STR)
417 
418 #endif
419 
420 
421 // Init/done...
422 void 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'
427 void 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...
437 void 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 
487 class CString *GetThreadTempString ();
501 
502 #define TTS (GetThreadTempString ())
504 
505 const char *StringF (class CString *ret, const char *fmt, ...);
507 
508 bool BoolFromString (const char *str, bool *ret);
512 bool ValidBoolFromString (const char *str, bool defaultVal);
514 bool IntFromString (const char *str, int *ret, int radix = 0);
518 int ValidIntFromString (const char *str, int defaultVal, int radix = 0);
520 bool UnsignedFromString (const char *str, unsigned *ret, int radix = 0);
524 unsigned ValidUnsignedFromString (const char *str, unsigned defaultVal, int radix = 0);
526 bool FloatFromString (const char *str, float *ret);
530 float ValidFloatFromString (const char *str, float defaultVal);
532 
533 void StringStrip (char *str, const char *sepChars = WHITESPACE);
535 void StringTruncate (char *str, const char *sepChars = WHITESPACE, bool after = false);
537 void StringSplit (const char *str, int *retArgc, char ***retArgv, int maxArgc = INT_MAX, const char *sepChars = NULL, char **retRef = NULL);
558 void StringSplitFree (char ***argv);
561 
562 bool CharIsWhiteSpace (char c);
564 
565 
568 void PathNormalize (char *str);
569 void PathRemoveTrailingSlashes (char *str);
570 const char *PathLeaf (const char *str);
571 
572 const char *GetAbsPath (class CString *ret, const char *relOrAbsPath, const char *defaultPath);
583 
584 
587 const char *ToUtf8 (class CString *ret, const char *iso8859str);
590 const char *ToIso8859 (class CString *ret, const char *str);
594 
595 
596 
597 // ***** CString *****
598 
599 
607 class 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;
650 
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); }
689 
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); }
720 
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 
791 class 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); }
808 
809  int Entries () const { return argc; }
810  const char *Get (int idx) const { return argv[idx]; }
811  const char *operator [] (int n) const { return Get (n); }
812 
813  int GetOffset (int argNo) { return (argv && ref) ? argv[argNo] - ref : 0; }
815  int GetOffset (const char *p) { return ref ? (p - ref) : 0; }
817  int GetIdx (int pos);
821 
822  protected:
823  int argc;
824  char **argv, *ref;
825 };
826 
827 
828 
829 // ***** Regexp *****
830 
831 
836 class CRegex {
837  public:
838  CRegex () { reValid = false; lastError = 0; }
839  ~CRegex () { if (reValid) regfree (&re); }
840 
841  bool SetPattern (const char *pattern, int cflags = REG_EXTENDED);
850  bool Match (const char *s, int eflags = 0, size_t maxMatches = 0, regmatch_t *retMatchList = NULL);
860 
862  bool IsValid () { return reValid; }
863  const char *ErrorStr ();
864 
865  private:
866  CString errorStr;
867  bool reValid;
868  int lastError;
869  regex_t re;
870 };
871 
872 
874 
875 
876 
877 
878 
879 // ********************** Container Classes ************************************
880 
881 
889 #define CONT_ALIGNMENT 4
890 #define CONT_ALIGN(X) (((X) + CONT_ALIGNMENT - 1) & ~(CONT_ALIGNMENT - 1))
891 
892 
893 
894 // ***** Stringification of container values ****
895 
896 
897 // Template for all classes, which must have a 'ToStr()' method ...
898 template <typename T> const char *ToStr (CString *ret, T *obj) { return obj->ToStr (ret); }
899 
900 // Specializations for non-class types (more specializations may be added here as required) ...
901 template <> const char *ToStr<int> (CString *ret, int *obj);
902 
903 
904 
905 // ***** CList... *****
906 
907 
913 class CListRaw {
914  public:
915  CListRaw (int _recSize);
916  virtual ~CListRaw () { Clear (); }
917 
920  int Entries () const { return entries; }
923 
926  void Clear () { SetEntries (0); }
928  void Del (int idx);
931 
934  virtual void Dump (const char *name);
936 
937  protected:
938 
939  // Methods to be overloaded by derived classes ...
940  virtual void RecInit (void *p);
941  // Initialize record in previously uninitialized memory.
942  // This method is also used to wipe entries that have been copied and are no longer owned.
943  virtual void RecClear (void *p);
944  // Clear (initialized) record such that no destructor call is necessary anymore.
945 
946  virtual void ValueInit (void *p) {}
947  // Initialize value data in previously uninitialized memory
948  virtual void ValueClear (void *p) {}
949  // Clear (initialized) record such that no destructor call is necessary anymore
950  virtual void ValueSet (void *p, void *orig) {}
951  // Copy or move 'orig' to 'p' properly. Both are initialized objects.
952  // The derived class must specify whether 'orig' is copied or moved (= disowned) by this
953  // and document the behavior for
954  virtual const char *ValueToStr (CString *ret, void *p);
955  // return readable string for the 'Dump' method
956 
957  // Helpers for derived classes ...
958  void SetEntries (int _entries);
959 
960  uint8_t *GetRecAdr (int idx) const { return idx < 0 ? NULL : data + recSize * idx; }
961  // Get memory address of whole record (including eventual tag)
962  uint8_t *GetValueAdr (int idx) const { return idx < 0 ? NULL : data + recSize * idx + tagSize; }
963  // Get memory address of the value part of the record (for '...Compact' classes)
964  void *GetValuePtr (int idx) const { return idx < 0 ? NULL : * (void **) (GetValueAdr (idx)); }
965  // (for non-compact classes) Take the value part inside the record as a pointer to the real value and dereference it
966 
967  void Copy (int idxDst, int idxSrc); // byte-copy entry
968  void Swap (void *rec0, void *rec1); // byte-swap two entries (potentially from different objects)
969 
970  void SetRaw (int idx, void *value);
971  // Set a new entry. The entry must exist and 'idx' be valid.
972  // 'value' may either be copied or moved, see comment to 'ValueSet()'.
973  void InsertRaw (int idx, void *value);
974  // Insert a new entry in position 'idx'.
975  // 'value' may either be copied or moved, see comment to 'ValueSet()'.
976  void *DisownRaw (int idx);
977  // (for non-compact classes) Take the value part inside the record as a pointer to the real value,
978  // return it and set it to NULL in the record.
979 
980  // Data ...
981  uint8_t *data;
982  int recSize, tagSize, entries, allocEntries;
983  // 'tagSize' is an offset inside a record. It can be used by derived classes,
984  // e.g. by 'CDictRaw' to reserve space for keys.
985 };
986 
987 
997 template <typename T> class CList: public CListRaw {
998  public:
999  CList (): CListRaw (sizeof (T *)) {}
1000 
1003  T *Get (int idx) { return (T *) GetValuePtr (idx); }
1004  T *operator [] (int idx) { return Get (idx); }
1006 
1012  void Set (int idx, T *value) { SetRaw (idx, value); }
1015  void Insert (int idx, T *value) { InsertRaw (idx, value); }
1018  void Append (T *value) { InsertRaw (INT_MAX, value); }
1021  T *Disown (int idx) { return (T *) DisownRaw (idx); }
1024 
1025  protected:
1026  virtual void ValueInit (void *p) { * (T **) p = NULL; }
1027  virtual void ValueClear (void *p) { if (* (T**) p) { delete * (T **) p; * (T **) p = NULL; } }
1028  virtual void ValueSet (void *p, void *orig) { ValueClear (p); * (T**) p = (T*) orig; }
1029  virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, * (T**) p); }
1030 };
1031 
1032 
1050 template <typename T> class CListCompact: public CListRaw {
1051  public:
1052  CListCompact (): CListRaw (sizeof (T)) {}
1053  virtual ~CListCompact () { Clear (); }
1054 
1057  T *Get (int idx) { return (T *) GetValueAdr (idx); }
1058  T *operator [] (int idx) { return Get (idx); }
1060 
1064  void Set (int idx, T *value) { SetRaw (idx, value); }
1067  void Insert (int idx, T *value) { InsertRaw (idx, value); }
1070  void Append (T *value) { InsertRaw (INT_MAX, value); }
1074 
1075  protected:
1076  virtual void ValueInit (void *p) { memcpy (p, &emptyObj, sizeof (emptyObj)); }
1077  virtual void ValueClear (void *p) { ValueSet (p, &emptyObj); }
1078  virtual void ValueSet (void *p, void *orig) { * (T *) p = * (T *) orig; }
1079  virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, (T*) p); }
1080 
1081  T emptyObj; // Template for an initialized object
1082 };
1083 
1084 
1090 template <typename T> class CListRef: public CList<T> {
1091  protected:
1092  virtual void ValueClear (void *p) { * (T **) p = NULL; }
1093  virtual void ValueSet (void *p, void *orig) { * (T**) p = (T*) orig; }
1094 };
1096 
1097 
1098 // ***** CDict... *****
1099 
1100 
1101 #define DICT_KEYSIZE CONT_ALIGN((int) sizeof (CString))
1102 
1103 
1109 class CDictRaw: public CListRaw {
1110  public:
1111  CDictRaw (int _valueSize): CListRaw (_valueSize + DICT_KEYSIZE) { tagSize = DICT_KEYSIZE; }
1112 
1115  void Del (int idx) { CListRaw::Del (idx); }
1121  void Del (const char *key) { Del (Find (key)); }
1124 
1127  const char *GetKey (int idx) const { return ((CString *) GetRecAdr (idx))->Get (); }
1129  int Find (const char *key, int *retInsIdx = NULL);
1132  void PrefixSearch (const char *key, int *retIdx0, int *retIdx1);
1138 
1141  virtual void Dump (const char *name);
1144  protected:
1145  virtual void RecInit (void *p);
1146  virtual void RecClear (void *p);
1147 
1148  void SetRaw (int idx, void *value) { CListRaw::SetRaw (idx, value); }
1149  int SetRaw (const char *key, void *value); // add or replace the keyed entry; returns new index
1150 
1151  void MergeRaw (CDictRaw *dict2); // merge 'dict2' into this one and clear 'dict2'
1152 };
1153 
1154 
1165 template <typename T> class CDict: public CDictRaw {
1166  public:
1167  CDict (): CDictRaw (sizeof (T *)) {}
1168 
1171  T *Get (int idx) { return (T *) GetValuePtr (idx); }
1172  T *Get (const char *key) { return Get (Find (key)); }
1173  T *operator [] (int idx) { return Get (idx); }
1174  T *operator [] (const char *key) { return Get (key); }
1176 
1182  int Set (const char *key, T *value) { return SetRaw (key, value); }
1185  void SetValue (int idx, T *value) { SetRaw (idx, value); }
1191  T *DisownValue (int idx) { return (T *) DisownRaw (idx); }
1193  T *DisownValue (const char *key) { return (T *) DisownRaw (Find (key)); }
1195 
1196  void Merge (CDict<T> *dict2) { MergeRaw (dict2); }
1204 
1205  protected:
1206  virtual void ValueInit (void *p) { * (T **) p = NULL; }
1207  virtual void ValueClear (void *p) { if (* (T**) p) { delete * (T **) p; * (T **) p = NULL; } }
1208  virtual void ValueSet (void *p, void *orig) { ValueClear (p); * (T**) p = (T*) orig; }
1209  virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, * (T**) p); }
1210 };
1211 
1212 
1220 template <typename T> class CDictCompact: public CDictRaw {
1221  public:
1222  CDictCompact (): CDictRaw (sizeof (T)) {}
1223 
1226  T *Get (int idx) { return (T *) GetValueAdr (idx); }
1227  T *Get (const char *key) { return Get (Find (key)); }
1228  T *operator [] (int idx) { return Get (idx); }
1229  T *operator [] (const char *key) { return Get (key); }
1231 
1234  int Set (const char *key, T *value) { return SetRaw (key, value); }
1237  void SetValue (int idx, T *value) { SetRaw (idx, value); }
1240  void Merge (CDictCompact<T> *dict2) { MergeRaw (dict2); }
1249  protected:
1250  virtual void ValueInit (void *p) { memcpy (p, (void *) &emptyObj, sizeof (emptyObj)); }
1251  virtual void ValueClear (void *p) { ValueSet (p, (void *) &emptyObj); }
1252  virtual void ValueSet (void *p, void *orig) { * (T *) p = * (T *) orig; }
1253  virtual const char *ValueToStr (CString *ret, void *p) { return ::ToStr<T> (ret, (T*) p); }
1254 
1255  T emptyObj; // Template for an initialized object
1256 };
1257 
1258 
1264 template <typename T> class CDictRef: public CDict<T> {
1265  protected:
1266  virtual void ValueClear (void *p) { * (T **) p = NULL; }
1267  virtual void ValueSet (void *p, void *orig) { * (T**) p = (T*) orig; }
1268 };
1269 
1270 
1271 
1272 // ***** CKeySet *****
1273 
1276 class CKeySet: public CDictRaw {
1277  public:
1278  CKeySet (): CDictRaw (0) {}
1279 
1282  const char *operator [] (int idx) { return GetKey (idx); }
1284 
1287  int Set (const char *key) { return SetRaw (key, NULL); }
1288  void Merge (CKeySet *set2) { MergeRaw (set2); }
1296 
1299  virtual void Dump (const char *name);
1301 };
1302 
1303 
1305 
1306 
1307 
1308 
1309 
1310 // *************************** Date & Time *************************************
1311 
1312 
1347 
1348 typedef int64_t TTicks;
1350 
1351 #define ASAP ((TTicks) 0)
1353 #define NEVER ((TTicks) INT64_MIN)
1357 
1358 
1359 TTicks TicksNow ();
1365 
1372 
1373 const char *TicksAbsToString (CString *ret, TTicks ticks, int fracDigits = INT_MAX, bool precise = false);
1382 const char *TicksRelToString (CString *ret, TTicks ticks);
1391 
1392 bool TicksFromString (const char *str, TTicks *ret, bool absolute);
1413 static inline bool TicksAbsFromString (const char *str, TTicks *ret) { return TicksFromString (str, ret, true); }
1415 static inline bool TicksRelFromString (const char *str, TTicks *ret) { return TicksFromString (str, ret, false); }
1417 
1418 void TicksToStructTimeval (TTicks t, struct timeval *retTv);
1419 
1420 #define TICKS_FROM_SECONDS(S) (((TTicks) (S)) * 1000)
1421 #define SECONDS_FROM_TICKS(T) (((TTicks) (T) + 500) / 1000)
1422 #define TICKS_FROM_MILLIS(MS) ((TTicks) (MS))
1423 #define MILLIS_FROM_TICKS(T) ((int) (T))
1424 
1426 
1427 
1430 
1431 typedef int TDate; // Date encoded as bit fields
1432 
1433 #define DATE_OF(Y,M,D) ((TDate) (((Y) << 9) | ((M) << 5) | (D)))
1434 #define YEAR_OF(DT) ((int) (DT) >> 9)
1435 #define MONTH_OF(DT) (((int) (DT) >> 5) & 0xf) // range is 1..12 (different from 'struct tm' in <time.h>)
1436 #define DAY_OF(DT) ((int) (DT) & 0x1f) // range is 1..31
1437 
1438 
1439 typedef int TTime; // Time in seconds since midnight
1440 
1441 #define TIME_OF(H,M,S) ((TTime) ((H) * 3600 + (M) * 60 + (S)))
1442 #define HOURS_OF(T) ((int) (T) / 3600)
1443 #define MINUTES_OF(T) ((int) (T) / 60)
1444 #define HOUR_OF(T) HOURS_OF(T)
1445 #define MINUTE_OF(T) (MINUTES_OF(T) % 60)
1446 #define SECOND_OF(T) ((int) (T) % 60)
1447 
1453 TTicks TicksOfDate (int dy, int dm, int dd); // range of 'dm' is 1..12
1454 TTicks TicksOfDate (TDate d);
1455 TTicks TicksOfTime (int th, int tm, int ts);
1456 TTicks TicksOfTime (TTime t);
1457 
1458 TDate DateOfTicks (TTicks t);
1459 TTime TimeOfTicks (TTicks t);
1460 
1461 TTicks DateTimeToTicks (TDate d, TTime t, struct tm *retTm = NULL);
1462 #if !ANDROID
1463 TTicks DateTimeToTicksUTC (TDate d, TTime t, struct tm *retTm = NULL);
1464 #endif
1465 void TicksToDateTime (TTicks t, TDate *retDate, TTime *retTime, struct tm *retTm = NULL);
1466 void TicksToDateTimeUTC (TTicks t, TDate *retDate, TTime *retTime, struct tm *retTm = NULL);
1468 
1469 
1472 static inline void DateTimeNow (TDate *d, TTime *t) { TicksToDateTime (TicksNow (), d, t, NULL); }
1474 TDate Today ();
1475 TTicks TicksToday ();
1477 
1478 
1481 TDate DateIncByDays (TDate date, int dDays);
1482 int DateDiffByDays (TDate d1, TDate d0); // returns "d1" - "d0" in days
1483 
1484 TDate DateIncByMonths (TDate date, int dMon);
1485 
1486 static inline TDate DateFirstOfMonth (TDate date) { return (date & ~0x1f) + 1; }
1487 
1488 int GetWeekDay (TDate date); // range is 0..6 (Mon..Sun)
1489 int GetCalWeek (TDate date);
1491 
1492 
1495 const char *MonthName (int dm);
1496 const char *MonthNameShort (int dm);
1497 const char *DayName (int wd);
1498 const char *DayNameShort (int wd);
1501 
1502 
1504 
1505 
1506 
1507 
1508 
1509 // *************************** Timer *******************************************
1510 
1511 
1544 typedef void FTimerCallback (class CTimer *timer, void *data);
1548 
1549 
1552 class CTimer {
1553  public:
1554  CTimer ();
1555  CTimer (FTimerCallback *_func, void *_data = NULL, void *_creator = NULL) { Set (_func, _data, _creator); }
1557  CTimer (TTicks _time, TTicks _interval = 0, FTimerCallback *_func = NULL, void *_data = NULL, void *_creator = NULL) { Set (_time, _interval, _func, _data, _creator); }
1559  virtual ~CTimer () { Clear (); }
1560 
1561  void Set (FTimerCallback *_func, void *_data = NULL, void *_creator = NULL);
1563  void Set (TTicks _time, TTicks _interval = 0, FTimerCallback *_func = NULL, void *_data = NULL, void *_creator = NULL);
1574 
1575  void Reschedule (TTicks _time, TTicks _interval = 0);
1577  void Clear ();
1578  static void DelByCreator (void *_creator);
1579  void *GetCreator () { return creator; }
1581  bool Pending () { return isLinked; }
1587 
1588  // Timer callback...
1589  virtual void OnTime () { if (func) func (this, data); }
1592  protected:
1593  friend bool TimerIterate ();
1594  friend TTicks TimerGetDelay ();
1595  friend void TimerRun ();
1596  friend void *TimerThreadRoutine (void *);
1597 
1598  static bool ClassIterateAL ();
1599  static TTicks GetDelayTimeAL ();
1600 
1601  void InsertAL ();
1602  void UnlinkAL ();
1604  static CTimer *first; // for chained list
1605  CTimer *next; // for chained list
1606  bool isLinked; // indicates, whether element is in the linked list
1607 
1608  TTicks nextTicks, interval;
1609  void *creator; // this object is managed externally, the caller has a reference to it and must remove it
1610 
1611  FTimerCallback *func;
1612  void *data;
1613 };
1614 
1615 
1616 
1619 bool TimerIterate ();
1623 
1624 void TimerStart ();
1627 int TimerRun (bool catchSignals = true);
1632 void TimerStop ();
1636 
1637 
1639 
1640 
1641 
1642 
1643 
1644 // ********************** Threading and Synchronization ************************
1645 
1646 
1654 typedef void *FThreadRoutine (void *data);
1657 
1658 
1669 class CThread {
1670  public:
1671  CThread () { running = false; }
1672  virtual ~CThread () { if (running) Join (); }
1673 
1674  void Start (FThreadRoutine *_routine, void *_data = NULL);
1676  void Start ();
1677  void *Join ();
1678 
1679  bool IsRunning () { return running; }
1680 
1681  protected:
1682  friend void *CThreadRoutine (void *);
1683 
1684  virtual void *Run () { return NULL; }
1685 
1686  bool running;
1687  pthread_t thread;
1688 };
1689 
1690 
1693 class CMutex {
1694  public:
1695  CMutex ();
1696  ~CMutex ();
1698  void Lock ();
1699  bool TryLock ();
1700  void Unlock ();
1701 
1702  protected:
1703  friend class CCond;
1704  pthread_mutex_t mutex;
1705 };
1706 
1710 class CCond {
1711  public:
1712  CCond ();
1713  ~CCond ();
1714 
1715  void Wait (CMutex *mutex);
1718  TTicks Wait (CMutex *mutex, TTicks maxTime);
1733  void Signal ();
1734  void Broadcast ();
1735 
1736  protected:
1737  pthread_cond_t cond;
1738 };
1739 
1740 
1747 class CSleeper {
1748  public:
1749  CSleeper ();
1750  ~CSleeper () { Done (); }
1751  void Done ();
1752 
1755  void EnableCmds (int _cmdRecSize);
1759 
1764  void Prepare ();
1766  void AddReadable (int fd);
1768  void AddWritable (int fd);
1771 
1774  void Sleep (TTicks maxTime = -1);
1780 
1783  bool IsReadable (int fd);
1784  bool IsWritable (int fd);
1785  bool GetCmd (void *retCmdRec);
1789 
1792  void PutCmd (const void *cmdRec, TTicks t = 0, TTicks _interval = 0);
1798  void ClearTimedCmds () { CTimer::DelByCreator (this); }
1803  protected:
1804  fd_set fdSetRead, fdSetWrite;
1805  int maxFd, cmdRecSize;
1806  int selfPipe[2];
1807 };
1808 
1809 
1810 
1811 void Sleep (TTicks mSecs);
1814 
1815 
1817 
1818 
1819 
1821 
1822 
1823 
1824 // *************************** CShell and variants *****************************
1825 
1835 // ***** Abstract base class and functions *****
1836 
1837 
1842 class CShell {
1843  public:
1844  CShell () { exitCode = -1; }
1845  virtual ~CShell () {}
1846 
1849  virtual bool Start (const char *cmd, bool readStdErr = false) = 0;
1862  virtual bool StartRestricted (const char *name, const char *args = NULL);
1871  virtual bool IsRunning () { return !ReadClosed (); }
1873  virtual void Wait () = 0;
1875  virtual void Kill (int sig = SIGTERM) { WriteClose (); }
1879  int ExitCode () { return exitCode; }
1882 
1885  int Run (const char *cmd, const char *input = NULL, CString *output = NULL);
1893 
1896  virtual void CheckIO (bool *canWrite, bool *canRead, TTicks maxTime = -1) = 0;
1913  bool WaitUntilReadable (TTicks maxTime = -1) { bool canRead; CheckIO (NULL, &canRead, maxTime); return canRead; }
1919  bool WaitUntilWritable (TTicks maxTime = -1) { bool canWrite; CheckIO (&canWrite, NULL, maxTime); return canWrite; }
1925 
1926  bool Writable () { return WaitUntilWritable (0); }
1928  virtual void WriteLine (const char *line) = 0;
1931  void WriteLine (CString *str) { WriteLine (str->Get ()); }
1933  virtual void WriteClose () = 0;
1935 
1936  bool Readable () { return WaitUntilReadable (0); }
1938  virtual bool ReadLine (CString *str) = 0;
1941  virtual bool ReadClosed () = 0;
1944 
1945  protected:
1946  int exitCode;
1947 };
1948 
1949 
1950 
1951 
1952 // ***** CShellBare *****
1953 
1959 class CShellBare: public CShell {
1960  public:
1961  CShellBare () { host = NULL; newProcessGroup = false; fdToScript = fdFromScript = childPid = -1; }
1962  virtual ~CShellBare () { Done (); }
1963  void Done ();
1967  virtual bool Start (const char *cmd, bool readStdErr = false);
1969  virtual bool IsRunning ();
1970  virtual void Wait ();
1971  virtual void Kill (int sig = SIGTERM);
1973 
1976  virtual void CheckIO (bool *canWrite, bool *canRead, TTicks maxTime = -1);
1978 
1979  virtual void WriteLine (const char *line);
1980  virtual void WriteClose ();
1981 
1982  virtual bool ReadLine (CString *str);
1983  virtual bool ReadClosed () { return fdFromScript < 0 && !readBufMayContainLine; }
1985 
1991 
1993  int ReadFd () { return fdFromScript; }
1994  int WriteFd () { return fdToScript; }
1996 
1999  void SetHost (const char *_host);
2001  const char *Host () { return host; }
2002  void SetNewProcessGroup (bool on = true) { newProcessGroup = on; }
2004  bool StartSession (bool readStdErr = false) { return Start (NULL, readStdErr); }
2008  protected:
2009  CString id, host;
2010  bool newProcessGroup;
2011  CString readBuf;
2012  bool readBufMayContainLine;
2013  int fdToScript, fdFromScript;
2014  int childPid, killSig;
2015 
2016  bool DoWaitPid (int options);
2017 };
2018 
2019 
2020 
2021 // ***** CShellSession *****
2023 
2030 class CShellSession: public CShell {
2031  public:
2032  CShellSession () { writeOpen = readOpen = false; }
2033  virtual ~CShellSession () { Done (); }
2034  void Done ();
2035 
2038  void SetHost (const char *_host) { session.SetHost (_host); }
2040  const char *Host () { return session.Host (); }
2042 
2045  virtual bool Start (const char *cmd, bool readStdErr = false);
2046  virtual void Wait ();
2048 
2051  virtual void CheckIO (bool *canWrite, bool *canRead, TTicks maxTime = -1);
2052 
2053  virtual void WriteLine (const char *line) { session.WriteLine (line); }
2054  virtual void WriteClose ();
2055 
2056  virtual bool ReadLine (CString *str);
2057  virtual bool ReadClosed () { return !readOpen; }
2059  int ReadFd () { return session.ReadFd (); }
2060  int WriteFd () { return session.WriteFd (); }
2062 
2063  protected:
2064  CShellBare session;
2065  bool writeOpen, readOpen;
2066 };
2067 
2068 
2070 
2071 
2072 
2075 // *************************** Service managing ********************************
2076 
2077 
2086 // ***** CServiceKeeper *****
2103 class CServiceKeeper {
2104  public:
2105 
2108  CServiceKeeper () { isOpen = shouldBeOpen = false; tDShort = tDLong = tShortToLong = 0; }
2109  CServiceKeeper (TTicks _tDShort, TTicks _tDLong = NEVER, TTicks _tShortToLong = NEVER)
2110  { isOpen = shouldBeOpen = false; Setup (_tDShort, _tDLong, _tShortToLong); }
2111  ~CServiceKeeper () { Close (); }
2112 
2113  void Setup (TTicks _tDShort, TTicks _tDLong = NEVER, TTicks _tShortToLong = NEVER) { tDShort = _tDShort; tDLong = _tDLong; tShortToLong = _tShortToLong; }
2119 
2122  void Open () { shouldBeOpen = true; Refresh (); }
2127  void Close () { shouldBeOpen = false; }
2135 
2136  void Refresh ();
2138 
2139  void Iterate ();
2142  bool IsOpen () { return isOpen; }
2144  bool ShouldBeOpen () { return shouldBeOpen; }
2147 
2153  virtual void DoOpen () {}
2157  virtual void DoClose () {}
2162 
2165  bool OpenAttemptNow ();
2168  bool CloseNow ();
2175  void ReportLost ();
2177  void ReportOpenAttempt (bool success);
2181  void ReportClosed () { isOpen = false; }
2186 
2187  protected:
2188  bool isOpen, shouldBeOpen;
2189  TTicks tLastOpen; // last time the service was known to be open (only valid if 'isOpen == false' and 'shouldBeOpen == true')
2190  TTicks tNextAttempt; // time of next open attempt (only valid if 'isOpen == false' and 'shouldBeOpen == true')
2191  TTicks tDShort, tDLong, tShortToLong;
2192 };
2194 
2197 
2198 
2199 
2200 
2201 // *************************** Doxygen Hooks **********************************
2202 //
2203 // Declare groups for the other modules in "common".
2204 
2207 
2210 
2211 
2212 
2214 
2215 
2216 #endif
Class to wrap (POSIX) condition variables.
Definition: base.H:1738
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:1248
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:1268
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:1265
int Set(const char *key, T *value)
Add or replace the keyed entry. Complexity is O(n).
Definition: base.H:1262
Raw dictionary (base class for other dictionary variants).
Definition: base.H:1137
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:1155
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:1143
Dictionary of references.
Definition: base.H:1292
Dictionary.
Definition: base.H:1193
int Set(const char *key, T *value)
Add or replace the keyed entry. Complexity is O(n).
Definition: base.H:1210
void SetValue(int idx, T *value)
Set (replace) a value.
Definition: base.H:1213
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:1224
T * DisownValue(int idx)
Disown a value and clear it in the dictionary.
Definition: base.H:1219
Set of strings (keys).
Definition: base.H:1304
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:1316
Compact list.
Definition: base.H:1078
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:1092
void Append(T *value)
Append a new value. Complexity is O(1) if no resizing is necessary, else O(1).
Definition: base.H:1098
void Insert(int idx, T *value)
Insert a new value. Complexity is O(n).
Definition: base.H:1095
Raw list (base class for other list variants).
Definition: base.H:941
void Clear()
Clear the list.
Definition: base.H:954
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:948
void Del(int idx)
Delete entry; complexity is O(n).
Reference list.
Definition: base.H:1118
Dynamic list.
Definition: base.H:1025
void Append(T *value)
Append a new value. Complexity is O(1) if no resizing is necessary, else O(1).
Definition: base.H:1046
T * Disown(int idx)
Disown a value and clear it in the array.
Definition: base.H:1049
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:1040
void Insert(int idx, T *value)
Insert a new value. Complexity is O(n).
Definition: base.H:1043
Class to wrap (POSIX) mutex objects.
Definition: base.H:1721
Factory class for regular expression matching.
Definition: base.H:864
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:2131
void Close()
Request the service to close.
Definition: base.H:2155
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:2181
void Setup(TTicks _tDShort, TTicks _tDLong=NEVER, TTicks _tShortToLong=NEVER)
Setup the retry policy.
Definition: base.H:2141
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:2150
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:2170
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:2172
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:2185
void ReportClosed()
Report that the service was actually closed. This must be calld from DoClose() or after CloseNow() ha...
Definition: base.H:2209
Normal shell: Commands are executed individually.
Definition: base.H:1987
int ReadFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2021
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:2030
virtual bool ReadClosed()
Close the read channel.
Definition: base.H:2011
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:2032
int WriteFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2022
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:2058
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:2081
void SetHost(const char *_host)
Define a remote host; must be called before first Start() call.
Definition: base.H:2066
int WriteFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2088
virtual void Wait()
Wait until current command completes.
virtual bool ReadClosed()
Close the read channel.
Definition: base.H:2085
int ReadFd()
Get FD to allow select() by owner with multiple scripts.
Definition: base.H:2087
Abstract base class for shells that can execute system commands.
Definition: base.H:1870
bool Writable()
Poll for writability (non-blocking).
Definition: base.H:1954
virtual bool IsRunning()
Still running?
Definition: base.H:1899
int ExitCode()
Get the exit code of last command.
Definition: base.H:1907
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:1903
bool Readable()
Poll for readability.
Definition: base.H:1964
bool WaitUntilReadable(TTicks maxTime=-1)
Wait until output of the external command is readable. Be aware of potential deadlocks....
Definition: base.H:1941
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:1947
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:1775
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:1826
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:841
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:837
const char * operator[](int n) const
Get one string.
Definition: base.H:839
int GetIdx(int pos)
Get the argument number of character number pos of the original string. On error, -1 is returned,...
const char * Get(int idx) const
Get one string.
Definition: base.H:838
void Clear()
Clear the object (only necessary if another string is to be split)
Dynamically allocated string.
Definition: base.H:635
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
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
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
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)....
char * Disown()
Return current string as a dynamic object and clear 'this'.
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:1697
virtual void * Run()
Main thread routine (to be overloaded)
Definition: base.H:1712
void * Join()
Join with the background thread.
void Start()
Run the virtual method Run() in the background.
bool IsRunning()
(only for main thread)
Definition: base.H:1707
Timer class.
Definition: base.H:1580
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:1617
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:1609
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 * MonthNameShort(int dm)
Get textual shortname. 1 = "Jan", ..., 12 = "Dec".
const char * DayNameShort(int wd)
Get textual name. 0 = "Mon", ..., 6 = "Sun".
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.
bool TicksFromString(const char *str, TTicks *ret, bool absolute)
Convert a string to a relative or absolute ticks value.
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:1441
static void DateTimeNow(TDate *d, TTime *t)
Retrieve current date and time (both pointers may be NULL)
Definition: base.H:1500
const char * DayName(int wd)
Get textual name. 0 = "Monday", ..., 6 = "Sunday".
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:1376
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:1443
TTicks TicksNowMonotonic()
Get the current monotonic time in milliseconds. This function never returns 0 or a negative value.
#define NEVER
Special value that may represent "never" for absolute or monotonic times. Other application-specific ...
Definition: base.H:1381
TTicks TicksMonotonicFromAbs(TTicks ta)
Get the approximated monotonic time for an absolute time . Arguments <= 0 are returned unmodified.
const char * TicksRelToString(CString *ret, TTicks ticks)
Get a string of the form "<integer>[<unit>]" for a relative time.
const char * MonthName(int dm)
Get textual name. 1 = "January", ..., 12 = "December".
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.
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.
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.
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....
const char * GetAbsPath(class CString *ret, const char *relOrAbsPath, const char *defaultPath)
Get absolute path.
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 * StringF(class CString *ret, const char *fmt,...)
Return 'ret->Get ()'.
const char * PathLeaf(const char *str)
Get leaf component of a path.
bool FloatFromString(const char *str, float *ret)
Convert a string to a floating-point value using 'strtof'. On success, '*ret' is set accordingly and ...
#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.
class CString * GetThreadTempString()
Get the thread-local temporary string (TTS) of the calling thread.
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 * ToIso8859(class CString *ret, const char *str)
Transcode an ISO8859-coded string to UTF-8. Result is valid until next call of this function.
void * FThreadRoutine(void *data)
Function type for thread routines.
Definition: base.H:1682
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:1572
void TimerStop()
Request TimerRun() to return at next occasion (can be called from any thread). If a dedicated timer t...
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...
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 const char * VersionGetOwnAsStr()
Get my own build version as a string.
Definition: base.H:402
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...
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