update.
[chise/ruby.git] / 0ext / libchise_c.c
diff --git a/0ext/libchise_c.c b/0ext/libchise_c.c
new file mode 100755 (executable)
index 0000000..fd26e62
--- /dev/null
@@ -0,0 +1,171 @@
+/* Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
+   This file is part of the Ruby/CHISE Extension.
+
+   This software is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the CHISE Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "ruby.h"
+#include "chise.h"
+
+static VALUE mCHISE, cDS, cCCS, cFEATURE, cVALUE;
+
+typedef struct {
+  CHISE_DS *ds;
+} RB_CHISE_DS;
+
+typedef struct {
+  CHISE_Feature_Table *feature;
+} RB_CHISE_FEATURE;
+
+typedef struct {
+  CHISE_CCS_Table *ccs;
+} RB_CHISE_CCS;
+
+typedef struct {
+  CHISE_Value value;
+} RB_CHISE_VALUE;
+
+static VALUE fds_new(VALUE klass, VALUE type, VALUE location, VALUE dbtype, VALUE mode){
+  RB_CHISE_DS *rds;
+  VALUE tdata = Data_Make_Struct(klass, RB_CHISE_DS, 0, free, rds);
+  rds->ds = CHISE_DS_open((CHISE_DS_Type)NUM2INT(type), RSTRING(rb_str_to_str(location))->ptr, NUM2INT(dbtype), NUM2INT(mode));
+  if (rds->ds == NULL){
+    return Qnil;
+  }
+  return tdata;
+}
+
+static VALUE fds_close(VALUE obj){
+  RB_CHISE_DS *rds;
+  Data_Get_Struct(obj, RB_CHISE_DS, rds);
+  CHISE_DS_close(rds->ds);
+  return Qnil;
+}
+
+static VALUE fds_get_feature(VALUE obj, VALUE feature){
+  RB_CHISE_DS *rds;
+  RB_CHISE_FEATURE *rfeature;
+  VALUE vfeature;
+  int status;
+  Data_Get_Struct(obj, RB_CHISE_DS, rds);
+  vfeature = Data_Make_Struct(cFEATURE, RB_CHISE_FEATURE, 0, free, rfeature);
+  rfeature->feature = chise_ds_get_feature(rds->ds, RSTRING(rb_str_to_str(feature))->ptr);
+  return vfeature;
+}
+
+static VALUE fds_get_ccs(VALUE obj, VALUE ccs){
+  RB_CHISE_DS *rds;
+  RB_CHISE_CCS *rccs;
+  VALUE vccs;
+  int status;
+  Data_Get_Struct(obj, RB_CHISE_DS, rds);
+  vccs = Data_Make_Struct(cCCS, RB_CHISE_CCS, 0, free, rccs);
+  rccs->ccs = chise_ds_get_ccs(rds->ds, RSTRING(rb_str_to_str(ccs))->ptr);
+  if (rccs->ccs == NULL){
+    return Qnil;
+  }
+  return vccs;
+}
+
+static VALUE fds_decode_char(VALUE obj, VALUE ccs, VALUE code_point){
+  RB_CHISE_DS *rds;
+  CHISE_Char_ID char_id;
+  Data_Get_Struct(obj, RB_CHISE_DS, rds);
+  char_id = chise_ds_decode_char(rds->ds, RSTRING(rb_str_to_str(ccs))->ptr, NUM2INT(code_point));
+  return INT2NUM(char_id);
+}
+
+static int name_map_func(CHISE_DS *ds, unsigned char *name){
+  rb_yield(rb_str_new2(name));
+  return 0; // important
+}
+
+static VALUE fds_each_feature_name(VALUE obj){
+  RB_CHISE_DS *rds;
+  Data_Get_Struct(obj, RB_CHISE_DS, rds);
+  chise_ds_foreach_char_feature_name(rds->ds, &name_map_func);
+  return Qnil;
+}
+
+static VALUE ffeature_get_value(VALUE obj, VALUE char_id){
+  RB_CHISE_FEATURE *rfeature;
+  RB_CHISE_VALUE *rvalue;
+  VALUE vvalue;
+  int status;
+  Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
+  vvalue = Data_Make_Struct(cVALUE, RB_CHISE_VALUE, 0, free, rvalue);
+  status = chise_char_load_feature_value((CHISE_Char_ID)NUM2INT(char_id), rfeature->feature, &rvalue->value);
+  if (status)
+    return Qnil;
+  return vvalue;
+}
+
+static int feature_map_func(CHISE_Char_ID cid, CHISE_Feature_Table *db, CHISE_Value *valdatum){
+  RB_CHISE_VALUE *rvalue;
+  VALUE vvalue;
+  VALUE var;
+  vvalue = Data_Make_Struct(cVALUE, RB_CHISE_VALUE, 0, free, rvalue);
+  memcpy(&rvalue->value, valdatum, sizeof(CHISE_Value));
+  var = rb_ary_new3(2, INT2NUM(cid), vvalue);
+  rb_yield(var);
+  return 0;
+}
+
+static VALUE ffeature_each_char(VALUE obj){
+  RB_CHISE_FEATURE *rfeature;
+  Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
+  chise_feature_foreach_char_with_value(rfeature->feature, &feature_map_func);
+  return Qnil;
+}
+
+static VALUE fccs_decode(VALUE obj, VALUE code_point){
+  RB_CHISE_CCS *rccs;
+  Data_Get_Struct(obj, RB_CHISE_CCS, rccs);
+  CHISE_Char_ID char_id;
+  char_id = chise_ccs_decode(rccs->ccs, NUM2INT(code_point));
+  return INT2NUM(char_id);
+}
+
+static VALUE fvalue_to_s(VALUE obj){
+  RB_CHISE_VALUE *rvalue;
+  Data_Get_Struct(obj, RB_CHISE_VALUE, rvalue);
+  return rb_str_new(chise_value_to_c_string(&rvalue->value), chise_value_size(&rvalue->value));
+}
+
+void Init_libchise_c(){
+  mCHISE = rb_define_module("CHISE");
+  rb_define_const(mCHISE, "DB_DIR", rb_str_new2(chise_system_db_dir));
+
+  cDS = rb_define_class_under(mCHISE, "DataSource", rb_cObject);
+  rb_define_singleton_method(cDS, "new", fds_new, 4);
+  rb_define_method(cDS, "close", fds_close, 0);
+  rb_define_const(cDS, "NONE", INT2FIX(CHISE_DS_NONE));
+  rb_define_const(cDS, "Berkeley_DB", INT2FIX(CHISE_DS_Berkeley_DB));
+
+  rb_define_method(cDS, "get_feature", fds_get_feature, 1);
+  rb_define_method(cDS, "get_ccs", fds_get_ccs, 1);
+  rb_define_method(cDS, "decode_char", fds_decode_char, 2);
+  rb_define_method(cDS, "each_feature_name", fds_each_feature_name, 0);
+
+  cFEATURE = rb_define_class_under(mCHISE, "Feature", rb_cObject);
+  rb_define_method(cFEATURE, "get_value", ffeature_get_value, 1);
+  rb_define_method(cFEATURE, "each_char", ffeature_each_char, 0);
+
+  cCCS = rb_define_class_under(mCHISE, "CCS", rb_cObject);
+  rb_define_method(cCCS, "decode", fccs_decode, 1);
+
+  cVALUE = rb_define_class_under(mCHISE, "Value", rb_cObject);
+  rb_define_method(cVALUE, "to_s", fvalue_to_s, 0);
+}