New files.
authortomo <tomo>
Thu, 6 Mar 2003 06:39:24 +0000 (06:39 +0000)
committertomo <tomo>
Thu, 6 Mar 2003 06:39:24 +0000 (06:39 +0000)
Makefile [new file with mode: 0644]
chise.c [new file with mode: 0644]
chise.h [new file with mode: 0644]
sample.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
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 (file)
index 0000000..509b473
--- /dev/null
+++ b/chise.h
@@ -0,0 +1,89 @@
+#ifndef _CHISE_H
+
+#include <db.h>
+#include <errno.h>
+
+
+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 (file)
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);
+}