nathan@25: /* nathan@25: * MP3/MPlayer plugin to VDR (C++) nathan@25: * nathan@25: * (C) 2001-2009 Stefan Huelswitt nathan@25: * nathan@25: * This code is free software; you can redistribute it and/or nathan@25: * modify it under the terms of the GNU General Public License nathan@25: * as published by the Free Software Foundation; either version 2 nathan@25: * of the License, or (at your option) any later version. nathan@25: * nathan@25: * This code is distributed in the hope that it will be useful, nathan@25: * but WITHOUT ANY WARRANTY; without even the implied warranty of nathan@25: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nathan@25: * GNU General Public License for more details. nathan@25: * nathan@25: * You should have received a copy of the GNU General Public License nathan@25: * along with this program; if not, write to the Free Software nathan@25: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. nathan@25: * Or, point your browser to http://www.gnu.org/copyleft/gpl.html nathan@25: */ nathan@25: nathan@25: #include nathan@25: #include nathan@25: nathan@25: #if APIVERSNUM < 10503 nathan@25: nathan@25: #include nathan@25: #include nathan@25: #include "common.h" nathan@25: nathan@25: // --- cCharSetConv ---------------------------------------------------------- nathan@25: nathan@25: char *cCharSetConv::systemCharacterTable = NULL; nathan@25: nathan@25: cCharSetConv::cCharSetConv(const char *FromCode, const char *ToCode) nathan@25: { nathan@25: if (!FromCode) nathan@25: FromCode = systemCharacterTable; nathan@25: if (!ToCode) nathan@25: ToCode = "UTF-8"; nathan@25: cd = (FromCode && ToCode) ? iconv_open(ToCode, FromCode) : (iconv_t)-1; nathan@25: result = NULL; nathan@25: length = 0; nathan@25: } nathan@25: nathan@25: cCharSetConv::~cCharSetConv() nathan@25: { nathan@25: free(result); nathan@25: iconv_close(cd); nathan@25: } nathan@25: nathan@25: void cCharSetConv::SetSystemCharacterTableX(const char *CharacterTable) nathan@25: { nathan@25: free(systemCharacterTable); nathan@25: systemCharacterTable = NULL; nathan@25: if (!strcasestr(CharacterTable, "UTF-8")) { nathan@25: systemCharacterTable = strdup(CharacterTable); nathan@25: } nathan@25: } nathan@25: nathan@25: const char *cCharSetConv::Convert(const char *From, char *To, size_t ToLength) nathan@25: { nathan@25: if (cd != (iconv_t)-1 && From && *From) { nathan@25: char *FromPtr = (char *)From; nathan@25: size_t FromLength = strlen(From); nathan@25: char *ToPtr = To; nathan@25: if (!ToPtr) { nathan@25: length = max(length, FromLength * 2); // some reserve to avoid later reallocations nathan@25: result = (char *)realloc(result, length); nathan@25: ToPtr = result; nathan@25: ToLength = length; nathan@25: } nathan@25: else if (!ToLength) nathan@25: return From; // can't convert into a zero sized buffer nathan@25: ToLength--; // save space for terminating 0 nathan@25: char *Converted = ToPtr; nathan@25: while (FromLength > 0) { nathan@25: if (iconv(cd, &FromPtr, &FromLength, &ToPtr, &ToLength) == size_t(-1)) { nathan@25: if (errno == E2BIG || errno == EILSEQ && ToLength < 1) { nathan@25: if (To) nathan@25: break; // caller provided a fixed size buffer, but it was too small nathan@25: // The result buffer is too small, so increase it: nathan@25: size_t d = ToPtr - result; nathan@25: size_t r = length / 2; nathan@25: length += r; nathan@25: Converted = result = (char *)realloc(result, length); nathan@25: ToLength += r; nathan@25: ToPtr = result + d; nathan@25: } nathan@25: if (errno == EILSEQ) { nathan@25: // A character can't be converted, so mark it with '?' and proceed: nathan@25: FromPtr++; nathan@25: FromLength--; nathan@25: *ToPtr++ = '?'; nathan@25: ToLength--; nathan@25: } nathan@25: else if (errno != E2BIG) nathan@25: return From; // unknown error, return original string nathan@25: } nathan@25: } nathan@25: *ToPtr = 0; nathan@25: return Converted; nathan@25: } nathan@25: return From; nathan@25: } nathan@25: nathan@25: #endif