X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=chise.c;h=e76172b315a054cd73e07a6ddf02bacdbdb61c43;hb=d87b4e5e974e44ab08e829c74e12aac7dea5f616;hp=b5ede8a9be66be1f0de5cc5e84dd387086854da5;hpb=51b2d2caeb46f18f2a6f03f666230d3211951586;p=chise%2Flibchise.git diff --git a/chise.c b/chise.c index b5ede8a..e76172b 100644 --- a/chise.c +++ b/chise.c @@ -1,4 +1,8 @@ #include +#include +#include +#include +#include #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -6,6 +10,8 @@ #include "chise.h" #include "chise-name.h" +const unsigned char chise_db_dir[] = CHISE_DB_DIR; +const unsigned char chise_system_db_dir[] = CHISE_SI_DB_DIR; CHISE_Feature_Table* chise_ds_open_feature_table (CHISE_DS *ds, const char *feature); @@ -23,7 +29,8 @@ typedef DB CHISE_Attribute_Table; CHISE_Attribute_Table* CHISE_Attribute_Table_open (const unsigned char *db_dir, - const char *encoding, const char *feature, + const char *category, + const char *key_type, const char *name, DBTYPE real_subtype, u_int32_t accessmask, int modemask); @@ -56,8 +63,8 @@ struct CHISE_DS }; CHISE_DS* -CHISE_DS_open (CHISE_DS_Type type, char *location, - DBTYPE subtype, int modemask) +CHISE_DS_open (CHISE_DS_Type type, const unsigned char *location, + int subtype, int modemask) { CHISE_DS *ds = (CHISE_DS*)malloc (sizeof (CHISE_DS)); size_t len = strlen (location); @@ -66,7 +73,7 @@ CHISE_DS_open (CHISE_DS_Type type, char *location, return NULL; ds->type = type; - ds->subtype = subtype; + ds->subtype = ( (subtype != 0) ? subtype : DB_HASH ); ds->modemask = modemask; ds->location = (unsigned char*)malloc (len + 1); if (ds->location == NULL) @@ -148,6 +155,99 @@ chise_ds_get_ccs (CHISE_DS *ds, const unsigned char *ccs) return ct; } +int +chise_ds_foreach_char_feature_name (CHISE_DS *ds, + int (*func) (CHISE_DS *ds, + unsigned char *name)) +{ + unsigned char *dname + = alloca (strlen (ds->location) + sizeof ("/character/feature") + 1); + DIR *dir; + struct dirent *de; + + strcpy (dname, ds->location); + strcat (dname, "/character/feature"); + + if ( (dir = opendir (dname)) == NULL) + return -1; + + while ( (de = readdir (dir)) != NULL ) + { + if ( (strcmp (de->d_name, ".") != 0) && + (strcmp (de->d_name, "..") != 0) ) + { + int i, need_to_decode = 0; + unsigned char *cp; + unsigned char *name; + unsigned char *np; + + for (cp = de->d_name, i = 0; *cp != '\0'; i++) + { + if (*cp++ == '%') + need_to_decode = 1; + } + if (need_to_decode) + { + int index = -1; + int ch, c[2]; + int hex[2]; + + name = (unsigned char *) alloca (i); + cp = de->d_name; + np = name; + + while ( (ch = *cp++) != '\0') + { + if (ch == '%') + { + if (index >= 0) + { + *np++ = '%'; + if (index == 1) + *np++ = c[0]; + } + index = 0; + } + else if (index >= 0) + { + c[index] = ch; + + if ( ('0' <= ch) && (ch <= '9') ) + hex[index++] = ch - '0'; + else if ( ('A' <= ch) && (ch <= 'F') ) + hex[index++] = ch - 'A' + 10; + else if ( ('a' <= ch) && (ch <= 'f') ) + hex[index++] = ch - 'a' + 10; + else + { + *np++ = '%'; + if (index == 1) + *np++ = c[0]; + *np++ = ch; + index = -1; + continue; + } + if (index == 2) + { + *np++ = (hex[0] << 4) | hex[1]; + index = -1; + continue; + } + } + else + *np++ = ch; + } + *np = '\0'; + } + else + name = de->d_name; + + if (func (ds, name)) + return closedir (dir); + } + } + return closedir (dir); +} struct CHISE_Feature_Table { @@ -207,11 +307,14 @@ chise_ft_close (CHISE_Feature_Table *table) return status; } -static int +int chise_feature_setup_db (CHISE_Feature feature, int writable) { u_int32_t access; + if (feature == NULL) + return -1; + if (writable) { if ((feature->access & DB_CREATE) == 0) @@ -233,8 +336,8 @@ chise_feature_setup_db (CHISE_Feature feature, int writable) CHISE_DS *ds = feature->ds; feature->db - = CHISE_Attribute_Table_open (ds->location, - "system-char-id", feature->name, + = CHISE_Attribute_Table_open (ds->location, "character", + "feature", feature->name, ds->subtype, access, ds->modemask); if (feature->db == NULL) return -1; @@ -244,6 +347,35 @@ chise_feature_setup_db (CHISE_Feature feature, int writable) } int +chise_feature_sync (CHISE_Feature feature) +{ + int status; + + if (feature->db == NULL) + status = 0; + else + status = CHISE_Attribute_Table_close (feature->db); + feature->db = NULL; + feature->access = 0; + return status; +} + +int +chise_char_set_feature_value (CHISE_Char_ID cid, + CHISE_Feature feature, + unsigned char *value) +{ + unsigned char key_buf[8]; + + if (feature == NULL) + return -1; + if (chise_feature_setup_db (feature, 1)) + return -1; + chise_format_char_id (cid, key_buf, 8); + return chise_attribute_table_put (feature->db, key_buf, value); +} + +int chise_char_load_feature_value (CHISE_Char_ID cid, CHISE_Feature_Table *table, CHISE_Value *valdatum) @@ -280,10 +412,10 @@ chise_char_gets_feature_value (CHISE_Char_ID cid, } int -chise_char_feature_value_iterate (CHISE_Feature feature, - int (*func) (CHISE_Char_ID cid, - CHISE_Feature feature, - CHISE_Value *valdatum)) +chise_feature_foreach_char_with_value (CHISE_Feature feature, + int (*func) (CHISE_Char_ID cid, + CHISE_Feature feature, + CHISE_Value *valdatum)) { DBT keydatum, valdatum; DBC *dbcp; @@ -371,6 +503,45 @@ chise_ccst_close (CHISE_CCS_Table *table) } int +chise_ccs_setup_db (CHISE_CCS ccs, int writable) +{ + u_int32_t access; + + if (ccs == NULL) + return -1; + + if (writable) + { + if ((ccs->access & DB_CREATE) == 0) + { + if (ccs->db != NULL) + { + CHISE_Attribute_Table_close (ccs->db); + ccs->db = NULL; + } + ccs->access = 0; + } + access = DB_CREATE; + } + else + access = DB_RDONLY; + + if (ccs->db == NULL) + { + CHISE_DS *ds = ccs->ds; + + ccs->db + = CHISE_Attribute_Table_open (ds->location, "character", + "by_feature", ccs->name, + ds->subtype, access, ds->modemask); + if (ccs->db == NULL) + return -1; + ccs->access = access; + } + return 0; +} + +int chise_ccs_sync (CHISE_CCS ccs) { int status; @@ -394,18 +565,8 @@ chise_ccs_decode (CHISE_CCS ccs, int code_point) if (ccs == NULL) return -1; - if (ccs->db == NULL) - { - CHISE_DS *ds = ccs->ds; - - ccs->db = CHISE_Attribute_Table_open (ds->location, - ccs->name, "system-char-id", - ds->subtype, - DB_RDONLY, ds->modemask); - if (ccs->db == NULL) - return -1; - ccs->access = DB_RDONLY; - } + if (chise_ccs_setup_db (ccs, 0)) + return -1; sprintf(key_buf, "%d", code_point); status = chise_attribute_table_get (ccs->db, key_buf, &valdatum); @@ -429,27 +590,8 @@ chise_ccs_set_decoded_char (CHISE_CCS ccs, if (ccs == NULL) return -1; - if ((ccs->access & DB_CREATE) == 0) - { - if (ccs->db != NULL) - { - CHISE_Attribute_Table_close (ccs->db); - ccs->db = NULL; - } - ccs->access = 0; - } - if (ccs->db == NULL) - { - CHISE_DS *ds = ccs->ds; - - ccs->db - = CHISE_Attribute_Table_open (ds->location, - ccs->name, "system-char-id", - ds->subtype, DB_CREATE, ds->modemask); - if (ccs->db == NULL) - return -1; - ccs->access = DB_CREATE; - } + if (chise_ccs_setup_db (ccs, 1)) + return -1; sprintf(key_buf, "%d", code_point); chise_format_char_id (cid, val_buf, 8); @@ -459,23 +601,28 @@ chise_ccs_set_decoded_char (CHISE_CCS ccs, CHISE_Attribute_Table* CHISE_Attribute_Table_open (const unsigned char *db_dir, - const char *encoding, const char *feature, + const char *category, + const char *key_type, const char *name, DBTYPE real_subtype, u_int32_t accessmask, int modemask) { DB* dbase; int status; - int len, flen, i; + int len, name_len, i; int size; char *db_file_name, *sp; + struct stat statbuf; status = db_create (&dbase, NULL, 0); if (status) return NULL; + if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) ) + mkdir (db_dir, modemask); + len = strlen (db_dir); - flen = strlen (feature); - size = len + strlen (encoding) + flen * 3 + 4; + name_len = strlen (name); + size = len + strlen (category) + strlen (key_type) + name_len * 3 + 5; db_file_name = alloca (size); strcpy (db_file_name, db_dir); if (db_file_name[len - 1] != '/') @@ -483,13 +630,22 @@ CHISE_Attribute_Table_open (const unsigned char *db_dir, db_file_name[len++] = '/'; db_file_name[len] = '\0'; } - strcat (db_file_name, encoding); + + strcat (db_file_name, category); + if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) ) + mkdir (db_file_name, modemask); strcat (db_file_name, "/"); - /* strcat (db_file_name, feature); */ + + strcat (db_file_name, key_type); + if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) ) + mkdir (db_file_name, modemask); + strcat (db_file_name, "/"); + + /* strcat (db_file_name, name); */ sp = &db_file_name[strlen (db_file_name)]; - for (i = 0; i < flen; i++) + for (i = 0; i < name_len; i++) { - int c = feature[i]; + int c = name[i]; if ( (c == '/') || (c == '%') ) {