11 #include "chise-name.h"
13 const unsigned char chise_db_dir[] = CHISE_DB_DIR;
16 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature);
18 int chise_ft_close (CHISE_Feature_Table *table);
22 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs);
24 int chise_ccst_close (CHISE_CCS_Table *table);
27 typedef DB CHISE_Attribute_Table;
29 CHISE_Attribute_Table*
30 CHISE_Attribute_Table_open (const unsigned char *db_dir,
32 const char *key_type, const char *name,
34 u_int32_t accessmask, int modemask);
36 int CHISE_Attribute_Table_close (CHISE_Attribute_Table *db);
38 int chise_attribute_table_get (CHISE_Attribute_Table *db,
39 char *key, CHISE_Value *valdatum);
41 int chise_attribute_table_put (CHISE_Attribute_Table *db,
42 char *key, unsigned char *value);
45 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
48 chise_char_id_parse_c_string (unsigned char *str, size_t len);
51 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len);
57 unsigned char *location;
58 CHISE_NAME_TABLE* feature_names;
59 CHISE_NAME_TABLE* ccs_names;
65 CHISE_DS_open (CHISE_DS_Type type, const unsigned char *location,
66 DBTYPE subtype, int modemask)
68 CHISE_DS *ds = (CHISE_DS*)malloc (sizeof (CHISE_DS));
69 size_t len = strlen (location);
75 ds->subtype = subtype;
76 ds->modemask = modemask;
77 ds->location = (unsigned char*)malloc (len + 1);
78 if (ds->location == NULL)
83 strcpy (ds->location, location);
85 ds->feature_names = chise_make_name_table ();
86 if (ds->feature_names == NULL)
92 ds->ccs_names = chise_make_name_table ();
93 if (ds->ccs_names == NULL)
95 free (ds->feature_names);
103 CHISE_DS_close (CHISE_DS *ds)
105 if (ds->location != NULL)
107 if (ds->feature_names != NULL)
108 free (ds->feature_names);
109 if (ds->ccs_names != NULL)
110 free (ds->ccs_names);
116 chise_ds_get_feature (CHISE_DS *ds, const unsigned char *feature)
118 CHISE_Feature_Table* ft;
120 ft = chise_name_table_get (ds->feature_names, feature);
124 ft = chise_ds_open_feature_table (ds, feature);
128 if (chise_name_table_put (ds->feature_names, feature, ft))
137 chise_ds_get_ccs (CHISE_DS *ds, const unsigned char *ccs)
141 ct = chise_name_table_get (ds->ccs_names, ccs);
145 ct = chise_ds_open_ccs_table (ds, ccs);
149 if (chise_name_table_put (ds->ccs_names, ccs, ct))
151 chise_ccst_close (ct);
158 chise_ds_foreach_char_feature_name (CHISE_DS *ds,
159 int (*func) (CHISE_DS *ds,
160 unsigned char *name))
163 = alloca (strlen (ds->location) + sizeof ("/character/feature") + 1);
167 strcpy (dname, ds->location);
168 strcat (dname, "/character/feature");
170 if ( (dir = opendir (dname)) == NULL)
173 while ( (de = readdir (dir)) != NULL )
175 if ( (strcmp (de->d_name, ".") != 0) &&
176 (strcmp (de->d_name, "..") != 0) )
178 int i, need_to_decode = 0;
183 for (cp = de->d_name, i = 0; *cp != '\0'; i++)
194 name = (unsigned char *) alloca (i);
198 while ( (ch = *cp++) != '\0')
214 if ( ('0' <= ch) && (ch <= '9') )
215 hex[index++] = ch - '0';
216 else if ( ('A' <= ch) && (ch <= 'F') )
217 hex[index++] = ch - 'A' + 10;
218 else if ( ('a' <= ch) && (ch <= 'f') )
219 hex[index++] = ch - 'a' + 10;
231 *np++ = (hex[0] << 4) | hex[1];
245 return closedir (dir);
248 return closedir (dir);
251 struct CHISE_Feature_Table
255 CHISE_Attribute_Table *db;
260 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature)
262 CHISE_Feature_Table* table;
263 size_t len = strlen (feature);
268 table = (CHISE_Feature_Table*)malloc (sizeof (CHISE_Feature_Table));
275 table->name = (unsigned char*)malloc (len + 1);
276 if (table->name == NULL)
281 strcpy (table->name, feature);
286 chise_ft_close (CHISE_Feature_Table *table)
293 if (table->db == NULL)
296 status = CHISE_Attribute_Table_close (table->db);
298 if (table->name == NULL)
310 chise_feature_setup_db (CHISE_Feature feature, int writable)
319 if ((feature->access & DB_CREATE) == 0)
321 if (feature->db != NULL)
323 CHISE_Attribute_Table_close (feature->db);
333 if (feature->db == NULL)
335 CHISE_DS *ds = feature->ds;
338 = CHISE_Attribute_Table_open (ds->location, "character",
339 "feature", feature->name,
340 ds->subtype, access, ds->modemask);
341 if (feature->db == NULL)
343 feature->access = access;
349 chise_feature_sync (CHISE_Feature feature)
353 if (feature->db == NULL)
356 status = CHISE_Attribute_Table_close (feature->db);
363 chise_char_set_feature_value (CHISE_Char_ID cid,
364 CHISE_Feature feature,
365 unsigned char *value)
367 unsigned char key_buf[8];
371 if (chise_feature_setup_db (feature, 1))
373 chise_format_char_id (cid, key_buf, 8);
374 return chise_attribute_table_put (feature->db, key_buf, value);
378 chise_char_load_feature_value (CHISE_Char_ID cid,
379 CHISE_Feature_Table *table,
380 CHISE_Value *valdatum)
382 unsigned char key_buf[8];
384 if (chise_feature_setup_db (table, 0))
386 chise_format_char_id (cid, key_buf, 8);
387 return chise_attribute_table_get (table->db, key_buf, valdatum);
391 chise_char_gets_feature_value (CHISE_Char_ID cid,
392 CHISE_Feature_Table *table,
393 unsigned char *buf, size_t size)
395 CHISE_Value valdatum;
396 unsigned char key_buf[8];
399 if (chise_feature_setup_db (table, 0))
401 chise_format_char_id (cid, key_buf, 8);
402 status = chise_attribute_table_get (table->db,
406 if (size < valdatum.size)
408 strncpy (buf, valdatum.data, valdatum.size);
409 buf[valdatum.size] = '\0';
414 chise_feature_foreach_char_with_value (CHISE_Feature feature,
415 int (*func) (CHISE_Char_ID cid,
416 CHISE_Feature feature,
417 CHISE_Value *valdatum))
419 DBT keydatum, valdatum;
423 if (chise_feature_setup_db (feature, 0))
428 status = feature->db->cursor (feature->db, NULL, &dbcp, 0);
429 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
431 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
433 unsigned char *key_str = (unsigned char *)keydatum.data;
434 int key_len = strnlen (key_str, keydatum.size);
435 CHISE_Char_ID key = chise_char_id_parse_c_string (key_str, key_len);
436 int ret = func (key, feature, &valdatum);
441 dbcp->c_close (dbcp);
446 struct CHISE_CCS_Table
450 CHISE_Attribute_Table *db;
455 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs)
457 CHISE_CCS_Table* table;
458 size_t len = strlen (ccs);
463 table = (CHISE_CCS_Table*)malloc (sizeof (CHISE_CCS_Table));
470 table->name = (unsigned char*)malloc (len + 1);
471 if (table->name == NULL)
476 strcpy (table->name, ccs);
481 chise_ccst_close (CHISE_CCS_Table *table)
488 if (table->db == NULL)
491 status = CHISE_Attribute_Table_close (table->db);
493 if (table->name == NULL)
505 chise_ccs_setup_db (CHISE_CCS ccs, int writable)
514 if ((ccs->access & DB_CREATE) == 0)
518 CHISE_Attribute_Table_close (ccs->db);
530 CHISE_DS *ds = ccs->ds;
533 = CHISE_Attribute_Table_open (ds->location, "character",
534 "by_feature", ccs->name,
535 ds->subtype, access, ds->modemask);
538 ccs->access = access;
544 chise_ccs_sync (CHISE_CCS ccs)
551 status = CHISE_Attribute_Table_close (ccs->db);
558 chise_ccs_decode (CHISE_CCS ccs, int code_point)
560 CHISE_Value valdatum;
567 if (chise_ccs_setup_db (ccs, 0))
570 sprintf(key_buf, "%d", code_point);
571 status = chise_attribute_table_get (ccs->db, key_buf, &valdatum);
575 = (unsigned char *)chise_value_data (&valdatum);
576 int len = strnlen (str, chise_value_size (&valdatum));
578 return chise_char_id_parse_c_string (str, len);
584 chise_ccs_set_decoded_char (CHISE_CCS ccs,
585 int code_point, CHISE_Char_ID cid)
587 char key_buf[16], val_buf[8];
592 if (chise_ccs_setup_db (ccs, 1))
595 sprintf(key_buf, "%d", code_point);
596 chise_format_char_id (cid, val_buf, 8);
597 return chise_attribute_table_put (ccs->db, key_buf, val_buf);
601 CHISE_Attribute_Table*
602 CHISE_Attribute_Table_open (const unsigned char *db_dir,
603 const char *category,
604 const char *key_type, const char *name,
606 u_int32_t accessmask, int modemask)
610 int len, name_len, i;
612 char *db_file_name, *sp;
615 status = db_create (&dbase, NULL, 0);
619 if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) )
620 mkdir (db_dir, modemask);
622 len = strlen (db_dir);
623 name_len = strlen (name);
624 size = len + strlen (category) + strlen (key_type) + name_len * 3 + 5;
625 db_file_name = alloca (size);
626 strcpy (db_file_name, db_dir);
627 if (db_file_name[len - 1] != '/')
629 db_file_name[len++] = '/';
630 db_file_name[len] = '\0';
633 strcat (db_file_name, category);
634 if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
635 mkdir (db_file_name, modemask);
636 strcat (db_file_name, "/");
638 strcat (db_file_name, key_type);
639 if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
640 mkdir (db_file_name, modemask);
641 strcat (db_file_name, "/");
643 /* strcat (db_file_name, name); */
644 sp = &db_file_name[strlen (db_file_name)];
645 for (i = 0; i < name_len; i++)
649 if ( (c == '/') || (c == '%') )
651 sprintf (sp, "%%%02X", c);
658 status = dbase->open (dbase, db_file_name, NULL,
659 real_subtype, accessmask, modemask);
662 dbase->close (dbase, 0);
669 CHISE_Attribute_Table_close (CHISE_Attribute_Table *db)
680 chise_attribute_table_get (CHISE_Attribute_Table *db,
681 char *key, CHISE_Value *valdatum)
686 /* DB Version 2 requires DBT's to be zeroed before use. */
691 keydatum.size = strlen (key);
693 status = db->get (db, NULL, &keydatum, valdatum, 0);
698 chise_attribute_table_put (CHISE_Attribute_Table *db,
699 char *key, unsigned char *value)
701 DBT keydatum, valdatum;
704 /* DB Version 2 requires DBT's to be zeroed before use. */
709 keydatum.size = strlen (key);
711 valdatum.data = value;
712 valdatum.size = strlen (value);
714 status = db->put (db, NULL, &keydatum, &valdatum, 0);
719 chise_char_id_parse_c_string (unsigned char *str, size_t len)
723 if ( (len >= 2) && (str[i++] == '?') )
725 unsigned char c = str[i++];
742 return c & (0x80 | 0x1F);
776 if (counter + 2 <= len)
780 for (j = 0; j < counter; j++)
781 cid = (cid << 6) | (str[j + i] & 0x3F);
789 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len)
801 else if (cid == '\n')
808 else if (cid == '\r')
815 else if (cid == 0x1C)
824 else if (cid <= 0x1F)
828 dest[i++] = '@' + cid;
832 else if ( (cid == ' ') || (cid == '"') ||
833 (cid == '#') || (cid == '\'') ||
834 (cid == '(') || (cid == ')') ||
835 (cid == ',') || (cid == '.') ||
836 (cid == ';') || (cid == '?') ||
837 (cid == '[') || (cid == '\\') ||
838 (cid == ']') || (cid == '`') )
845 else if (cid <= 0x7E)
851 else if (cid == 0x7F)
859 else if (cid <= 0x9F)
863 dest[i++] = ((cid + '@') >> 6) | 0xC0;
864 dest[i++] = ((cid + '@') & 0x3F) | 0x80;
868 else if (cid <= 0x7FF)
870 dest[i++] = (cid >> 6) | 0xC0;
871 dest[i++] = (cid & 0x3F) | 0x80;
875 else if (cid <= 0xFFFF)
877 dest[i++] = (cid >> 12) | 0xE0;
878 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
879 dest[i++]= (cid & 0x3F) | 0x80;
883 else if (cid <= 0x1FFFFF)
885 dest[i++]= (cid >> 18) | 0xF0;
886 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
887 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
888 dest[i++]= (cid & 0x3F) | 0x80;
892 else if (cid <= 0x3FFFFFF)
894 dest[i++]= (cid >> 24) | 0xF8;
895 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
896 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
897 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
898 dest[i++]= (cid & 0x3F) | 0x80;
904 dest[i++]= (cid >> 30) | 0xFC;
905 dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
906 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
907 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
908 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
909 dest[i++]= (cid & 0x3F) | 0x80;