libcdb-ruby 0.0.1-x86-mswin32-60 → 0.0.2-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +7 -0
- data/README +31 -4
- data/TODO +1 -0
- data/ext/libcdb/ruby_cdb.h +53 -2
- data/ext/libcdb/ruby_cdb_reader.c +57 -163
- data/ext/libcdb/ruby_cdb_reader.h +35 -15
- data/ext/libcdb/ruby_cdb_writer.c +7 -40
- data/ext/libcdb/ruby_cdb_writer.h +1 -8
- data/lib/libcdb/1.8/libcdb_ruby.so +0 -0
- data/lib/libcdb/1.9/libcdb_ruby.so +0 -0
- data/lib/libcdb/version.rb +1 -1
- data/lib/libcdb.rb +4 -4
- data/spec/libcdb/reader_spec.rb +54 -0
- data/spec/spec_helper.rb +2 -2
- metadata +8 -8
data/ChangeLog
CHANGED
data/README
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
== VERSION
|
4
4
|
|
5
|
-
This documentation refers to libcdb-ruby version 0.0.
|
5
|
+
This documentation refers to libcdb-ruby version 0.0.2
|
6
6
|
|
7
7
|
|
8
8
|
== DESCRIPTION
|
@@ -35,6 +35,8 @@ creating and reading {constant databases}[http://cr.yp.to/cdb.html].
|
|
35
35
|
cdb['b'] #=> "123"
|
36
36
|
cdb['c'] #=> nil
|
37
37
|
|
38
|
+
# database is truncated whenever
|
39
|
+
# a new writer is opened:
|
38
40
|
cdb['a'] = 'two'
|
39
41
|
cdb['c'] = 'xyz'
|
40
42
|
|
@@ -45,8 +47,10 @@ creating and reading {constant databases}[http://cr.yp.to/cdb.html].
|
|
45
47
|
|
46
48
|
# update existing database
|
47
49
|
LibCDB::CDB.open('foo.cdb', 'r+') { |cdb|
|
48
|
-
|
50
|
+
# store existing records
|
51
|
+
cdb << cdb.to_h
|
49
52
|
|
53
|
+
# and add a new one
|
50
54
|
cdb['d'] = '42'
|
51
55
|
|
52
56
|
cdb['a'] #=> "two"
|
@@ -56,10 +60,23 @@ creating and reading {constant databases}[http://cr.yp.to/cdb.html].
|
|
56
60
|
}
|
57
61
|
|
58
62
|
|
63
|
+
== PREREQUISITES
|
64
|
+
|
65
|
+
<b></b>
|
66
|
+
* Ruby 1.8.7+ or 1.9+ (see below for details)
|
67
|
+
* TinyCDB[http://corpit.ru/mjt/tinycdb.html] headers (not
|
68
|
+
needed when installing the fat binary gem on Windows)
|
69
|
+
|
70
|
+
Debian/Ubuntu:: +libcdb-dev+
|
71
|
+
Fedora/SuSE:: +tinycdb-devel+
|
72
|
+
Gentoo:: +dev-db/tinycdb+
|
73
|
+
|
74
|
+
|
59
75
|
== SUPPORTED PLATFORMS
|
60
76
|
|
61
|
-
|
62
|
-
|
77
|
+
<b></b>
|
78
|
+
Linux:: 1.8 & 1.9 (Tested on Ubuntu with 1.8.7p302 and 1.9.3p19)
|
79
|
+
Windows:: 1.9 only (Tested on XP with 1.9.3p0)
|
63
80
|
|
64
81
|
|
65
82
|
== LINKS
|
@@ -77,6 +94,16 @@ CDB:: http://cr.yp.to/cdb.html
|
|
77
94
|
* Jens Wille <mailto:jens.wille@uni-koeln.de>
|
78
95
|
|
79
96
|
|
97
|
+
== CREDITS
|
98
|
+
|
99
|
+
This project was inspired by ruby-cdb[https://github.com/mbj/ruby-cdb] and
|
100
|
+
cdb-full[https://rubygems.org/gems/cdb-full]. The code organization, especially the
|
101
|
+
extension part, was modeled after libxml-ruby[https://github.com/xml4r/libxml-ruby].
|
102
|
+
|
103
|
+
And props to the rake-compiler[http://github.com/luislavena/rake-compiler]
|
104
|
+
team for making extension building such a breeze :)
|
105
|
+
|
106
|
+
|
80
107
|
== LICENSE AND COPYRIGHT
|
81
108
|
|
82
109
|
Copyright (C) 2012 University of Cologne,
|
data/TODO
CHANGED
data/ext/libcdb/ruby_cdb.h
CHANGED
@@ -2,11 +2,62 @@
|
|
2
2
|
#define __RUBY_CDB_H__
|
3
3
|
|
4
4
|
#ifdef HAVE_RUBY_IO_H
|
5
|
-
#define
|
5
|
+
#define RCDB_GET_FD(fptr) (fptr)->fd
|
6
6
|
#else
|
7
|
-
#define
|
7
|
+
#define RCDB_GET_FD(fptr) fileno((fptr)->f)
|
8
8
|
#endif
|
9
9
|
|
10
|
+
#define RCDB_GET_STRUCT(what, _struct, obj, ptr) {\
|
11
|
+
if (RTEST(rcdb_##what##er_closed_p(obj))) {\
|
12
|
+
rb_raise(rb_eIOError, "closed stream");\
|
13
|
+
}\
|
14
|
+
else {\
|
15
|
+
Data_Get_Struct((obj), struct _struct, (ptr));\
|
16
|
+
}\
|
17
|
+
}
|
18
|
+
|
19
|
+
#define RCDB_DEFINE_ALLOC(what, _struct) \
|
20
|
+
static void \
|
21
|
+
rcdb_##what##er_free(void *ptr) {\
|
22
|
+
free(ptr);\
|
23
|
+
}\
|
24
|
+
\
|
25
|
+
static VALUE \
|
26
|
+
rcdb_##what##er_alloc(VALUE klass) {\
|
27
|
+
struct _struct *ptr = ALLOC_N(struct _struct, 1);\
|
28
|
+
return Data_Wrap_Struct(klass, NULL, rcdb_##what##er_free, ptr);\
|
29
|
+
}
|
30
|
+
|
31
|
+
#define RCDB_INITIALIZE(what, WHAT, _struct, init) \
|
32
|
+
struct _struct *ptr = NULL;\
|
33
|
+
rb_io_t *fptr;\
|
34
|
+
\
|
35
|
+
Check_Type(io, T_FILE);\
|
36
|
+
GetOpenFile(io, fptr);\
|
37
|
+
\
|
38
|
+
rb_io_check_##what##able(fptr);\
|
39
|
+
rb_iv_set(self, "@io", io);\
|
40
|
+
rb_iv_set(self, "closed", Qfalse);\
|
41
|
+
\
|
42
|
+
RCDB_##WHAT##ER_GET(self, ptr);\
|
43
|
+
\
|
44
|
+
if (cdb_##init(ptr, RCDB_GET_FD(fptr)) == -1) {\
|
45
|
+
rb_sys_fail(0);\
|
46
|
+
}
|
47
|
+
|
48
|
+
#define RCDB_DEFINE_INSPECT(what) \
|
49
|
+
static VALUE \
|
50
|
+
rcdb_##what##er_inspect(VALUE self) {\
|
51
|
+
VALUE str = rb_call_super(0, NULL);\
|
52
|
+
\
|
53
|
+
if (RTEST(rcdb_##what##er_closed_p(self))) {\
|
54
|
+
rb_funcall(str,\
|
55
|
+
rb_intern("insert"), 2, INT2FIX(-2), rb_str_new2(" (closed)"));\
|
56
|
+
}\
|
57
|
+
\
|
58
|
+
return str;\
|
59
|
+
}
|
60
|
+
|
10
61
|
VALUE cCDB;
|
11
62
|
void rcdb_init_cdb(void);
|
12
63
|
|
@@ -1,15 +1,6 @@
|
|
1
1
|
#include "ruby_libcdb.h"
|
2
2
|
|
3
|
-
|
4
|
-
rcdb_reader_free(void *ptr) {
|
5
|
-
free(ptr);
|
6
|
-
}
|
7
|
-
|
8
|
-
static VALUE
|
9
|
-
rcdb_reader_alloc(VALUE klass) {
|
10
|
-
struct cdb *cdb = ALLOC_N(struct cdb, 1);
|
11
|
-
return Data_Wrap_Struct(klass, NULL, rcdb_reader_free, cdb);
|
12
|
-
}
|
3
|
+
RCDB_DEFINE_ALLOC(read, cdb)
|
13
4
|
|
14
5
|
/*
|
15
6
|
* call-seq:
|
@@ -31,64 +22,22 @@ rcdb_reader_closed_p(VALUE self) {
|
|
31
22
|
*/
|
32
23
|
static VALUE
|
33
24
|
rcdb_reader_initialize(VALUE self, VALUE io) {
|
34
|
-
|
35
|
-
rb_io_t *fptr;
|
36
|
-
|
37
|
-
Check_Type(io, T_FILE);
|
38
|
-
GetOpenFile(io, fptr);
|
39
|
-
|
40
|
-
rb_io_check_readable(fptr);
|
41
|
-
rb_iv_set(self, "@io", io);
|
42
|
-
rb_iv_set(self, "closed", Qfalse);
|
43
|
-
|
44
|
-
Get_CDB_Reader(self, cdb);
|
45
|
-
|
46
|
-
if (cdb_init(cdb, GetFileFD(fptr)) == -1) {
|
47
|
-
rb_sys_fail(0);
|
48
|
-
}
|
49
|
-
|
25
|
+
RCDB_INITIALIZE(read, READ, cdb, init)
|
50
26
|
return self;
|
51
27
|
}
|
52
28
|
|
53
|
-
|
54
|
-
|
55
|
-
rcdb_reader_read_key(struct cdb *cdb) {
|
56
|
-
size_t len;
|
57
|
-
VALUE key;
|
58
|
-
|
59
|
-
len = cdb_keylen(cdb);
|
60
|
-
key = rb_str_buf_new(len);
|
61
|
-
|
62
|
-
cdb_read(cdb, RSTRING_PTR(key), len, cdb_keypos(cdb));
|
63
|
-
rb_str_set_len(key, len);
|
64
|
-
|
65
|
-
return key;
|
66
|
-
}
|
67
|
-
|
68
|
-
/* Helper method */
|
69
|
-
static VALUE
|
70
|
-
rcdb_reader_read_value(struct cdb *cdb) {
|
71
|
-
size_t len;
|
72
|
-
VALUE val;
|
73
|
-
|
74
|
-
len = cdb_datalen(cdb);
|
75
|
-
val = rb_str_buf_new(len);
|
76
|
-
|
77
|
-
cdb_read(cdb, RSTRING_PTR(val), len, cdb_datapos(cdb));
|
78
|
-
rb_str_set_len(val, len);
|
79
|
-
|
80
|
-
return val;
|
81
|
-
}
|
29
|
+
RCDB_READER_DEFINE_READ(key)
|
30
|
+
RCDB_READER_DEFINE_READ(data)
|
82
31
|
|
83
32
|
/* Helper method */
|
84
33
|
static VALUE
|
85
|
-
|
34
|
+
_rcdb_reader_iter_push(VALUE val, VALUE ary) {
|
86
35
|
return rb_ary_push(ary, val);
|
87
36
|
}
|
88
37
|
|
89
38
|
/* Helper method */
|
90
39
|
static VALUE
|
91
|
-
|
40
|
+
_rcdb_reader_iter_aset(VALUE pair, VALUE hash) {
|
92
41
|
VALUE key = rb_ary_entry(pair, 0), val = rb_ary_entry(pair, 1), old;
|
93
42
|
|
94
43
|
if (!st_lookup(RHASH_TBL(hash), key, 0)) {
|
@@ -112,8 +61,8 @@ rcdb_reader_iter_aset(VALUE pair, VALUE hash) {
|
|
112
61
|
|
113
62
|
/* Helper method */
|
114
63
|
static VALUE
|
115
|
-
|
116
|
-
if (
|
64
|
+
_rcdb_reader_break_equal(VALUE val, VALUE ary) {
|
65
|
+
if (RCDB_READER_EQUAL(val)) {
|
117
66
|
rb_ary_store(ary, 0, Qtrue);
|
118
67
|
rb_iter_break();
|
119
68
|
}
|
@@ -123,8 +72,8 @@ rcdb_reader_break_equal(VALUE val, VALUE ary) {
|
|
123
72
|
|
124
73
|
/* Helper method */
|
125
74
|
static VALUE
|
126
|
-
|
127
|
-
if (
|
75
|
+
_rcdb_reader_break_equal2(VALUE pair, VALUE ary) {
|
76
|
+
if (RCDB_READER_EQUAL(rb_ary_entry(pair, 1))) {
|
128
77
|
rb_ary_store(ary, 0, rb_ary_entry(pair, 0));
|
129
78
|
rb_iter_break();
|
130
79
|
}
|
@@ -134,7 +83,7 @@ rcdb_reader_break_equal2(VALUE pair, VALUE ary) {
|
|
134
83
|
|
135
84
|
/* Helper method */
|
136
85
|
static VALUE
|
137
|
-
|
86
|
+
_rcdb_reader_break_shift(VALUE val, VALUE ary) {
|
138
87
|
rb_ary_shift(ary);
|
139
88
|
rb_iter_break();
|
140
89
|
|
@@ -143,16 +92,14 @@ rcdb_reader_break_shift(VALUE val, VALUE ary) {
|
|
143
92
|
|
144
93
|
/* Helper method */
|
145
94
|
static VALUE
|
146
|
-
|
95
|
+
_rcdb_reader_iter_inc(VALUE val, VALUE ary) {
|
147
96
|
rb_ary_store(ary, 0, rb_funcall(rb_ary_entry(ary, 0), rb_intern("succ"), 0));
|
148
97
|
return Qnil;
|
149
98
|
}
|
150
99
|
|
151
100
|
/* Helper method */
|
152
101
|
static VALUE
|
153
|
-
|
154
|
-
VALUE str = rb_ary_entry(ary, 0);
|
155
|
-
|
102
|
+
_rcdb_reader_iter_dump(VALUE val, VALUE str) {
|
156
103
|
rb_str_append(str, val);
|
157
104
|
rb_str_cat2(str, "\n");
|
158
105
|
|
@@ -161,7 +108,7 @@ rcdb_reader_iter_dump(VALUE val, VALUE ary) {
|
|
161
108
|
|
162
109
|
/* Helper method */
|
163
110
|
static VALUE
|
164
|
-
|
111
|
+
_rcdb_reader_dump_pair(VALUE key, VALUE val) {
|
165
112
|
VALUE str = rb_str_new2("");
|
166
113
|
|
167
114
|
rb_str_cat2(str, "+");
|
@@ -178,40 +125,21 @@ rcdb_reader_dump_pair(VALUE key, VALUE val) {
|
|
178
125
|
|
179
126
|
/* Helper method */
|
180
127
|
static VALUE
|
181
|
-
|
182
|
-
return rb_yield(
|
128
|
+
_rcdb_reader_yield_dump(VALUE pair, VALUE ary) {
|
129
|
+
return rb_yield(_rcdb_reader_dump_pair(
|
183
130
|
rb_ary_entry(pair, 0), rb_ary_entry(pair, 1)));
|
184
131
|
}
|
185
132
|
|
186
133
|
/* Helper method */
|
187
134
|
static VALUE
|
188
|
-
|
189
|
-
return rb_yield(
|
135
|
+
_rcdb_reader_yield_dump2(VALUE val, VALUE ary) {
|
136
|
+
return rb_yield(_rcdb_reader_dump_pair(rb_ary_entry(ary, 0), val));
|
190
137
|
}
|
191
138
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
}
|
197
|
-
|
198
|
-
/* Helper method */
|
199
|
-
static VALUE
|
200
|
-
rcdb_reader_call_each_key(VALUE args) {
|
201
|
-
CALL_ITERATOR("each_key")
|
202
|
-
}
|
203
|
-
|
204
|
-
/* Helper method */
|
205
|
-
static VALUE
|
206
|
-
rcdb_reader_call_each_value(VALUE args) {
|
207
|
-
CALL_ITERATOR("each_value")
|
208
|
-
}
|
209
|
-
|
210
|
-
/* Helper method */
|
211
|
-
static VALUE
|
212
|
-
rcdb_reader_call_each_dump(VALUE args) {
|
213
|
-
CALL_ITERATOR("each_dump")
|
214
|
-
}
|
139
|
+
RCDB_READER_DEFINE_CALL(each)
|
140
|
+
RCDB_READER_DEFINE_CALL(each_key)
|
141
|
+
RCDB_READER_DEFINE_CALL(each_value)
|
142
|
+
RCDB_READER_DEFINE_CALL(each_dump)
|
215
143
|
|
216
144
|
/*
|
217
145
|
* call-seq:
|
@@ -235,7 +163,7 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
|
|
235
163
|
|
236
164
|
RETURN_ENUMERATOR(self, argc, argv);
|
237
165
|
|
238
|
-
|
166
|
+
RCDB_READER_GET(self, cdb);
|
239
167
|
|
240
168
|
if (rb_scan_args(argc, argv, "01", &key) == 1 && !NIL_P(key)) {
|
241
169
|
StringValue(key);
|
@@ -245,7 +173,7 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
|
|
245
173
|
}
|
246
174
|
|
247
175
|
while (cdb_findnext(&cdbf) > 0) {
|
248
|
-
rb_yield(
|
176
|
+
rb_yield(_rcdb_reader_read_data(cdb));
|
249
177
|
}
|
250
178
|
}
|
251
179
|
else {
|
@@ -253,8 +181,8 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
|
|
253
181
|
|
254
182
|
while (cdb_seqnext(&cdbp, cdb) > 0) {
|
255
183
|
rb_yield(rb_ary_new3(2,
|
256
|
-
|
257
|
-
|
184
|
+
_rcdb_reader_read_key(cdb),
|
185
|
+
_rcdb_reader_read_data(cdb)));
|
258
186
|
}
|
259
187
|
}
|
260
188
|
|
@@ -273,7 +201,7 @@ rcdb_reader_each(int argc, VALUE *argv, VALUE self) {
|
|
273
201
|
static VALUE
|
274
202
|
rcdb_reader_each_dump(int argc, VALUE *argv, VALUE self) {
|
275
203
|
VALUE key, args = rb_ary_new3(1, self), ary = rb_ary_new();
|
276
|
-
VALUE (*block)(ANYARGS) =
|
204
|
+
VALUE (*block)(ANYARGS) = _rcdb_reader_yield_dump;
|
277
205
|
|
278
206
|
if (argc > 1) {
|
279
207
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0-1)", argc);
|
@@ -285,10 +213,10 @@ rcdb_reader_each_dump(int argc, VALUE *argv, VALUE self) {
|
|
285
213
|
rb_ary_push(ary, key);
|
286
214
|
rb_ary_push(args, key);
|
287
215
|
|
288
|
-
block =
|
216
|
+
block = _rcdb_reader_yield_dump2;
|
289
217
|
}
|
290
218
|
|
291
|
-
rb_iterate(
|
219
|
+
rb_iterate(_rcdb_reader_call_each, args, block, ary);
|
292
220
|
|
293
221
|
return self;
|
294
222
|
}
|
@@ -307,11 +235,11 @@ rcdb_reader_each_key(VALUE self) {
|
|
307
235
|
unsigned cdbp;
|
308
236
|
VALUE key, hash = rb_hash_new();
|
309
237
|
|
310
|
-
|
238
|
+
RCDB_READER_GET(self, cdb);
|
311
239
|
cdb_seqinit(&cdbp, cdb);
|
312
240
|
|
313
241
|
while (cdb_seqnext(&cdbp, cdb) > 0) {
|
314
|
-
if (!st_lookup(RHASH_TBL(hash), key =
|
242
|
+
if (!st_lookup(RHASH_TBL(hash), key = _rcdb_reader_read_key(cdb), 0)) {
|
315
243
|
rb_hash_aset(hash, key, Qtrue);
|
316
244
|
rb_yield(key);
|
317
245
|
}
|
@@ -333,11 +261,11 @@ rcdb_reader_each_value(VALUE self) {
|
|
333
261
|
struct cdb *cdb = NULL;
|
334
262
|
unsigned cdbp;
|
335
263
|
|
336
|
-
|
264
|
+
RCDB_READER_GET(self, cdb);
|
337
265
|
cdb_seqinit(&cdbp, cdb);
|
338
266
|
|
339
267
|
while (cdb_seqnext(&cdbp, cdb) > 0) {
|
340
|
-
rb_yield(
|
268
|
+
rb_yield(_rcdb_reader_read_data(cdb));
|
341
269
|
}
|
342
270
|
|
343
271
|
return self;
|
@@ -351,12 +279,10 @@ rcdb_reader_each_value(VALUE self) {
|
|
351
279
|
*/
|
352
280
|
static VALUE
|
353
281
|
rcdb_reader_fetch(VALUE self, VALUE key) {
|
354
|
-
|
355
|
-
|
356
|
-
rb_iterate(rcdb_reader_call_each,
|
357
|
-
rb_ary_new3(2, self, key), rcdb_reader_iter_push, ary);
|
282
|
+
RCDB_READER_ITERATE0(each, iter_push,
|
283
|
+
rb_ary_new(), rb_ary_new3(2, self, key))
|
358
284
|
|
359
|
-
return
|
285
|
+
return arg;
|
360
286
|
}
|
361
287
|
|
362
288
|
/*
|
@@ -371,10 +297,10 @@ rcdb_reader_fetch_first(VALUE self, VALUE key) {
|
|
371
297
|
VALUE val = Qnil;
|
372
298
|
|
373
299
|
StringValue(key);
|
374
|
-
|
300
|
+
RCDB_READER_GET(self, cdb);
|
375
301
|
|
376
302
|
if (cdb_find(cdb, RSTRING_PTR(key), RSTRING_LEN(key)) > 0) {
|
377
|
-
val =
|
303
|
+
val = _rcdb_reader_read_data(cdb);
|
378
304
|
}
|
379
305
|
|
380
306
|
return val;
|
@@ -395,7 +321,7 @@ rcdb_reader_fetch_last(VALUE self, VALUE key) {
|
|
395
321
|
size_t len = 0;
|
396
322
|
|
397
323
|
StringValue(key);
|
398
|
-
|
324
|
+
RCDB_READER_GET(self, cdb);
|
399
325
|
|
400
326
|
if (cdb_findinit(&cdbf, cdb, RSTRING_PTR(key), RSTRING_LEN(key)) == -1) {
|
401
327
|
rb_sys_fail(0);
|
@@ -423,12 +349,7 @@ rcdb_reader_fetch_last(VALUE self, VALUE key) {
|
|
423
349
|
*/
|
424
350
|
static VALUE
|
425
351
|
rcdb_reader_keys(VALUE self) {
|
426
|
-
|
427
|
-
|
428
|
-
rb_iterate(rcdb_reader_call_each_key,
|
429
|
-
rb_ary_new3(1, self), rcdb_reader_iter_push, ary);
|
430
|
-
|
431
|
-
return ary;
|
352
|
+
RCDB_READER_ITERATE(each_key, iter_push, rb_ary_new())
|
432
353
|
}
|
433
354
|
|
434
355
|
/*
|
@@ -439,12 +360,7 @@ rcdb_reader_keys(VALUE self) {
|
|
439
360
|
*/
|
440
361
|
static VALUE
|
441
362
|
rcdb_reader_values(VALUE self) {
|
442
|
-
|
443
|
-
|
444
|
-
rb_iterate(rcdb_reader_call_each_value,
|
445
|
-
rb_ary_new3(1, self), rcdb_reader_iter_push, ary);
|
446
|
-
|
447
|
-
return ary;
|
363
|
+
RCDB_READER_ITERATE(each_value, iter_push, rb_ary_new())
|
448
364
|
}
|
449
365
|
|
450
366
|
/*
|
@@ -473,8 +389,8 @@ rcdb_reader_values_at(int argc, VALUE *argv, VALUE self) {
|
|
473
389
|
*/
|
474
390
|
static VALUE
|
475
391
|
rcdb_reader_has_key_p(VALUE self, VALUE key) {
|
476
|
-
|
477
|
-
|
392
|
+
RCDB_READER_ITERATE_ARY(each_key, break_equal,
|
393
|
+
rb_ary_new3(2, Qfalse, key))
|
478
394
|
}
|
479
395
|
|
480
396
|
/*
|
@@ -485,8 +401,8 @@ rcdb_reader_has_key_p(VALUE self, VALUE key) {
|
|
485
401
|
*/
|
486
402
|
static VALUE
|
487
403
|
rcdb_reader_has_value_p(VALUE self, VALUE val) {
|
488
|
-
|
489
|
-
|
404
|
+
RCDB_READER_ITERATE_ARY(each_value, break_equal,
|
405
|
+
rb_ary_new3(2, Qfalse, val))
|
490
406
|
}
|
491
407
|
|
492
408
|
/*
|
@@ -498,8 +414,8 @@ rcdb_reader_has_value_p(VALUE self, VALUE val) {
|
|
498
414
|
*/
|
499
415
|
static VALUE
|
500
416
|
rcdb_reader_key(VALUE self, VALUE val) {
|
501
|
-
|
502
|
-
|
417
|
+
RCDB_READER_ITERATE_ARY(each, break_equal2,
|
418
|
+
rb_ary_new3(2, Qnil, val))
|
503
419
|
}
|
504
420
|
|
505
421
|
/*
|
@@ -510,8 +426,8 @@ rcdb_reader_key(VALUE self, VALUE val) {
|
|
510
426
|
*/
|
511
427
|
static VALUE
|
512
428
|
rcdb_reader_empty_p(VALUE self) {
|
513
|
-
|
514
|
-
|
429
|
+
RCDB_READER_ITERATE_ARY(each_key, break_shift,
|
430
|
+
rb_ary_new3(2, Qtrue, Qfalse))
|
515
431
|
}
|
516
432
|
|
517
433
|
/*
|
@@ -522,8 +438,8 @@ rcdb_reader_empty_p(VALUE self) {
|
|
522
438
|
*/
|
523
439
|
static VALUE
|
524
440
|
rcdb_reader_size(VALUE self) {
|
525
|
-
|
526
|
-
|
441
|
+
RCDB_READER_ITERATE_ARY(each_key, iter_inc,
|
442
|
+
rb_ary_new3(1, INT2FIX(0)))
|
527
443
|
}
|
528
444
|
|
529
445
|
/*
|
@@ -538,7 +454,7 @@ rcdb_reader_total(VALUE self) {
|
|
538
454
|
unsigned cdbp;
|
539
455
|
long i = 0;
|
540
456
|
|
541
|
-
|
457
|
+
RCDB_READER_GET(self, cdb);
|
542
458
|
cdb_seqinit(&cdbp, cdb);
|
543
459
|
|
544
460
|
while (cdb_seqnext(&cdbp, cdb) > 0) {
|
@@ -556,8 +472,7 @@ rcdb_reader_total(VALUE self) {
|
|
556
472
|
*/
|
557
473
|
static VALUE
|
558
474
|
rcdb_reader_dump(VALUE self) {
|
559
|
-
|
560
|
-
ITER_RESULT(rcdb_reader_call_each_dump, rcdb_reader_iter_dump)
|
475
|
+
RCDB_READER_ITERATE(each_dump, iter_dump, rb_str_new2(""))
|
561
476
|
}
|
562
477
|
|
563
478
|
/*
|
@@ -571,12 +486,7 @@ rcdb_reader_dump(VALUE self) {
|
|
571
486
|
*/
|
572
487
|
static VALUE
|
573
488
|
rcdb_reader_to_h(VALUE self) {
|
574
|
-
|
575
|
-
|
576
|
-
rb_iterate(rcdb_reader_call_each,
|
577
|
-
rb_ary_new3(1, self), rcdb_reader_iter_aset, hash);
|
578
|
-
|
579
|
-
return hash;
|
489
|
+
RCDB_READER_ITERATE(each, iter_aset, rb_hash_new())
|
580
490
|
}
|
581
491
|
|
582
492
|
/*
|
@@ -589,12 +499,7 @@ rcdb_reader_to_h(VALUE self) {
|
|
589
499
|
*/
|
590
500
|
static VALUE
|
591
501
|
rcdb_reader_to_a(VALUE self) {
|
592
|
-
|
593
|
-
|
594
|
-
rb_iterate(rcdb_reader_call_each,
|
595
|
-
rb_ary_new3(1, self), rcdb_reader_iter_push, ary);
|
596
|
-
|
597
|
-
return ary;
|
502
|
+
RCDB_READER_ITERATE(each, iter_push, rb_ary_new())
|
598
503
|
}
|
599
504
|
|
600
505
|
/*
|
@@ -611,7 +516,7 @@ rcdb_reader_close(VALUE self) {
|
|
611
516
|
return Qnil;
|
612
517
|
}
|
613
518
|
|
614
|
-
|
519
|
+
RCDB_READER_GET(self, cdb);
|
615
520
|
rb_iv_set(self, "closed", Qtrue);
|
616
521
|
|
617
522
|
rb_io_close(rb_iv_get(self, "@io"));
|
@@ -619,18 +524,7 @@ rcdb_reader_close(VALUE self) {
|
|
619
524
|
return Qnil;
|
620
525
|
}
|
621
526
|
|
622
|
-
|
623
|
-
static VALUE
|
624
|
-
rcdb_reader_inspect(VALUE self) {
|
625
|
-
VALUE str = rb_call_super(0, NULL);
|
626
|
-
|
627
|
-
if (RTEST(rcdb_reader_closed_p(self))) {
|
628
|
-
rb_funcall(str,
|
629
|
-
rb_intern("insert"), 2, INT2FIX(-2), rb_str_new2(" (closed)"));
|
630
|
-
}
|
631
|
-
|
632
|
-
return str;
|
633
|
-
}
|
527
|
+
RCDB_DEFINE_INSPECT(read)
|
634
528
|
|
635
529
|
void
|
636
530
|
rcdb_init_reader(void) {
|
@@ -1,29 +1,49 @@
|
|
1
1
|
#ifndef __RCDB_READER_H__
|
2
2
|
#define __RCDB_READER_H__
|
3
3
|
|
4
|
-
#define
|
5
|
-
if (RTEST(rcdb_reader_closed_p(obj))) {\
|
6
|
-
rb_raise(rb_eRuntimeError, "closed stream");\
|
7
|
-
}\
|
8
|
-
else {\
|
9
|
-
Data_Get_Struct((obj), struct cdb, (var));\
|
10
|
-
}\
|
11
|
-
}
|
4
|
+
#define RCDB_READER_GET(obj, ptr) RCDB_GET_STRUCT(read, cdb, obj, ptr)
|
12
5
|
|
13
|
-
#define
|
6
|
+
#define RCDB_READER_DEFINE_CALL(iter) \
|
7
|
+
static VALUE \
|
8
|
+
_rcdb_reader_call_##iter(VALUE args) {\
|
14
9
|
VALUE self = rb_ary_shift(args);\
|
15
|
-
return rb_funcall2(self, rb_intern(iter),\
|
10
|
+
return rb_funcall2(self, rb_intern(#iter),\
|
16
11
|
RARRAY_LEN(args), RARRAY_PTR(args));\
|
17
12
|
}
|
18
13
|
|
19
|
-
#define
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
#define RCDB_READER_ITERATE0(method, block, arg1, arg2) \
|
15
|
+
VALUE arg = arg1;\
|
16
|
+
rb_iterate(_rcdb_reader_call_##method, arg2, _rcdb_reader_##block, arg);
|
17
|
+
|
18
|
+
#define RCDB_READER_ITERATE1(method, block, arg1) \
|
19
|
+
RCDB_READER_ITERATE0(method, block, arg1, rb_ary_new3(1, self))
|
20
|
+
|
21
|
+
#define RCDB_READER_ITERATE(method, block, arg1) \
|
22
|
+
RCDB_READER_ITERATE1(method, block, arg1)\
|
23
|
+
return arg;
|
23
24
|
|
24
|
-
#define
|
25
|
+
#define RCDB_READER_ITERATE_ARY(method, block, arg1) \
|
26
|
+
RCDB_READER_ITERATE1(method, block, arg1)\
|
27
|
+
return rb_ary_entry(arg, 0);
|
28
|
+
|
29
|
+
#define RCDB_READER_EQUAL(val) \
|
25
30
|
RTEST(rb_funcall((val), rb_intern("=="), 1, rb_ary_entry(ary, 1)))
|
26
31
|
|
32
|
+
#define RCDB_READER_DEFINE_READ(what) \
|
33
|
+
static VALUE \
|
34
|
+
_rcdb_reader_read_##what(struct cdb *cdb) {\
|
35
|
+
size_t len;\
|
36
|
+
VALUE ret;\
|
37
|
+
\
|
38
|
+
len = cdb_##what##len(cdb);\
|
39
|
+
ret = rb_str_buf_new(len);\
|
40
|
+
\
|
41
|
+
cdb_read(cdb, RSTRING_PTR(ret), len, cdb_##what##pos(cdb));\
|
42
|
+
rb_str_set_len(ret, len);\
|
43
|
+
\
|
44
|
+
return ret;\
|
45
|
+
}
|
46
|
+
|
27
47
|
VALUE cCDBReader;
|
28
48
|
void rcdb_init_reader(void);
|
29
49
|
|
@@ -1,15 +1,6 @@
|
|
1
1
|
#include "ruby_libcdb.h"
|
2
2
|
|
3
|
-
|
4
|
-
rcdb_writer_free(void *ptr) {
|
5
|
-
free(ptr);
|
6
|
-
}
|
7
|
-
|
8
|
-
static VALUE
|
9
|
-
rcdb_writer_alloc(VALUE klass) {
|
10
|
-
struct cdb_make *cdbm = ALLOC_N(struct cdb_make, 1);
|
11
|
-
return Data_Wrap_Struct(klass, NULL, rcdb_writer_free, cdbm);
|
12
|
-
}
|
3
|
+
RCDB_DEFINE_ALLOC(writ, cdb_make)
|
13
4
|
|
14
5
|
/*
|
15
6
|
* call-seq:
|
@@ -32,23 +23,9 @@ rcdb_writer_closed_p(VALUE self) {
|
|
32
23
|
*/
|
33
24
|
static VALUE
|
34
25
|
rcdb_writer_initialize(VALUE self, VALUE io) {
|
35
|
-
|
36
|
-
rb_io_t *fptr;
|
37
|
-
|
38
|
-
Check_Type(io, T_FILE);
|
39
|
-
GetOpenFile(io, fptr);
|
40
|
-
|
41
|
-
rb_io_check_writable(fptr);
|
42
|
-
rb_iv_set(self, "@io", io);
|
43
|
-
rb_iv_set(self, "closed", Qfalse);
|
44
|
-
|
45
|
-
Get_CDB_Writer(self, cdbm);
|
26
|
+
RCDB_INITIALIZE(writ, WRIT, cdb_make, make_start)
|
46
27
|
|
47
|
-
if (
|
48
|
-
rb_sys_fail(0);
|
49
|
-
}
|
50
|
-
|
51
|
-
if (lseek(cdb_fileno(cdbm), 0, SEEK_SET) == -1) {
|
28
|
+
if (lseek(cdb_fileno(ptr), 0, SEEK_SET) == -1) {
|
52
29
|
rb_sys_fail(0);
|
53
30
|
}
|
54
31
|
|
@@ -137,7 +114,7 @@ rcdb_writer_put(int argc, VALUE *argv, VALUE self, enum cdb_put_mode mode) {
|
|
137
114
|
VALUE arg, val;
|
138
115
|
long i;
|
139
116
|
|
140
|
-
|
117
|
+
RCDB_WRITER_GET(self, cdbm);
|
141
118
|
|
142
119
|
switch (argc) {
|
143
120
|
case 1:
|
@@ -256,7 +233,7 @@ rcdb_writer_close(VALUE self) {
|
|
256
233
|
return Qnil;
|
257
234
|
}
|
258
235
|
|
259
|
-
|
236
|
+
RCDB_WRITER_GET(self, cdbm);
|
260
237
|
rb_iv_set(self, "closed", Qtrue);
|
261
238
|
|
262
239
|
if (cdb_make_finish(cdbm) == -1) {
|
@@ -268,18 +245,7 @@ rcdb_writer_close(VALUE self) {
|
|
268
245
|
return Qnil;
|
269
246
|
}
|
270
247
|
|
271
|
-
|
272
|
-
static VALUE
|
273
|
-
rcdb_writer_inspect(VALUE self) {
|
274
|
-
VALUE str = rb_call_super(0, NULL);
|
275
|
-
|
276
|
-
if (RTEST(rcdb_writer_closed_p(self))) {
|
277
|
-
rb_funcall(str,
|
278
|
-
rb_intern("insert"), 2, INT2FIX(-2), rb_str_new2(" (closed)"));
|
279
|
-
}
|
280
|
-
|
281
|
-
return str;
|
282
|
-
}
|
248
|
+
RCDB_DEFINE_INSPECT(writ)
|
283
249
|
|
284
250
|
void rcdb_init_writer(void) {
|
285
251
|
/*
|
@@ -296,6 +262,7 @@ void rcdb_init_writer(void) {
|
|
296
262
|
rb_define_method(cCDBWriter, "replace", rcdb_writer_replace, -1);
|
297
263
|
rb_define_method(cCDBWriter, "store", rcdb_writer_store, -1);
|
298
264
|
|
265
|
+
rb_define_alias(cCDBWriter, "<<", "store");
|
299
266
|
rb_define_alias(cCDBWriter, "[]=", "replace");
|
300
267
|
rb_define_alias(cCDBWriter, "add", "store");
|
301
268
|
}
|
@@ -1,14 +1,7 @@
|
|
1
1
|
#ifndef __RCDB_WRITER_H__
|
2
2
|
#define __RCDB_WRITER_H__
|
3
3
|
|
4
|
-
#define
|
5
|
-
if (RTEST(rcdb_writer_closed_p(obj))) {\
|
6
|
-
rb_raise(rb_eRuntimeError, "closed stream");\
|
7
|
-
}\
|
8
|
-
else {\
|
9
|
-
Data_Get_Struct((obj), struct cdb_make, (var));\
|
10
|
-
}\
|
11
|
-
}
|
4
|
+
#define RCDB_WRITER_GET(obj, ptr) RCDB_GET_STRUCT(writ, cdb_make, obj, ptr)
|
12
5
|
|
13
6
|
VALUE cCDBWriter;
|
14
7
|
void rcdb_init_writer(void);
|
Binary file
|
Binary file
|
data/lib/libcdb/version.rb
CHANGED
data/lib/libcdb.rb
CHANGED
@@ -13,8 +13,8 @@ module LibCDB
|
|
13
13
|
|
14
14
|
extend Forwardable
|
15
15
|
|
16
|
-
MODE_READ = 'r'
|
17
|
-
MODE_WRITE = 'w'
|
16
|
+
MODE_READ = 'r' # :nodoc:
|
17
|
+
MODE_WRITE = 'w' # :nodoc:
|
18
18
|
|
19
19
|
class << self
|
20
20
|
|
@@ -133,9 +133,9 @@ module LibCDB
|
|
133
133
|
:fetch_first, :fetch_last, :get, :has_key?,
|
134
134
|
:has_value?, :include?, :key, :key?, :keys,
|
135
135
|
:length, :member?, :rget, :size, :to_a,
|
136
|
-
:to_h, :value?, :values, :values_at
|
136
|
+
:to_h, :total, :value?, :values, :values_at
|
137
137
|
|
138
|
-
def_delegators :writer, :[]=, :add, :insert, :replace, :store
|
138
|
+
def_delegators :writer, :<<, :[]=, :add, :insert, :replace, :store
|
139
139
|
|
140
140
|
# call-seq:
|
141
141
|
# cdb.read? -> true | false
|
data/spec/libcdb/reader_spec.rb
CHANGED
@@ -55,6 +55,18 @@ describe LibCDB::CDB::Reader do
|
|
55
55
|
@db.size.should == 0
|
56
56
|
end
|
57
57
|
|
58
|
+
it "should know its total" do
|
59
|
+
@db.total.should == 0
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should know its keys" do
|
63
|
+
@db.keys.should == []
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should know its values" do
|
67
|
+
@db.values.should == []
|
68
|
+
end
|
69
|
+
|
58
70
|
it "should know if it doesn't have a key" do
|
59
71
|
@db.should_not have_key('key3')
|
60
72
|
end
|
@@ -63,6 +75,18 @@ describe LibCDB::CDB::Reader do
|
|
63
75
|
@db.should_not have_value('value3.2')
|
64
76
|
end
|
65
77
|
|
78
|
+
it "should dump itself" do
|
79
|
+
@db.dump.should == ''
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should convert itself into a hash" do
|
83
|
+
@db.to_h.should == {}
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should convert itself into an array" do
|
87
|
+
@db.to_a.should == []
|
88
|
+
end
|
89
|
+
|
66
90
|
end
|
67
91
|
|
68
92
|
describe "non-empty" do
|
@@ -87,6 +111,18 @@ describe LibCDB::CDB::Reader do
|
|
87
111
|
@db.size.should == 11
|
88
112
|
end
|
89
113
|
|
114
|
+
it "should know its total" do
|
115
|
+
@db.total.should == 56
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should know its keys" do
|
119
|
+
@db.keys.should == TEST_DATA.map { |k, _| k }.uniq
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should know its values" do
|
123
|
+
@db.values.should == TEST_DATA.map { |_, v| v }.flatten
|
124
|
+
end
|
125
|
+
|
90
126
|
it "should know if it has a key" do
|
91
127
|
@db.should have_key('key3')
|
92
128
|
end
|
@@ -137,6 +173,24 @@ describe LibCDB::CDB::Reader do
|
|
137
173
|
@db.key('value33.22').should be_nil
|
138
174
|
end
|
139
175
|
|
176
|
+
it "should dump records for key" do
|
177
|
+
d = []
|
178
|
+
@db.each_dump('key3') { |e| d << e }
|
179
|
+
d.should == %w[+4,8:key3->value3.1 +4,8:key3->value3.2 +4,8:key3->value3.3]
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should convert itself into a hash" do
|
183
|
+
h = {}
|
184
|
+
TEST_DATA.each { |k, v| h[k] = v.size > 1 ? v : v.first }
|
185
|
+
@db.to_h.should == h
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should convert itself into an array" do
|
189
|
+
a = []
|
190
|
+
TEST_DATA.each { |k, v| v.each { |w| a << [k, w] } }
|
191
|
+
@db.to_a.should == a
|
192
|
+
end
|
193
|
+
|
140
194
|
end
|
141
195
|
|
142
196
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,8 +8,8 @@ RSpec.configure { |config|
|
|
8
8
|
TEST_DATA = {}
|
9
9
|
|
10
10
|
1.upto(10) { |i|
|
11
|
-
|
12
|
-
1.upto(i) { |j|
|
11
|
+
v = TEST_DATA["key#{i}"] = []
|
12
|
+
1.upto(i) { |j| v << "value#{i}.#{j}" }
|
13
13
|
}
|
14
14
|
|
15
15
|
TEST_DATA['a' * 1024] = Array('b' * 1024 ** 2)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libcdb-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: x86-mswin32-60
|
12
12
|
authors:
|
13
13
|
- Jens Wille
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-20 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Ruby bindings for CDB Constant Databases.
|
@@ -63,13 +63,13 @@ licenses: []
|
|
63
63
|
|
64
64
|
post_install_message:
|
65
65
|
rdoc_options:
|
66
|
-
- --charset
|
67
|
-
- UTF-8
|
68
|
-
- --title
|
69
|
-
- libcdb-ruby Application documentation (v0.0.1)
|
70
66
|
- --main
|
71
67
|
- README
|
72
68
|
- --all
|
69
|
+
- --charset
|
70
|
+
- UTF-8
|
71
|
+
- --title
|
72
|
+
- libcdb-ruby Application documentation (v0.0.2)
|
73
73
|
- --line-numbers
|
74
74
|
require_paths:
|
75
75
|
- lib
|