diff options
Diffstat (limited to 'tools.c')
-rw-r--r-- | tools.c | 240 |
1 files changed, 240 insertions, 0 deletions
@@ -0,0 +1,240 @@ +/* + * tools.c: Tools for handling configuration files and strings + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "tools.h" + +// +// HTML conversion code taken from RSS Reader plugin for VDR +// http://www.saunalahti.fi/~rahrenbe/vdr/rssreader/ +// by Rolf Ahrenberg +// + +// --- Static ----------------------------------------------------------- + +#define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) + +struct conv_table { + const char *from; + const char *to; +}; + +static struct conv_table pre_conv_table[] = +{ + // 'to' field must be smaller than 'from' + {"<br />", "\n"} +}; + +// Conversion page: http://www.ltg.ed.ac.uk/~richard/utf-8.cgi + +static struct conv_table post_conv_table[] = +{ + // 'to' field must be smaller than 'from' + {""", "\x22"}, + {""", "\x22"}, + {"&", "\x26"}, + {"&", "\x26"}, + {"&", "\x26"}, + {"'", "\x27"}, + {"(", "\x28"}, + {")", "\x29"}, + {":", "\x3a"}, + {"<", "\x3c"}, + {"<", "\x3c"}, + {">", "\x3e"}, + {">", "\x3e"}, + {"[", "\x5b"}, + {"]", "\x5d"}, + {" ", "\xc2\xa0"}, + {" ", "\xc2\xa0"}, + {"°", "\xc2\xb0"}, + {"°", "\xc2\xb0"}, + {"´", "\xc2\xb4"}, + {"´", "\xc2\xb4"}, + {"Ä", "\xc3\x84"}, + {"Ä", "\xc3\x84"}, + {"Å", "\xc3\x85"}, + {"Å", "\xc3\x85"}, + {"Ö", "\xc3\x96"}, + {"Ö", "\xc3\x96"}, + {"Ü", "\xc3\x9c"}, + {"Ü", "\xc3\x9c"}, + {"ß", "\xc3\x9f"}, + {"ß", "\xc3\x9f"}, + {"â", "\xc3\xa2"}, + {"â", "\xc3\xa2"}, + {"ä", "\xc3\xa4"}, + {"ä", "\xc3\xa4"}, + {"å", "\xc3\xa5"}, + {"å", "\xc3\xa5"}, + {"ç", "\xc3\xa7"}, + {"ç", "\xc3\xa7"}, + {"é", "\xc3\xa9"}, + {"é", "\xc3\xa9"}, + {"ê", "\xc3\xaa"}, + {"ê", "\xc3\xaa"}, + {"ö", "\xc3\xb6"}, + {"ö", "\xc3\xb6"}, + {"ü", "\xc3\xbc"}, + {"ü", "\xc3\xbc"}, + {"–", "\xe2\x80\x93"}, + {"–", "\xe2\x80\x93"}, + {"—", "\xe2\x80\x94"}, + {"—", "\xe2\x80\x94"}, + {"‘", "\xe2\x80\x98"}, + {"‘", "\xe2\x80\x98"}, + {"’", "\xe2\x80\x99"}, + {"’", "\xe2\x80\x99"}, + {"‚", "\xe2\x80\x9a"}, + {"‚", "\xe2\x80\x9a"}, + {"“", "\xe2\x80\x9c"}, + {"“", "\xe2\x80\x9c"}, + {"”", "\xe2\x80\x9d"}, + {"”", "\xe2\x80\x9d"}, + {"„", "\xe2\x80\x9e"}, + {"„", "\xe2\x80\x9e"}, + {"′", "\xe2\x80\xb3"}, + {"″", "\xe2\x80\xb3"}, + {"€", "\xe2\x82\xac"}, + {"€", "\xe2\x82\xac"}, + {"\n\n", "\n"}, // let's also strip multiple linefeeds +}; + +static char *htmlcharconv(char *str, struct conv_table *conv, unsigned int elem) +{ + if (str && conv) { + for (unsigned int i = 0; i < elem; ++i) { + char *ptr = strstr(str, conv[i].from); + while (ptr) { + long of = ptr - str; + size_t l = strlen(str); + size_t l1 = strlen(conv[i].from); + size_t l2 = strlen(conv[i].to); + if (l2 > l1) { + esyslog("htmlcharconv(): cannot reallocate string"); + return str; + } + if (l2 != l1) + memmove(str + of + l2, str + of + l1, l - of - l1 + 1); + strncpy(str + of, conv[i].to, l2); + ptr = strstr(str, conv[i].from); + } + } + return str; + } + return NULL; +} + +// --- General functions ------------------------------------------------ + +char *striphtml(char *str) +{ + if (str) { + char *c, t = 0, *r; + str = htmlcharconv(str, pre_conv_table, ELEMENTS(pre_conv_table)); + c = str; + r = str; + while (*str != '\0') { + if (*str == '<') + t++; + else if (*str == '>') + t--; + else if (t < 1) + *(c++) = *str; + str++; + } + *c = '\0'; + return htmlcharconv(r, post_conv_table, ELEMENTS(post_conv_table)); + } + return NULL; +} + +int count(const char *string, const char separator) +{ + int num = 0; + while (string) { + num++; + string = strchr(string+1, separator); + } + return num; +} + +int loadChannelsFromString(const char *string, int **channels_num, char ***channels_str) +{ + int numchannels = count(string, ','); + if (numchannels > 0) { + char *c = strdup(string); + // Use channel numbers + if (atoi(string)) + *channels_num = (int *)malloc(sizeof(int)*numchannels); + else// use channel IDs + *channels_str = (char **)malloc(sizeof(char *)*numchannels); + int i = 0; + char *pc = strtok(c, ","); + while (i < numchannels) { + // Use channel numbers + if (atoi(string)) + (*channels_num)[i] = atoi(pc); + else// use channel IDs + (*channels_str)[i] = strdup(pc); + pc = strtok(NULL, ","); + i++; + } + } + return numchannels; +} + +cListItem::cListItem() +{ + enabled = false; + string = NULL; + numchannels = 0; + channels_num = NULL; + channels_str = NULL; +} + +cListItem::~cListItem(void) +{ + Free(); +} + +void cListItem::Free(void) +{ + free(channels_num); + if (channels_str) { + int i = 0; + while (i < numchannels) { + free(channels_str[i]); + i++; + } + } + free(channels_str); + free(string); + channels_num = NULL; + channels_str = NULL; + string = NULL; +} + +const char *cListItem::GetChannelID(int index) +{ + if (channels_str && index >= 0 && index < numchannels) + return channels_str[index]; + else + return NULL; +} + +int cListItem::GetChannelNum(int index) +{ + if (channels_num && index >= 0 && index < numchannels) + return channels_num[index]; + else + return -1; +} + +void cListItem::ToggleEnabled(void) +{ + enabled = enabled ? 0 : 1; +} |