6 /* original in mysql, strings/strnlen.c.
7 uint strnlen(register const char *s, register uint maxlen)
9 const char *end= (const char *)memchr(s, '\0', maxlen);
10 return end ? (uint) (end - s) : maxlen;
14 strnlen (register const char *s, register int maxlen)
16 const char *end= (const char *)memchr(s, '\0', maxlen);
17 return end ? (int) (end - s) : maxlen;
22 #include "chise-name.h"
24 typedef DB CHISE_Attribute_Table;
26 CHISE_Attribute_Table*
27 chise_open_attribute_table (const unsigned char *db_dir,
28 const char *encoding, const char *feature,
30 u_int32_t accessmask, int modemask);
32 int chise_close_attribute_table (CHISE_Attribute_Table *db);
34 int chise_get_attribute_table (CHISE_Attribute_Table *db,
35 char *key, CHISE_Value *valdatum);
37 int chise_put_attribute_table (CHISE_Attribute_Table *db,
38 char *key, unsigned char *value);
41 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
44 chise_char_id_parse_c_string (unsigned char *str, int len)
48 if ( (len >= 2) && (str[i++] == '?') )
50 unsigned char c = str[i++];
67 return c & (0x80 | 0x1F);
101 if (counter + 2 <= len)
105 for (j = 0; j < counter; j++)
106 cid = (cid << 6) | (str[j + i] & 0x3F);
114 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, int len)
126 else if (cid == '\n')
133 else if (cid == '\r')
140 else if (cid == 0x1C)
149 else if (cid <= 0x1F)
153 dest[i++] = '@' + cid;
157 else if ( (cid == ' ') || (cid == '"') ||
158 (cid == '#') || (cid == '\'') ||
159 (cid == '(') || (cid == ')') ||
160 (cid == ',') || (cid == '.') ||
161 (cid == ';') || (cid == '?') ||
162 (cid == '[') || (cid == '\\') ||
163 (cid == ']') || (cid == '`') )
170 else if (cid <= 0x7E)
176 else if (cid == 0x7F)
184 else if (cid <= 0x9F)
188 dest[i++] = ((cid + '@') >> 6) | 0xC0;
189 dest[i++] = ((cid + '@') & 0x3F) | 0x80;
193 else if (cid <= 0x7FF)
195 dest[i++] = (cid >> 6) | 0xC0;
196 dest[i++] = (cid & 0x3F) | 0x80;
200 else if (cid <= 0xFFFF)
202 dest[i++] = (cid >> 12) | 0xE0;
203 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
204 dest[i++]= (cid & 0x3F) | 0x80;
208 else if (cid <= 0x1FFFFF)
210 dest[i++]= (cid >> 18) | 0xF0;
211 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
212 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
213 dest[i++]= (cid & 0x3F) | 0x80;
217 else if (cid <= 0x3FFFFFF)
219 dest[i++]= (cid >> 24) | 0xF8;
220 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
221 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
222 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
223 dest[i++]= (cid & 0x3F) | 0x80;
229 dest[i++]= (cid >> 30) | 0xFC;
230 dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
231 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
232 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
233 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
234 dest[i++]= (cid & 0x3F) | 0x80;
244 unsigned char *location;
245 CHISE_NAME_TABLE* feature_names;
246 CHISE_NAME_TABLE* ccs_names;
250 chise_open_data_source (CHISE_DS_Type type, char *location)
252 CHISE_DS *ds = (CHISE_DS*)malloc (sizeof (CHISE_DS));
253 size_t len = strlen (location);
259 ds->location = (unsigned char*)malloc (len + 1);
260 if (ds->location == NULL)
265 strcpy (ds->location, location);
267 ds->feature_names = chise_make_name_table ();
268 if (ds->feature_names == NULL)
274 ds->ccs_names = chise_make_name_table ();
275 if (ds->ccs_names == NULL)
277 free (ds->feature_names);
285 chise_ds_close (CHISE_DS *ds)
287 if (ds->location != NULL)
289 if (ds->feature_names != NULL)
290 free (ds->feature_names);
291 if (ds->ccs_names != NULL)
292 free (ds->ccs_names);
298 chise_ds_get_feature (CHISE_DS *ds, const unsigned char *feature,
300 u_int32_t accessmask, int modemask)
302 CHISE_Feature_Table* ft;
304 ft = chise_name_table_get (ds->feature_names, feature);
308 ft = chise_ds_open_feature_table (ds, feature,
310 accessmask, modemask);
314 if (chise_name_table_put (ds->feature_names, feature, ft))
323 chise_ds_get_ccs (CHISE_DS *ds, const unsigned char *ccs,
325 u_int32_t accessmask, int modemask)
329 ct = chise_name_table_get (ds->ccs_names, ccs);
333 ct = chise_ds_open_ccs_table (ds, ccs,
335 accessmask, modemask);
339 if (chise_name_table_put (ds->ccs_names, ccs, ct))
341 chise_ccst_close (ct);
348 struct CHISE_Feature_Table
351 CHISE_Attribute_Table *db;
355 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature,
357 u_int32_t accessmask, int modemask)
359 CHISE_Feature_Table* table;
364 table = (CHISE_Feature_Table*)malloc (sizeof (CHISE_Feature_Table));
369 table->db = chise_open_attribute_table (ds->location,
370 "system-char-id", feature,
372 accessmask, modemask);
373 if (table->db == NULL)
382 chise_ft_close (CHISE_Feature_Table *table)
389 if (table->db == NULL)
392 status = chise_close_attribute_table (table->db);
398 chise_char_load_feature_value (CHISE_Char_ID cid,
399 CHISE_Feature_Table *table,
400 CHISE_Value *valdatum)
402 unsigned char key_buf[8];
404 chise_format_char_id (cid, key_buf, 8);
405 return chise_get_attribute_table (table->db,
410 chise_char_gets_feature_value (CHISE_Char_ID cid,
411 CHISE_Feature_Table *table,
412 unsigned char *buf, size_t size)
414 CHISE_Value valdatum;
415 unsigned char key_buf[8];
418 chise_format_char_id (cid, key_buf, 8);
419 status = chise_get_attribute_table (table->db,
423 if (size < valdatum.size)
425 strncpy (buf, valdatum.data, valdatum.size);
426 buf[valdatum.size] = '\0';
431 chise_char_feature_value_iterate (CHISE_Feature feature,
432 int (*func) (CHISE_Char_ID cid,
433 CHISE_Feature feature,
434 CHISE_Value *valdatum))
436 DBT keydatum, valdatum;
443 status = feature->db->cursor (feature->db, NULL, &dbcp, 0);
444 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
446 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
448 unsigned char *key_str = (unsigned char *)keydatum.data;
449 int key_len = strnlen (key_str, keydatum.size);
450 CHISE_Char_ID key = chise_char_id_parse_c_string (key_str, key_len);
453 if (ret = func (key, feature, &valdatum))
456 dbcp->c_close (dbcp);
460 struct CHISE_CCS_Table
463 CHISE_Attribute_Table *db;
467 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs,
469 u_int32_t accessmask, int modemask)
471 CHISE_CCS_Table* table;
476 table = (CHISE_CCS_Table*)malloc (sizeof (CHISE_CCS_Table));
481 table->db = chise_open_attribute_table (ds->location,
482 ccs, "system-char-id",
484 accessmask, modemask);
485 if (table->db == NULL)
494 chise_ccst_close (CHISE_CCS_Table *table)
501 if (table->db == NULL)
504 status = chise_close_attribute_table (table->db);
510 chise_ccs_decode (CHISE_CCS ccs, int code_point)
512 CHISE_Value valdatum;
516 sprintf(key_buf, "%d", code_point);
517 status = chise_get_attribute_table (ccs->db, key_buf, &valdatum);
521 = (unsigned char *)chise_value_data (&valdatum);
522 int len = strnlen (str, chise_value_size (&valdatum));
524 return chise_char_id_parse_c_string (str, len);
530 chise_ccst_put_char (CHISE_CCS_Table *table,
531 int code_point, CHISE_Char_ID cid)
533 CHISE_Value valdatum;
534 char key_buf[16], val_buf[8];
536 sprintf(key_buf, "%d", code_point);
537 chise_format_char_id (cid, val_buf, 8);
538 return chise_put_attribute_table (table->db, key_buf, val_buf);
542 CHISE_Attribute_Table*
543 chise_open_attribute_table (const unsigned char *db_dir,
544 const char *encoding, const char *feature,
546 u_int32_t accessmask, int modemask)
552 char *db_file_name, *sp;
554 status = db_create (&dbase, NULL, 0);
558 len = strlen (db_dir);
559 flen = strlen (feature);
560 size = len + strlen (encoding) + flen * 3 + 4;
561 db_file_name = alloca (size);
562 strcpy (db_file_name, db_dir);
563 if (db_file_name[len - 1] != '/')
565 db_file_name[len++] = '/';
566 db_file_name[len] = '\0';
568 strcat (db_file_name, encoding);
569 strcat (db_file_name, "/");
570 /* strcat (db_file_name, feature); */
571 sp = &db_file_name[strlen (db_file_name)];
572 for (i = 0; i < flen; i++)
576 if ( (c == '/') || (c == '%') )
578 sprintf (sp, "%%%02X", c);
585 status = dbase->open (dbase, db_file_name, NULL,
586 real_subtype, accessmask, modemask);
589 dbase->close (dbase, 0);
596 chise_close_attribute_table (CHISE_Attribute_Table *db)
607 chise_get_attribute_table (CHISE_Attribute_Table *db,
608 char *key, CHISE_Value *valdatum)
613 /* DB Version 2 requires DBT's to be zeroed before use. */
618 keydatum.size = strlen (key);
620 status = db->get (db, NULL, &keydatum, valdatum, 0);
625 chise_put_attribute_table (CHISE_Attribute_Table *db,
626 char *key, unsigned char *value)
628 DBT keydatum, valdatum;
631 /* DB Version 2 requires DBT's to be zeroed before use. */
636 keydatum.size = strlen (key);
638 valdatum.data = value;
639 valdatum.size = strlen (value);
641 status = db->put (db, NULL, &keydatum, &valdatum, 0);