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;
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 static VALUE fds_new(VALUE klass, VALUE type, VALUE location, VALUE dbtype, VALUE mode){
37   RB_CHISE_DS *rds;
38   VALUE tdata = Data_Make_Struct(klass, RB_CHISE_DS, 0, free, rds);
39   rds->ds = CHISE_DS_open((CHISE_DS_Type)NUM2INT(type), STR2CSTR(location), NUM2INT(dbtype), NUM2INT(mode));
40   if (rds->ds == NULL) return Qnil;
41   return tdata;
42 }
43
44 static VALUE fds_close(VALUE obj){
45   RB_CHISE_DS *rds;
46   Data_Get_Struct(obj, RB_CHISE_DS, rds);
47   CHISE_DS_close(rds->ds);
48   return Qnil;
49 }
50
51 static int name_map_func(CHISE_DS *ds, unsigned char *name){
52   rb_yield(rb_str_new2(name));
53   return 0; // important
54 }
55
56 static VALUE fds_each_feature_name(VALUE obj){
57   RB_CHISE_DS *rds;
58   Data_Get_Struct(obj, RB_CHISE_DS, rds);
59   chise_ds_foreach_char_feature_name(rds->ds, &name_map_func);
60   return Qnil;
61 }
62
63 static VALUE fds_get_feature(VALUE obj, VALUE name){
64   RB_CHISE_DS *rds;
65   RB_CHISE_FEATURE *rfeature;
66   Data_Get_Struct(obj, RB_CHISE_DS, rds);
67   VALUE vfeature = Data_Make_Struct(cFEATURE, RB_CHISE_FEATURE, 0, free, rfeature);
68   rfeature->feature = chise_ds_get_feature(rds->ds, STR2CSTR(name));
69   return vfeature;
70 }
71
72 static VALUE ffeature_setup_db(VALUE obj, VALUE writable){
73   RB_CHISE_FEATURE *rfeature;
74   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
75   int status = chise_feature_setup_db(rfeature->feature, NUM2INT(writable));
76   if (status) return Qnil;
77   return Qtrue;
78 }
79
80 static VALUE ffeature_sync(VALUE obj){
81   RB_CHISE_FEATURE *rfeature;
82   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
83   int status = chise_feature_sync(rfeature->feature);
84   if (status) return Qnil;
85   return Qtrue;
86 }
87
88 static VALUE ffeature_set_value(VALUE obj, VALUE cid, VALUE value){
89   RB_CHISE_FEATURE *rfeature;
90   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
91   int status = chise_char_set_feature_value((CHISE_Char_ID)NUM2INT(cid), rfeature->feature, STR2CSTR(value));
92   if (status) return Qnil;
93   return Qtrue;
94 }
95
96 static VALUE ffeature_get_value(VALUE obj, VALUE cid){
97   RB_CHISE_FEATURE *rfeature;
98   CHISE_Value valdatum;
99   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
100   int status = chise_char_load_feature_value((CHISE_Char_ID)NUM2INT(cid), rfeature->feature, &valdatum);
101   if (status) return Qnil;
102   return rb_str_new(valdatum.data, valdatum.size);
103 }
104
105 static VALUE fds_load_feature(VALUE obj, VALUE cid, VALUE name){
106   RB_CHISE_DS *rds;
107   CHISE_Value valdatum;
108   Data_Get_Struct(obj, RB_CHISE_DS, rds);
109   int status = chise_ds_load_char_feature_value(rds->ds, NUM2INT(cid), STR2CSTR(name), &valdatum);
110   if (status) return Qnil;
111   return rb_str_new(valdatum.data, valdatum.size);
112 }
113
114 static int feature_map_func(CHISE_Char_ID cid, CHISE_Feature_Table *db, CHISE_Value *valdatum){
115   VALUE vstr = rb_str_new(valdatum->data, valdatum->size);
116   rb_yield(rb_assoc_new(INT2NUM(cid), vstr));
117   return 0;
118 }
119
120 static VALUE ffeature_each_char(VALUE obj){
121   RB_CHISE_FEATURE *rfeature;
122   Data_Get_Struct(obj, RB_CHISE_FEATURE, rfeature);
123   chise_feature_foreach_char_with_value(rfeature->feature, &feature_map_func);
124   return Qnil;
125 }
126
127 static VALUE fds_get_ccs(VALUE obj, VALUE ccs){
128   RB_CHISE_DS *rds;
129   RB_CHISE_CCS *rccs;
130   Data_Get_Struct(obj, RB_CHISE_DS, rds);
131   VALUE vccs = Data_Make_Struct(cCCS, RB_CHISE_CCS, 0, free, rccs);
132   rccs->ccs = chise_ds_get_ccs(rds->ds, STR2CSTR(ccs));
133   if (rccs->ccs == NULL) return Qnil;
134   return vccs;
135 }
136
137 static VALUE fds_decode_char(VALUE obj, VALUE ccs, VALUE code_point){
138   RB_CHISE_DS *rds;
139   Data_Get_Struct(obj, RB_CHISE_DS, rds);
140   CHISE_Char_ID cid = chise_ds_decode_char(rds->ds, STR2CSTR(ccs), NUM2INT(code_point));
141   return INT2NUM(cid);
142 }
143
144 static VALUE fccs_setup_db(VALUE obj, VALUE writable){
145   RB_CHISE_CCS *rccs;
146   Data_Get_Struct(obj, RB_CHISE_CCS, rccs);
147   int status = chise_ccs_setup_db(rccs->ccs, NUM2INT(writable));
148   if (status) return Qnil;
149   return Qtrue;
150 }
151
152 static VALUE fccs_sync(VALUE obj){
153   RB_CHISE_CCS *rccs;
154   Data_Get_Struct(obj, RB_CHISE_CCS, rccs);
155   int status = chise_ccs_sync(rccs->ccs);
156   if (status) return Qnil;
157   return Qtrue;
158 }
159
160 static VALUE fccs_set(VALUE obj, VALUE code_point, VALUE cid){
161   RB_CHISE_CCS *rccs;
162   Data_Get_Struct(obj, RB_CHISE_CCS, rccs);
163   int status = chise_ccs_set_decoded_char(rccs->ccs, NUM2INT(code_point), (CHISE_Char_ID)NUM2INT(cid));
164   if (status) return Qnil;
165   return Qtrue;
166 }
167
168 static VALUE fccs_decode(VALUE obj, VALUE code_point){
169   RB_CHISE_CCS *rccs;
170   Data_Get_Struct(obj, RB_CHISE_CCS, rccs);
171   CHISE_Char_ID cid = chise_ccs_decode(rccs->ccs, NUM2INT(code_point));
172   if (cid == -1) return Qnil;
173   return INT2NUM(cid);
174 }
175
176 void Init_libchise_c(){
177   mCHISE = rb_define_module("CHISE");
178
179   cDS = rb_define_class_under(mCHISE, "DataSource_C", rb_cObject);
180   rb_define_const(cDS, "NONE", INT2FIX(CHISE_DS_NONE));
181   rb_define_const(cDS, "Berkeley_DB", INT2FIX(CHISE_DS_Berkeley_DB));
182   rb_define_const(cDS, "DB_DIR", rb_str_new2(chise_system_db_dir));
183   rb_define_singleton_method(cDS, "new", fds_new, 4);
184   rb_define_method(cDS, "close", fds_close, 0);
185   rb_define_method(cDS, "each_feature_name", fds_each_feature_name, 0);
186   rb_define_method(cDS, "get_feature", fds_get_feature, 1);
187   rb_define_method(cDS, "load_feature", fds_load_feature, 2);
188   rb_define_method(cDS, "get_ccs", fds_get_ccs, 1);
189   rb_define_method(cDS, "decode_char", fds_decode_char, 2);
190
191   cFEATURE = rb_define_class_under(mCHISE, "Feature_C", rb_cObject);
192   rb_define_method(cFEATURE, "setup_db", ffeature_setup_db, 1);
193   rb_define_method(cFEATURE, "sync", ffeature_sync, 0);
194   rb_define_method(cFEATURE, "set_value", ffeature_set_value, 2);
195   rb_define_method(cFEATURE, "get_value", ffeature_get_value, 1);
196   rb_define_method(cFEATURE, "each_char", ffeature_each_char, 0);
197
198   cCCS = rb_define_class_under(mCHISE, "CCS_C", rb_cObject);
199   rb_define_method(cCCS, "setup_db", fccs_setup_db, 1);
200   rb_define_method(cCCS, "sync", fccs_sync, 0);
201   rb_define_method(cCCS, "set", fccs_set, 2);
202   rb_define_method(cCCS, "decode", fccs_decode, 1);
203 }