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:
		| @@ -45,7 +45,6 @@ mpd_headers = \ | ||||
| 	output_control.h \ | ||||
| 	audioOutputs/audioOutput_shout.h \ | ||||
| 	buffer2array.h \ | ||||
| 	charConv.h \ | ||||
| 	command.h \ | ||||
| 	idle.h \ | ||||
| 	condition.h \ | ||||
| @@ -131,7 +130,6 @@ mpd_SOURCES = \ | ||||
| 	output_control.c \ | ||||
| 	output_init.c \ | ||||
| 	buffer2array.c \ | ||||
| 	charConv.c \ | ||||
| 	command.c \ | ||||
| 	idle.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 "log.h" | ||||
| #include "charConv.h" | ||||
| #include "conf.h" | ||||
| #include "utf8.h" | ||||
| #include "utils.h" | ||||
| @@ -32,28 +31,48 @@ | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| const char *musicDir; | ||||
| static const char *playlistDir; | ||||
| static size_t music_dir_len; | ||||
| static size_t playlist_dir_len; | ||||
| 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 *ret = path_conv_charset(dst, "UTF-8", fsCharset, str); | ||||
| 	return (ret && !validUtf8String(ret, strlen(ret))) ? NULL : ret; | ||||
| 	gchar *p; | ||||
| 	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 *ret = path_conv_charset(dst, fsCharset, "UTF-8", str); | ||||
| 	return ret ? ret : strcpy(dst, str); | ||||
| 	gchar *p; | ||||
| 	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) | ||||
| @@ -67,19 +86,6 @@ void setFsCharset(const char *charset) | ||||
|  | ||||
| 	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) { | ||||
| 		free(fsCharset); | ||||
| 		WARNING("setting fs charset to ISO-8859-1!\n"); | ||||
|   | ||||
| @@ -21,9 +21,9 @@ | ||||
| #include "utils.h" | ||||
| #include "log.h" | ||||
| #include "conf.h" | ||||
| #include "charConv.h" | ||||
|  | ||||
| #ifdef HAVE_ID3TAG | ||||
| #include <glib.h> | ||||
| #include <id3tag.h> | ||||
| #endif | ||||
|  | ||||
| @@ -54,16 +54,21 @@ static id3_utf8_t * processID3FieldString (int is_id3v1, const id3_ucs4_t *ucs4, | ||||
| 	/* use encoding field here? */ | ||||
| 	if (is_id3v1 && | ||||
| 	    (encoding = getConfigParamValue(CONF_ID3V1_ENCODING))) { | ||||
| 		GError *error = NULL; | ||||
|  | ||||
| 		isostr = id3_ucs4_latin1duplicate(ucs4); | ||||
| 		if (mpd_unlikely(!isostr)) { | ||||
| 			return NULL; | ||||
| 		} | ||||
| 		setCharSetConversion("UTF-8", encoding); | ||||
| 		utf8 = xmalloc(strlen((char *)isostr) + 1); | ||||
| 		utf8 = (id3_utf8_t *)char_conv_str((char *)utf8, (char *)isostr); | ||||
| 		if (!utf8) { | ||||
|  | ||||
| 		utf8 = (id3_utf8_t *) | ||||
| 			g_convert_with_fallback((const char*)isostr, -1, | ||||
| 						encoding, "utf-8", | ||||
| 						NULL, NULL, NULL, &error); | ||||
| 		if (utf8 == NULL) { | ||||
| 			DEBUG("Unable to convert %s string to UTF-8: " | ||||
| 			      "'%s'\n", encoding, isostr); | ||||
| 			g_error_free(error); | ||||
| 			free(isostr); | ||||
| 			return NULL; | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann