33#define MAXSYSLOGBUF 256
41 vsyslog(priority, fmt, ap);
53ssize_t
safe_read(
int filedes,
void *buffer,
size_t size)
56 ssize_t p = read(filedes, buffer, size);
57 if (p < 0 && errno == EINTR) {
58 dsyslog(
"EINTR while reading from file handle %d - retrying", filedes);
65ssize_t
safe_write(
int filedes,
const void *buffer,
size_t size)
68 ssize_t written = size;
69 const unsigned char *ptr = (
const unsigned char *)buffer;
71 p = write(filedes, ptr, size);
74 dsyslog(
"EINTR while writing to file handle %d - retrying", filedes);
82 return p < 0 ? p : written;
94 int w = write(fd, Data + written, Length);
103 Poller.
Poll(RetryMs);
104 if (TimeoutMs > 0 && (TimeoutMs -= t.
Elapsed()) <= 0)
117 int l =
max(dest ? strlen(dest) : 0, strlen(src)) + 1;
118 dest = (
char *)realloc(dest, l);
122 esyslog(
"ERROR: out of memory");
131char *
strn0cpy(
char *dest,
const char *src,
size_t n)
134 for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
154 if (!s || !s1 || !s2)
156 char *p = strstr(s, s1);
163 if (
char *NewBuffer = (
char *)realloc(s, l + l2 - l1 + 1))
166 esyslog(
"ERROR: out of memory");
172 memmove(sof + l2, sof + l1, l - of - l1 + 1);
178const char *
strchrn(
const char *s,
char c,
size_t n)
184 if (*s == c && --n == 0)
205 const char *p = strrchr(s, 0);
207 if (*p == c && --n == 0)
215 const char *p = strrchr(s, c);
216 return p ? p + 1 : s;
222 for (
char *p = s + strlen(s) - 1; p >= s; p--) {
239 memmove(p + 1, q, strlen(q) + 1);
243 memmove(s, t, strlen(t) + 1);
259 else if (t != s && n == 0) {
278 if (strchr(chars, *p)) {
280 buffer =
MALLOC(
char, 2 * strlen(s) + 1);
281 t = buffer + (p - s);
282 s = strcpy(buffer, s);
298 int l = strlen(name);
300 while (
const char *p = strstr(t, name)) {
302 if (p == s || *(p - 1) <=
' ') {
322 memmove(s, s + n, l - n + 1);
340 const char *se = s + strlen(s) - 1;
341 const char *pe = p + strlen(p) - 1;
343 if (*pe-- != *se-- || (se < s && pe >= p))
378 int64_t n = strtoll(s, &t, 10);
394 if (strcmp(*a, s) == 0)
404 if (*FileName ==
'/')
406 return cString::sprintf(
"%s/%s", DirName && *DirName ? DirName :
".", FileName);
409#define DECIMAL_POINT_C '.'
413 static lconv *loc = localeconv();
415 char buf[strlen(s) + 1];
419 *p = *loc->decimal_point;
434 static lconv *loc = localeconv();
436 snprintf(buf,
sizeof(buf), Format, d);
445 snprintf(buf,
sizeof(buf),
"%d", n);
452 if (stat(File1, &st) == 0) {
453 dev_t dev1 = st.st_dev;
454 if (stat(File2, &st) == 0)
455 return st.st_dev == dev1;
469 struct statfs statFs;
470 if (statfs(Directory, &statFs) == 0) {
471 double blocksPerMeg = 1024.0 * 1024.0 / statFs.f_bsize;
473 *UsedMB = int((statFs.f_blocks - statFs.f_bfree) / blocksPerMeg);
474 Free = int(statFs.f_bavail / blocksPerMeg);
484 if (stat(DirName, &ds) == 0) {
485 if (S_ISDIR(ds.st_mode)) {
486 if (access(DirName, R_OK | W_OK | X_OK) == 0)
489 esyslog(
"ERROR: can't access %s", DirName);
492 esyslog(
"ERROR: %s is not a directory", DirName);
499bool MakeDirs(
const char *FileName,
bool IsDirectory)
502 char *s = strdup(FileName);
506 while ((p = strchr(p,
'/')) != NULL || IsDirectory) {
510 if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
511 dsyslog(
"creating directory %s", s);
512 if (mkdir(s, ACCESSPERMS) == -1) {
530 if (stat(FileName, &st) == 0) {
531 if (S_ISDIR(st.st_mode)) {
535 while ((e = d.
Next()) != NULL) {
537 if (FollowSymlinks) {
539 if (lstat(buffer, &st2) == 0) {
540 if (S_ISLNK(st2.st_mode)) {
541 int size = st2.st_size + 1;
542 char *l =
MALLOC(
char, size);
543 int n = readlink(buffer, l, size - 1);
557 else if (errno != ENOENT) {
562 dsyslog(
"removing %s", *buffer);
563 if (remove(buffer) < 0)
572 dsyslog(
"removing %s", FileName);
573 if (remove(FileName) < 0) {
578 else if (errno != ENOENT) {
587 bool HasIgnoredFiles =
false;
592 while ((e = d.
Next()) != NULL) {
593 if (strcmp(e->d_name,
"lost+found")) {
596 if (stat(buffer, &st) == 0) {
597 if (S_ISDIR(st.st_mode)) {
601 else if (RemoveThis && IgnoreFiles &&
StrInArray(IgnoreFiles, e->d_name))
602 HasIgnoredFiles =
true;
612 if (RemoveThis && empty) {
613 if (HasIgnoredFiles) {
614 while (*IgnoreFiles) {
616 if (access(buffer, F_OK) == 0) {
617 dsyslog(
"removing %s", *buffer);
618 if (remove(buffer) < 0) {
626 dsyslog(
"removing %s", DirName);
627 if (remove(DirName) < 0) {
645 while (size >= 0 && (e = d.
Next()) != NULL) {
648 if (stat(buffer, &st) == 0) {
649 if (S_ISDIR(st.st_mode)) {
666 else if (errno != ENOENT)
675 char *TargetName = canonicalize_file_name(FileName);
678 TargetName = strdup(FileName);
687 for (
int n = 0; n < 10; n++) {
693 if (access(buf, F_OK) != 0) {
695 gettimeofday(&tp1, NULL);
696 int f = open(buf, O_WRONLY | O_CREAT, DEFFILEMODE);
699 if (fdatasync(f) < 0)
703 gettimeofday(&tp2, NULL);
704 double seconds = (((
long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((
long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
706 dsyslog(
"SpinUpDisk took %.2f seconds", seconds);
713 esyslog(
"ERROR: SpinUpDisk failed");
719 if (utime(FileName, NULL) == -1 && errno != ENOENT)
726 if (stat(FileName, &fs) == 0)
734 if (stat(FileName, &fs) == 0)
751#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
752#define MIN_RESOLUTION 5
753 static bool initialized =
false;
754 static bool monotonic =
false;
758 if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
759 long Resolution = tp.tv_nsec;
761 if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
762 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
763 dsyslog(
"cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution);
767 esyslog(
"cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
770 dsyslog(
"cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
773 esyslog(
"cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
777 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
778 return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
779 esyslog(
"cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
784# warning Posix monotonic clock not available
787 if (gettimeofday(&t, NULL) == 0)
788 return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
815#define MT(s, m, v) ((*(s) & (m)) == (v))
816 if (
MT(s, 0xE0, 0xC0) &&
MT(s + 1, 0xC0, 0x80))
818 if (
MT(s, 0xF0, 0xE0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80))
820 if (
MT(s, 0xF8, 0xF0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80) &&
MT(s + 3, 0xC0, 0x80))
832 case 2:
return ((*s & 0x1F) << 6) | (*(s + 1) & 0x3F);
833 case 3:
return ((*s & 0x0F) << 12) | ((*(s + 1) & 0x3F) << 6) | (*(s + 2) & 0x3F);
834 case 4:
return ((*s & 0x07) << 18) | ((*(s + 1) & 0x3F) << 12) | ((*(s + 2) & 0x3F) << 6) | (*(s + 3) & 0x3F);
849 *s++ = ((c >> 6) & 0x1F) | 0xC0;
850 *s = (c & 0x3F) | 0x80;
856 *s++ = ((c >> 12) & 0x0F) | 0xE0;
857 *s++ = ((c >> 6) & 0x3F) | 0x80;
858 *s = (c & 0x3F) | 0x80;
864 *s++ = ((c >> 18) & 0x07) | 0xF0;
865 *s++ = ((c >> 12) & 0x3F) | 0x80;
866 *s++ = ((c >> 6) & 0x3F) | 0x80;
867 *s = (c & 0x3F) | 0x80;
879 while (*s && Symbols--) {
921 while (*s && --Size > 0) {
923 *a++ = (
uchar)(*s++);
940 while (*a && NumChars < Size) {
941 if (Max >= 0 && NumSyms++ >= Max)
949 if (NumChars + sl <= Size) {
974 cd = iconv_open(ToCode, FromCode);
982 if (
cd != (iconv_t)-1)
990 if (!strcasestr(CharacterTable,
"UTF-8")) {
993 for (
int i = 0; i < 128; i++)
997 const char *s = csc.
Convert(buf);
1011 if (
cd != (iconv_t)-1 && From && *From) {
1012 char *FromPtr = (
char *)From;
1013 size_t FromLength = strlen(From);
1016 int NewLength =
max(
length, FromLength * 2);
1017 if (
char *NewBuffer = (
char *)realloc(
result, NewLength)) {
1022 esyslog(
"ERROR: out of memory");
1031 char *Converted = ToPtr;
1032 while (FromLength > 0) {
1033 if (iconv(
cd, &FromPtr, &FromLength, &ToPtr, &ToLength) ==
size_t(-1)) {
1034 if (errno == E2BIG || errno == EILSEQ && ToLength < 1) {
1038 size_t d = ToPtr -
result;
1040 int NewLength =
length + r;
1041 if (
char *NewBuffer = (
char *)realloc(
result, NewLength)) {
1043 Converted =
result = NewBuffer;
1046 esyslog(
"ERROR: out of memory");
1052 if (errno == EILSEQ) {
1059 else if (errno != E2BIG)
1073 s = TakePointer ? (
char *)S : S ? strdup(S) : NULL;
1092 s = String.
s ? strdup(String.
s) : NULL;
1102 if (
this == &String)
1105 s = String.
s ? strdup(String.
s) : NULL;
1114 s = String ? strdup(String) : NULL;
1121 int l1 =
s ? strlen(
s) : 0;
1122 int l2 = strlen(String);
1123 if (
char *p = (
char *)realloc(
s, l1 + l2 + 1)) {
1125 strcpy(
s + l1, String);
1128 esyslog(
"ERROR: out of memory");
1138 if (Index >= 0 && Index < l)
1154 if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
1155 esyslog(
"error in vasprintf('%s', ...)", fmt);
1156 buffer = strdup(
"???");
1165 if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
1166 esyslog(
"error in vasprintf('%s', ...)", fmt);
1167 buffer = strdup(
"???");
1175 WeekDay = WeekDay == 0 ? 6 : WeekDay - 1;
1176 if (0 <= WeekDay && WeekDay <= 6) {
1178 const char *day =
tr(
"MonTueWedThuFriSatSun");
1190 return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
1195 WeekDay = WeekDay == 0 ? 6 : WeekDay - 1;
1197 case 0:
return tr(
"Monday");
1198 case 1:
return tr(
"Tuesday");
1199 case 2:
return tr(
"Wednesday");
1200 case 3:
return tr(
"Thursday");
1201 case 4:
return tr(
"Friday");
1202 case 5:
return tr(
"Saturday");
1203 case 6:
return tr(
"Sunday");
1204 default:
return "???";
1220 tm *tm = localtime_r(&t, &tm_r);
1221 snprintf(buffer,
sizeof(buffer),
"%s %02d.%02d. %02d:%02d", *
WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
1228 if (ctime_r(&t, buffer)) {
1229 buffer[strlen(buffer) - 1] = 0;
1239 tm *tm = localtime_r(&t, &tm_r);
1242 strftime(p,
sizeof(buf) - (p - buf),
"%d.%m.%Y", tm);
1250 tm *tm = localtime_r(&t, &tm_r);
1251 strftime(buf,
sizeof(buf),
"%d.%m.%y", tm);
1259 strftime(buf,
sizeof(buf),
"%R", localtime_r(&t, &tm_r));
1265#define JPEGCOMPRESSMEM 500000
1285 int Used = jcd->
size;
1287 if (
uchar *NewBuffer = (
uchar *)realloc(jcd->
mem, NewSize)) {
1288 jcd->
size = NewSize;
1289 jcd->
mem = NewBuffer;
1292 esyslog(
"ERROR: out of memory");
1296 cinfo->dest->next_output_byte = jcd->
mem + Used;
1297 cinfo->dest->free_in_buffer = jcd->
size - Used;
1308 int Used = cinfo->dest->next_output_byte - jcd->
mem;
1309 if (Used < jcd->size) {
1312 jcd->
mem = NewBuffer;
1315 esyslog(
"ERROR: out of memory");
1324 else if (Quality > 100)
1327 jpeg_destination_mgr jdm;
1333 struct jpeg_compress_struct cinfo;
1334 struct jpeg_error_mgr jerr;
1335 cinfo.err = jpeg_std_error(&jerr);
1336 jpeg_create_compress(&cinfo);
1339 cinfo.client_data = &jcd;
1340 cinfo.image_width = Width;
1341 cinfo.image_height = Height;
1342 cinfo.input_components = 3;
1343 cinfo.in_color_space = JCS_RGB;
1345 jpeg_set_defaults(&cinfo);
1346 jpeg_set_quality(&cinfo, Quality, TRUE);
1347 jpeg_start_compress(&cinfo, TRUE);
1350 JSAMPROW rp[Height];
1351 for (
int k = 0; k < Height; k++)
1352 rp[k] = &Mem[rs * k];
1353 jpeg_write_scanlines(&cinfo, rp, Height);
1354 jpeg_finish_compress(&cinfo);
1355 jpeg_destroy_compress(&cinfo);
1365 static char buffer[HOST_NAME_MAX] =
"";
1367 if (gethostname(buffer,
sizeof(buffer)) < 0) {
1369 strcpy(buffer,
"vdr");
1377const char *
cBase64Encoder::b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1400 c |= (
data[
i] >> 4) & 0x0F;
1403 c = (
data[
i] << 2) & 0x3F;
1405 c |= (
data[
i] >> 6) & 0x03;
1504 Add(FileHandle, Out);
1509 if (FileHandle >= 0) {
1511 if (
pfd[i].fd == FileHandle &&
pfd[i].events == (Out ? POLLOUT : POLLIN))
1521 esyslog(
"ERROR: too many file handles in cPoller");
1528 if (FileHandle >= 0) {
1530 if (
pfd[i].fd == FileHandle &&
pfd[i].events == (Out ? POLLOUT : POLLIN)) {
1565#if !__GLIBC_PREREQ(2, 24)
1570 if (strcmp(
result->d_name,
".") && strcmp(
result->d_name,
".."))
1586 for (
int i = 0; i < Size(); i++) {
1587 if (!strcmp(s, At(i)))
1595 for (
int i = 0; i < Size(); i++)
1605 Load(Directory, DirsOnly);
1615 while ((e =
d.Next()) != NULL) {
1618 if (stat(
AddDirectory(Directory, e->d_name), &ds) == 0) {
1619 if (!S_ISDIR(ds.st_mode))
1623 Append(strdup(e->d_name));
1637bool cFile::files[FD_SETSIZE] = {
false };
1638int cFile::maxFiles = 0;
1654 return Open(open(FileName, Flags, Mode));
1655 esyslog(
"ERROR: attempt to re-open %s", FileName);
1666 if (f < FD_SETSIZE) {
1672 esyslog(
"ERROR: file descriptor %d already in files[]", f);
1676 esyslog(
"ERROR: file descriptor %d is larger than FD_SETSIZE (%d)", f, FD_SETSIZE);
1681 esyslog(
"ERROR: attempt to re-open file descriptor %d", FileDes);
1699 return f >= 0 && FileReady(f, Wait ? 1000 : 0);
1703bool cFile::AnyFileReady(
int FileDes,
int TimeoutMs)
1707 for (
int i = 0; i < maxFiles; i++) {
1711 if (0 <= FileDes && FileDes < FD_SETSIZE && !files[FileDes])
1712 FD_SET(FileDes, &set);
1715 struct timeval timeout;
1716 timeout.tv_sec = TimeoutMs / 1000;
1717 timeout.tv_usec = (TimeoutMs % 1000) * 1000;
1718 return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && (FileDes < 0 || FD_ISSET(FileDes, &set));
1725 struct timeval timeout;
1727 FD_SET(FileDes, &set);
1728 if (TimeoutMs >= 0) {
1729 if (TimeoutMs < 100)
1731 timeout.tv_sec = TimeoutMs / 1000;
1732 timeout.tv_usec = (TimeoutMs % 1000) * 1000;
1734 return select(FD_SETSIZE, &set, NULL, NULL, (TimeoutMs >= 0) ? &timeout : NULL) > 0 && FD_ISSET(FileDes, &set);
1738bool cFile::FileReadyForWriting(
int FileDes,
int TimeoutMs)
1741 struct timeval timeout;
1743 FD_SET(FileDes, &set);
1744 if (TimeoutMs < 100)
1747 timeout.tv_usec = TimeoutMs * 1000;
1748 return select(FD_SETSIZE, NULL, &set, NULL, &timeout) > 0 && FD_ISSET(FileDes, &set);
1758 tempName = fileName ?
MALLOC(
char, strlen(fileName) + 5) : NULL;
1760 strcat(strcpy(tempName, fileName),
".$$$");
1774 if (!f && fileName && tempName) {
1775 f = fopen(tempName,
"w");
1786 if (ferror(f) != 0) {
1792 if (fclose(f) < 0) {
1797 if (
result && rename(tempName, fileName) < 0) {
1809#ifndef USE_FADVISE_READ
1810#define USE_FADVISE_READ 0
1812#ifndef USE_FADVISE_WRITE
1813#define USE_FADVISE_WRITE 1
1816#define WRITE_BUFFER KILOBYTE(800)
1831 fd = open(FileName, Flags, Mode);
1833#if USE_FADVISE_READ || USE_FADVISE_WRITE
1834 begin = lastpos = ahead = 0;
1841 posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
1849#if USE_FADVISE_READ || USE_FADVISE_WRITE
1852 posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
1856 return close(OldFd);
1867#define FADVGRAN KILOBYTE(4)
1868#define READCHUNK MEGABYTE(8)
1878 return posix_fadvise(fd, Offset - (
FADVGRAN - 1), Len + (
FADVGRAN - 1) * 2, POSIX_FADV_DONTNEED);
1883 if (Whence == SEEK_SET && Offset == curpos)
1885 curpos = lseek(fd, Offset, Whence);
1893 off_t jumped = curpos-lastpos;
1894 if ((cachedstart < cachedend) && (curpos < cachedstart || curpos > cachedend)) {
1896 FadviseDrop(cachedstart, cachedend-cachedstart);
1897 cachedstart = curpos;
1900 cachedstart =
min(cachedstart, curpos);
1902 ssize_t bytesRead =
safe_read(fd, Data, Size);
1903 if (bytesRead > 0) {
1904 curpos += bytesRead;
1906 cachedend =
max(cachedend, curpos);
1910 if (jumped >= 0 && jumped <= (off_t)readahead) {
1914 if (ahead - curpos < (off_t)(readahead / 2)) {
1915 posix_fadvise(fd, curpos, readahead, POSIX_FADV_WILLNEED);
1916 ahead = curpos + readahead;
1917 cachedend =
max(cachedend, ahead);
1919 if (readahead < Size * 32) {
1920 readahead = Size * 32;
1928 if (cachedstart < cachedend) {
1929 if (curpos - cachedstart >
READCHUNK * 2) {
1931 FadviseDrop(cachedstart, curpos -
READCHUNK - cachedstart);
1934 else if (cachedend > ahead && cachedend - curpos >
READCHUNK * 2) {
1950 ssize_t bytesWritten =
safe_write(fd, Data, Size);
1951#if USE_FADVISE_WRITE
1952 if (bytesWritten > 0) {
1953 begin =
min(begin, curpos);
1954 curpos += bytesWritten;
1955 written += bytesWritten;
1956 lastpos =
max(lastpos, curpos);
1958 if (lastpos > begin) {
1968 posix_fadvise(fd, begin - headdrop, lastpos - begin + headdrop, POSIX_FADV_DONTNEED);
1970 begin = lastpos = curpos;
1971 totwritten += written;
1986 off_t headdrop =
min(off_t(curpos - totwritten), off_t(totwritten * 2));
1987 posix_fadvise(fd, curpos - totwritten - headdrop, totwritten + headdrop, POSIX_FADV_DONTNEED);
1993 return bytesWritten;
2001 if (File->
Open(FileName, Flags, Mode) < 0) {
2010#define LOCKFILENAME ".lock-vdr"
2011#define LOCKFILESTALETIME 600
2029 if (f < 0 && fileName) {
2030 time_t Timeout = time(NULL) + WaitSeconds;
2032 f = open(fileName, O_WRONLY | O_CREAT | O_EXCL, DEFFILEMODE);
2034 if (errno == EEXIST) {
2036 if (stat(fileName, &fs) == 0) {
2038 esyslog(
"ERROR: removing stale lock file '%s'", fileName);
2039 if (remove(fileName) < 0) {
2046 else if (errno != ENOENT) {
2058 }
while (f < 0 && time(NULL) < Timeout);
2086 Object->
prev =
this;
2092 Object->
next =
this;
2118#define LIST_GARBAGE_COLLECTOR_TIMEOUT 5
2131 esyslog(
"ERROR: ListGarbageCollector destroyed without prior Purge()!");
2137 Object->
next = objects;
2139 lastPut = time(NULL);
2152 objects = Object->next;
2162:stateLock(NeedsLocking)
2180 esyslog(
"ERROR: cListBase::Lock() called for a list that doesn't require locking");
2202 if (Before && Before !=
objects) {
2239 if (From && To && From != To) {
2296 while (
object && Index-- > 0)
2297 object =
object->
Next();
2316 while (
object && i < n) {
2318 object =
object->
Next();
2322 for (i = 0; i < n; i++) {
2346 if (
size < NewSize) {
2353 esyslog(
"ERROR: out of memory");
2385 unsigned int hash =
hashfn(Id);
2396 if (hob->object == Object) {
2406 for (
int i = 0; i <
size; i++) {
cBase64Encoder(const uchar *Data, int Length, int MaxResult=64)
Sets up a new base 64 encoder for the given Data, with the given Length.
const char * NextLine(void)
Returns the next line of encoded data (terminated by '\0'), or NULL if there is no more encoded data.
bool SetLength(int Length)
cCharSetConv(const char *FromCode=NULL, const char *ToCode=NULL)
Sets up a character set converter to convert from FromCode to ToCode.
static const char * SystemCharacterTable(void)
static void SetSystemCharacterTable(const char *CharacterTable)
static char * systemCharacterTable
const char * Convert(const char *From, char *To=NULL, size_t ToLength=0)
Converts the given Text from FromCode to ToCode (as set in the constructor).
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
cDynamicBuffer(int InitialSize=1024)
bool Realloc(int NewSize)
void Append(const uchar *Data, int Length)
bool Load(const char *Directory, bool DirsOnly=false)
cFileNameList(const char *Directory=NULL, bool DirsOnly=false)
static bool FileReady(int FileDes, int TimeoutMs=1000)
bool Ready(bool Wait=true)
bool Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
void Del(cListObject *Object, unsigned int Id)
cListObject * Get(unsigned int Id) const
cList< cHashObject > ** hashTable
cList< cHashObject > * GetList(unsigned int Id) const
cHashBase(int Size, bool OwnObjects)
Creates a new hash of the given Size.
void Add(cListObject *Object, unsigned int Id)
unsigned int hashfn(unsigned int Id) const
void Ins(cListObject *Object, cListObject *Before=NULL)
bool Contains(const cListObject *Object) const
If a pointer to an object contained in this list has been obtained while holding a lock,...
void Del(cListObject *Object, bool DeleteObject=true)
virtual void Move(int From, int To)
void SetExplicitModify(void)
If you have obtained a write lock on this list, and you don't want it to be automatically marked as m...
void SetModified(void)
Unconditionally marks this list as modified.
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0) const
Tries to get a lock on this list and returns true if successful.
const char * needsLocking
cListBase(const char *NeedsLocking=NULL)
const cListObject * Get(int Index) const
void Add(cListObject *Object, cListObject *After=NULL)
void Purge(bool Force=false)
cListGarbageCollector(void)
void Put(cListObject *Object)
cListObject * Prev(void) const
virtual int Compare(const cListObject &ListObject) const
Must return 0 if this object is equal to ListObject, a positive value if it is "greater",...
void Insert(cListObject *Object)
cListObject * Next(void) const
void Append(cListObject *Object)
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
bool Lock(int WaitSeconds=0)
cLockFile(const char *Directory)
cPoller(int FileHandle=-1, bool Out=false)
bool Add(int FileHandle, bool Out)
bool Poll(int TimeoutMs=0)
void Del(int FileHandle, bool Out)
cReadDir(const char *Directory)
struct dirent * Next(void)
cSafeFile(const char *FileName)
void SetExplicitModify(void)
If you have obtained a write lock on this lock, and you don't want its state to be automatically incr...
void SetModified(void)
Sets this lock to have its state incremented when the current write lock state key is removed.
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0)
Tries to get a lock and returns true if successful.
int Find(const char *s) const
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
static cString static cString vsprintf(const char *fmt, va_list &ap)
cString(const char *S=NULL, bool TakePointer=false)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
cString & operator=(const cString &String)
cString & Append(const char *String)
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
static tThreadId ThreadId(void)
uint64_t Elapsed(void) const
void Set(int Ms=0)
Sets the timer.
bool TimedOut(void) const
cTimeMs(int Ms=0)
Creates a timer with ms resolution and an initial timeout of Ms.
static uint64_t Now(void)
cUnbufferedFile is used for large files that are mainly written or read in a streaming manner,...
static cUnbufferedFile * Create(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
void SetReadAhead(size_t ra)
ssize_t Write(const void *Data, size_t Size)
int Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
ssize_t Read(void *Data, size_t Size)
int FadviseDrop(off_t Offset, off_t Len)
off_t Seek(off_t Offset, int Whence)