Initial revision 6759
[qball-mpd.git] / src / .svn / text-base / utf8.c.svn-base
blob2061a78de768c5f58c93ec73aff857347c4f6034
1 /* the Music Player Daemon (MPD)
2  * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
3  * This project's homepage is: http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
19 #include "utf8.h"
20 #include "utils.h"
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
26 static char *latin1ToUtf8(char c)
28         static unsigned char utf8[3];
29         unsigned char uc = c;
31         memset(utf8, 0, 3);
33         if (uc < 128)
34                 utf8[0] = uc;
35         else if (uc < 192) {
36                 utf8[0] = 194;
37                 utf8[1] = uc;
38         } else {
39                 utf8[0] = 195;
40                 utf8[1] = uc - 64;
41         }
43         return (char *)utf8;
46 char *latin1StrToUtf8Dup(char *latin1)
48         /* utf8 should have at most two char's per latin1 char */
49         int len = strlen(latin1) * 2 + 1;
50         char *ret = xmalloc(len);
51         char *cp = ret;
52         char *utf8;
54         memset(ret, 0, len);
56         len = 0;
58         while (*latin1) {
59                 utf8 = latin1ToUtf8(*latin1);
60                 while (*utf8) {
61                         *(cp++) = *(utf8++);
62                         len++;
63                 }
64                 latin1++;
65         }
67         return xrealloc(ret, len + 1);
70 static char utf8ToLatin1(char *inUtf8)
72         unsigned char c = 0;
73         unsigned char *utf8 = (unsigned char *)inUtf8;
75         if (utf8[0] < 128)
76                 return utf8[0];
77         else if (utf8[0] == 195)
78                 c += 64;
79         else if (utf8[0] != 194)
80                 return '?';
81         return (char)(c + utf8[1]);
84 static int validateUtf8Char(char *inUtf8Char)
86         unsigned char *utf8Char = (unsigned char *)inUtf8Char;
88         if (utf8Char[0] < 0x80)
89                 return 1;
91         if (utf8Char[0] >= 0xC0 && utf8Char[0] <= 0xFD) {
92                 int count = 1;
93                 char t = 1 << 5;
94                 int i;
95                 while (count < 6 && (t & utf8Char[0])) {
96                         t = (t >> 1);
97                         count++;
98                 }
99                 if (count > 5)
100                         return 0;
101                 for (i = 1; i <= count; i++) {
102                         if (utf8Char[i] < 0x80 || utf8Char[i] > 0xBF)
103                                 return 0;
104                 }
105                 return count + 1;
106         } else
107                 return 0;
110 int validUtf8String(char *string)
112         int ret;
114         while (*string) {
115                 ret = validateUtf8Char(string);
116                 if (0 == ret)
117                         return 0;
118                 string += ret;
119         }
121         return 1;
124 char *utf8StrToLatin1Dup(char *utf8)
126         /* utf8 should have at most two char's per latin1 char */
127         int len = strlen(utf8) + 1;
128         char *ret = xmalloc(len);
129         char *cp = ret;
130         int count;
132         memset(ret, 0, len);
134         len = 0;
136         while (*utf8) {
137                 count = validateUtf8Char(utf8);
138                 if (!count) {
139                         free(ret);
140                         return NULL;
141                 }
142                 *(cp++) = utf8ToLatin1(utf8);
143                 utf8 += count;
144                 len++;
145         }
147         return xrealloc(ret, len + 1);