1 /*************************************************************************************************
2  * Implementation of Villa for Ruby
3  *                                                      Copyright (C) 2000-2006 Mikio Hirabayashi
4  * This file is part of QDBM, Quick Database Manager.
5  * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * Lesser General Public License as published by the Free Software Foundation; either version
7  * 2.1 of the License or any later version.  QDBM is distributed in the hope that it will be
8  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
10  * details.
11  * You should have received a copy of the GNU Lesser General Public License along with QDBM; if
12  * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
13  * 02111-1307 USA.
14  *************************************************************************************************/
15 
16 
17 #include "ruby.h"
18 #include <depot.h>
19 #include <cabin.h>
20 #include <villa.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 
26 #define MAXOPEN 1024
27 
28 
29 VALUE cvillaerror;
30 VALUE cvillaerror_ENOERR;
31 VALUE cvillaerror_EFATAL;
32 VALUE cvillaerror_EMODE;
33 VALUE cvillaerror_EBROKEN;
34 VALUE cvillaerror_EKEEP;
35 VALUE cvillaerror_ENOITEM;
36 VALUE cvillaerror_EALLOC;
37 VALUE cvillaerror_EMAP;
38 VALUE cvillaerror_EOPEN;
39 VALUE cvillaerror_ECLOSE;
40 VALUE cvillaerror_ETRUNC;
41 VALUE cvillaerror_ESYNC;
42 VALUE cvillaerror_ESTAT;
43 VALUE cvillaerror_ESEEK;
44 VALUE cvillaerror_EREAD;
45 VALUE cvillaerror_EWRITE;
46 VALUE cvillaerror_ELOCK;
47 VALUE cvillaerror_EUNLINK;
48 VALUE cvillaerror_EMKDIR;
49 VALUE cvillaerror_ERMDIR;
50 VALUE cvillaerror_EMISC;
51 VALUE mvilla;
52 ID idcompare;
53 VILLA *vltable[MAXOPEN];
54 char vlsltable[MAXOPEN];
55 
56 
57 static void vlinit(void);
58 static int getnewindex(void);
59 static int checkdup(const char *name);
60 static void myerror(int ecode);
61 static int objcompare(const char *aptr, int asiz, const char *bptr, int bsiz);
62 static VALUE rbvlversion(VALUE vself);
63 static VALUE rbvlerrmsg(VALUE vself, VALUE vecode);
64 static VALUE rbvlopen(VALUE vself, VALUE vname, VALUE vomode, VALUE vcmode);
65 static VALUE rbvlclose(VALUE vself, VALUE vindex);
66 static VALUE rbvlsetsilent(VALUE vself, VALUE vindex, VALUE vvalue);
67 static VALUE rbvlput(VALUE vself, VALUE vindex, VALUE vkey, VALUE vval, VALUE vdmode);
68 static VALUE rbvlout(VALUE vself, VALUE vindex, VALUE vkey);
69 static VALUE rbvlget(VALUE vself, VALUE vindex, VALUE vkey);
70 static VALUE rbvlvsiz(VALUE vself, VALUE vindex, VALUE vkey);
71 static VALUE rbvlvnum(VALUE vself, VALUE vindex, VALUE vkey);
72 static VALUE rbvlcurfirst(VALUE vself, VALUE vindex);
73 static VALUE rbvlcurlast(VALUE vself, VALUE vindex);
74 static VALUE rbvlcurprev(VALUE vself, VALUE vindex);
75 static VALUE rbvlcurnext(VALUE vself, VALUE vindex);
76 static VALUE rbvlcurjump(VALUE vself, VALUE vindex, VALUE vkey, VALUE vjmode);
77 static VALUE rbvlcurkey(VALUE vself, VALUE vindex);
78 static VALUE rbvlcurval(VALUE vself, VALUE vindex);
79 static VALUE rbvlcurput(VALUE vself, VALUE vindex, VALUE vval, VALUE vjmode);
80 static VALUE rbvlcurout(VALUE vself, VALUE vindex);
81 static VALUE rbvlsettuning(VALUE vself, VALUE vindex,
82                            VALUE vlrecmax, VALUE vnidxmax, VALUE vlcnum, VALUE vncnum);
83 static VALUE rbvlsync(VALUE vself, VALUE vindex);
84 static VALUE rbvloptimize(VALUE vself, VALUE vindex);
85 static VALUE rbvlfsiz(VALUE vself, VALUE vindex);
86 static VALUE rbvlrnum(VALUE vself, VALUE vindex);
87 static VALUE rbvlwritable(VALUE vself, VALUE vindex);
88 static VALUE rbvlfatalerror(VALUE vself, VALUE vindex);
89 static VALUE rbvltranbegin(VALUE vself, VALUE vindex);
90 static VALUE rbvltrancommit(VALUE vself, VALUE vindex);
91 static VALUE rbvltranabort(VALUE vself, VALUE vindex);
92 
93 
94 
95 /*************************************************************************************************
96  * public objects
97  *************************************************************************************************/
98 
99 
Init_mod_villa()100 Init_mod_villa(){
101   vlinit();
102   cvillaerror = rb_define_class("VillaError", rb_eStandardError);
103   cvillaerror_ENOERR = rb_define_class("VillaError_ENOERR", cvillaerror);
104   cvillaerror_EFATAL = rb_define_class("VillaError_EFATAL", cvillaerror);
105   cvillaerror_EMODE = rb_define_class("VillaError_EMODE", cvillaerror);
106   cvillaerror_EBROKEN = rb_define_class("VillaError_EBROKEN", cvillaerror);
107   cvillaerror_EKEEP = rb_define_class("VillaError_EKEEP", cvillaerror);
108   cvillaerror_ENOITEM = rb_define_class("VillaError_ENOITEM", cvillaerror);
109   cvillaerror_EALLOC = rb_define_class("VillaError_EALLOC", cvillaerror);
110   cvillaerror_EMAP = rb_define_class("VillaError_EMAP", cvillaerror);
111   cvillaerror_EOPEN = rb_define_class("VillaError_EOPEN", cvillaerror);
112   cvillaerror_ECLOSE = rb_define_class("VillaError_ECLOSE", cvillaerror);
113   cvillaerror_ETRUNC = rb_define_class("VillaError_ETRUNC", cvillaerror);
114   cvillaerror_ESYNC = rb_define_class("VillaError_ESYNC", cvillaerror);
115   cvillaerror_ESTAT = rb_define_class("VillaError_ESTAT", cvillaerror);
116   cvillaerror_ESEEK = rb_define_class("VillaError_ESEEK", cvillaerror);
117   cvillaerror_EREAD = rb_define_class("VillaError_EREAD", cvillaerror);
118   cvillaerror_EWRITE = rb_define_class("VillaError_EWRITE", cvillaerror);
119   cvillaerror_ELOCK = rb_define_class("VillaError_ELOCK", cvillaerror);
120   cvillaerror_EUNLINK = rb_define_class("VillaError_EUNLINK", cvillaerror);
121   cvillaerror_EMKDIR = rb_define_class("VillaError_EMKDIR", cvillaerror);
122   cvillaerror_ERMDIR = rb_define_class("VillaError_ERMDIR", cvillaerror);
123   cvillaerror_EMISC = rb_define_class("VillaError_EMISC", cvillaerror);
124   mvilla = rb_define_module("Mod_Villa");
125   rb_define_const(mvilla, "EANY", cvillaerror);
126   rb_define_const(mvilla, "ENOERR", cvillaerror_ENOERR);
127   rb_define_const(mvilla, "EFATAL", cvillaerror_EFATAL);
128   rb_define_const(mvilla, "EMODE", cvillaerror_EMODE);
129   rb_define_const(mvilla, "EBROKEN", cvillaerror_EBROKEN);
130   rb_define_const(mvilla, "EKEEP", cvillaerror_EKEEP);
131   rb_define_const(mvilla, "ENOITEM", cvillaerror_ENOITEM);
132   rb_define_const(mvilla, "EALLOC", cvillaerror_EALLOC);
133   rb_define_const(mvilla, "EMAP", cvillaerror_EMAP);
134   rb_define_const(mvilla, "EOPEN", cvillaerror_EOPEN);
135   rb_define_const(mvilla, "ECLOSE", cvillaerror_ECLOSE);
136   rb_define_const(mvilla, "ETRUNC", cvillaerror_ETRUNC);
137   rb_define_const(mvilla, "ESYNC", cvillaerror_ESYNC);
138   rb_define_const(mvilla, "ESTAT", cvillaerror_ESTAT);
139   rb_define_const(mvilla, "ESEEK", cvillaerror_ESEEK);
140   rb_define_const(mvilla, "EREAD", cvillaerror_EREAD);
141   rb_define_const(mvilla, "EWRITE", cvillaerror_EWRITE);
142   rb_define_const(mvilla, "ELOCK", cvillaerror_ELOCK);
143   rb_define_const(mvilla, "EUNLINK", cvillaerror_EUNLINK);
144   rb_define_const(mvilla, "EMKDIR", cvillaerror_EMKDIR);
145   rb_define_const(mvilla, "ERMDIR", cvillaerror_ERMDIR);
146   rb_define_const(mvilla, "EMISC", cvillaerror_EMISC);
147   rb_define_const(mvilla, "OREADER", INT2FIX(VL_OREADER));
148   rb_define_const(mvilla, "OWRITER", INT2FIX(VL_OWRITER));
149   rb_define_const(mvilla, "OCREAT", INT2FIX(VL_OCREAT));
150   rb_define_const(mvilla, "OTRUNC", INT2FIX(VL_OTRUNC));
151   rb_define_const(mvilla, "ONOLCK", INT2FIX(VL_ONOLCK));
152   rb_define_const(mvilla, "OLCKNB", INT2FIX(VL_OLCKNB));
153   rb_define_const(mvilla, "OZCOMP", INT2FIX(VL_OZCOMP));
154   rb_define_const(mvilla, "OYCOMP", INT2FIX(VL_OYCOMP));
155   rb_define_const(mvilla, "OXCOMP", INT2FIX(VL_OXCOMP));
156   rb_define_const(mvilla, "CMPLEX", INT2FIX(0));
157   rb_define_const(mvilla, "CMPDEC", INT2FIX(1));
158   rb_define_const(mvilla, "CMPOBJ", INT2FIX(2));
159   rb_define_const(mvilla, "DOVER", INT2FIX(VL_DOVER));
160   rb_define_const(mvilla, "DKEEP", INT2FIX(VL_DKEEP));
161   rb_define_const(mvilla, "DCAT", INT2FIX(VL_DCAT));
162   rb_define_const(mvilla, "DDUP", INT2FIX(VL_DDUP));
163   rb_define_const(mvilla, "DDUPR", INT2FIX(VL_DDUPR));
164   rb_define_const(mvilla, "JFORWARD", INT2FIX(VL_JFORWARD));
165   rb_define_const(mvilla, "JBACKWARD", INT2FIX(VL_JBACKWARD));
166   rb_define_const(mvilla, "CPCURRENT", INT2FIX(VL_CPCURRENT));
167   rb_define_const(mvilla, "CPBEFORE", INT2FIX(VL_CPBEFORE));
168   rb_define_const(mvilla, "CPAFTER", INT2FIX(VL_CPAFTER));
169   rb_define_module_function(mvilla, "mod_open", rbvlopen, 3);
170   rb_define_module_function(mvilla, "mod_close", rbvlclose, 1);
171   rb_define_module_function(mvilla, "mod_setsilent", rbvlsetsilent, 2);
172   rb_define_module_function(mvilla, "mod_put", rbvlput, 4);
173   rb_define_module_function(mvilla, "mod_out", rbvlout, 2);
174   rb_define_module_function(mvilla, "mod_get", rbvlget, 2);
175   rb_define_module_function(mvilla, "mod_vsiz", rbvlvsiz, 2);
176   rb_define_module_function(mvilla, "mod_vnum", rbvlvnum, 2);
177   rb_define_module_function(mvilla, "mod_curfirst", rbvlcurfirst, 1);
178   rb_define_module_function(mvilla, "mod_curlast", rbvlcurlast, 1);
179   rb_define_module_function(mvilla, "mod_curprev", rbvlcurprev, 1);
180   rb_define_module_function(mvilla, "mod_curnext", rbvlcurnext, 1);
181   rb_define_module_function(mvilla, "mod_curjump", rbvlcurjump, 3);
182   rb_define_module_function(mvilla, "mod_curkey", rbvlcurkey, 1);
183   rb_define_module_function(mvilla, "mod_curval", rbvlcurval, 1);
184   rb_define_module_function(mvilla, "mod_curput", rbvlcurput, 3);
185   rb_define_module_function(mvilla, "mod_curout", rbvlcurout, 1);
186   rb_define_module_function(mvilla, "mod_settuning", rbvlsettuning, 5);
187   rb_define_module_function(mvilla, "mod_sync", rbvlsync, 1);
188   rb_define_module_function(mvilla, "mod_optimize", rbvloptimize, 1);
189   rb_define_module_function(mvilla, "mod_fsiz", rbvlfsiz, 1);
190   rb_define_module_function(mvilla, "mod_rnum", rbvlrnum, 1);
191   rb_define_module_function(mvilla, "mod_writable", rbvlwritable, 1);
192   rb_define_module_function(mvilla, "mod_fatalerror", rbvlfatalerror, 1);
193   rb_define_module_function(mvilla, "mod_tranbegin", rbvltranbegin, 1);
194   rb_define_module_function(mvilla, "mod_trancommit", rbvltrancommit, 1);
195   rb_define_module_function(mvilla, "mod_tranabort", rbvltranabort, 1);
196   rb_eval_string("def Mod_Villa.compare(astr, bstr)\n"
197                  "  aobj = nil\n"
198                  "  bobj = nil\n"
199                  "  begin\n"
200                  "    aobj = Marshal.load(astr);\n"
201                  "  rescue\n"
202                  "  end\n"
203                  "  begin\n"
204                  "    bobj = Marshal.load(bstr);\n"
205                  "  rescue\n"
206                  "  end\n"
207                  "  if(aobj && !bobj)\n"
208                  "    return 1\n"
209                  "  end\n"
210                  "  if(!aobj && bobj)\n"
211                  "    return -1\n"
212                  "  end\n"
213                  "  if(!aobj && !bobj)\n"
214                  "    return 0\n"
215                  "  end\n"
216                  "  begin\n"
217                  "    aobj <=> bobj\n"
218                  "  rescue\n"
219                  "    0\n"
220                  "  end\n"
221                  "end\n");
222   idcompare = rb_intern("compare");
223 }
224 
225 
226 
227 /*************************************************************************************************
228  * private objects
229  *************************************************************************************************/
230 
231 
vlinit(void)232 static void vlinit(void){
233   int i;
234   for(i = 0; i < MAXOPEN; i++){
235     vltable[i] = NULL;
236     vlsltable[i] = 0;
237   }
238 }
239 
240 
getnewindex(void)241 static int getnewindex(void){
242   int i;
243   for(i = 0; i < MAXOPEN; i++){
244     if(vltable[i] == NULL) return i;
245   }
246   return -1;
247 }
248 
249 
checkdup(const char * name)250 static int checkdup(const char *name){
251   struct stat sbuf;
252   int i, inode;
253   if(stat(name, &sbuf) == -1) return 0;
254   inode = sbuf.st_ino;
255   for(i = 0; i < MAXOPEN; i++){
256     if(vltable[i] != NULL && vlinode(vltable[i]) == inode) return -1;
257   }
258   return 0;
259 }
260 
261 
myerror(int ecode)262 static void myerror(int ecode){
263   VALUE verr;
264   switch(ecode){
265   case DP_ENOERR: verr = cvillaerror_ENOERR; break;
266   case DP_EFATAL: verr = cvillaerror_EFATAL; break;
267   case DP_EMODE: verr = cvillaerror_EMODE; break;
268   case DP_EBROKEN: verr = cvillaerror_EBROKEN; break;
269   case DP_EKEEP: verr = cvillaerror_EKEEP; break;
270   case DP_ENOITEM: verr = cvillaerror_ENOITEM; break;
271   case DP_EALLOC: verr = cvillaerror_EALLOC; break;
272   case DP_EMAP: verr = cvillaerror_EMAP; break;
273   case DP_EOPEN: verr = cvillaerror_EOPEN; break;
274   case DP_ECLOSE: verr = cvillaerror_ECLOSE; break;
275   case DP_ETRUNC: verr = cvillaerror_ETRUNC; break;
276   case DP_ESYNC: verr = cvillaerror_ESYNC; break;
277   case DP_ESTAT: verr = cvillaerror_ESTAT; break;
278   case DP_ESEEK: verr = cvillaerror_ESEEK; break;
279   case DP_EREAD: verr = cvillaerror_EREAD; break;
280   case DP_EWRITE: verr = cvillaerror_EWRITE; break;
281   case DP_ELOCK: verr = cvillaerror_ELOCK; break;
282   case DP_EUNLINK: verr = cvillaerror_EUNLINK; break;
283   case DP_EMKDIR: verr = cvillaerror_EMKDIR; break;
284   case DP_ERMDIR: verr = cvillaerror_ERMDIR; break;
285   case DP_EMISC: verr = cvillaerror_EMISC; break;
286   default: verr = cvillaerror; break;
287   }
288   rb_raise(verr, "%s", dperrmsg(ecode));
289 }
290 
291 
objcompare(const char * aptr,int asiz,const char * bptr,int bsiz)292 static int objcompare(const char *aptr, int asiz, const char *bptr, int bsiz){
293   VALUE vastr, vbstr, vret;
294   vastr = rb_str_new(aptr, asiz);
295   vbstr = rb_str_new(bptr, bsiz);
296   vret = rb_funcall(mvilla, idcompare, 2, vastr, vbstr);
297   return FIX2INT(vret);
298 }
299 
300 
rbvlopen(VALUE vself,VALUE vname,VALUE vomode,VALUE vcmode)301 static VALUE rbvlopen(VALUE vself, VALUE vname, VALUE vomode, VALUE vcmode){
302   VILLA *villa;
303   const char *name;
304   int index, omode, cmode;
305   VLCFUNC cmp;
306   if((index = getnewindex()) == -1) myerror(DP_EMISC);
307   name = STR2CSTR(vname);
308   FIXNUM_P(vomode);
309   omode = FIX2INT(vomode);
310   FIXNUM_P(vcmode);
311   cmode = FIX2INT(vcmode);
312   cmp = NULL;
313   switch(cmode){
314   case 0: cmp = VL_CMPLEX; break;
315   case 1: cmp = VL_CMPDEC; break;
316   case 2: cmp = objcompare; break;
317   default: myerror(DP_EMISC);
318   }
319   if(checkdup(name) == -1) myerror(DP_EMISC);
320   villa = vlopen(name, omode, cmp);
321   if(!villa) myerror(dpecode);
322   vltable[index] = villa;
323   vlsltable[index] = 0;
324   return INT2FIX(index);
325 }
326 
327 
rbvlclose(VALUE vself,VALUE vindex)328 static VALUE rbvlclose(VALUE vself, VALUE vindex){
329   VILLA *villa;
330   int index;
331   FIXNUM_P(vindex);
332   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
333   villa = vltable[index];
334   vltable[index] = NULL;
335   if(!vlclose(villa)) myerror(dpecode);
336   return Qtrue;
337 }
338 
339 
rbvlsetsilent(VALUE vself,VALUE vindex,VALUE vvalue)340 static VALUE rbvlsetsilent(VALUE vself, VALUE vindex, VALUE vvalue){
341   int index;
342   FIXNUM_P(vindex);
343   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
344   vlsltable[index] = FIX2INT(vvalue);
345   return Qnil;
346 }
347 
348 
rbvlput(VALUE vself,VALUE vindex,VALUE vkey,VALUE vval,VALUE vdmode)349 static VALUE rbvlput(VALUE vself, VALUE vindex, VALUE vkey, VALUE vval, VALUE vdmode){
350   VILLA *villa;
351   const char *kbuf, *vbuf;
352   int index, ksiz, vsiz, dmode;
353   FIXNUM_P(vindex);
354   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
355   kbuf = STR2CSTR(vkey);
356   ksiz = RSTRING(vkey)->len;
357   vbuf = STR2CSTR(vval);
358   vsiz = RSTRING(vval)->len;
359   FIXNUM_P(vdmode);
360   dmode = FIX2INT(vdmode);
361   villa = vltable[index];
362   if(!vlput(villa, kbuf, ksiz, vbuf, vsiz, dmode)){
363     if(vlsltable[index] && dpecode == DP_EKEEP) return Qfalse;
364     myerror(dpecode);
365   }
366   return Qtrue;
367 }
368 
369 
rbvlout(VALUE vself,VALUE vindex,VALUE vkey)370 static VALUE rbvlout(VALUE vself, VALUE vindex, VALUE vkey){
371   VILLA *villa;
372   const char *kbuf;
373   int index, ksiz;
374   FIXNUM_P(vindex);
375   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
376   kbuf = STR2CSTR(vkey);
377   ksiz = RSTRING(vkey)->len;
378   villa = vltable[index];
379   if(!vlout(villa, kbuf, ksiz)){
380     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
381     myerror(dpecode);
382   }
383   return Qtrue;
384 }
385 
386 
rbvlget(VALUE vself,VALUE vindex,VALUE vkey)387 static VALUE rbvlget(VALUE vself, VALUE vindex, VALUE vkey){
388   VILLA *villa;
389   const char *kbuf, *vbuf;
390   int index, ksiz, vsiz;
391   VALUE vval;
392   FIXNUM_P(vindex);
393   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
394   kbuf = STR2CSTR(vkey);
395   ksiz = RSTRING(vkey)->len;
396   villa = vltable[index];
397   if(!(vbuf = vlget(villa, kbuf, ksiz, &vsiz))){
398     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qnil;
399     myerror(dpecode);
400   }
401   vval = rb_str_new(vbuf, vsiz);
402   return vval;
403 }
404 
405 
rbvlvsiz(VALUE vself,VALUE vindex,VALUE vkey)406 static VALUE rbvlvsiz(VALUE vself, VALUE vindex, VALUE vkey){
407   VILLA *villa;
408   const char *kbuf;
409   int index, ksiz, vsiz;
410   FIXNUM_P(vindex);
411   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
412   kbuf = STR2CSTR(vkey);
413   ksiz = RSTRING(vkey)->len;
414   villa = vltable[index];
415   if((vsiz = vlvsiz(villa, kbuf, ksiz)) == -1){
416     if(vlsltable[index] && dpecode == DP_ENOITEM) return INT2FIX(-1);
417     myerror(dpecode);
418   }
419   return INT2FIX(vsiz);
420 }
421 
422 
rbvlvnum(VALUE vself,VALUE vindex,VALUE vkey)423 static VALUE rbvlvnum(VALUE vself, VALUE vindex, VALUE vkey){
424   VILLA *villa;
425   const char *kbuf;
426   int index, ksiz, vnum;
427   FIXNUM_P(vindex);
428   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
429   kbuf = STR2CSTR(vkey);
430   ksiz = RSTRING(vkey)->len;
431   villa = vltable[index];
432   vnum = vlvnum(villa, kbuf, ksiz);
433   return INT2FIX(vnum);
434 }
435 
436 
rbvlcurfirst(VALUE vself,VALUE vindex)437 static VALUE rbvlcurfirst(VALUE vself, VALUE vindex){
438   VILLA *villa;
439   int index;
440   FIXNUM_P(vindex);
441   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
442   villa = vltable[index];
443   if(!vlcurfirst(villa)){
444     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
445     myerror(dpecode);
446   }
447   return Qtrue;
448 }
449 
450 
rbvlcurlast(VALUE vself,VALUE vindex)451 static VALUE rbvlcurlast(VALUE vself, VALUE vindex){
452   VILLA *villa;
453   int index;
454   FIXNUM_P(vindex);
455   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
456   villa = vltable[index];
457   if(!vlcurlast(villa)){
458     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
459     myerror(dpecode);
460   }
461   return Qtrue;
462 }
463 
464 
rbvlcurprev(VALUE vself,VALUE vindex)465 static VALUE rbvlcurprev(VALUE vself, VALUE vindex){
466   VILLA *villa;
467   int index;
468   FIXNUM_P(vindex);
469   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
470   villa = vltable[index];
471   if(!vlcurprev(villa)){
472     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
473     myerror(dpecode);
474   }
475   return Qtrue;
476 }
477 
478 
rbvlcurnext(VALUE vself,VALUE vindex)479 static VALUE rbvlcurnext(VALUE vself, VALUE vindex){
480   VILLA *villa;
481   int index;
482   FIXNUM_P(vindex);
483   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
484   villa = vltable[index];
485   if(!vlcurnext(villa)){
486     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
487     myerror(dpecode);
488   }
489   return Qtrue;
490 }
491 
492 
rbvlcurjump(VALUE vself,VALUE vindex,VALUE vkey,VALUE vjmode)493 static VALUE rbvlcurjump(VALUE vself, VALUE vindex, VALUE vkey, VALUE vjmode){
494   VILLA *villa;
495   const char *kbuf;
496   int index, ksiz, jmode;
497   VALUE vval;
498   FIXNUM_P(vindex);
499   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
500   kbuf = STR2CSTR(vkey);
501   ksiz = RSTRING(vkey)->len;
502   FIXNUM_P(vjmode);
503   jmode = FIX2INT(vjmode);
504   villa = vltable[index];
505   if(!vlcurjump(villa, kbuf, ksiz, jmode)){
506     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
507     myerror(dpecode);
508   }
509   return Qtrue;
510 }
511 
512 
513 
rbvlcurkey(VALUE vself,VALUE vindex)514 static VALUE rbvlcurkey(VALUE vself, VALUE vindex){
515   VILLA *villa;
516   const char *kbuf;
517   int index, ksiz;
518   VALUE vkey;
519   FIXNUM_P(vindex);
520   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
521   villa = vltable[index];
522   if(!(kbuf = vlcurkeycache(villa, &ksiz))){
523     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qnil;
524     myerror(dpecode);
525   }
526   vkey = rb_str_new(kbuf, ksiz);
527   return vkey;
528 }
529 
530 
rbvlcurval(VALUE vself,VALUE vindex)531 static VALUE rbvlcurval(VALUE vself, VALUE vindex){
532   VILLA *villa;
533   const char *vbuf;
534   int index, vsiz;
535   VALUE vval;
536   FIXNUM_P(vindex);
537   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
538   villa = vltable[index];
539   if(!(vbuf = vlcurvalcache(villa, &vsiz))){
540     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qnil;
541     myerror(dpecode);
542   }
543   vval = rb_str_new(vbuf, vsiz);
544   return vval;
545 }
546 
547 
rbvlcurput(VALUE vself,VALUE vindex,VALUE vval,VALUE vcpmode)548 static VALUE rbvlcurput(VALUE vself, VALUE vindex, VALUE vval, VALUE vcpmode){
549   VILLA *villa;
550   const char *vbuf;
551   int index, vsiz, cpmode;
552   FIXNUM_P(vindex);
553   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
554   vbuf = STR2CSTR(vval);
555   vsiz = RSTRING(vval)->len;
556   FIXNUM_P(vcpmode);
557   cpmode = FIX2INT(vcpmode);
558   villa = vltable[index];
559   if(!vlcurput(villa, vbuf, vsiz, cpmode)){
560     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
561     myerror(dpecode);
562   }
563   return Qtrue;
564 }
565 
566 
rbvlcurout(VALUE vself,VALUE vindex)567 static VALUE rbvlcurout(VALUE vself, VALUE vindex){
568   VILLA *villa;
569   int index;
570   FIXNUM_P(vindex);
571   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
572   villa = vltable[index];
573   if(!vlcurout(villa)){
574     if(vlsltable[index] && dpecode == DP_ENOITEM) return Qfalse;
575     myerror(dpecode);
576   }
577   return Qtrue;
578 }
579 
580 
rbvlsettuning(VALUE vself,VALUE vindex,VALUE vlrecmax,VALUE vnidxmax,VALUE vlcnum,VALUE vncnum)581 static VALUE rbvlsettuning(VALUE vself, VALUE vindex,
582                            VALUE vlrecmax, VALUE vnidxmax, VALUE vlcnum, VALUE vncnum){
583   VILLA *villa;
584   int index, lrecmax, nidxmax, lcnum, ncnum;
585   FIXNUM_P(vindex);
586   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
587   FIXNUM_P(vlrecmax);
588   lrecmax = FIX2INT(vlrecmax);
589   FIXNUM_P(vnidxmax);
590   nidxmax = FIX2INT(vnidxmax);
591   FIXNUM_P(vlcnum);
592   lcnum = FIX2INT(vlcnum);
593   FIXNUM_P(vncnum);
594   ncnum = FIX2INT(vncnum);
595   villa = vltable[index];
596   vlsettuning(villa, lrecmax, nidxmax, lcnum, ncnum);
597   return Qtrue;
598 }
599 
600 
rbvlsync(VALUE vself,VALUE vindex)601 static VALUE rbvlsync(VALUE vself, VALUE vindex){
602   VILLA *villa;
603   int index;
604   FIXNUM_P(vindex);
605   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
606   villa = vltable[index];
607   if(!vlsync(villa)) myerror(dpecode);
608   return Qtrue;
609 }
610 
611 
rbvloptimize(VALUE vself,VALUE vindex)612 static VALUE rbvloptimize(VALUE vself, VALUE vindex){
613   VILLA *villa;
614   int index;
615   FIXNUM_P(vindex);
616   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
617   villa = vltable[index];
618   if(!vloptimize(villa)) myerror(dpecode);
619   return Qtrue;
620 }
621 
622 
rbvlfsiz(VALUE vself,VALUE vindex)623 static VALUE rbvlfsiz(VALUE vself, VALUE vindex){
624   VILLA *villa;
625   int index, fsiz;
626   FIXNUM_P(vindex);
627   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
628   villa = vltable[index];
629   if((fsiz = vlfsiz(villa)) == -1) myerror(dpecode);
630   return INT2FIX(fsiz);
631 }
632 
633 
rbvlrnum(VALUE vself,VALUE vindex)634 static VALUE rbvlrnum(VALUE vself, VALUE vindex){
635   VILLA *villa;
636   int index, rnum;
637   FIXNUM_P(vindex);
638   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
639   villa = vltable[index];
640   if((rnum = vlrnum(villa)) == -1) myerror(dpecode);
641   return INT2FIX(rnum);
642 }
643 
644 
rbvlwritable(VALUE vself,VALUE vindex)645 static VALUE rbvlwritable(VALUE vself, VALUE vindex){
646   VILLA *villa;
647   int index;
648   FIXNUM_P(vindex);
649   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
650   villa = vltable[index];
651   return vlwritable(villa) ? Qtrue : Qfalse;
652 }
653 
654 
rbvlfatalerror(VALUE vself,VALUE vindex)655 static VALUE rbvlfatalerror(VALUE vself, VALUE vindex){
656   VILLA *villa;
657   int index;
658   FIXNUM_P(vindex);
659   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
660   villa = vltable[index];
661   return vlfatalerror(villa) ? Qtrue : Qfalse;
662 }
663 
664 
rbvltranbegin(VALUE vself,VALUE vindex)665 static VALUE rbvltranbegin(VALUE vself, VALUE vindex){
666   VILLA *villa;
667   int index;
668   FIXNUM_P(vindex);
669   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
670   villa = vltable[index];
671   if(!vltranbegin(villa)) myerror(dpecode);
672   return Qtrue;
673 }
674 
675 
rbvltrancommit(VALUE vself,VALUE vindex)676 static VALUE rbvltrancommit(VALUE vself, VALUE vindex){
677   VILLA *villa;
678   int index;
679   FIXNUM_P(vindex);
680   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
681   villa = vltable[index];
682   if(!vltrancommit(villa)) myerror(dpecode);
683   return Qtrue;
684 }
685 
686 
rbvltranabort(VALUE vself,VALUE vindex)687 static VALUE rbvltranabort(VALUE vself, VALUE vindex){
688   VILLA *villa;
689   int index;
690   FIXNUM_P(vindex);
691   if((index = FIX2INT(vindex)) == -1) myerror(DP_EMISC);
692   villa = vltable[index];
693   if(!vltranabort(villa)) myerror(dpecode);
694   return Qtrue;
695 }
696 
697 
698 
699 /* END OF FILE */
700