lots of fsCharset, utf8/ascii converting clean-up and robustness stuff
Also, if fsCharsetToUtf8 can't convert to valid UTF-8, then don't add it to the db, this way clients don't have to worry about weirdness and it will force ppl to convert it. git-svn-id: https://svn.musicpd.org/mpd/trunk@711 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
107
src/charConv.c
107
src/charConv.c
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
|
||||
#include "charConv.h"
|
||||
#include "mpd_types.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
@@ -25,14 +27,21 @@
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
iconv_t char_conv_iconv;
|
||||
#endif
|
||||
|
||||
char * char_conv_to = NULL;
|
||||
char * char_conv_from = NULL;
|
||||
#endif
|
||||
mpd_sint8 char_conv_same = 0;
|
||||
mpd_sint8 char_conv_use_iconv = 0;
|
||||
|
||||
/* 1 is to use asciiToUtf8
|
||||
0 is not to use ascii/utf8 converter
|
||||
-1 is to use utf8ToAscii*/
|
||||
mpd_sint8 char_conv_asciiToUtf8 = 0;
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
int setCharSetConversion(char * to, char * from) {
|
||||
#ifdef HAVE_ICONV
|
||||
if(char_conv_to && strcmp(to,char_conv_to)==0 &&
|
||||
char_conv_from && strcmp(from,char_conv_from)==0)
|
||||
{
|
||||
@@ -41,60 +50,100 @@ int setCharSetConversion(char * to, char * from) {
|
||||
|
||||
closeCharSetConversion();
|
||||
|
||||
if(0==strcmp(to,from)) {
|
||||
char_conv_same = 1;
|
||||
char_conv_to = strdup(to);
|
||||
char_conv_from = strdup(from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(to,"UTF-8")==0 && strcmp(from,"ISO-8859-1")==0) {
|
||||
char_conv_asciiToUtf8 = 1;
|
||||
}
|
||||
else if(strcmp(to,"ISO-8859-1")==0 && strcmp(from,"UTF-8")==0) {
|
||||
char_conv_asciiToUtf8 = -1;
|
||||
}
|
||||
|
||||
if(char_conv_asciiToUtf8!=0) {
|
||||
char_conv_to = strdup(to);
|
||||
char_conv_from = strdup(from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
if((char_conv_iconv = iconv_open(to,from))==(iconv_t)(-1)) return -1;
|
||||
|
||||
char_conv_to = strdup(to);
|
||||
char_conv_from = strdup(from);
|
||||
char_conv_use_iconv = 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char * convStrDup(char * string) {
|
||||
#ifdef HAVE_ICONV
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t inleft = strlen(string);
|
||||
char * ret;
|
||||
size_t outleft;
|
||||
size_t retlen = 0;
|
||||
size_t err;
|
||||
char * bufferPtr;
|
||||
|
||||
if(!char_conv_to) return NULL;
|
||||
|
||||
ret = malloc(1);
|
||||
ret[0] = '\0';
|
||||
if(char_conv_same) return strdup(string);
|
||||
|
||||
while(inleft) {
|
||||
bufferPtr = buffer;
|
||||
outleft = BUFFER_SIZE;
|
||||
err = iconv(char_conv_iconv,&string,&inleft,&bufferPtr,
|
||||
#ifdef HAVE_ICONV
|
||||
if(char_conv_use_iconv) {
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t inleft = strlen(string);
|
||||
char * ret;
|
||||
size_t outleft;
|
||||
size_t retlen = 0;
|
||||
size_t err;
|
||||
char * bufferPtr;
|
||||
|
||||
ret = malloc(1);
|
||||
ret[0] = '\0';
|
||||
|
||||
while(inleft) {
|
||||
bufferPtr = buffer;
|
||||
outleft = BUFFER_SIZE;
|
||||
err = iconv(char_conv_iconv,&string,&inleft,&bufferPtr,
|
||||
&outleft);
|
||||
if(outleft==BUFFER_SIZE || (err<0 && errno!=E2BIG)) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
if(outleft==BUFFER_SIZE || (err<0 && errno!=E2BIG)) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = realloc(ret,retlen+BUFFER_SIZE-outleft+1);
|
||||
memcpy(ret+retlen,buffer,BUFFER_SIZE-outleft);
|
||||
retlen+=BUFFER_SIZE-outleft;
|
||||
ret[retlen] = '\0';
|
||||
}
|
||||
|
||||
ret = realloc(ret,retlen+BUFFER_SIZE-outleft+1);
|
||||
memcpy(ret+retlen,buffer,BUFFER_SIZE-outleft);
|
||||
retlen+=BUFFER_SIZE-outleft;
|
||||
ret[retlen] = '\0';
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(char_conv_asciiToUtf8) {
|
||||
case 1:
|
||||
return asciiStrToUtf8Dup(string);
|
||||
break;
|
||||
case -1:
|
||||
return utf8StrToAsciiDup(string);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void closeCharSetConversion() {
|
||||
#ifdef HAVE_ICONV
|
||||
if(char_conv_to) {
|
||||
iconv_close(char_conv_iconv);
|
||||
#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_asciiToUtf8 = 0;
|
||||
char_conv_use_iconv = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user