path, tag_id3: use g_convert() instead of charConv.c
GLib provides an easier API for character set conversion than iconv(). Use g_convert() / g_convert_with_fallback() for all character conversions. We should optimize the path.h API later to return a newly allocated buffer, so we can just pass GLib's return value.
This commit is contained in:
parent
e89599eaad
commit
8746a58ab9
@ -45,7 +45,6 @@ mpd_headers = \
|
|||||||
output_control.h \
|
output_control.h \
|
||||||
audioOutputs/audioOutput_shout.h \
|
audioOutputs/audioOutput_shout.h \
|
||||||
buffer2array.h \
|
buffer2array.h \
|
||||||
charConv.h \
|
|
||||||
command.h \
|
command.h \
|
||||||
idle.h \
|
idle.h \
|
||||||
condition.h \
|
condition.h \
|
||||||
@ -131,7 +130,6 @@ mpd_SOURCES = \
|
|||||||
output_control.c \
|
output_control.c \
|
||||||
output_init.c \
|
output_init.c \
|
||||||
buffer2array.c \
|
buffer2array.c \
|
||||||
charConv.c \
|
|
||||||
command.c \
|
command.c \
|
||||||
idle.c \
|
idle.c \
|
||||||
condition.c \
|
condition.c \
|
||||||
|
177
src/charConv.c
177
src/charConv.c
@ -1,177 +0,0 @@
|
|||||||
/* the Music Player Daemon (MPD)
|
|
||||||
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
|
|
||||||
* This project's homepage is: http://www.musicpd.org
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "charConv.h"
|
|
||||||
#include "utf8.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "path.h"
|
|
||||||
#include "os_compat.h"
|
|
||||||
|
|
||||||
#include "../config.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
#include <iconv.h>
|
|
||||||
static iconv_t char_conv_iconv;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char *char_conv_to;
|
|
||||||
static char *char_conv_from;
|
|
||||||
static int8_t char_conv_same;
|
|
||||||
static int8_t char_conv_use_iconv;
|
|
||||||
|
|
||||||
/* 1 is to use latin1ToUtf8
|
|
||||||
0 is not to use latin1/utf8 converter
|
|
||||||
-1 is to use utf8ToLatin1*/
|
|
||||||
static int8_t char_conv_latin1ToUtf8;
|
|
||||||
|
|
||||||
#define BUFFER_SIZE MPD_PATH_MAX
|
|
||||||
|
|
||||||
static void closeCharSetConversion(void);
|
|
||||||
|
|
||||||
int setCharSetConversion(const char *to, const char *from)
|
|
||||||
{
|
|
||||||
if (char_conv_to && char_conv_from) {
|
|
||||||
if (char_conv_latin1ToUtf8 &&
|
|
||||||
!strcmp(from, char_conv_to) &&
|
|
||||||
!strcmp(to, char_conv_from)) {
|
|
||||||
char *swap = char_conv_from;
|
|
||||||
char_conv_from = char_conv_to;
|
|
||||||
char_conv_to = swap;
|
|
||||||
char_conv_latin1ToUtf8 *= -1;
|
|
||||||
return 0;
|
|
||||||
} else if (!strcmp(to, char_conv_to) &&
|
|
||||||
!strcmp(from,char_conv_from)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closeCharSetConversion();
|
|
||||||
|
|
||||||
if (0 == strcmp(to, from)) {
|
|
||||||
char_conv_same = 1;
|
|
||||||
char_conv_to = xstrdup(to);
|
|
||||||
char_conv_from = xstrdup(from);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(to, "UTF-8") == 0 && strcmp(from, "ISO-8859-1") == 0) {
|
|
||||||
char_conv_latin1ToUtf8 = 1;
|
|
||||||
} else if (strcmp(to, "ISO-8859-1") == 0 && strcmp(from, "UTF-8") == 0) {
|
|
||||||
char_conv_latin1ToUtf8 = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (char_conv_latin1ToUtf8 != 0) {
|
|
||||||
char_conv_to = xstrdup(to);
|
|
||||||
char_conv_from = xstrdup(from);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
if ((char_conv_iconv = iconv_open(to, from)) == (iconv_t) (-1))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
char_conv_to = xstrdup(to);
|
|
||||||
char_conv_from = xstrdup(from);
|
|
||||||
char_conv_use_iconv = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
static inline size_t deconst_iconv(iconv_t cd,
|
|
||||||
const char **inbuf, size_t *inbytesleft,
|
|
||||||
char **outbuf, size_t *outbytesleft)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
const char **a;
|
|
||||||
char **b;
|
|
||||||
} deconst;
|
|
||||||
|
|
||||||
deconst.a = inbuf;
|
|
||||||
|
|
||||||
return iconv(cd, deconst.b, inbytesleft, outbuf, outbytesleft);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *char_conv_str(char *dest, const char *string)
|
|
||||||
{
|
|
||||||
if (!char_conv_to)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (char_conv_same)
|
|
||||||
return strcpy(dest, string);
|
|
||||||
|
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
if (char_conv_use_iconv) {
|
|
||||||
/* not optimized: */
|
|
||||||
char buffer[BUFFER_SIZE];
|
|
||||||
size_t inleft = strlen(string);
|
|
||||||
size_t outleft;
|
|
||||||
size_t retlen = 0;
|
|
||||||
size_t err;
|
|
||||||
char *bufferPtr;
|
|
||||||
|
|
||||||
dest[0] = '\0';
|
|
||||||
|
|
||||||
while (inleft) {
|
|
||||||
bufferPtr = buffer;
|
|
||||||
outleft = BUFFER_SIZE;
|
|
||||||
err =
|
|
||||||
deconst_iconv(char_conv_iconv, &string, &inleft,
|
|
||||||
&bufferPtr, &outleft);
|
|
||||||
if (outleft == BUFFER_SIZE
|
|
||||||
|| (err == (size_t)-1L && errno != E2BIG)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(dest + retlen, buffer, BUFFER_SIZE - outleft);
|
|
||||||
retlen += BUFFER_SIZE - outleft;
|
|
||||||
dest[retlen] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (char_conv_latin1ToUtf8) {
|
|
||||||
case 1:
|
|
||||||
return latin1_to_utf8(dest, string);
|
|
||||||
case -1:
|
|
||||||
return utf8_to_latin1(dest, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void closeCharSetConversion(void)
|
|
||||||
{
|
|
||||||
if (char_conv_to) {
|
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
if (char_conv_use_iconv)
|
|
||||||
iconv_close(char_conv_iconv);
|
|
||||||
#endif
|
|
||||||
free(char_conv_to);
|
|
||||||
free(char_conv_from);
|
|
||||||
char_conv_to = NULL;
|
|
||||||
char_conv_from = NULL;
|
|
||||||
char_conv_same = 0;
|
|
||||||
char_conv_latin1ToUtf8 = 0;
|
|
||||||
char_conv_use_iconv = 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/* the Music Player Daemon (MPD)
|
|
||||||
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
|
|
||||||
* This project's homepage is: http://www.musicpd.org
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CHAR_CONV_H
|
|
||||||
#define CHAR_CONV_H
|
|
||||||
|
|
||||||
int setCharSetConversion(const char *to, const char *from);
|
|
||||||
|
|
||||||
char *char_conv_str(char *dest, const char *string);
|
|
||||||
|
|
||||||
#endif
|
|
54
src/path.c
54
src/path.c
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "charConv.h"
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -32,28 +31,48 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
const char *musicDir;
|
const char *musicDir;
|
||||||
static const char *playlistDir;
|
static const char *playlistDir;
|
||||||
static size_t music_dir_len;
|
static size_t music_dir_len;
|
||||||
static size_t playlist_dir_len;
|
static size_t playlist_dir_len;
|
||||||
static char *fsCharset;
|
static char *fsCharset;
|
||||||
|
|
||||||
static char *path_conv_charset(char *dest, const char *to,
|
|
||||||
const char *from, const char *str)
|
|
||||||
{
|
|
||||||
return setCharSetConversion(to, from) ? NULL : char_conv_str(dest, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *fs_charset_to_utf8(char *dst, const char *str)
|
char *fs_charset_to_utf8(char *dst, const char *str)
|
||||||
{
|
{
|
||||||
char *ret = path_conv_charset(dst, "UTF-8", fsCharset, str);
|
gchar *p;
|
||||||
return (ret && !validUtf8String(ret, strlen(ret))) ? NULL : ret;
|
GError *error = NULL;
|
||||||
|
|
||||||
|
p = g_convert(str, -1,
|
||||||
|
fsCharset, "utf-8",
|
||||||
|
NULL, NULL, &error);
|
||||||
|
if (p == NULL)
|
||||||
|
/* no fallback */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
g_strlcpy(dst, p, MPD_PATH_MAX);
|
||||||
|
g_free(p);
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *utf8_to_fs_charset(char *dst, const char *str)
|
char *utf8_to_fs_charset(char *dst, const char *str)
|
||||||
{
|
{
|
||||||
char *ret = path_conv_charset(dst, fsCharset, "UTF-8", str);
|
gchar *p;
|
||||||
return ret ? ret : strcpy(dst, str);
|
GError *error = NULL;
|
||||||
|
|
||||||
|
p = g_convert(str, -1,
|
||||||
|
"utf-8", fsCharset,
|
||||||
|
NULL, NULL, &error);
|
||||||
|
if (p == NULL) {
|
||||||
|
/* fall back to UTF-8 */
|
||||||
|
g_error_free(error);
|
||||||
|
return strcpy(dst, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strlcpy(dst, p, MPD_PATH_MAX);
|
||||||
|
g_free(p);
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFsCharset(const char *charset)
|
void setFsCharset(const char *charset)
|
||||||
@ -67,19 +86,6 @@ void setFsCharset(const char *charset)
|
|||||||
|
|
||||||
DEBUG("setFsCharset: fs charset is: %s\n", fsCharset);
|
DEBUG("setFsCharset: fs charset is: %s\n", fsCharset);
|
||||||
|
|
||||||
if (setCharSetConversion("UTF-8", fsCharset) != 0) {
|
|
||||||
WARNING("fs charset conversion problem: "
|
|
||||||
"not able to convert from \"%s\" to \"%s\"\n",
|
|
||||||
fsCharset, "UTF-8");
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
if (setCharSetConversion(fsCharset, "UTF-8") != 0) {
|
|
||||||
WARNING("fs charset conversion problem: "
|
|
||||||
"not able to convert from \"%s\" to \"%s\"\n",
|
|
||||||
"UTF-8", fsCharset);
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
free(fsCharset);
|
free(fsCharset);
|
||||||
WARNING("setting fs charset to ISO-8859-1!\n");
|
WARNING("setting fs charset to ISO-8859-1!\n");
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "charConv.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_ID3TAG
|
#ifdef HAVE_ID3TAG
|
||||||
|
#include <glib.h>
|
||||||
#include <id3tag.h>
|
#include <id3tag.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -54,16 +54,21 @@ static id3_utf8_t * processID3FieldString (int is_id3v1, const id3_ucs4_t *ucs4,
|
|||||||
/* use encoding field here? */
|
/* use encoding field here? */
|
||||||
if (is_id3v1 &&
|
if (is_id3v1 &&
|
||||||
(encoding = getConfigParamValue(CONF_ID3V1_ENCODING))) {
|
(encoding = getConfigParamValue(CONF_ID3V1_ENCODING))) {
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
isostr = id3_ucs4_latin1duplicate(ucs4);
|
isostr = id3_ucs4_latin1duplicate(ucs4);
|
||||||
if (mpd_unlikely(!isostr)) {
|
if (mpd_unlikely(!isostr)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
setCharSetConversion("UTF-8", encoding);
|
|
||||||
utf8 = xmalloc(strlen((char *)isostr) + 1);
|
utf8 = (id3_utf8_t *)
|
||||||
utf8 = (id3_utf8_t *)char_conv_str((char *)utf8, (char *)isostr);
|
g_convert_with_fallback((const char*)isostr, -1,
|
||||||
if (!utf8) {
|
encoding, "utf-8",
|
||||||
|
NULL, NULL, NULL, &error);
|
||||||
|
if (utf8 == NULL) {
|
||||||
DEBUG("Unable to convert %s string to UTF-8: "
|
DEBUG("Unable to convert %s string to UTF-8: "
|
||||||
"'%s'\n", encoding, isostr);
|
"'%s'\n", encoding, isostr);
|
||||||
|
g_error_free(error);
|
||||||
free(isostr);
|
free(isostr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user