globegit-postgresql-plruby 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. data/Changes +121 -0
  2. data/README.markdown +155 -0
  3. data/Rakefile +48 -0
  4. data/docs/plruby.rb +1931 -0
  5. data/ex_trans.sql +33 -0
  6. data/extconf.rb +267 -0
  7. data/plruby.html +1454 -0
  8. data/plruby.rd +1571 -0
  9. data/postgresql-plruby.gemspec +56 -0
  10. data/src/conversions.h +5 -0
  11. data/src/conversions/basic/conversions.h +25 -0
  12. data/src/conversions/basic/extconf.rb +8 -0
  13. data/src/conversions/basic/plruby_basic.c +357 -0
  14. data/src/conversions/bitstring/bitstring.sql +75 -0
  15. data/src/conversions/bitstring/conversions.h +15 -0
  16. data/src/conversions/bitstring/extconf.rb +8 -0
  17. data/src/conversions/bitstring/plruby_bitstring.c +579 -0
  18. data/src/conversions/convcommon.h +129 -0
  19. data/src/conversions/datetime/conversions.h +13 -0
  20. data/src/conversions/datetime/extconf.rb +8 -0
  21. data/src/conversions/datetime/plruby_datetime.c +269 -0
  22. data/src/conversions/geometry/conversions.h +37 -0
  23. data/src/conversions/geometry/extconf.rb +8 -0
  24. data/src/conversions/geometry/geometry.sql +196 -0
  25. data/src/conversions/geometry/plruby_geometry.c +2494 -0
  26. data/src/conversions/network/conversions.h +21 -0
  27. data/src/conversions/network/extconf.rb +8 -0
  28. data/src/conversions/network/network.sql +63 -0
  29. data/src/conversions/network/plruby_network.c +537 -0
  30. data/src/package.h +20 -0
  31. data/src/plpl.c +1708 -0
  32. data/src/plplan.c +893 -0
  33. data/src/plruby.c +1676 -0
  34. data/src/plruby.h +324 -0
  35. data/src/pltrans.c +388 -0
  36. data/test/conv_bitstring/b.rb +45 -0
  37. data/test/conv_bitstring/runtest +26 -0
  38. data/test/conv_bitstring/test.expected.73 +148 -0
  39. data/test/conv_bitstring/test.expected.74 +148 -0
  40. data/test/conv_bitstring/test.expected.80 +148 -0
  41. data/test/conv_bitstring/test.expected.81 +148 -0
  42. data/test/conv_bitstring/test.expected.82 +148 -0
  43. data/test/conv_bitstring/test.expected.83 +148 -0
  44. data/test/conv_bitstring/test.expected.84 +148 -0
  45. data/test/conv_bitstring/test.out +148 -0
  46. data/test/conv_bitstring/test_mklang.sql +8 -0
  47. data/test/conv_bitstring/test_queries.sql +63 -0
  48. data/test/conv_bitstring/test_queries.sql.in +63 -0
  49. data/test/conv_geometry/b.rb +45 -0
  50. data/test/conv_geometry/runtest +26 -0
  51. data/test/conv_geometry/test.expected.73 +265 -0
  52. data/test/conv_geometry/test.expected.74 +265 -0
  53. data/test/conv_geometry/test.expected.80 +265 -0
  54. data/test/conv_geometry/test.expected.81 +265 -0
  55. data/test/conv_geometry/test.expected.82 +265 -0
  56. data/test/conv_geometry/test.expected.83 +265 -0
  57. data/test/conv_geometry/test.expected.84 +265 -0
  58. data/test/conv_geometry/test.out +265 -0
  59. data/test/conv_geometry/test_mklang.sql +8 -0
  60. data/test/conv_geometry/test_queries.sql +194 -0
  61. data/test/conv_geometry/test_queries.sql.in +194 -0
  62. data/test/conv_network/b.rb +45 -0
  63. data/test/conv_network/runtest +26 -0
  64. data/test/conv_network/test.expected.73 +213 -0
  65. data/test/conv_network/test.expected.74 +237 -0
  66. data/test/conv_network/test.expected.80 +237 -0
  67. data/test/conv_network/test.expected.81 +237 -0
  68. data/test/conv_network/test.expected.82 +237 -0
  69. data/test/conv_network/test.expected.83 +237 -0
  70. data/test/conv_network/test.expected.84 +237 -0
  71. data/test/conv_network/test.out +237 -0
  72. data/test/conv_network/test_mklang.sql +8 -0
  73. data/test/conv_network/test_queries.sql +60 -0
  74. data/test/conv_network/test_queries.sql.in +60 -0
  75. data/test/plp/b.rb +34 -0
  76. data/test/plp/runtest +29 -0
  77. data/test/plp/test.expected.73 +472 -0
  78. data/test/plp/test.expected.74 +472 -0
  79. data/test/plp/test.expected.75 +472 -0
  80. data/test/plp/test.expected.80 +472 -0
  81. data/test/plp/test.expected.81 +472 -0
  82. data/test/plp/test.expected.82 +472 -0
  83. data/test/plp/test.expected.83 +472 -0
  84. data/test/plp/test.expected.84 +472 -0
  85. data/test/plp/test.out +472 -0
  86. data/test/plp/test_mklang.sql +8 -0
  87. data/test/plp/test_queries.sql +273 -0
  88. data/test/plp/test_setup.sql +931 -0
  89. data/test/plp/test_setup.sql.in +931 -0
  90. data/test/plt/b.rb +34 -0
  91. data/test/plt/runtest +29 -0
  92. data/test/plt/test.expected.73 +178 -0
  93. data/test/plt/test.expected.74 +178 -0
  94. data/test/plt/test.expected.75 +178 -0
  95. data/test/plt/test.expected.80 +178 -0
  96. data/test/plt/test.expected.81 +178 -0
  97. data/test/plt/test.expected.82 +178 -0
  98. data/test/plt/test.expected.83 +164 -0
  99. data/test/plt/test.expected.84 +168 -0
  100. data/test/plt/test.out +168 -0
  101. data/test/plt/test_mklang.sql +8 -0
  102. data/test/plt/test_queries.sql +72 -0
  103. data/test/plt/test_setup.sql +252 -0
  104. data/test/plt/test_setup.sql.in +252 -0
  105. data/test/range/b.rb +45 -0
  106. data/test/range/runtest +26 -0
  107. data/test/range/test.expected.73 +396 -0
  108. data/test/range/test.expected.73.in +396 -0
  109. data/test/range/test.expected.74 +396 -0
  110. data/test/range/test.expected.74.in +396 -0
  111. data/test/range/test.expected.75 +396 -0
  112. data/test/range/test.expected.75.in +396 -0
  113. data/test/range/test.expected.80 +396 -0
  114. data/test/range/test.expected.81 +397 -0
  115. data/test/range/test.expected.82 +397 -0
  116. data/test/range/test.expected.83 +397 -0
  117. data/test/range/test.expected.84 +399 -0
  118. data/test/range/test.out +399 -0
  119. data/test/range/test_mklang.sql +8 -0
  120. data/test/range/test_queries.sql +249 -0
  121. data/test/range/test_queries.sql.in +249 -0
  122. metadata +207 -0
@@ -0,0 +1,75 @@
1
+ drop table bit_op cascade;
2
+
3
+ create table bit_op (
4
+ b0 bit(8), b1 bit(8), band bit(8), bor bit(8),
5
+ bxor bit(8), bnot0 bit(8), bnot1 bit(8)
6
+ );
7
+
8
+ create function bt(integer, integer) returns bit_op as '
9
+ b0 = BitString.new(args[0], 8)
10
+ b1 = BitString.new(args[1], 8)
11
+ [b0, b1, b0 & b1, b0 | b1, b0 ^ b1, ~b0, ~b1]
12
+ ' language 'plruby';
13
+
14
+ select * from bt(12, 24);
15
+ select * from bt(12, 32);
16
+ select * from bt(15, 278);
17
+
18
+
19
+ drop function be(integer);
20
+
21
+ create function be(integer) returns setof integer as '
22
+ BitString.new(args[0], 8).each {|i| yield i}
23
+ ' language 'plruby';
24
+
25
+ select * from be(12);
26
+ select * from be(257);
27
+
28
+ drop function bx(integer, integer);
29
+
30
+ create function bx(integer, integer) returns bit varying as '
31
+ BitString.new(*args)
32
+ ' language 'plruby';
33
+
34
+ select bx(12, 6);
35
+ select bx(12, 8);
36
+
37
+ drop table bit_sht cascade;
38
+
39
+ create table bit_sht (
40
+ b0 bit(8), shft int, bl bit(8), br bit(8), bs text, bi integer,
41
+ sz integer, osz integer
42
+ );
43
+
44
+ create function bs(integer, integer) returns bit_sht as '
45
+ b0 = BitString.new(args[0], 8)
46
+ [b0, args[1], b0 << args[1], b0 >> args[1], b0.to_s, b0.to_i,
47
+ b0.size, b0.octet_size]
48
+ ' language 'plruby';
49
+
50
+ select * from bs(12, 2);
51
+ select * from bs(277, -3);
52
+
53
+ drop function ext(text, integer);
54
+
55
+ create function ext(text, integer) returns integer as '
56
+ b0 = BitString.new(args[0])
57
+ b0[args[1]]
58
+ ' language 'plruby';
59
+
60
+ select ext('011110', 0);
61
+ select ext('011110', -1);
62
+ select ext('011110', 1);
63
+ select ext('011110', 4);
64
+
65
+ drop function ext2(text, integer, integer);
66
+
67
+ create function ext2(text, integer, integer) returns bit varying(8) as '
68
+ b0 = BitString.new(args[0])
69
+ b0[args[1], args[2]]
70
+ ' language 'plruby';
71
+
72
+ select ext2('0111101', 0, 2);
73
+ select ext2('0111101', -1, 3);
74
+ select ext2('0111101', 1, 2);
75
+ select ext2('0111101', 4, 1);
@@ -0,0 +1,15 @@
1
+ {
2
+ VALUE tmp;
3
+
4
+ #if RUBY_CAN_USE_AUTOLOAD
5
+ rb_funcall(rb_mKernel, rb_intern("autoload"), 2, rb_str_new2("BitString"),
6
+ rb_str_new2("plruby/plruby_bitstring"));
7
+ tmp = INT2NUM(rb_intern("BitString"));
8
+ rb_hash_aset(plruby_conversions, INT2NUM(BITOID), tmp);
9
+ rb_hash_aset(plruby_conversions, INT2NUM(VARBITOID), tmp);
10
+ #else
11
+ tmp = plruby_define_void_class("BitString", "plruby/plruby_bitstring");
12
+ rb_hash_aset(plruby_classes, INT2NUM(BITOID), tmp);
13
+ rb_hash_aset(plruby_classes, INT2NUM(VARBITOID), tmp);
14
+ #endif
15
+ }
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ if CONFIG["LIBRUBYARG"] == "$(LIBRUBYARG_SHARED)" &&
4
+ !enable_config("plruby-shared")
5
+ $LIBRUBYARG = ""
6
+ end
7
+ have_library('ruby18', 'ruby_init')
8
+ create_makefile('plruby/plruby_bitstring')
@@ -0,0 +1,579 @@
1
+ #include "convcommon.h"
2
+ #include "utils/varbit.h"
3
+
4
+ static void pl_bit_mark(VarBit *p) {}
5
+
6
+ static VALUE
7
+ pl_bit_s_alloc(VALUE obj)
8
+ {
9
+ VarBit *inst;
10
+
11
+ inst = (VarBit *)ALLOC_N(char, VARBITTOTALLEN(0));
12
+ #ifdef SET_VARSIZE
13
+ SET_VARSIZE(inst, VARBITTOTALLEN(0));
14
+ #else
15
+ VARATT_SIZEP(inst) = VARBITTOTALLEN(0);
16
+ #endif
17
+ VARBITLEN(inst) = 0;
18
+ return Data_Wrap_Struct(obj, pl_bit_mark, free, inst);
19
+ }
20
+
21
+ static VALUE
22
+ pl_bit_init_copy(VALUE copy, VALUE orig)
23
+ {
24
+ VarBit *t0, *t1;
25
+ int s0, s1;
26
+
27
+ if (copy == orig) return copy;
28
+ if (TYPE(orig) != T_DATA ||
29
+ RDATA(orig)->dmark != (RUBY_DATA_FUNC)pl_bit_mark) {
30
+ rb_raise(rb_eTypeError, "wrong argument type to clone");
31
+ }
32
+ Data_Get_Struct(orig, VarBit, t0);
33
+ Data_Get_Struct(copy, VarBit, t1);
34
+ s0 = VARSIZE(t0);
35
+ s1 = VARSIZE(t1);
36
+ if (s0 != s1) {
37
+ free(t1);
38
+ DATA_PTR(copy) = 0;
39
+ t1 = (VarBit *)ALLOC_N(char, s0);
40
+ DATA_PTR(copy) = t1;
41
+ }
42
+ memcpy(t1, t0, s0);
43
+ return copy;
44
+ }
45
+
46
+ static VALUE
47
+ pl_bit_s_datum(VALUE obj, VALUE a)
48
+ {
49
+ VarBit *ip0, *ip1;
50
+ Oid typoid;
51
+ VALUE res;
52
+
53
+ ip0 = (VarBit *)plruby_datum_get(a, &typoid);
54
+ if (typoid != BITOID && typoid != VARBITOID) {
55
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
56
+ }
57
+ ip1 = (VarBit *)ALLOC_N(char, VARSIZE(ip0));
58
+ memcpy(ip1, ip0, VARSIZE(ip0));
59
+ res = Data_Wrap_Struct(obj, pl_bit_mark, free, ip1);
60
+ OBJ_TAINT(res);
61
+ return res;
62
+ }
63
+
64
+ static VALUE
65
+ pl_bit_to_datum(VALUE obj, VALUE a)
66
+ {
67
+ VarBit *ip0, *ip1;
68
+ int length;
69
+ Oid typoid;
70
+
71
+ typoid = plruby_datum_oid(a, &length);
72
+ switch (typoid) {
73
+ case BITOID:
74
+ case VARBITOID:
75
+ Data_Get_Struct(obj, VarBit, ip0);
76
+ ip1 = (VarBit *)PLRUBY_DFC3(bit, ip0, Int32GetDatum(length), true);
77
+ break;
78
+ default:
79
+ /* a faire */
80
+ return Qnil;
81
+ }
82
+ return plruby_datum_set(a, (Datum)ip1);
83
+ }
84
+
85
+ PL_MLOADVAR(pl_bit_mload, varbit_recv, VarBit, VARSIZE);
86
+ PL_MDUMP(pl_bit_mdump, varbit_send);
87
+
88
+ static VALUE
89
+ pl_bit_init(int argc, VALUE *argv, VALUE obj)
90
+ {
91
+ VarBit *inst;
92
+ VALUE a, b;
93
+ void *v = 0;
94
+ int length = -1;
95
+ int taint = 0;
96
+
97
+ if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
98
+ length = NUM2INT(b);
99
+ }
100
+ taint = OBJ_TAINTED(a);
101
+ if (rb_respond_to(a, rb_intern("to_int"))) {
102
+ a = rb_funcall2(a, rb_intern("to_int"), 0, 0);
103
+ #if PG_PL_VERSION >= 75
104
+ v = (void *)PLRUBY_DFC2(bitfromint4, Int32GetDatum(NUM2LONG(a)),
105
+ Int32GetDatum(length));
106
+ #else
107
+ v = (void *)PLRUBY_DFC1(bitfromint4, Int32GetDatum(NUM2LONG(a)));
108
+ if (length > 0) {
109
+ void *v1;
110
+
111
+ int ll = DatumGetInt32(PLRUBY_DFC1(bitlength, v));
112
+ if (length != ll) {
113
+ if (length < ll) {
114
+ v1 = (void *)PLRUBY_DFC2(bitshiftleft, v,
115
+ Int32GetDatum(ll - length));
116
+ pfree(v);
117
+ }
118
+ else {
119
+ v1 = v;
120
+ }
121
+ v = (void *)PLRUBY_DFC3(bit, v1, Int32GetDatum(length), true);
122
+ pfree(v1);
123
+ }
124
+ }
125
+ #endif
126
+ }
127
+ if (!v) {
128
+ a = plruby_to_s(a);
129
+ v = (void *)PLRUBY_DFC3(bit_in, RSTRING_PTR(a), ObjectIdGetDatum(0),
130
+ Int32GetDatum(length));
131
+ }
132
+ Data_Get_Struct(obj, VarBit, inst);
133
+ free(inst);
134
+ inst = (VarBit *)ALLOC_N(char, VARSIZE(v));
135
+ CPY_FREE(inst, v, VARSIZE(v));
136
+ RDATA(obj)->data = inst;
137
+ if (taint) OBJ_TAINT(obj);
138
+ return obj;
139
+ }
140
+
141
+ static VALUE
142
+ pl_bit_cmp(VALUE a, VALUE b)
143
+ {
144
+ VarBit *inst0, *inst1;
145
+ int result;
146
+
147
+ if (!rb_obj_is_kind_of(b, rb_obj_class(a))) {
148
+ return Qnil;
149
+ }
150
+ Data_Get_Struct(a, VarBit, inst0);
151
+ Data_Get_Struct(b, VarBit, inst1);
152
+ result = DatumGetInt32(PLRUBY_DFC2(bitcmp, inst0, inst1));
153
+ return INT2FIX(result);
154
+ }
155
+
156
+ static VALUE
157
+ pl_bit_to_s(VALUE obj)
158
+ {
159
+ VarBit *src;
160
+ char *str;
161
+ VALUE res;
162
+
163
+ Data_Get_Struct(obj, VarBit, src);
164
+ str = (char *)PLRUBY_DFC1(bit_out, src);
165
+ if (OBJ_TAINTED(obj)) {
166
+ res = rb_tainted_str_new2(str);
167
+ }
168
+ else {
169
+ res = rb_str_new2(str);
170
+ }
171
+ pfree(str);
172
+ return res;
173
+ }
174
+
175
+ #define BIT_OPERATOR(name_, function_) \
176
+ static VALUE \
177
+ name_(VALUE obj, VALUE a) \
178
+ { \
179
+ VarBit *v0, *v1, *vp, *vr; \
180
+ VALUE res; \
181
+ \
182
+ if (TYPE(a) != T_DATA || \
183
+ RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_bit_mark) { \
184
+ rb_raise(rb_eArgError, "invalid argument for %s", \
185
+ rb_id2name(rb_frame_last_func())); \
186
+ } \
187
+ Data_Get_Struct(obj, VarBit, v0); \
188
+ Data_Get_Struct(a, VarBit, v1); \
189
+ vp = (VarBit *)PLRUBY_DFC2(function_, v0, v1); \
190
+ vr = (VarBit *)ALLOC_N(char, VARSIZE(vp)); \
191
+ CPY_FREE(vr, vp, VARSIZE(vp)); \
192
+ res = Data_Wrap_Struct(rb_class_of(obj), pl_bit_mark, free, vr); \
193
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res); \
194
+ return res; \
195
+ }
196
+
197
+ BIT_OPERATOR(pl_bit_add, bitcat);
198
+ BIT_OPERATOR(pl_bit_and, bitand);
199
+ BIT_OPERATOR(pl_bit_or, bitor);
200
+ BIT_OPERATOR(pl_bit_xor, bitxor);
201
+
202
+ static VALUE
203
+ pl_bit_push(VALUE obj, VALUE a)
204
+ {
205
+ VarBit *v0, *v1, *vp;
206
+
207
+ if (TYPE(a) != T_DATA ||
208
+ RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_bit_mark) {
209
+ rb_raise(rb_eArgError, "invalid argument for %s",
210
+ rb_id2name(rb_frame_last_func()));
211
+ }
212
+ Data_Get_Struct(obj, VarBit, v0);
213
+ Data_Get_Struct(a, VarBit, v1);
214
+ vp = (VarBit *)PLRUBY_DFC2(bitcat, v0, v1);
215
+ free(v0);
216
+ v0 = (VarBit *)ALLOC_N(char, VARSIZE(vp));
217
+ CPY_FREE(v0, vp, VARSIZE(vp));
218
+ DATA_PTR(obj) = v0;
219
+ return obj;
220
+ }
221
+
222
+ static VALUE
223
+ pl_bit_not(VALUE obj)
224
+ {
225
+ VarBit *v0, *vp, *vr;
226
+ VALUE res;
227
+
228
+ Data_Get_Struct(obj, VarBit, v0);
229
+ vp = (VarBit *)PLRUBY_DFC1(bitnot, v0);
230
+ vr = (VarBit *)ALLOC_N(char, VARSIZE(vp));
231
+ CPY_FREE(vr, vp, VARSIZE(vp));
232
+ res = Data_Wrap_Struct(rb_class_of(obj), pl_bit_mark, free, vr);
233
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
234
+ return res;
235
+ }
236
+
237
+ #define SHIFT_OPERATOR(name_, function_) \
238
+ static VALUE \
239
+ name_(VALUE obj, VALUE a) \
240
+ { \
241
+ VarBit *v0, *vp, *vr; \
242
+ VALUE res; \
243
+ \
244
+ Data_Get_Struct(obj, VarBit, v0); \
245
+ a = rb_Integer(a); \
246
+ vp = (VarBit *)PLRUBY_DFC2(function_, v0, Int32GetDatum(NUM2INT(a)));\
247
+ vr = (VarBit *)ALLOC_N(char, VARSIZE(vp)); \
248
+ CPY_FREE(vr, vp, VARSIZE(vp)); \
249
+ res = Data_Wrap_Struct(rb_class_of(obj), pl_bit_mark, free, vr); \
250
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res); \
251
+ return res; \
252
+ }
253
+
254
+ SHIFT_OPERATOR(pl_bit_left_shift, bitshiftleft);
255
+ SHIFT_OPERATOR(pl_bit_right_shift, bitshiftright);
256
+
257
+ static VALUE
258
+ pl_bit_length(VALUE obj)
259
+ {
260
+ VarBit *v;
261
+ int l;
262
+
263
+ Data_Get_Struct(obj, VarBit, v);
264
+ l = DatumGetInt32(PLRUBY_DFC1(bitlength, v));
265
+ return INT2NUM(l);
266
+ }
267
+
268
+ static VALUE
269
+ pl_bit_octet_length(VALUE obj)
270
+ {
271
+ VarBit *v;
272
+ int l;
273
+
274
+ Data_Get_Struct(obj, VarBit, v);
275
+ l = DatumGetInt32(PLRUBY_DFC1(bitoctetlength, v));
276
+ return INT2NUM(l);
277
+ }
278
+
279
+ static VALUE
280
+ pl_bit_to_i(VALUE obj)
281
+ {
282
+ VarBit *v;
283
+ int l;
284
+
285
+ Data_Get_Struct(obj, VarBit, v);
286
+ l = DatumGetInt32(PLRUBY_DFC1(bittoint4, v));
287
+ return INT2NUM(l);
288
+ }
289
+
290
+ /* This is varbit_out() from utils/adt/varbit.c */
291
+
292
+ #ifndef IS_HIGHBIT_SET
293
+ #define IS_HIGHBIT_SET(x) ((x) & BITHIGH)
294
+ #endif
295
+
296
+ static VALUE
297
+ pl_bit_each(VALUE obj)
298
+ {
299
+ VarBit *s;
300
+ VALUE i1, i0;
301
+ bits8 *sp, x;
302
+ int i, k, len;
303
+
304
+ i1 = INT2FIX(1);
305
+ i0 = INT2FIX(0);
306
+ Data_Get_Struct(obj, VarBit, s);
307
+ len = VARBITLEN(s);
308
+ sp = VARBITS(s);
309
+ for (i = 0; i < len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++) {
310
+ x = *sp;
311
+ for (k = 0; k < BITS_PER_BYTE; k++) {
312
+ if (IS_HIGHBIT_SET(x)) {
313
+ rb_yield(i1);
314
+ }
315
+ else {
316
+ rb_yield(i0);
317
+ }
318
+ x <<= 1;
319
+ }
320
+ }
321
+ x = *sp;
322
+ for (k = i; k < len; k++){
323
+ if (IS_HIGHBIT_SET(x)) {
324
+ rb_yield(i1);
325
+ }
326
+ else {
327
+ rb_yield(i0);
328
+ }
329
+ x <<= 1;
330
+ }
331
+ return Qnil;
332
+ }
333
+
334
+ static VALUE
335
+ pl_bit_index(VALUE obj, VALUE a)
336
+ {
337
+ VarBit *v0, *v1;
338
+ int i;
339
+
340
+ if (TYPE(a) != T_DATA ||
341
+ RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_bit_mark) {
342
+ rb_raise(rb_eArgError, "invalid argument for %s",
343
+ rb_id2name(rb_frame_last_func()));
344
+ }
345
+ Data_Get_Struct(obj, VarBit, v0);
346
+ Data_Get_Struct(a, VarBit, v1);
347
+ i = DatumGetInt32(PLRUBY_DFC2(bitposition, v0, v1));
348
+ i -= 1;
349
+ if (i < 0) return Qnil;
350
+ return INT2NUM(i);
351
+ }
352
+
353
+ static VALUE
354
+ pl_bit_include(VALUE obj, VALUE a)
355
+ {
356
+ if (NIL_P(pl_bit_index(obj, a))) {
357
+ return Qfalse;
358
+ }
359
+ return Qtrue;
360
+ }
361
+
362
+ extern long rb_reg_search();
363
+
364
+ static VALUE
365
+ pl_bit_subpat(VALUE obj, VALUE a, int nth)
366
+ {
367
+ VALUE res;
368
+
369
+ obj = pl_bit_to_s(obj);
370
+ if (rb_reg_search(a, obj, 0, 0) >= 0) {
371
+ res = rb_reg_nth_match(nth, rb_backref_get());
372
+ return rb_funcall(rb_obj_class(obj), rb_intern("new"), 1, res);
373
+ }
374
+ return Qnil;
375
+ }
376
+
377
+ static VALUE
378
+ pl_bit_substr(VALUE obj, long beg, long len)
379
+ {
380
+ VarBit *v, *v0, *v1;
381
+ long ll;
382
+ VALUE res;
383
+
384
+ Data_Get_Struct(obj, VarBit, v);
385
+ ll = DatumGetInt32(PLRUBY_DFC1(bitlength, v));
386
+ if (len < 0) return Qnil;
387
+ if (beg > ll) return Qnil;
388
+ if (beg < 0) {
389
+ beg += ll;
390
+ if (beg < 0) return Qnil;
391
+ }
392
+ if (beg + len > ll) {
393
+ len = ll - beg;
394
+ }
395
+ if (len < 0) {
396
+ len = 0;
397
+ }
398
+ if (len == 0) {
399
+ res = rb_funcall2(rb_obj_class(obj), rb_intern("allocate"), 0, 0);
400
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
401
+ return res;
402
+ }
403
+ v0 = (VarBit *)PLRUBY_DFC3(bitsubstr, v, Int32GetDatum(beg + 1),
404
+ Int32GetDatum(len));
405
+ v1 = (VarBit *)ALLOC_N(char, VARSIZE(v0));
406
+ CPY_FREE(v1, v0, VARSIZE(v0));
407
+ res = Data_Wrap_Struct(rb_obj_class(obj), pl_bit_mark, free, v1);
408
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
409
+ return res;
410
+ }
411
+
412
+ static VALUE
413
+ pl_bit_aref(VALUE obj, VALUE a)
414
+ {
415
+ VarBit *v, *v0, *v1;
416
+ long l, idx;
417
+ bits8 *sp, x;
418
+ VALUE res;
419
+
420
+ Data_Get_Struct(obj, VarBit, v);
421
+ l = DatumGetInt32(PLRUBY_DFC1(bitlength, v));
422
+
423
+ switch (TYPE(a)) {
424
+ case T_FIXNUM:
425
+ idx = FIX2LONG(a);
426
+
427
+ num_index:
428
+ if (idx < 0) {
429
+ idx = l + idx;
430
+ }
431
+ if (idx < 0 || l <= idx) {
432
+ return Qnil;
433
+ }
434
+ sp = VARBITS(v);
435
+ sp += (idx / BITS_PER_BYTE);
436
+ x = *sp <<= (idx % BITS_PER_BYTE);
437
+ if (IS_HIGHBIT_SET(x)) return INT2FIX(1);
438
+ return INT2FIX(0);
439
+
440
+ case T_REGEXP:
441
+ return pl_bit_subpat(obj, a, 0);
442
+
443
+ case T_STRING:
444
+ a = plruby_to_s(a);
445
+ v0 = (void *)PLRUBY_DFC3(bit_in, RSTRING_PTR(a),
446
+ ObjectIdGetDatum(0), Int32GetDatum(-1));
447
+ if (DatumGetInt32(PLRUBY_DFC2(bitposition, v, v0)) > 0) {
448
+ v1 = (VarBit *)ALLOC_N(char, VARSIZE(v0));
449
+ CPY_FREE(v1, v0, VARSIZE(v0));
450
+ res = Data_Wrap_Struct(CLASS_OF(obj), pl_bit_mark, free, v1);
451
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
452
+ return res;
453
+ }
454
+ pfree(v0);
455
+ return Qnil;
456
+
457
+ case T_DATA:
458
+ if (RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_bit_mark) {
459
+ rb_raise(rb_eArgError, "expected a BitString object");
460
+ }
461
+ Data_Get_Struct(a, VarBit, v0);
462
+ if (DatumGetInt32(PLRUBY_DFC2(bitposition, v, v0)) > 0) {
463
+ return rb_funcall2(a, rb_intern("dup"), 0, 0);
464
+ }
465
+ return Qnil;
466
+
467
+ default:
468
+ {
469
+ long beg, len;
470
+
471
+ switch (rb_range_beg_len(a, &beg, &len, l, 0)) {
472
+ case Qfalse:
473
+ break;
474
+ case Qnil:
475
+ return Qnil;
476
+ default:
477
+ return pl_bit_substr(obj, beg, len);
478
+ }
479
+ }
480
+ idx = NUM2LONG(a);
481
+ goto num_index;
482
+ }
483
+ return Qnil;
484
+ }
485
+
486
+ static VALUE
487
+ pl_bit_aref_m(int argc, VALUE *argv, VALUE obj)
488
+ {
489
+ if (argc == 2) {
490
+ if (TYPE(argv[0]) == T_REGEXP) {
491
+ return pl_bit_subpat(obj, argv[0], NUM2INT(argv[1]));
492
+ }
493
+ return pl_bit_substr(obj, NUM2LONG(argv[0]), NUM2LONG(argv[1]));
494
+ }
495
+ if (argc != 1) {
496
+ rb_raise(rb_eArgError, "wrong number of arguments(%d for 1)", argc);
497
+ }
498
+ return pl_bit_aref(obj, argv[0]);
499
+ }
500
+
501
+ static VALUE
502
+ pl_bit_aset(int argc, VALUE *argv, VALUE obj)
503
+ {
504
+ VALUE res;
505
+ int i;
506
+ void *v;
507
+ VarBit *inst;
508
+
509
+ for (i = 0; i < argc; ++i) {
510
+ if (TYPE(argv[i]) == T_DATA &&
511
+ RDATA(argv[i])->dmark == (RUBY_DATA_FUNC)pl_bit_mark) {
512
+ argv[i] = pl_bit_to_s(argv[i]);
513
+ }
514
+ }
515
+ res = rb_funcall2(pl_bit_to_s(obj), rb_intern("[]="), argc, argv);
516
+ if (NIL_P(res)) return res;
517
+ res = plruby_to_s(res);
518
+ v = (void *)PLRUBY_DFC3(bit_in, RSTRING_PTR(res), ObjectIdGetDatum(0),
519
+ Int32GetDatum(-1));
520
+ Data_Get_Struct(obj, VarBit, inst);
521
+ free(inst);
522
+ inst = (VarBit *)ALLOC_N(char, VARSIZE(v));
523
+ CPY_FREE(inst, v, VARSIZE(v));
524
+ RDATA(obj)->data = inst;
525
+ return obj;
526
+ }
527
+
528
+ void Init_plruby_bitstring()
529
+ {
530
+ VALUE pl_cBit;
531
+
532
+ pl_cBit = rb_define_class("BitString", rb_cObject);
533
+ rb_include_module(pl_cBit, rb_mComparable);
534
+ rb_include_module(pl_cBit, rb_mEnumerable);
535
+ rb_undef_method(CLASS_OF(pl_cBit), "method_missing");
536
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
537
+ rb_define_alloc_func(pl_cBit, pl_bit_s_alloc);
538
+ #else
539
+ rb_define_singleton_method(pl_cBit, "allocate", pl_bit_s_alloc, 0);
540
+ #endif
541
+ rb_define_singleton_method(pl_cBit, "new", plruby_s_new, -1);
542
+ rb_define_singleton_method(pl_cBit, "from_string", plruby_s_new, -1);
543
+ rb_define_singleton_method(pl_cBit, "from_datum", pl_bit_s_datum, 1);
544
+ rb_define_method(pl_cBit, "to_datum", pl_bit_to_datum, 1);
545
+ rb_define_method(pl_cBit, "initialize", pl_bit_init, -1);
546
+ #ifndef HAVE_RB_INITIALIZE_COPY
547
+ rb_define_method(pl_cBit, "clone", plruby_clone, 0);
548
+ #endif
549
+ rb_define_method(pl_cBit, "initialize_copy", pl_bit_init_copy, 1);
550
+ #if PG_PL_VERSION >= 74
551
+ rb_define_method(pl_cBit, "marshal_load", pl_bit_mload, 1);
552
+ rb_define_method(pl_cBit, "marshal_dump", pl_bit_mdump, -1);
553
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
554
+ rb_define_singleton_method(pl_cBit, "_load", plruby_s_load, 1);
555
+ rb_define_alias(pl_cBit, "_dump", "marshal_dump");
556
+ #endif
557
+ #endif
558
+ rb_define_method(pl_cBit, "<=>", pl_bit_cmp, 1);
559
+ rb_define_method(pl_cBit, "each", pl_bit_each, 0);
560
+ rb_define_method(pl_cBit, "+", pl_bit_add, 1);
561
+ rb_define_method(pl_cBit, "concat", pl_bit_push, 1);
562
+ rb_define_method(pl_cBit, "push", pl_bit_push, 1);
563
+ rb_define_method(pl_cBit, "index", pl_bit_index, 1);
564
+ rb_define_method(pl_cBit, "include?", pl_bit_include, 1);
565
+ rb_define_method(pl_cBit, "&", pl_bit_and, 1);
566
+ rb_define_method(pl_cBit, "|", pl_bit_or, 1);
567
+ rb_define_method(pl_cBit, "^", pl_bit_xor, 1);
568
+ rb_define_method(pl_cBit, "~", pl_bit_not, 0);
569
+ rb_define_method(pl_cBit, "<<", pl_bit_left_shift, 1);
570
+ rb_define_method(pl_cBit, ">>", pl_bit_right_shift, 1);
571
+ rb_define_method(pl_cBit, "[]", pl_bit_aref_m, -1);
572
+ rb_define_method(pl_cBit, "[]=", pl_bit_aset, -1);
573
+ rb_define_method(pl_cBit, "length", pl_bit_length, 0);
574
+ rb_define_method(pl_cBit, "size", pl_bit_length, 0);
575
+ rb_define_method(pl_cBit, "octet_length", pl_bit_octet_length, 0);
576
+ rb_define_method(pl_cBit, "octet_size", pl_bit_octet_length, 0);
577
+ rb_define_method(pl_cBit, "to_s", pl_bit_to_s, 0);
578
+ rb_define_method(pl_cBit, "to_i", pl_bit_to_i, 0);
579
+ }