update.
[chise/ruby.git] / ext / libchise_c.c
1 /* Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
2    This file is part of the Ruby/CHISE Extension.
3
4    This software is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    This software is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the CHISE Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include "ruby.h"
20 #include "chise.h"
21
22 static VALUE mCHISE, cDS, cCCS, cFEATURE, cVALUE;
23
24 typedef struct {
25   CHISE_DS *ds;
26 } RB_CHISE_DS;
27
28 typedef struct {
29   CHISE_Feature_Table *feature;
30 } RB_CHISE_FEATURE;
31
32 typedef struct {
33   CHISE_CCS_Table *ccs;
34 } RB_CHISE_CCS;
35
36 typedef struct {
37   CHISE_Value value;
38 } RB_CHISE_VALUE;
39
40 static VALUE fds_new(VALUE klass, VALUE type, VALUE location, VALUE dbtype, VALUE mode){
41   RB_CHISE_DS *rds;
42   VALUE tdata = Data_Make_Struct(klass, RB_CHISE_DS, 0, free, rds);
43   rds->ds = CHISE_DS_open((CHISE_DS_Type)NUM2INT(type), RSTRING(rb_str_to_str(location))->ptr, NUM2INT(dbtype), NUM2INT(mode));
44   if (rds->ds == NULL){
45     return Qnil;
46   }
47   return tdata;
48 }
49
50 static VALUE fds_close(VALUE obj){
51   RB_CHISE_DS *rds;
52   Data_Get_Struct(obj, RB_CHISE_DS, rds);
53   CHISE_DS_close(rds->ds);
54   return Qnil;
55 }
56
57 static VALUE fds_get_feature(VALUE obj, VALUE feature){
58   RB_CHISE_DS *rds;
59   RB_CHISE_FEATURE *rfeature;
60   VALUE vfeature;
61   int status;
62   Data_Get_Struct(obj, RB_CHISE_DS, rds);
63   vfeature = Data_Make_Struct(cFEATURE, RB_CHISE_FEATURE, 0, free, rfeature);
64   rfeature->feature = chise_ds_get_feature(rds->ds, RSTRING(rb_str_to_str(feature))->ptr);
65   return vfeature;
66 }
67
68 static VALUE fds_get_ccs(VALUE obj, VALUE ccs){
69   RB_CHISE_DS *rds;
70   RB_CHISE_CCS *rccs;
71   VALUE vccs;
72   int status;
73   Data_Get_Struct(obj, RB_CHISE_DS, rds);
74   vccs = Data_Make_Struct(cCCS, RB_CHISE_CCS, 0, free, rccs);
75   rccs->ccs = chise_ds_get_ccs(rds->ds, RSTRING(rb_str_to_str(ccs))->ptr);
76   if (rccs->ccs == NULL){
77     return Qnil;
78   }
79   return vccs;
80 }
81
82 static VALUE fds_decode_char(VALUE obj, VALUE ccs, VALUE code_point){
83   RB_CHISE_DS *rds;
84   CHISE_Char_ID char_id;
85   Data_Get_Struct(obj, RB_CHISE_DS, rds);
86   char_id = chise_ds_decode_char(rds->ds, RSTRING(rb_str_to_str(ccs))->ptr, NUM2INT(code_point));
87   return INT2NUM(char_id);
88 }
89
90 static int name_map_func(CHISE_DS *ds, unsigned char *name){
91   rb_yield(rb_str_new2(name));
92   return 0; // important
93 }
94
95 static VALUE fds_each_feature_name(VALUE obj){
96   RB_CHISE_DS *rds;
97   Data_Get_Struct(obj, RB_CHISE_DS, rds);
98   chise_ds_foreach_char_feature_name(rds->ds, &name_map_func);
99   return Qnil;
100 }
101
102 static VALUE ffeature_get_value(VALUE obj, VALUE char_id){
103   RB_CHISE_FEATURE *rfeature;
104   RB_CHISE_VALUE *rvalue;
105   VALUE vvalue;
106   int status;
107   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
108   vvalue = Data_Make_Struct(cVALUE, RB_CHISE_VALUE, 0, free, rvalue);
109   status = chise_char_load_feature_value((CHISE_Char_ID)NUM2INT(char_id), rfeature->feature, &rvalue->value);
110   if (status)
111     return Qnil;
112   return vvalue;
113 }
114
115 static int feature_map_func(CHISE_Char_ID cid, CHISE_Feature_Table *db, CHISE_Value *valdatum){
116   RB_CHISE_VALUE *rvalue;
117   VALUE vvalue;
118   VALUE var;
119   vvalue = Data_Make_Struct(cVALUE, RB_CHISE_VALUE, 0, free, rvalue);
120   memcpy(&rvalue->value, valdatum, sizeof(CHISE_Value));
121   var = rb_ary_new3(2, INT2NUM(cid), vvalue);
122   rb_yield(var);
123   return 0;
124 }
125
126 static VALUE ffeature_each_char(VALUE obj){
127   RB_CHISE_FEATURE *rfeature;
128   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
129   chise_feature_foreach_char_with_value(rfeature->feature, &feature_map_func);
130   return Qnil;
131 }
132
133 static VALUE fccs_decode(VALUE obj, VALUE code_point){
134   RB_CHISE_CCS *rccs;
135   Data_Get_Struct(obj, RB_CHISE_CCS, rccs);
136   CHISE_Char_ID char_id;
137   char_id = chise_ccs_decode(rccs->ccs, NUM2INT(code_point));
138   return INT2NUM(char_id);
139 }
140
141 static VALUE fvalue_to_s(VALUE obj){
142   RB_CHISE_VALUE *rvalue;
143   Data_Get_Struct(obj, RB_CHISE_VALUE, rvalue);
144   return rb_str_new(chise_value_to_c_string(&rvalue->value), chise_value_size(&rvalue->value));
145 }
146
147 void Init_libchise_c(){
148   mCHISE = rb_define_module("CHISE");
149   rb_define_const(mCHISE, "DB_DIR", rb_str_new2(chise_system_db_dir));
150
151   cDS = rb_define_class_under(mCHISE, "DataSource", rb_cObject);
152   rb_define_singleton_method(cDS, "new", fds_new, 4);
153   rb_define_method(cDS, "close", fds_close, 0);
154   rb_define_const(cDS, "NONE", INT2FIX(CHISE_DS_NONE));
155   rb_define_const(cDS, "Berkeley_DB", INT2FIX(CHISE_DS_Berkeley_DB));
156
157   rb_define_method(cDS, "get_feature", fds_get_feature, 1);
158   rb_define_method(cDS, "get_ccs", fds_get_ccs, 1);
159   rb_define_method(cDS, "decode_char", fds_decode_char, 2);
160   rb_define_method(cDS, "each_feature_name", fds_each_feature_name, 0);
161
162   cFEATURE = rb_define_class_under(mCHISE, "Feature", rb_cObject);
163   rb_define_method(cFEATURE, "get_value", ffeature_get_value, 1);
164   rb_define_method(cFEATURE, "each_char", ffeature_each_char, 0);
165
166   cCCS = rb_define_class_under(mCHISE, "CCS", rb_cObject);
167   rb_define_method(cCCS, "decode", fccs_decode, 1);
168
169   cVALUE = rb_define_class_under(mCHISE, "Value", rb_cObject);
170   rb_define_method(cVALUE, "to_s", fvalue_to_s, 0);
171 }