10 #include "chise-name.h"
12 const unsigned char chise_db_dir[] = CHISE_DB_DIR;
15 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature);
17 int chise_ft_close (CHISE_Feature_Table *table);
21 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs);
23 int chise_ccst_close (CHISE_CCS_Table *table);
26 typedef DB CHISE_Attribute_Table;
28 CHISE_Attribute_Table*
29 CHISE_Attribute_Table_open (const unsigned char *db_dir,
30 const char *encoding, const char *feature,
32 u_int32_t accessmask, int modemask);
34 int CHISE_Attribute_Table_close (CHISE_Attribute_Table *db);
36 int chise_attribute_table_get (CHISE_Attribute_Table *db,
37 char *key, CHISE_Value *valdatum);
39 int chise_attribute_table_put (CHISE_Attribute_Table *db,
40 char *key, unsigned char *value);
43 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
46 chise_char_id_parse_c_string (unsigned char *str, size_t len);
49 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len);
55 unsigned char *location;
56 CHISE_NAME_TABLE* feature_names;
57 CHISE_NAME_TABLE* ccs_names;
63 CHISE_DS_open (CHISE_DS_Type type, const unsigned char *location,
64 DBTYPE subtype, int modemask)
66 CHISE_DS *ds = (CHISE_DS*)malloc (sizeof (CHISE_DS));
67 size_t len = strlen (location);
73 ds->subtype = subtype;
74 ds->modemask = modemask;
75 ds->location = (unsigned char*)malloc (len + 1);
76 if (ds->location == NULL)
81 strcpy (ds->location, location);
83 ds->feature_names = chise_make_name_table ();
84 if (ds->feature_names == NULL)
90 ds->ccs_names = chise_make_name_table ();
91 if (ds->ccs_names == NULL)
93 free (ds->feature_names);
101 CHISE_DS_close (CHISE_DS *ds)
103 if (ds->location != NULL)
105 if (ds->feature_names != NULL)
106 free (ds->feature_names);
107 if (ds->ccs_names != NULL)
108 free (ds->ccs_names);
114 chise_ds_get_feature (CHISE_DS *ds, const unsigned char *feature)
116 CHISE_Feature_Table* ft;
118 ft = chise_name_table_get (ds->feature_names, feature);
122 ft = chise_ds_open_feature_table (ds, feature);
126 if (chise_name_table_put (ds->feature_names, feature, ft))
135 chise_ds_get_ccs (CHISE_DS *ds, const unsigned char *ccs)
139 ct = chise_name_table_get (ds->ccs_names, ccs);
143 ct = chise_ds_open_ccs_table (ds, ccs);
147 if (chise_name_table_put (ds->ccs_names, ccs, ct))
149 chise_ccst_close (ct);
156 struct CHISE_Feature_Table
160 CHISE_Attribute_Table *db;
165 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature)
167 CHISE_Feature_Table* table;
168 size_t len = strlen (feature);
173 table = (CHISE_Feature_Table*)malloc (sizeof (CHISE_Feature_Table));
180 table->name = (unsigned char*)malloc (len + 1);
181 if (table->name == NULL)
186 strcpy (table->name, feature);
191 chise_ft_close (CHISE_Feature_Table *table)
198 if (table->db == NULL)
201 status = CHISE_Attribute_Table_close (table->db);
203 if (table->name == NULL)
215 chise_feature_setup_db (CHISE_Feature feature, int writable)
224 if ((feature->access & DB_CREATE) == 0)
226 if (feature->db != NULL)
228 CHISE_Attribute_Table_close (feature->db);
238 if (feature->db == NULL)
240 CHISE_DS *ds = feature->ds;
243 = CHISE_Attribute_Table_open (ds->location,
244 "system-char-id", feature->name,
245 ds->subtype, access, ds->modemask);
246 if (feature->db == NULL)
248 feature->access = access;
254 chise_feature_sync (CHISE_Feature feature)
258 if (feature->db == NULL)
261 status = CHISE_Attribute_Table_close (feature->db);
268 chise_char_set_feature_value (CHISE_Char_ID cid,
269 CHISE_Feature feature,
270 unsigned char *value)
272 unsigned char key_buf[8];
276 if (chise_feature_setup_db (feature, 1))
278 chise_format_char_id (cid, key_buf, 8);
279 return chise_attribute_table_put (feature->db, key_buf, value);
283 chise_char_load_feature_value (CHISE_Char_ID cid,
284 CHISE_Feature_Table *table,
285 CHISE_Value *valdatum)
287 unsigned char key_buf[8];
289 if (chise_feature_setup_db (table, 0))
291 chise_format_char_id (cid, key_buf, 8);
292 return chise_attribute_table_get (table->db, key_buf, valdatum);
296 chise_char_gets_feature_value (CHISE_Char_ID cid,
297 CHISE_Feature_Table *table,
298 unsigned char *buf, size_t size)
300 CHISE_Value valdatum;
301 unsigned char key_buf[8];
304 if (chise_feature_setup_db (table, 0))
306 chise_format_char_id (cid, key_buf, 8);
307 status = chise_attribute_table_get (table->db,
311 if (size < valdatum.size)
313 strncpy (buf, valdatum.data, valdatum.size);
314 buf[valdatum.size] = '\0';
319 chise_char_feature_value_iterate (CHISE_Feature feature,
320 int (*func) (CHISE_Char_ID cid,
321 CHISE_Feature feature,
322 CHISE_Value *valdatum))
324 DBT keydatum, valdatum;
328 if (chise_feature_setup_db (feature, 0))
333 status = feature->db->cursor (feature->db, NULL, &dbcp, 0);
334 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
336 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
338 unsigned char *key_str = (unsigned char *)keydatum.data;
339 int key_len = strnlen (key_str, keydatum.size);
340 CHISE_Char_ID key = chise_char_id_parse_c_string (key_str, key_len);
341 int ret = func (key, feature, &valdatum);
346 dbcp->c_close (dbcp);
351 struct CHISE_CCS_Table
355 CHISE_Attribute_Table *db;
360 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs)
362 CHISE_CCS_Table* table;
363 size_t len = strlen (ccs);
368 table = (CHISE_CCS_Table*)malloc (sizeof (CHISE_CCS_Table));
375 table->name = (unsigned char*)malloc (len + 1);
376 if (table->name == NULL)
381 strcpy (table->name, ccs);
386 chise_ccst_close (CHISE_CCS_Table *table)
393 if (table->db == NULL)
396 status = CHISE_Attribute_Table_close (table->db);
398 if (table->name == NULL)
410 chise_ccs_setup_db (CHISE_CCS ccs, int writable)
419 if ((ccs->access & DB_CREATE) == 0)
423 CHISE_Attribute_Table_close (ccs->db);
435 CHISE_DS *ds = ccs->ds;
438 = CHISE_Attribute_Table_open (ds->location,
439 ccs->name, "system-char-id",
440 ds->subtype, access, ds->modemask);
443 ccs->access = access;
449 chise_ccs_sync (CHISE_CCS ccs)
456 status = CHISE_Attribute_Table_close (ccs->db);
463 chise_ccs_decode (CHISE_CCS ccs, int code_point)
465 CHISE_Value valdatum;
472 if (chise_ccs_setup_db (ccs, 0))
475 sprintf(key_buf, "%d", code_point);
476 status = chise_attribute_table_get (ccs->db, key_buf, &valdatum);
480 = (unsigned char *)chise_value_data (&valdatum);
481 int len = strnlen (str, chise_value_size (&valdatum));
483 return chise_char_id_parse_c_string (str, len);
489 chise_ccs_set_decoded_char (CHISE_CCS ccs,
490 int code_point, CHISE_Char_ID cid)
492 char key_buf[16], val_buf[8];
497 if (chise_ccs_setup_db (ccs, 1))
500 sprintf(key_buf, "%d", code_point);
501 chise_format_char_id (cid, val_buf, 8);
502 return chise_attribute_table_put (ccs->db, key_buf, val_buf);
506 CHISE_Attribute_Table*
507 CHISE_Attribute_Table_open (const unsigned char *db_dir,
508 const char *encoding, const char *feature,
510 u_int32_t accessmask, int modemask)
516 char *db_file_name, *sp;
519 status = db_create (&dbase, NULL, 0);
523 if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) )
524 mkdir (db_dir, modemask);
526 len = strlen (db_dir);
527 flen = strlen (feature);
528 size = len + strlen (encoding) + flen * 3 + 4;
529 db_file_name = alloca (size);
530 strcpy (db_file_name, db_dir);
531 if (db_file_name[len - 1] != '/')
533 db_file_name[len++] = '/';
534 db_file_name[len] = '\0';
536 strcat (db_file_name, encoding);
538 if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
539 mkdir (db_file_name, modemask);
541 strcat (db_file_name, "/");
542 /* strcat (db_file_name, feature); */
543 sp = &db_file_name[strlen (db_file_name)];
544 for (i = 0; i < flen; i++)
548 if ( (c == '/') || (c == '%') )
550 sprintf (sp, "%%%02X", c);
557 status = dbase->open (dbase, db_file_name, NULL,
558 real_subtype, accessmask, modemask);
561 dbase->close (dbase, 0);
568 CHISE_Attribute_Table_close (CHISE_Attribute_Table *db)
579 chise_attribute_table_get (CHISE_Attribute_Table *db,
580 char *key, CHISE_Value *valdatum)
585 /* DB Version 2 requires DBT's to be zeroed before use. */
590 keydatum.size = strlen (key);
592 status = db->get (db, NULL, &keydatum, valdatum, 0);
597 chise_attribute_table_put (CHISE_Attribute_Table *db,
598 char *key, unsigned char *value)
600 DBT keydatum, valdatum;
603 /* DB Version 2 requires DBT's to be zeroed before use. */
608 keydatum.size = strlen (key);
610 valdatum.data = value;
611 valdatum.size = strlen (value);
613 status = db->put (db, NULL, &keydatum, &valdatum, 0);
618 chise_char_id_parse_c_string (unsigned char *str, size_t len)
622 if ( (len >= 2) && (str[i++] == '?') )
624 unsigned char c = str[i++];
641 return c & (0x80 | 0x1F);
675 if (counter + 2 <= len)
679 for (j = 0; j < counter; j++)
680 cid = (cid << 6) | (str[j + i] & 0x3F);
688 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len)
700 else if (cid == '\n')
707 else if (cid == '\r')
714 else if (cid == 0x1C)
723 else if (cid <= 0x1F)
727 dest[i++] = '@' + cid;
731 else if ( (cid == ' ') || (cid == '"') ||
732 (cid == '#') || (cid == '\'') ||
733 (cid == '(') || (cid == ')') ||
734 (cid == ',') || (cid == '.') ||
735 (cid == ';') || (cid == '?') ||
736 (cid == '[') || (cid == '\\') ||
737 (cid == ']') || (cid == '`') )
744 else if (cid <= 0x7E)
750 else if (cid == 0x7F)
758 else if (cid <= 0x9F)
762 dest[i++] = ((cid + '@') >> 6) | 0xC0;
763 dest[i++] = ((cid + '@') & 0x3F) | 0x80;
767 else if (cid <= 0x7FF)
769 dest[i++] = (cid >> 6) | 0xC0;
770 dest[i++] = (cid & 0x3F) | 0x80;
774 else if (cid <= 0xFFFF)
776 dest[i++] = (cid >> 12) | 0xE0;
777 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
778 dest[i++]= (cid & 0x3F) | 0x80;
782 else if (cid <= 0x1FFFFF)
784 dest[i++]= (cid >> 18) | 0xF0;
785 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
786 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
787 dest[i++]= (cid & 0x3F) | 0x80;
791 else if (cid <= 0x3FFFFFF)
793 dest[i++]= (cid >> 24) | 0xF8;
794 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
795 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
796 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
797 dest[i++]= (cid & 0x3F) | 0x80;
803 dest[i++]= (cid >> 30) | 0xFC;
804 dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
805 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
806 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
807 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
808 dest[i++]= (cid & 0x3F) | 0x80;