Imported Upstream version 1.0.5
[platform/upstream/fribidi.git] / lib / fribidi-char-sets.c
1 /* FriBidi
2  * fribidi-char-sets.c - character set conversion routines
3  *
4  * Authors:
5  *   Behdad Esfahbod, 2001, 2002, 2004
6  *   Dov Grobgeld, 1999, 2000
7  *
8  * Copyright (C) 2004 Sharif FarsiWeb, Inc
9  * Copyright (C) 2001,2002 Behdad Esfahbod
10  * Copyright (C) 1999,2000 Dov Grobgeld
11  * 
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * 
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  * 
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this library, in a file named COPYING; if not, write to the
24  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA
26  * 
27  * For licensing issues, contact <fribidi.license@gmail.com>.
28  */
29
30 #include <common.h>
31
32 #include <fribidi-char-sets.h>
33
34 #include "fribidi-char-sets-cap-rtl.h"
35 #include "fribidi-char-sets-utf8.h"
36 #include "fribidi-char-sets-iso8859-6.h"
37 #include "fribidi-char-sets-cp1256.h"
38 #include "fribidi-char-sets-iso8859-8.h"
39 #include "fribidi-char-sets-cp1255.h"
40
41 typedef struct
42 {
43   FriBidiChar (
44   *charset_to_unicode_c
45   ) (
46   char ch
47   );
48
49   FriBidiStrIndex (
50   *charset_to_unicode
51   ) (
52   const char *s,
53   FriBidiStrIndex len,
54   FriBidiChar *us
55   );
56
57   char (
58   *unicode_to_charset_c
59   ) (
60   FriBidiChar uch
61   );
62
63   FriBidiStrIndex (
64   *unicode_to_charset
65   ) (
66   const FriBidiChar *us,
67   FriBidiStrIndex len,
68   char *s
69   );
70
71   const char *name;
72
73   const char *title;
74
75   const char *(
76   *desc
77   ) (
78   void
79   );
80 }
81 FriBidiCharSetHandler;
82
83 static FriBidiCharSetHandler char_sets[FRIBIDI_CHAR_SETS_NUM + 1] = {
84   {NULL, NULL, NULL, NULL, "N/A", "Character set not available", NULL},
85 # define _FRIBIDI_ADD_CHAR_SET_ONE2ONE(CHAR_SET, char_set) \
86   { \
87     fribidi_##char_set##_to_unicode_c, \
88     NULL, \
89     fribidi_unicode_to_##char_set##_c, \
90     NULL, \
91     fribidi_char_set_name_##char_set, \
92     fribidi_char_set_title_##char_set, \
93     fribidi_char_set_desc_##char_set \
94   },
95 # define _FRIBIDI_ADD_CHAR_SET_OTHERS(CHAR_SET, char_set) \
96   { \
97     NULL, \
98     fribidi_##char_set##_to_unicode, \
99     NULL, \
100     fribidi_unicode_to_##char_set, \
101     fribidi_char_set_name_##char_set, \
102     fribidi_char_set_title_##char_set, \
103     fribidi_char_set_desc_##char_set \
104   },
105 # include <fribidi-char-sets-list.h>
106 # undef _FRIBIDI_ADD_CHAR_SET_OTHERS
107 # undef _FRIBIDI_ADD_CHAR_SET_ONE2ONE
108 };
109
110 static char
111 fribidi_toupper (
112   /* input */
113   char c
114 )
115 {
116   return c < 'a' || c > 'z' ? c : c + 'A' - 'a';
117 }
118
119 static int
120 fribidi_strcasecmp (
121   /* input */
122   const char *s1,
123   const char *s2
124 )
125 {
126   while (*s1 && fribidi_toupper (*s1) == fribidi_toupper (*s2))
127     {
128       s1++;
129       s2++;
130     }
131   return fribidi_toupper (*s1) - fribidi_toupper (*s2);
132 }
133
134 FRIBIDI_ENTRY FriBidiCharSet
135 fribidi_parse_charset (
136   /* input */
137   const char *s
138 )
139 {
140   int i;
141
142   for (i = FRIBIDI_CHAR_SETS_NUM; i; i--)
143     if (fribidi_strcasecmp (s, char_sets[i].name) == 0)
144       return i;
145
146   return FRIBIDI_CHAR_SET_NOT_FOUND;
147 }
148
149 FRIBIDI_ENTRY FriBidiStrIndex
150 fribidi_charset_to_unicode (
151   /* input */
152   FriBidiCharSet char_set,
153   const char *s,
154   FriBidiStrIndex len,
155   /* output */
156   FriBidiChar *us
157 )
158 {
159   if (char_sets[char_set].charset_to_unicode)
160     return (*char_sets[char_set].charset_to_unicode) (s, len, us);
161   else if (char_sets[char_set].charset_to_unicode_c)
162     {
163       register FriBidiStrIndex l;
164       for (l = len; l; l--)
165         *us++ = (*char_sets[char_set].charset_to_unicode_c) (*s++);
166       return len;
167     }
168   else
169     return 0;
170 }
171
172 FRIBIDI_ENTRY FriBidiStrIndex
173 fribidi_unicode_to_charset (
174   /* input */
175   FriBidiCharSet char_set,
176   const FriBidiChar *us,
177   FriBidiStrIndex len,
178   /* output */
179   char *s
180 )
181 {
182   if (char_sets[char_set].unicode_to_charset)
183     return (*char_sets[char_set].unicode_to_charset) (us, len, s);
184   else if (char_sets[char_set].unicode_to_charset_c)
185     {
186       register FriBidiStrIndex l;
187       for (l = len; l; l--)
188         *s++ = (*char_sets[char_set].unicode_to_charset_c) (*us++);
189       *s = '\0';
190       return len;
191     }
192   else
193     return 0;
194 }
195
196 FRIBIDI_ENTRY const char *
197 fribidi_char_set_name (
198   /* input */
199   FriBidiCharSet char_set
200 )
201 {
202   return char_sets[char_set].name ? char_sets[char_set].name : "";
203 }
204
205 FRIBIDI_ENTRY const char *
206 fribidi_char_set_title (
207   /* input */
208   FriBidiCharSet char_set
209 )
210 {
211   return char_sets[char_set].title ? char_sets[char_set].
212     title : fribidi_char_set_name (char_set);
213 }
214
215 FRIBIDI_ENTRY const char *
216 fribidi_char_set_desc (
217   /* input */
218   FriBidiCharSet char_set
219 )
220 {
221   return char_sets[char_set].desc ? char_sets[char_set].desc () : NULL;
222 }
223
224 /* Editor directions:
225  * vim:textwidth=78:tabstop=8:shiftwidth=2:autoindent:cindent
226  */