diff options
-rw-r--r-- | HISTORY | 2 | ||||
-rw-r--r-- | recording.c | 76 |
2 files changed, 70 insertions, 8 deletions
@@ -989,3 +989,5 @@ Video Disk Recorder Revision History the '-'). - If Setup.ShowInfoOnChSwitch is set to "no", the box for the EPG display is no longer shown (thanks to Andy Grobb). +- If compiled with VFAT=1, characters that can't be handled by a VFAT system are + now encoded to '#XX'. diff --git a/recording.c b/recording.c index 7a55e1a7..3c0d15bd 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.49 2002/02/03 15:46:42 kls Exp $ + * $Id: recording.c 1.50 2002/02/10 14:19:06 kls Exp $ */ #include "recording.h" @@ -196,22 +196,82 @@ tCharExchange CharExchange[] = { { ' ', '_' }, { '\'', '\x01' }, { '/', '\x02' }, -#ifdef VFAT - { ':', '\x03' }, -#endif { 0, 0 } }; -char *ExchangeChars(char *s, bool ToFileSystem) +static char *ExchangeChars(char *s, bool ToFileSystem) { char *p = s; while (*p) { +#define VFAT 1 +#ifdef VFAT + // The VFAT file system can't handle all characters, so we + // have to take extra efforts to encode/decode them: + if (ToFileSystem) { + switch (*p) { + // characters that can be used "as is": + case '!': + case '@': + case '$': + case '%': + case '&': + case '(': + case ')': + case '+': + case ',': + case '-': + case '.': + case ';': + case '=': + case '0' ... '9': + case 'a' ... 'z': + case 'A' ... 'Z': break; + // characters that can be mapped to other characters: + case ' ': *p = '_'; break; + case '~': *p = '/'; break; + // characters that have to be encoded: + default: { + int l = p - s; + s = (char *)realloc(s, strlen(s) + 10); + p = s + l; + char buf[4]; + sprintf(buf, "#%02X", (unsigned char)*p); + memmove(p + 2, p, strlen(p) + 1); + strncpy(p, buf, 3); + p += 2; + } + } + } + else { + switch (*p) { + // mapped characters: + case '_': *p = ' '; break; + case '/': *p = '~'; break; + // encodes characters: + case '#': { + if (strlen(p) > 2) { + char buf[3]; + sprintf(buf, "%c%c", *(p + 1), *(p + 2)); + unsigned char c = strtol(buf, NULL, 16); + *p = c; + memmove(p + 1, p + 3, strlen(p) - 2); + } + } + break; + // backwards compatibility: + case '\x01': *p = '\''; break; + case '\x02': *p = '/'; break; + case '\x03': *p = ':'; break; + } + } +#else for (struct tCharExchange *ce = CharExchange; ce->a && ce->b; ce++) { if (*p == (ToFileSystem ? ce->a : ce->b)) { *p = ToFileSystem ? ce->b : ce->a; break; } } +#endif p++; } return s; @@ -285,7 +345,7 @@ cRecording::cRecording(const char *FileName) name = new char[p - FileName + 1]; strncpy(name, FileName, p - FileName); name[p - FileName] = 0; - ExchangeChars(name, false); + name = ExchangeChars(name, false); } // read an optional summary file: char *SummaryFileName = NULL; @@ -384,9 +444,9 @@ const char *cRecording::FileName(void) if (!fileName) { struct tm tm_r; struct tm *t = localtime_r(&start, &tm_r); - ExchangeChars(name, true); + name = ExchangeChars(name, true); asprintf(&fileName, NAMEFORMAT, VideoDirectory, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, priority, lifetime); - ExchangeChars(name, false); + name = ExchangeChars(name, false); } return fileName; } |