10 #include "chise-name.h"
14 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature);
16 int chise_ft_close (CHISE_Feature_Table *table);
20 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs);
22 int chise_ccst_close (CHISE_CCS_Table *table);
25 typedef DB CHISE_Attribute_Table;
27 CHISE_Attribute_Table*
28 CHISE_Attribute_Table_open (const unsigned char *db_dir,
29 const char *encoding, const char *feature,
31 u_int32_t accessmask, int modemask);
33 int CHISE_Attribute_Table_close (CHISE_Attribute_Table *db);
35 int chise_attribute_table_get (CHISE_Attribute_Table *db,
36 char *key, CHISE_Value *valdatum);
38 int chise_attribute_table_put (CHISE_Attribute_Table *db,
39 char *key, unsigned char *value);
42 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
45 chise_char_id_parse_c_string (unsigned char *str, size_t len);
48 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len);
54 unsigned char *location;
55 CHISE_NAME_TABLE* feature_names;
56 CHISE_NAME_TABLE* ccs_names;
62 CHISE_DS_open (CHISE_DS_Type type, char *location,
63 DBTYPE subtype, int modemask)
65 CHISE_DS *ds = (CHISE_DS*)malloc (sizeof (CHISE_DS));
66 size_t len = strlen (location);
72 ds->subtype = subtype;
73 ds->modemask = modemask;
74 ds->location = (unsigned char*)malloc (len + 1);
75 if (ds->location == NULL)
80 strcpy (ds->location, location);
82 ds->feature_names = chise_make_name_table ();
83 if (ds->feature_names == NULL)
89 ds->ccs_names = chise_make_name_table ();
90 if (ds->ccs_names == NULL)
92 free (ds->feature_names);
100 CHISE_DS_close (CHISE_DS *ds)
102 if (ds->location != NULL)
104 if (ds->feature_names != NULL)
105 free (ds->feature_names);
106 if (ds->ccs_names != NULL)
107 free (ds->ccs_names);
113 chise_ds_get_feature (CHISE_DS *ds, const unsigned char *feature)
115 CHISE_Feature_Table* ft;
117 ft = chise_name_table_get (ds->feature_names, feature);
121 ft = chise_ds_open_feature_table (ds, feature);
125 if (chise_name_table_put (ds->feature_names, feature, ft))
134 chise_ds_get_ccs (CHISE_DS *ds, const unsigned char *ccs)
138 ct = chise_name_table_get (ds->ccs_names, ccs);
142 ct = chise_ds_open_ccs_table (ds, ccs);
146 if (chise_name_table_put (ds->ccs_names, ccs, ct))
148 chise_ccst_close (ct);
155 struct CHISE_Feature_Table
159 CHISE_Attribute_Table *db;
164 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature)
166 CHISE_Feature_Table* table;
167 size_t len = strlen (feature);
172 table = (CHISE_Feature_Table*)malloc (sizeof (CHISE_Feature_Table));
179 table->name = (unsigned char*)malloc (len + 1);
180 if (table->name == NULL)
185 strcpy (table->name, feature);
190 chise_ft_close (CHISE_Feature_Table *table)
197 if (table->db == NULL)
200 status = CHISE_Attribute_Table_close (table->db);
202 if (table->name == NULL)
214 chise_feature_setup_db (CHISE_Feature feature, int writable)
220 if ((feature->access & DB_CREATE) == 0)
222 if (feature->db != NULL)
224 CHISE_Attribute_Table_close (feature->db);
234 if (feature->db == NULL)
236 CHISE_DS *ds = feature->ds;
239 = CHISE_Attribute_Table_open (ds->location,
240 "system-char-id", feature->name,
241 ds->subtype, access, ds->modemask);
242 if (feature->db == NULL)
244 feature->access = access;
250 chise_feature_sync (CHISE_Feature feature)
254 if (feature->db == NULL)
257 status = CHISE_Attribute_Table_close (feature->db);
264 chise_char_set_feature_value (CHISE_Char_ID cid,
265 CHISE_Feature feature,
266 unsigned char *value)
268 unsigned char key_buf[8];
272 if (chise_feature_setup_db (feature, 1))
274 chise_format_char_id (cid, key_buf, 8);
275 return chise_attribute_table_put (feature->db, key_buf, value);
279 chise_char_load_feature_value (CHISE_Char_ID cid,
280 CHISE_Feature_Table *table,
281 CHISE_Value *valdatum)
283 unsigned char key_buf[8];
285 if (chise_feature_setup_db (table, 0))
287 chise_format_char_id (cid, key_buf, 8);
288 return chise_attribute_table_get (table->db, key_buf, valdatum);
292 chise_char_gets_feature_value (CHISE_Char_ID cid,
293 CHISE_Feature_Table *table,
294 unsigned char *buf, size_t size)
296 CHISE_Value valdatum;
297 unsigned char key_buf[8];
300 if (chise_feature_setup_db (table, 0))
302 chise_format_char_id (cid, key_buf, 8);
303 status = chise_attribute_table_get (table->db,
307 if (size < valdatum.size)
309 strncpy (buf, valdatum.data, valdatum.size);
310 buf[valdatum.size] = '\0';
315 chise_char_feature_value_iterate (CHISE_Feature feature,
316 int (*func) (CHISE_Char_ID cid,
317 CHISE_Feature feature,
318 CHISE_Value *valdatum))
320 DBT keydatum, valdatum;
324 if (chise_feature_setup_db (feature, 0))
329 status = feature->db->cursor (feature->db, NULL, &dbcp, 0);
330 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
332 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
334 unsigned char *key_str = (unsigned char *)keydatum.data;
335 int key_len = strnlen (key_str, keydatum.size);
336 CHISE_Char_ID key = chise_char_id_parse_c_string (key_str, key_len);
337 int ret = func (key, feature, &valdatum);
342 dbcp->c_close (dbcp);
347 struct CHISE_CCS_Table
351 CHISE_Attribute_Table *db;
356 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs)
358 CHISE_CCS_Table* table;
359 size_t len = strlen (ccs);
364 table = (CHISE_CCS_Table*)malloc (sizeof (CHISE_CCS_Table));
371 table->name = (unsigned char*)malloc (len + 1);
372 if (table->name == NULL)
377 strcpy (table->name, ccs);
382 chise_ccst_close (CHISE_CCS_Table *table)
389 if (table->db == NULL)
392 status = CHISE_Attribute_Table_close (table->db);
394 if (table->name == NULL)
406 chise_ccs_sync (CHISE_CCS ccs)
413 status = CHISE_Attribute_Table_close (ccs->db);
420 chise_ccs_decode (CHISE_CCS ccs, int code_point)
422 CHISE_Value valdatum;
431 CHISE_DS *ds = ccs->ds;
433 ccs->db = CHISE_Attribute_Table_open (ds->location,
434 ccs->name, "system-char-id",
436 DB_RDONLY, ds->modemask);
439 ccs->access = DB_RDONLY;
442 sprintf(key_buf, "%d", code_point);
443 status = chise_attribute_table_get (ccs->db, key_buf, &valdatum);
447 = (unsigned char *)chise_value_data (&valdatum);
448 int len = strnlen (str, chise_value_size (&valdatum));
450 return chise_char_id_parse_c_string (str, len);
456 chise_ccs_set_decoded_char (CHISE_CCS ccs,
457 int code_point, CHISE_Char_ID cid)
459 char key_buf[16], val_buf[8];
464 if ((ccs->access & DB_CREATE) == 0)
468 CHISE_Attribute_Table_close (ccs->db);
475 CHISE_DS *ds = ccs->ds;
478 = CHISE_Attribute_Table_open (ds->location,
479 ccs->name, "system-char-id",
480 ds->subtype, DB_CREATE, ds->modemask);
483 ccs->access = DB_CREATE;
486 sprintf(key_buf, "%d", code_point);
487 chise_format_char_id (cid, val_buf, 8);
488 return chise_attribute_table_put (ccs->db, key_buf, val_buf);
492 CHISE_Attribute_Table*
493 CHISE_Attribute_Table_open (const unsigned char *db_dir,
494 const char *encoding, const char *feature,
496 u_int32_t accessmask, int modemask)
502 char *db_file_name, *sp;
505 status = db_create (&dbase, NULL, 0);
509 if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) )
510 mkdir (db_dir, modemask);
512 len = strlen (db_dir);
513 flen = strlen (feature);
514 size = len + strlen (encoding) + flen * 3 + 4;
515 db_file_name = alloca (size);
516 strcpy (db_file_name, db_dir);
517 if (db_file_name[len - 1] != '/')
519 db_file_name[len++] = '/';
520 db_file_name[len] = '\0';
522 strcat (db_file_name, encoding);
524 if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
525 mkdir (db_file_name, modemask);
527 strcat (db_file_name, "/");
528 /* strcat (db_file_name, feature); */
529 sp = &db_file_name[strlen (db_file_name)];
530 for (i = 0; i < flen; i++)
534 if ( (c == '/') || (c == '%') )
536 sprintf (sp, "%%%02X", c);
543 status = dbase->open (dbase, db_file_name, NULL,
544 real_subtype, accessmask, modemask);
547 dbase->close (dbase, 0);
554 CHISE_Attribute_Table_close (CHISE_Attribute_Table *db)
565 chise_attribute_table_get (CHISE_Attribute_Table *db,
566 char *key, CHISE_Value *valdatum)
571 /* DB Version 2 requires DBT's to be zeroed before use. */
576 keydatum.size = strlen (key);
578 status = db->get (db, NULL, &keydatum, valdatum, 0);
583 chise_attribute_table_put (CHISE_Attribute_Table *db,
584 char *key, unsigned char *value)
586 DBT keydatum, valdatum;
589 /* DB Version 2 requires DBT's to be zeroed before use. */
594 keydatum.size = strlen (key);
596 valdatum.data = value;
597 valdatum.size = strlen (value);
599 status = db->put (db, NULL, &keydatum, &valdatum, 0);
604 chise_char_id_parse_c_string (unsigned char *str, size_t len)
608 if ( (len >= 2) && (str[i++] == '?') )
610 unsigned char c = str[i++];
627 return c & (0x80 | 0x1F);
661 if (counter + 2 <= len)
665 for (j = 0; j < counter; j++)
666 cid = (cid << 6) | (str[j + i] & 0x3F);
674 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len)
686 else if (cid == '\n')
693 else if (cid == '\r')
700 else if (cid == 0x1C)
709 else if (cid <= 0x1F)
713 dest[i++] = '@' + cid;
717 else if ( (cid == ' ') || (cid == '"') ||
718 (cid == '#') || (cid == '\'') ||
719 (cid == '(') || (cid == ')') ||
720 (cid == ',') || (cid == '.') ||
721 (cid == ';') || (cid == '?') ||
722 (cid == '[') || (cid == '\\') ||
723 (cid == ']') || (cid == '`') )
730 else if (cid <= 0x7E)
736 else if (cid == 0x7F)
744 else if (cid <= 0x9F)
748 dest[i++] = ((cid + '@') >> 6) | 0xC0;
749 dest[i++] = ((cid + '@') & 0x3F) | 0x80;
753 else if (cid <= 0x7FF)
755 dest[i++] = (cid >> 6) | 0xC0;
756 dest[i++] = (cid & 0x3F) | 0x80;
760 else if (cid <= 0xFFFF)
762 dest[i++] = (cid >> 12) | 0xE0;
763 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
764 dest[i++]= (cid & 0x3F) | 0x80;
768 else if (cid <= 0x1FFFFF)
770 dest[i++]= (cid >> 18) | 0xF0;
771 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
772 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
773 dest[i++]= (cid & 0x3F) | 0x80;
777 else if (cid <= 0x3FFFFFF)
779 dest[i++]= (cid >> 24) | 0xF8;
780 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
781 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
782 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
783 dest[i++]= (cid & 0x3F) | 0x80;
789 dest[i++]= (cid >> 30) | 0xFC;
790 dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
791 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
792 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
793 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
794 dest[i++]= (cid & 0x3F) | 0x80;