diff options
Diffstat (limited to 'common.c')
-rw-r--r-- | common.c | 703 |
1 files changed, 703 insertions, 0 deletions
diff --git a/common.c b/common.c new file mode 100644 index 0000000..81940c3 --- /dev/null +++ b/common.c @@ -0,0 +1,703 @@ +/** + * GraphTFT plugin for the Video Disk Recorder + * + * common.c - A plugin for the Video Disk Recorder + * + * (c) 2004 Lars Tegeler, Sascha Volkenandt + * (c) 2006-2008 Jörg Wendel + * + * This code is distributed under the terms and conditions of the + * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details. + * + * $Id: common.c,v 1.10 2007/12/03 19:58:20 root Exp $ + * + **/ + +// includes + +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/stat.h> + +#include <time.h> +#include <stdio.h> +#include <stdarg.h> +#include <time.h> +#include <syslog.h> +#include <regex.h> +#include <string.h> +#include <errno.h> + +#include <string> + +using std::string; + +#ifdef VDR_PLUGIN +# include "setup.h" +# include <vdr/tools.h> +# include <vdr/thread.h> + + cMutex logMutex; +#endif + +#include "common.h" + +int logLevel = eloOff; +int logDevice = devSyslog; + +//*************************************************************************** +// Log +//*************************************************************************** + +void tell(int eloquence, const char* format, ...) +{ + if (logLevel < eloquence) + return ; + + const int sizeBuffer = 100000; + char t[sizeBuffer+100]; + va_list ap; + time_t now; + struct tm tim; + + memset(&tim, 0, sizeof(tm)); + +#ifdef VDR_PLUGIN + cMutexLock lock(&logMutex); +#endif + + va_start(ap, format); + + switch (logDevice) + { + case devNone: break; + + case devStdOut: + { + char buf[50+TB]; + timeval tp; + + gettimeofday(&tp, 0); + tm* tm = localtime(&tp.tv_sec); + + sprintf(buf,"%2.2d:%2.2d:%2.2d,%3.3ld ", + tm->tm_hour, tm->tm_min, tm->tm_sec, + tp.tv_usec / 1000); + + vsnprintf(t, sizeBuffer, format, ap); + printf("%s %s\n", buf, t); + + break; + } + + case devSyslog: + { + snprintf(t, sizeBuffer, "[graphTFT] "); + vsnprintf(t+strlen(t), sizeBuffer-strlen(t), format, ap); + + syslog(LOG_DEBUG, "%s", t); + + break; + } + + case devFile: + { + FILE* lf; + + lf = fopen("/tmp/graphTFT.log", "a"); + + if (lf) + { + timeval tp; + tm* tm; + + vsnprintf(t + 24, sizeBuffer+21, format, ap); + + time(&now); + strftime(t, sizeof(t), "%Y.%m.%d ", localtime_r(&now, &tim)); + gettimeofday(&tp, 0); + tm = localtime_r(&tp.tv_sec, &tim); + + sprintf(t + strlen(t),"%2.2d:%2.2d:%2.2d,%3.3ld", + tm->tm_hour, tm->tm_min, tm->tm_sec, tp.tv_usec / 1000); + + t[23] = ' '; + fprintf(lf, "%s\n", t); + fclose(lf); + } + + break; + } + } + + va_end(ap); +} + +//*************************************************************************** +// Save Realloc +//*************************************************************************** + +char* srealloc(void* ptr, size_t size) +{ + void* n = realloc(ptr, size); + + if (!n) + { + free(ptr); + ptr = 0; + } + + return (char*)n; +} + +//*************************************************************************** +// RGBA Stuff +//*************************************************************************** + +p_rgba str2rgba(const char* value, p_rgba rgba) +{ + int index; + char* pc; + char* col = strdup(value); + + memset(rgba, 255, sizeof(t_rgba)); + + // "220:30:110:200" -> rgba + + for (index = 0, pc = strtok(col, ":"); pc && index < 4; pc = strtok(0, ":"), index++) + rgba[index] = (unsigned char)atoi(pc); + + free(col); + + return rgba; +} + +p_rgba int2rgba(int r, int g, int b, int a, p_rgba rgba) +{ + rgba[rgbR] = r; + rgba[rgbG] = g; + rgba[rgbB] = b; + rgba[rgbA] = a; + + return rgba; +} + +void rgba2int(p_rgba rgba, int& r, int& g, int& b, int& a) +{ + r = rgba[rgbR]; + g = rgba[rgbG]; + b = rgba[rgbB]; + a = rgba[rgbA]; +} + +//*************************************************************************** +// check if a file exists +//*************************************************************************** + +int fileExists(std::string filename) +{ + struct stat file_stat; + + return (stat(filename.c_str(), &file_stat) == 0) ? true : false; +} + +const char* suffixOf(const char* path) +{ + const char* p; + + if (path && (p = strrchr(path, '.'))) + return p+1; + + return ""; +} + +#ifdef VDR_PLUGIN + +//*************************************************************************** +// To UTF8 +//*************************************************************************** + +int toUTF8(char* out, int outMax, const char* in) +{ + iconv_t cd; + size_t ret; + char* toPtr; + char* fromPtr; + size_t fromLen, outlen; + + const char* to_code = "UTF-8"; + const char* from_code = "ISO8859-1"; + + if (!out || !in || !outMax) + return fail; + + *out = 0; + fromLen = strlen(in); + + if (!fromLen) + return fail; + +#if VDRVERSNUM >= 10509 + switch (I18nCurrentLanguage()) +#else + switch (Setup.OSDLanguage) +#endif + { + case 11: from_code = "ISO8859-7"; break; + case 13: + case 17: from_code = "ISO8859-2"; break; + case 16: from_code = "ISO8859-5"; break; + case 18: from_code = "ISO8859-15"; break; + default: from_code = "ISO8859-1"; break; + } + + cd = iconv_open(to_code, from_code); + + if (cd == (iconv_t)-1) + return fail; + + fromPtr = (char*)in; + toPtr = out; + outlen = outMax; + + ret = iconv(cd, &fromPtr, &fromLen, &toPtr, &outlen); + + *toPtr = 0; + iconv_close(cd); + + if (ret == (size_t)-1) + { + tell(0, "Converting [%s] from '%s' to '%s' failed", + fromPtr, from_code, to_code); + + return fail; + } + + return success; +} +#endif + +//*************************************************************************** +// Load From File +//*************************************************************************** + +int loadFromFile(const char* infile, MemoryStruct* data) +{ + FILE* fin; + struct stat sb; + + data->clear(); + + if (!fileExists(infile)) + { + tell(0, "File '%s' not found'", infile); + return fail; + } + + if (stat(infile, &sb) < 0) + { + tell(0, "Can't get info of '%s', error was '%s'", infile, strerror(errno)); + return fail; + } + + if ((fin = fopen(infile, "r"))) + { + const char* sfx = suffixOf(infile); + + data->size = sb.st_size; + data->modTime = sb.st_mtime; + data->memory = (char*)malloc(data->size); + fread(data->memory, sizeof(char), data->size, fin); + fclose(fin); + sprintf(data->tag, "%ld", (long int)data->size); + + if (strcmp(sfx, "gz") == 0) + sprintf(data->contentEncoding, "gzip"); + + if (strcmp(sfx, "js") == 0) + sprintf(data->contentType, "application/javascript"); + + else if (strcmp(sfx, "png") == 0 || strcmp(sfx, "jpg") == 0 || strcmp(sfx, "gif") == 0) + sprintf(data->contentType, "image/%s", sfx); + + else if (strcmp(sfx, "ico") == 0) + strcpy(data->contentType, "image/x-icon"); + + else + sprintf(data->contentType, "text/%s", sfx); + } + else + { + tell(0, "Error, can't open '%s' for reading, error was '%s'", infile, strerror(errno)); + return fail; + } + + return success; +} + +//*************************************************************************** +// JPEG Dimensions +//*************************************************************************** + +int jpegDimensions(const char* path, unsigned int& pWidth, unsigned int& pHeight) +{ + MemoryStruct data; + unsigned char* pData; + + pWidth = pHeight = 0; + + if (loadFromFile(path, &data) != success) + { + tell(0, "Error loading '%s', error was '%s'", path, strerror(errno)); + return fail; + } + + pData = (unsigned char*)data.memory; + + if (pData[0] != 0xFF || pData[1] != 0xD8) + return fail; + + // retrieve the block length of the first block since the first block will not contain the size of file + + for (unsigned int i = 4; i < data.size; i += 2) + { + unsigned short block_length = pData[i] * 256 + pData[i+1]; + + i += block_length; // next block + + if (i >= data.size || pData[i] != 0xFF) + return fail; + + // 0xFFC0 is the "Start Of Frame" marker which contains the file size + + if (pData[i+1] == 0xC0) + { + pHeight = pData[i+5] * 256 + pData[i+6]; + pWidth = pData[i+7] * 256 + pData[i+8]; + + return success; + } + } + + return fail; +} + +//*************************************************************************** +// Left Trim +//*************************************************************************** + +char* Str::lTrim(char* buf) +{ + if (buf) + { + char *tp = buf; + + while (*tp && strchr("\n\r\t ",*tp)) + tp++; + + memmove(buf, tp, strlen(tp) +1); + } + + return buf; +} + +//************************************************************************* +// Right Trim +//************************************************************************* + +char* Str::rTrim(char* buf) +{ + if (buf) + { + char *tp = buf + strlen(buf); + + while (tp >= buf && strchr("\n\r\t ",*tp)) + tp--; + + *(tp+1) = 0; + } + + return buf; +} + +//************************************************************************* +// All Trim +//************************************************************************* + +char* Str::allTrim(char* buf) +{ + return lTrim(rTrim(buf)); +} + +//************************************************************************* +// Is Empyt +//************************************************************************* + +int Str::isEmpty(const char* buf) +{ + if (buf && *buf) + return no; + + return yes; +} + +int Str::isBlank(const char* buf) +{ + int i = 0; + + while (buf[i]) + { + if (buf[i] != ' ' && buf[i] != '\t') + return no; + + i++; + } + + return yes; +} + +const char* Str::toStr(const char* s) +{ + static char* buf = 0; + static unsigned int sizeBuf = 0; + + if (!s) + return ""; + + if (!buf || sizeBuf < strlen(s)) + { + if (buf) free(buf); + + sizeBuf = strlen(s); + buf = (char*)malloc(sizeBuf); + } + + strcpy(buf, s); + + return buf; +} + +const char* Str::toStr(bool value) +{ + static char buf[10+TB]; + + sprintf(buf, "%s", value ? "1" : "0"); + + return buf; +} + +const char* Str::toStr(int value) +{ + static char buf[100+TB]; + + sprintf(buf, "%d", value); + + return buf; +} + +const char* Str::toStr(double value, int precision) +{ + static char buf[100+TB]; + + sprintf(buf, "%.*f", precision, value); + + return buf; +} + +//*************************************************************************** +// To Case (UTF-8 save) +//*************************************************************************** + +const char* Str::toCase(Case cs, char* str) +{ + char* s = str; + int lenSrc = strlen(str); + + int csSrc; // size of character + + for (int ps = 0; ps < lenSrc; ps += csSrc) + { + csSrc = max(mblen(&s[ps], lenSrc-ps), 1); + + if (csSrc == 1) + s[ps] = cs == cUpper ? toupper(s[ps]) : tolower(s[ps]); + else if (csSrc == 2 && s[ps] == (char)0xc3 && s[ps+1] >= (char)0xa0) + { + s[ps] = s[ps]; + s[ps+1] = cs == cUpper ? toupper(s[ps+1]) : tolower(s[ps+1]); + } + else + { + for (int i = 0; i < csSrc; i++) + s[ps+i] = s[ps+i]; + } + } + + return str; +} + +//*************************************************************************** +// Class LogDuration +//*************************************************************************** + +#ifdef VDR_PLUGIN + +# include <vdr/plugin.h> + +LogDuration::LogDuration(const char* aMessage, int aLogLevel) +{ + logLevel = aLogLevel; + strcpy(message, aMessage); + + // at last ! + + durationStart = cTimeMs::Now(); +} + +LogDuration::~LogDuration() +{ + tell(logLevel, "duration '%s' was (%ldms)", + message, cTimeMs::Now() - durationStart); +} + +void LogDuration::show(const char* label) +{ + tell(logLevel, "elapsed '%s' at '%s' was (%ldms)", + message, label, cTimeMs::Now() - durationStart); +} + +#endif + +//************************************************************************** +// Regular Expression Searching +//************************************************************************** + +int rep(const char* string, const char* expression, Option options) +{ + const char* tmpA; + const char* tmpB; + + return rep(string, expression, tmpA, tmpB, options); +} + +int rep(const char* string, const char* expression, const char*& s_location, + Option options) +{ + const char* tmpA; + + return rep(string, expression, s_location, tmpA, options); +} + + +int rep(const char* string, const char* expression, const char*& s_location, + const char*& e_location, Option options) +{ + regex_t reg; + regmatch_t rm; + int status; + int opt = 0; + + // Vorbereiten von reg fuer die Expressionsuche mit regexec + // Flags: REG_EXTENDED = Use Extended Regular Expressions + // REG_ICASE = Ignore case in match. + + reg.re_nsub = 0; + + // Options umwandeln + if (options & repUseRegularExpression) + opt = opt | REG_EXTENDED; + if (options & repIgnoreCase) + opt = opt | REG_ICASE; + + if (regcomp( ®, expression, opt) != 0) + return fail; + + // Suchen des ersten Vorkommens von reg in string + + status = regexec(®, string, 1, &rm, 0); + regfree(®); + + if (status != 0) + return fail; + + // Suche erfolgreich => + // Setzen der ermittelten Start- und Endpositionen + + s_location = (char*)(string + rm.rm_so); + e_location = (char*)(string + rm.rm_eo); + + return success; +} + +#ifdef VDR_PLUGIN +//*************************************************************************** +// STR / SNR +//*************************************************************************** + +#define FRONTEND_DEVICE "/dev/dvb/adapter%d/frontend%d" + +int getFrontendSTR() +{ + uint16_t value = 0; + cString dev = cString::sprintf(FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); + + int fe = open(dev, O_RDONLY | O_NONBLOCK); + + if (fe < 0) + return 0; + + CHECK(ioctl(fe, FE_READ_SIGNAL_STRENGTH, &value)); + close(fe); + + return value / 655; +} + +int getFrontendSNR() +{ + uint16_t value = 0; + cString dev = cString::sprintf(FRONTEND_DEVICE, cDevice::ActualDevice()->CardIndex(), 0); + + int fe = open(dev, O_RDONLY | O_NONBLOCK); + + if (fe < 0) + return 0; + + CHECK(ioctl(fe, FE_READ_SNR, &value)); + close(fe); + + return value / 655; +} +#endif + +uint64_t msNow() +{ + struct timeval t; + + if (gettimeofday(&t, NULL) == 0) + return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000; + + return 0; +} + +string replaceChar(string str, char ch1, char ch2) +{ + for (unsigned int i = 0; i < str.length(); ++i) + { + if (str[i] == ch1) + str[i] = ch2; + } + + return str; +} + +int clen(const char* s) +{ + int blen = strlen(s); + int cs; + int len = 0; + + for (int bp = 0; bp < blen; bp += cs, len++) + cs = max(mblen(&s[bp], blen-bp), 1); + + return len; +} |