From 6a2ea4bad7fd501f5749aa9fc998ce19dafc142c Mon Sep 17 00:00:00 2001 From: tomo Date: Thu, 6 Mar 2003 06:39:24 +0000 Subject: [PATCH 1/1] New files. --- Makefile | 32 ++++++++ chise.c | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chise.h | 89 ++++++++++++++++++++++ sample.c | 63 ++++++++++++++++ 4 files changed, 438 insertions(+) create mode 100644 Makefile create mode 100644 chise.c create mode 100644 chise.h create mode 100644 sample.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e545521 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +CC = gcc +CFLAGS = -g -O2 -c +LINKER = $(CC) -shared -o + +LIB_INSTALLDIR = /usr/local/lib + +VERSION = 0.1 + +RM = /bin/rm -f + + +all: libchise.so + +libchise.so: chise.o + $(LINKER) libchise.so chise.o -ldb + +chise.o: chise.c chise.h + $(CC) $(CFLAGS) chise.c + + +install: install.so + +install.so: libchise.so + install -c libchise.so $(LIB_INSTALLDIR)/libchise.so.$(VERSION) + (cd $(LIB_INSTALLDIR); ln -sf libchise.so.$(VERSION) libchise.so) + +clean: + -$(RM) *.o *.so sample + + +sample: sample.c libchise.so + gcc -o sample sample.c -lchise diff --git a/chise.c b/chise.c new file mode 100644 index 0000000..ea6f086 --- /dev/null +++ b/chise.c @@ -0,0 +1,254 @@ +#include "chise.h" + +#define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue))) + + +int +chise_open_data_source (CHISE_DS *ds, CHISE_DS_Type type, char *location) +{ + ds->type = type; + ds->location = location; + return 0; +} + +int +chise_close_data_source (CHISE_DS *ds) +{ + ds->type = CHISE_DS_NONE; + ds->location = NULL; + return 0; +} + + +int +chise_open_decoding_table (CHISE_Decoding_Table **db, + CHISE_DS *ds, const char *ccs, + DBTYPE real_subtype, + u_int32_t accessmask, int modemask) +{ + return + chise_open_attribute_table (db, ds->location, + ccs, "system-char-id", + real_subtype, accessmask, modemask); +} + +int +chise_close_decoding_table (CHISE_Decoding_Table *db) +{ + if (db) + return chise_close_attribute_table (db); + return -1; +} + +CHISE_Char_ID +chise_dt_get_char (CHISE_Decoding_Table *db, int code_point) +{ + CHISE_Value valdatum; + int status = 0; + char key_buf[16]; + + sprintf(key_buf, "%d", code_point); + status = chise_get_attribute_table (db, key_buf, &valdatum); + if (!status) + { + unsigned char *str + = (unsigned char *)chise_value_to_c_string (&valdatum); + int len = strlen (str); + int i; + + if ( (len >= 2) && (str[0] == '?') ) + { + unsigned char c = str[1]; + int counter; + CHISE_Char_ID cid; + + if ( c < 0xC0 ) + { + cid = c; + counter = 0; + } + else if ( c < 0xE0 ) + { + cid = c & 0x1f; + counter = 1; + } + else if ( c < 0xF0 ) + { + cid = c & 0x0f; + counter = 2; + } + else if ( c < 0xF8 ) + { + cid = c & 0x07; + counter = 3; + } + else if ( c < 0xFC ) + { + cid = c & 0x03; + counter = 4; + } + else + { + cid = c & 0x01; + counter = 5; + } + + if (counter + 2 <= len) + { + int i; + + for (i = 0; i < counter; i++) + cid = (cid << 6) | (str[i + 2] & 0x3F); + return cid; + } + } + } + return -1; +} + + + +int +chise_open_feature_table (CHISE_Feature_Table **db, + CHISE_DS *ds, const char *feature, + DBTYPE real_subtype, + u_int32_t accessmask, int modemask) +{ + return + chise_open_attribute_table (db, ds->location, + "system-char-id", feature, + real_subtype, accessmask, modemask); +} + +int +chise_close_feature_table (CHISE_Feature_Table *db) +{ + if (db) + return chise_close_attribute_table (db); + return -1; +} + +int chise_ft_get_value (CHISE_Feature_Table *db, + CHISE_Char_ID cid, CHISE_Value *valdatum) +{ + unsigned char key_buf[8]; + + key_buf[0] = '?'; + if (cid <= 0x7f) + { + key_buf[1] = cid; + key_buf[2] = '\0'; + } + else if (cid <= 0x7ff) + { + key_buf[1] = (cid >> 6) | 0xc0; + key_buf[2] = (cid & 0x3f) | 0x80; + key_buf[3] = '\0'; + } + else if (cid <= 0xffff) + { + key_buf[1] = (cid >> 12) | 0xe0; + key_buf[2]= ((cid >> 6) & 0x3f) | 0x80; + key_buf[3]= (cid & 0x3f) | 0x80; + key_buf[4] = '\0'; + } + else if (cid <= 0x1fffff) + { + key_buf[1]= (cid >> 18) | 0xf0; + key_buf[2]= ((cid >> 12) & 0x3f) | 0x80; + key_buf[3]= ((cid >> 6) & 0x3f) | 0x80; + key_buf[4]= (cid & 0x3f) | 0x80; + key_buf[5] = '\0'; + } + else if (cid <= 0x3ffffff) + { + key_buf[1]= (cid >> 24) | 0xf8; + key_buf[2]= ((cid >> 18) & 0x3f) | 0x80; + key_buf[3]= ((cid >> 12) & 0x3f) | 0x80; + key_buf[4]= ((cid >> 6) & 0x3f) | 0x80; + key_buf[5]= (cid & 0x3f) | 0x80; + key_buf[6] = '\0'; + } + else + { + key_buf[1]= (cid >> 30) | 0xfc; + key_buf[2]= ((cid >> 24) & 0x3f) | 0x80; + key_buf[3]= ((cid >> 18) & 0x3f) | 0x80; + key_buf[4]= ((cid >> 12) & 0x3f) | 0x80; + key_buf[5]= ((cid >> 6) & 0x3f) | 0x80; + key_buf[6]= (cid & 0x3f) | 0x80; + key_buf[7] = '\0'; + } + return + chise_get_attribute_table (db, key_buf, valdatum); +} + + +int +chise_open_attribute_table (CHISE_Attribute_Table **db, + const char *db_dir, + const char *encoding, const char *feature, + DBTYPE real_subtype, + u_int32_t accessmask, int modemask) +{ + DB* dbase; + int status; + int len; + int size; + char *db_file_name; + + status = db_create (&dbase, NULL, 0); + if (status) + return -1; + + len = strlen (db_dir); + size = len + strlen (encoding) + strlen (feature) + 4; + db_file_name = alloca (size); + strcpy (db_file_name, db_dir); + if (db_file_name[len - 1] != '/') + { + db_file_name[len++] = '/'; + db_file_name[len] = '\0'; + } + strcat (db_file_name, encoding); + strcat (db_file_name, "/"); + strcat (db_file_name, feature); + status = dbase->open (dbase, db_file_name, NULL, + real_subtype, accessmask, modemask); + if (status) + { + dbase->close (dbase, 0); + return -1; + } + *db = dbase; + return 0; +} + +int +chise_close_attribute_table (CHISE_Attribute_Table *db) +{ + if (db) + { + db->sync (db, 0); + db->close (db, 0); + } + return 0; +} + +int +chise_get_attribute_table (CHISE_Attribute_Table *db, + char *key, CHISE_Value *valdatum) +{ + DBT keydatum; + int status = 0; + + /* DB Version 2 requires DBT's to be zeroed before use. */ + xzero (keydatum); + xzero (*valdatum); + + keydatum.data = key; + keydatum.size = strlen (key); + + status = db->get (db, NULL, &keydatum, valdatum, 0); + return status; +} diff --git a/chise.h b/chise.h new file mode 100644 index 0000000..509b473 --- /dev/null +++ b/chise.h @@ -0,0 +1,89 @@ +#ifndef _CHISE_H + +#include +#include + + +typedef enum CHISE_DS_Type +{ + CHISE_DS_NONE, + CHISE_DS_Berkeley_DB +} CHISE_DS_Type; + +typedef struct CHISE_DS +{ + CHISE_DS_Type type; + char *location; +} CHISE_DS; + +int chise_open_data_source (CHISE_DS *ds, CHISE_DS_Type type, + char *location); + +int chise_close_data_source (CHISE_DS *ds); + + +typedef int CHISE_Char_ID; + + +typedef DBT CHISE_Value; + +static inline int +chise_value_size (const CHISE_Value *s) +{ + return s->size; +} + +static inline char * +chise_value_to_c_string (const CHISE_Value *s) +{ + return s->data; +} + + +typedef DB CHISE_Attribute_Table; + + +typedef CHISE_Attribute_Table CHISE_Decoding_Table; + +int chise_open_decoding_table (CHISE_Decoding_Table **db, + CHISE_DS *ds, const char *ccs, + DBTYPE real_subtype, + u_int32_t accessmask, int modemask); + +int chise_close_decoding_table (CHISE_Decoding_Table *db); + +CHISE_Char_ID chise_dt_get_char (CHISE_Decoding_Table *db, int code_point); + + +typedef CHISE_Attribute_Table CHISE_Feature_Table; + +int chise_open_feature_table (CHISE_Feature_Table **db, + CHISE_DS *ds, const char *feature, + DBTYPE real_subtype, + u_int32_t accessmask, int modemask); + +int chise_close_feature_table (CHISE_Feature_Table *db); + +int chise_ft_get_value (CHISE_Feature_Table *db, + CHISE_Char_ID cid, CHISE_Value *valdatum); + + + +CHISE_Char_ID chise_decode_char (CHISE_DS *ds, char *ccs, int code_point); + +int chise_get_feature (CHISE_DS *ds, CHISE_Char_ID cid, + char *key, CHISE_Value *valdatum); + + +int chise_open_attribute_table (CHISE_Attribute_Table **db, + const char *db_dir, + const char *encoding, const char *feature, + DBTYPE real_subtype, + u_int32_t accessmask, int modemask); + +int chise_close_attribute_table (CHISE_Attribute_Table *db); + +int chise_get_attribute_table (CHISE_Attribute_Table *db, + char *key, CHISE_Value *valdatum); + +#endif /* !_CHISE_H */ diff --git a/sample.c b/sample.c new file mode 100644 index 0000000..b43b1e9 --- /dev/null +++ b/sample.c @@ -0,0 +1,63 @@ +#include "chise.h" + +#define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue))) + +char db_dir[] = "/usr/local/lib/xemacs-21.4.10/i586-pc-linux/char-db"; + +int +main (int argc, char* argv[]) +{ + CHISE_DS ds; + CHISE_Decoding_Table *dt; + CHISE_Feature_Table *ft; + int modemask; + int accessmask = 0; + DBTYPE real_subtype; + int status; + CHISE_Char_ID char_id; + CHISE_Value value; + + status = chise_open_data_source (&ds, CHISE_DS_Berkeley_DB, db_dir); + if (status) + { + chise_close_data_source (&ds); + return -1; + } + + modemask = 0755; /* rwxr-xr-x */ + + real_subtype = DB_HASH; + accessmask = DB_RDONLY; + + status = chise_open_decoding_table (&dt, &ds, + "ideograph-daikanwa", + real_subtype, accessmask, modemask); + if (status) + { + chise_close_decoding_table (dt); + chise_close_data_source (&ds); + return -1; + } + + char_id = chise_dt_get_char (dt, 20); + chise_close_decoding_table (dt); + + status = chise_open_feature_table (&ft, &ds, + "ideographic-structure", + real_subtype, accessmask, modemask); + if (status) + { + chise_close_feature_table (ft); + chise_close_data_source (&ds); + return -1; + } + + status = chise_ft_get_value (ft, char_id, &value); + if (!status) + printf ("#x%X => %s\n", char_id, chise_value_to_c_string(&value)); + else + printf ("#x%X (%d)\n", char_id, status); + + chise_close_feature_table (ft); + chise_close_data_source (&ds); +} -- 1.7.10.4