7 #include "chise-name.h"
11 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature);
13 int chise_ft_close (CHISE_Feature_Table *table);
17 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs);
19 int chise_ccst_close (CHISE_CCS_Table *table);
22 typedef DB CHISE_Attribute_Table;
24 CHISE_Attribute_Table*
25 CHISE_Attribute_Table_open (const unsigned char *db_dir,
26 const char *encoding, const char *feature,
28 u_int32_t accessmask, int modemask);
30 int CHISE_Attribute_Table_close (CHISE_Attribute_Table *db);
32 int chise_attribute_table_get (CHISE_Attribute_Table *db,
33 char *key, CHISE_Value *valdatum);
35 int chise_attribute_table_put (CHISE_Attribute_Table *db,
36 char *key, unsigned char *value);
39 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
42 chise_char_id_parse_c_string (unsigned char *str, size_t len);
45 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len);
51 unsigned char *location;
52 CHISE_NAME_TABLE* feature_names;
53 CHISE_NAME_TABLE* ccs_names;
59 CHISE_DS_open (CHISE_DS_Type type, char *location,
60 DBTYPE subtype, int modemask)
62 CHISE_DS *ds = (CHISE_DS*)malloc (sizeof (CHISE_DS));
63 size_t len = strlen (location);
69 ds->subtype = subtype;
70 ds->modemask = modemask;
71 ds->location = (unsigned char*)malloc (len + 1);
72 if (ds->location == NULL)
77 strcpy (ds->location, location);
79 ds->feature_names = chise_make_name_table ();
80 if (ds->feature_names == NULL)
86 ds->ccs_names = chise_make_name_table ();
87 if (ds->ccs_names == NULL)
89 free (ds->feature_names);
97 CHISE_DS_close (CHISE_DS *ds)
99 if (ds->location != NULL)
101 if (ds->feature_names != NULL)
102 free (ds->feature_names);
103 if (ds->ccs_names != NULL)
104 free (ds->ccs_names);
110 chise_ds_get_feature (CHISE_DS *ds, const unsigned char *feature)
112 CHISE_Feature_Table* ft;
114 ft = chise_name_table_get (ds->feature_names, feature);
118 ft = chise_ds_open_feature_table (ds, feature);
122 if (chise_name_table_put (ds->feature_names, feature, ft))
131 chise_ds_get_ccs (CHISE_DS *ds, const unsigned char *ccs)
135 ct = chise_name_table_get (ds->ccs_names, ccs);
139 ct = chise_ds_open_ccs_table (ds, ccs);
143 if (chise_name_table_put (ds->ccs_names, ccs, ct))
145 chise_ccst_close (ct);
152 struct CHISE_Feature_Table
156 CHISE_Attribute_Table *db;
161 chise_ds_open_feature_table (CHISE_DS *ds, const char *feature)
163 CHISE_Feature_Table* table;
164 size_t len = strlen (feature);
169 table = (CHISE_Feature_Table*)malloc (sizeof (CHISE_Feature_Table));
176 table->name = (unsigned char*)malloc (len + 1);
177 if (table->name == NULL)
182 strcpy (table->name, feature);
187 chise_ft_close (CHISE_Feature_Table *table)
194 if (table->db == NULL)
197 status = CHISE_Attribute_Table_close (table->db);
199 if (table->name == NULL)
211 chise_feature_setup_db (CHISE_Feature feature, int writable)
217 if ((feature->access & DB_CREATE) == 0)
219 if (feature->db != NULL)
221 CHISE_Attribute_Table_close (feature->db);
231 if (feature->db == NULL)
233 CHISE_DS *ds = feature->ds;
236 = CHISE_Attribute_Table_open (ds->location,
237 "system-char-id", feature->name,
238 ds->subtype, access, ds->modemask);
239 if (feature->db == NULL)
241 feature->access = access;
247 chise_feature_sync (CHISE_Feature feature)
251 if (feature->db == NULL)
254 status = CHISE_Attribute_Table_close (feature->db);
261 chise_char_set_feature_value (CHISE_Char_ID cid,
262 CHISE_Feature feature,
263 unsigned char *value)
265 unsigned char key_buf[8];
269 if (chise_feature_setup_db (feature, 1))
271 chise_format_char_id (cid, key_buf, 8);
272 return chise_attribute_table_put (feature->db, key_buf, value);
276 chise_char_load_feature_value (CHISE_Char_ID cid,
277 CHISE_Feature_Table *table,
278 CHISE_Value *valdatum)
280 unsigned char key_buf[8];
282 if (chise_feature_setup_db (table, 0))
284 chise_format_char_id (cid, key_buf, 8);
285 return chise_attribute_table_get (table->db, key_buf, valdatum);
289 chise_char_gets_feature_value (CHISE_Char_ID cid,
290 CHISE_Feature_Table *table,
291 unsigned char *buf, size_t size)
293 CHISE_Value valdatum;
294 unsigned char key_buf[8];
297 if (chise_feature_setup_db (table, 0))
299 chise_format_char_id (cid, key_buf, 8);
300 status = chise_attribute_table_get (table->db,
304 if (size < valdatum.size)
306 strncpy (buf, valdatum.data, valdatum.size);
307 buf[valdatum.size] = '\0';
312 chise_char_feature_value_iterate (CHISE_Feature feature,
313 int (*func) (CHISE_Char_ID cid,
314 CHISE_Feature feature,
315 CHISE_Value *valdatum))
317 DBT keydatum, valdatum;
321 if (chise_feature_setup_db (feature, 0))
326 status = feature->db->cursor (feature->db, NULL, &dbcp, 0);
327 for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
329 status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
331 unsigned char *key_str = (unsigned char *)keydatum.data;
332 int key_len = strnlen (key_str, keydatum.size);
333 CHISE_Char_ID key = chise_char_id_parse_c_string (key_str, key_len);
334 int ret = func (key, feature, &valdatum);
339 dbcp->c_close (dbcp);
344 struct CHISE_CCS_Table
348 CHISE_Attribute_Table *db;
353 chise_ds_open_ccs_table (CHISE_DS *ds, const char *ccs)
355 CHISE_CCS_Table* table;
356 size_t len = strlen (ccs);
361 table = (CHISE_CCS_Table*)malloc (sizeof (CHISE_CCS_Table));
368 table->name = (unsigned char*)malloc (len + 1);
369 if (table->name == NULL)
374 strcpy (table->name, ccs);
379 chise_ccst_close (CHISE_CCS_Table *table)
386 if (table->db == NULL)
389 status = CHISE_Attribute_Table_close (table->db);
391 if (table->name == NULL)
403 chise_ccs_sync (CHISE_CCS ccs)
410 status = CHISE_Attribute_Table_close (ccs->db);
417 chise_ccs_decode (CHISE_CCS ccs, int code_point)
419 CHISE_Value valdatum;
428 CHISE_DS *ds = ccs->ds;
430 ccs->db = CHISE_Attribute_Table_open (ds->location,
431 ccs->name, "system-char-id",
433 DB_RDONLY, ds->modemask);
436 ccs->access = DB_RDONLY;
439 sprintf(key_buf, "%d", code_point);
440 status = chise_attribute_table_get (ccs->db, key_buf, &valdatum);
444 = (unsigned char *)chise_value_data (&valdatum);
445 int len = strnlen (str, chise_value_size (&valdatum));
447 return chise_char_id_parse_c_string (str, len);
453 chise_ccs_set_decoded_char (CHISE_CCS ccs,
454 int code_point, CHISE_Char_ID cid)
456 char key_buf[16], val_buf[8];
461 if ((ccs->access & DB_CREATE) == 0)
465 CHISE_Attribute_Table_close (ccs->db);
472 CHISE_DS *ds = ccs->ds;
475 = CHISE_Attribute_Table_open (ds->location,
476 ccs->name, "system-char-id",
477 ds->subtype, DB_CREATE, ds->modemask);
480 ccs->access = DB_CREATE;
483 sprintf(key_buf, "%d", code_point);
484 chise_format_char_id (cid, val_buf, 8);
485 return chise_attribute_table_put (ccs->db, key_buf, val_buf);
489 CHISE_Attribute_Table*
490 CHISE_Attribute_Table_open (const unsigned char *db_dir,
491 const char *encoding, const char *feature,
493 u_int32_t accessmask, int modemask)
499 char *db_file_name, *sp;
501 status = db_create (&dbase, NULL, 0);
505 len = strlen (db_dir);
506 flen = strlen (feature);
507 size = len + strlen (encoding) + flen * 3 + 4;
508 db_file_name = alloca (size);
509 strcpy (db_file_name, db_dir);
510 if (db_file_name[len - 1] != '/')
512 db_file_name[len++] = '/';
513 db_file_name[len] = '\0';
515 strcat (db_file_name, encoding);
516 strcat (db_file_name, "/");
517 /* strcat (db_file_name, feature); */
518 sp = &db_file_name[strlen (db_file_name)];
519 for (i = 0; i < flen; i++)
523 if ( (c == '/') || (c == '%') )
525 sprintf (sp, "%%%02X", c);
532 status = dbase->open (dbase, db_file_name, NULL,
533 real_subtype, accessmask, modemask);
536 dbase->close (dbase, 0);
543 CHISE_Attribute_Table_close (CHISE_Attribute_Table *db)
554 chise_attribute_table_get (CHISE_Attribute_Table *db,
555 char *key, CHISE_Value *valdatum)
560 /* DB Version 2 requires DBT's to be zeroed before use. */
565 keydatum.size = strlen (key);
567 status = db->get (db, NULL, &keydatum, valdatum, 0);
572 chise_attribute_table_put (CHISE_Attribute_Table *db,
573 char *key, unsigned char *value)
575 DBT keydatum, valdatum;
578 /* DB Version 2 requires DBT's to be zeroed before use. */
583 keydatum.size = strlen (key);
585 valdatum.data = value;
586 valdatum.size = strlen (value);
588 status = db->put (db, NULL, &keydatum, &valdatum, 0);
593 chise_char_id_parse_c_string (unsigned char *str, size_t len)
597 if ( (len >= 2) && (str[i++] == '?') )
599 unsigned char c = str[i++];
616 return c & (0x80 | 0x1F);
650 if (counter + 2 <= len)
654 for (j = 0; j < counter; j++)
655 cid = (cid << 6) | (str[j + i] & 0x3F);
663 chise_format_char_id (CHISE_Char_ID cid, unsigned char *dest, size_t len)
675 else if (cid == '\n')
682 else if (cid == '\r')
689 else if (cid == 0x1C)
698 else if (cid <= 0x1F)
702 dest[i++] = '@' + cid;
706 else if ( (cid == ' ') || (cid == '"') ||
707 (cid == '#') || (cid == '\'') ||
708 (cid == '(') || (cid == ')') ||
709 (cid == ',') || (cid == '.') ||
710 (cid == ';') || (cid == '?') ||
711 (cid == '[') || (cid == '\\') ||
712 (cid == ']') || (cid == '`') )
719 else if (cid <= 0x7E)
725 else if (cid == 0x7F)
733 else if (cid <= 0x9F)
737 dest[i++] = ((cid + '@') >> 6) | 0xC0;
738 dest[i++] = ((cid + '@') & 0x3F) | 0x80;
742 else if (cid <= 0x7FF)
744 dest[i++] = (cid >> 6) | 0xC0;
745 dest[i++] = (cid & 0x3F) | 0x80;
749 else if (cid <= 0xFFFF)
751 dest[i++] = (cid >> 12) | 0xE0;
752 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
753 dest[i++]= (cid & 0x3F) | 0x80;
757 else if (cid <= 0x1FFFFF)
759 dest[i++]= (cid >> 18) | 0xF0;
760 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
761 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
762 dest[i++]= (cid & 0x3F) | 0x80;
766 else if (cid <= 0x3FFFFFF)
768 dest[i++]= (cid >> 24) | 0xF8;
769 dest[i++]= ((cid >> 18) & 0x3F) | 0x80;
770 dest[i++]= ((cid >> 12) & 0x3F) | 0x80;
771 dest[i++]= ((cid >> 6) & 0x3F) | 0x80;
772 dest[i++]= (cid & 0x3F) | 0x80;
778 dest[i++]= (cid >> 30) | 0xFC;
779 dest[i++]= ((cid >> 24) & 0x3F) | 0x80;
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;