Use <chise.h>.
[chise/libchise.git] / chise.c
1 #include "chise.h"
2
3 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
4
5
6 int
7 chise_open_data_source (CHISE_DS *ds, CHISE_DS_Type type, char *location)
8 {
9   ds->type = type;
10   ds->location = location;
11   return 0;
12 }
13
14 int
15 chise_close_data_source (CHISE_DS *ds)
16 {
17   ds->type = CHISE_DS_NONE;
18   ds->location = NULL;
19   return 0;
20 }
21
22
23 int
24 chise_open_decoding_table (CHISE_Decoding_Table **db,
25                            CHISE_DS *ds, const char *ccs,
26                            DBTYPE real_subtype,
27                            u_int32_t accessmask, int modemask)
28 {
29   return
30     chise_open_attribute_table (db, ds->location,
31                                 ccs, "system-char-id",
32                                 real_subtype, accessmask, modemask);
33 }
34
35 int
36 chise_close_decoding_table (CHISE_Decoding_Table *db)
37 {
38   if (db)
39     return chise_close_attribute_table (db);
40   return -1;
41 }
42
43 CHISE_Char_ID
44 chise_dt_get_char (CHISE_Decoding_Table *db, int code_point)
45 {
46   CHISE_Value valdatum;
47   int status = 0;
48   char key_buf[16];
49
50   sprintf(key_buf, "%d", code_point);
51   status = chise_get_attribute_table (db, key_buf, &valdatum);
52   if (!status)
53     {
54       unsigned char *str
55         = (unsigned char *)chise_value_to_c_string (&valdatum);
56       int len = strlen (str);
57       int i;
58
59       if ( (len >= 2) && (str[0] == '?') )
60         {
61           unsigned char c = str[1];
62           int counter;
63           CHISE_Char_ID cid;
64
65           if ( c < 0xC0 )
66             {
67               cid = c;
68               counter = 0;
69             }
70           else if ( c < 0xE0 )
71             {
72               cid = c & 0x1f;
73               counter = 1;
74             }
75           else if ( c < 0xF0 )
76             {
77               cid = c & 0x0f;
78               counter = 2;
79             }
80           else if ( c < 0xF8 )
81             {
82               cid = c & 0x07;
83               counter = 3;
84             }
85           else if ( c < 0xFC )
86             {
87               cid = c & 0x03;
88               counter = 4;
89             }
90           else
91             {
92               cid = c & 0x01;
93               counter = 5;
94             }
95
96           if (counter + 2 <= len)
97             {
98               int i;
99
100               for (i = 0; i < counter; i++)
101                 cid = (cid << 6) | (str[i + 2] & 0x3F);
102               return cid;
103             }
104         }
105     }
106   return -1;
107 }
108
109
110
111 int
112 chise_open_feature_table (CHISE_Feature_Table **db,
113                           CHISE_DS *ds, const char *feature,
114                           DBTYPE real_subtype,
115                           u_int32_t accessmask, int modemask)
116 {
117   return
118     chise_open_attribute_table (db, ds->location,
119                                 "system-char-id", feature,
120                                 real_subtype, accessmask, modemask);
121 }
122
123 int
124 chise_close_feature_table (CHISE_Feature_Table *db)
125 {
126   if (db)
127     return chise_close_attribute_table (db);
128   return -1;
129 }
130
131 int chise_ft_get_value (CHISE_Feature_Table *db,
132                         CHISE_Char_ID cid, CHISE_Value *valdatum)
133 {
134   unsigned char key_buf[8];
135
136   key_buf[0] = '?';
137   if (cid <= 0x7f)
138     {
139       key_buf[1] = cid;
140       key_buf[2] = '\0';
141     }
142   else if (cid <= 0x7ff)
143     {
144       key_buf[1] = (cid >> 6) | 0xc0;
145       key_buf[2] = (cid & 0x3f) | 0x80;
146       key_buf[3] = '\0';
147     }
148   else if (cid <= 0xffff)
149     {
150       key_buf[1] = (cid >> 12) | 0xe0;
151       key_buf[2]= ((cid >>  6) & 0x3f) | 0x80;
152       key_buf[3]=  (cid        & 0x3f) | 0x80;
153       key_buf[4] = '\0';
154     }
155   else if (cid <= 0x1fffff)
156     {
157       key_buf[1]=  (cid >> 18) | 0xf0;
158       key_buf[2]= ((cid >> 12) & 0x3f) | 0x80;
159       key_buf[3]= ((cid >>  6) & 0x3f) | 0x80;
160       key_buf[4]=  (cid        & 0x3f) | 0x80;
161       key_buf[5] = '\0';
162     }
163   else if (cid <= 0x3ffffff)
164     {
165       key_buf[1]=  (cid >> 24) | 0xf8;
166       key_buf[2]= ((cid >> 18) & 0x3f) | 0x80;
167       key_buf[3]= ((cid >> 12) & 0x3f) | 0x80;
168       key_buf[4]= ((cid >>  6) & 0x3f) | 0x80;
169       key_buf[5]=  (cid        & 0x3f) | 0x80;
170       key_buf[6] = '\0';
171     }
172   else
173     {
174       key_buf[1]=  (cid >> 30) | 0xfc;
175       key_buf[2]= ((cid >> 24) & 0x3f) | 0x80;
176       key_buf[3]= ((cid >> 18) & 0x3f) | 0x80;
177       key_buf[4]= ((cid >> 12) & 0x3f) | 0x80;
178       key_buf[5]= ((cid >>  6) & 0x3f) | 0x80;
179       key_buf[6]=  (cid        & 0x3f) | 0x80;
180       key_buf[7] = '\0';
181     }
182   return
183     chise_get_attribute_table (db, key_buf, valdatum);
184 }
185
186
187 int
188 chise_open_attribute_table (CHISE_Attribute_Table **db,
189                             const char *db_dir,
190                             const char *encoding, const char *feature,
191                             DBTYPE real_subtype,
192                             u_int32_t accessmask, int modemask)
193 {
194   DB* dbase;
195   int status;
196   int len;
197   int size;
198   char *db_file_name;
199
200   status = db_create (&dbase, NULL, 0);
201   if (status)
202     return -1;
203
204   len = strlen (db_dir);
205   size = len + strlen (encoding) + strlen (feature) + 4;
206   db_file_name = alloca (size);
207   strcpy (db_file_name, db_dir);
208   if (db_file_name[len - 1] != '/')
209     {
210       db_file_name[len++] = '/';
211       db_file_name[len] = '\0';
212     }
213   strcat (db_file_name, encoding);
214   strcat (db_file_name, "/");
215   strcat (db_file_name, feature);
216   status = dbase->open (dbase, db_file_name, NULL,
217                         real_subtype, accessmask, modemask);
218   if (status)
219     {
220       dbase->close (dbase, 0);
221       return -1;
222     }
223   *db = dbase;
224   return 0;
225 }
226
227 int
228 chise_close_attribute_table (CHISE_Attribute_Table *db)
229 {
230   if (db)
231     {
232       db->sync  (db, 0);
233       db->close (db, 0);
234     }
235   return 0;
236 }
237
238 int
239 chise_get_attribute_table (CHISE_Attribute_Table *db,
240                            char *key, CHISE_Value *valdatum)
241 {
242   DBT keydatum;
243   int status = 0;
244
245   /* DB Version 2 requires DBT's to be zeroed before use. */
246   xzero (keydatum);
247   xzero (*valdatum);
248
249   keydatum.data = key;
250   keydatum.size = strlen (key);
251
252   status = db->get (db, NULL, &keydatum, valdatum, 0);
253   return status;
254 }