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,21 @@
1
+ {
2
+ VALUE tmp;
3
+
4
+ #if RUBY_CAN_USE_AUTOLOAD
5
+ rb_funcall(rb_mKernel, rb_intern("autoload"), 2, rb_str_new2("NetAddr"),
6
+ rb_str_new2("plruby/plruby_network"));
7
+ rb_funcall(rb_mKernel, rb_intern("autoload"), 2, rb_str_new2("MacAddr"),
8
+ rb_str_new2("plruby/plruby_network"));
9
+ tmp = INT2NUM(rb_intern("NetAddr"));
10
+ rb_hash_aset(plruby_conversions, INT2NUM(INETOID), tmp);
11
+ rb_hash_aset(plruby_conversions, INT2NUM(CIDROID), tmp);
12
+ tmp = INT2NUM(rb_intern("MacAddr"));
13
+ rb_hash_aset(plruby_conversions, INT2NUM(MACADDROID), tmp);
14
+ #else
15
+ tmp = plruby_define_void_class("NetAddr", "plruby/plruby_network");
16
+ rb_hash_aset(plruby_classes, INT2NUM(INETOID), tmp);
17
+ rb_hash_aset(plruby_classes, INT2NUM(CIDROID), tmp);
18
+ tmp = plruby_define_void_class("MacAddr", "plruby/plruby_network");
19
+ rb_hash_aset(plruby_classes, INT2NUM(MACADDROID), tmp);
20
+ #endif
21
+ }
@@ -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_network')
@@ -0,0 +1,63 @@
1
+ drop function inet_val(inet);
2
+ drop table pl_inet;
3
+
4
+ create table pl_inet (
5
+ host text, abbrev text, masklen int,
6
+ network inet, netmask inet, first inet, last inet
7
+ );
8
+
9
+
10
+ create or replace function inet_val(inet) returns pl_inet as '
11
+ a = args[0]
12
+ [a.host, a.abbrev, a.masklen, a.network, a.netmask,
13
+ a.first, a.last]
14
+ ' language 'plruby';
15
+
16
+
17
+ select * from inet_val('192.168.1'::cidr);
18
+ select * from inet_val('192.168.1.226/24'::inet);
19
+ select * from inet_val('192.168.1.0/24'::cidr);
20
+ select * from inet_val('192.168.1.226'::inet);
21
+ select * from inet_val('192.168.1'::cidr);
22
+ select * from inet_val('192.168.1.0/24'::inet);
23
+ select * from inet_val('192.168.1'::cidr);
24
+ select * from inet_val('192.168.1.0/25'::inet);
25
+ select * from inet_val('192.168.1'::cidr);
26
+ select * from inet_val('192.168.1.255/24'::inet);
27
+ select * from inet_val('192.168.1'::cidr);
28
+ select * from inet_val('192.168.1.255/25'::inet);
29
+ select * from inet_val('10'::cidr);
30
+ select * from inet_val('10.1.2.3/8'::inet);
31
+ select * from inet_val('10.0.0.0'::cidr);
32
+ select * from inet_val('10.1.2.3/8'::inet);
33
+ select * from inet_val('10.1.2.3'::cidr);
34
+ select * from inet_val('10.1.2.3/32'::inet);
35
+ select * from inet_val('10.1.2'::cidr);
36
+ select * from inet_val('10.1.2.3/24'::inet);
37
+ select * from inet_val('10.1'::cidr);
38
+ select * from inet_val('10.1.2.3/16'::inet);
39
+ select * from inet_val('10'::cidr);
40
+ select * from inet_val('10.1.2.3/8'::inet);
41
+ select * from inet_val('10'::cidr);
42
+ select * from inet_val('11.1.2.3/8'::inet);
43
+ select * from inet_val('10'::cidr);
44
+ select * from inet_val('9.1.2.3/8'::inet);
45
+ select * from inet_val('10:23::f1'::cidr);
46
+ select * from inet_val('10:23::f1/64'::inet);
47
+ select * from inet_val('10:23::8000/113'::cidr);
48
+ select * from inet_val('10:23::ffff'::inet);
49
+ select * from inet_val('::ffff:1.2.3.4'::cidr);
50
+ select * from inet_val('::4.3.2.1/24'::inet);
51
+
52
+ create or replace function mac_cmp(macaddr, macaddr) returns int as '
53
+ args[0] <=> args[1]
54
+ ' language 'plruby';
55
+
56
+ select mac_cmp('00:07:E9:85:3E:C5'::macaddr, '00:E0:29:3E:E7:25'::macaddr);
57
+
58
+ create or replace function mac_trunc(macaddr) returns macaddr as '
59
+ args[0].truncate
60
+ ' language 'plruby';
61
+
62
+ select mac_trunc('00:07:E9:85:3E:C5'::macaddr);
63
+ select mac_trunc('00:E0:29:3E:E7:25'::macaddr);
@@ -0,0 +1,537 @@
1
+ #include "convcommon.h"
2
+ #include <utils/inet.h>
3
+
4
+ static void pl_inet_mark(inet *p) {}
5
+
6
+ static VALUE
7
+ pl_inet_s_alloc(VALUE obj)
8
+ {
9
+ void *v;
10
+ inet *inst;
11
+
12
+ v = (void *)PLRUBY_DFC1(inet_in, "0.0.0.0");
13
+ inst = (inet *)ALLOC_N(char, VARSIZE(v));
14
+ CPY_FREE(inst, v, VARSIZE(v));
15
+ return Data_Wrap_Struct(obj, pl_inet_mark, free, inst);
16
+ }
17
+
18
+ static VALUE
19
+ pl_inet_init_copy(VALUE copy, VALUE orig)
20
+ {
21
+ inet *t0, *t1;
22
+ int s0, s1;
23
+
24
+ if (copy == orig) return copy;
25
+ if (TYPE(orig) != T_DATA ||
26
+ RDATA(orig)->dmark != (RUBY_DATA_FUNC) pl_inet_mark) {
27
+ rb_raise(rb_eTypeError, "wrong argument type to clone");
28
+ }
29
+ Data_Get_Struct(orig, inet, t0);
30
+ Data_Get_Struct(copy, inet, t1);
31
+ s0 = VARSIZE(t0);
32
+ s1 = VARSIZE(t1);
33
+ if (s0 != s1) {
34
+ free(t1);
35
+ DATA_PTR(copy) = 0;
36
+ t1 = (inet *)ALLOC_N(char, s0);
37
+ DATA_PTR(copy) = t1;
38
+ }
39
+ memcpy(t1, t0, s0);
40
+ return copy;
41
+ }
42
+
43
+ static VALUE
44
+ pl_inet_s_datum(VALUE obj, VALUE a)
45
+ {
46
+ inet *ip0, *ip1;
47
+ Oid typoid;
48
+ VALUE res;
49
+
50
+ ip0 = (inet *)plruby_datum_get(a, &typoid);
51
+ if (typoid != INETOID && typoid != CIDROID) {
52
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
53
+ }
54
+ ip1 = (inet *)ALLOC_N(char, VARSIZE(ip0));
55
+ memcpy(ip1, ip0, VARSIZE(ip0));
56
+ res = Data_Wrap_Struct(obj, pl_inet_mark, free, ip1);
57
+ OBJ_TAINT(res);
58
+ return res;
59
+ }
60
+
61
+ static VALUE
62
+ pl_inet_to_datum(VALUE obj, VALUE a)
63
+ {
64
+ inet *ip0, *ip1;
65
+ Oid typoid;
66
+
67
+ typoid = plruby_datum_oid(a, 0);
68
+ if (typoid != INETOID && typoid != CIDROID) {
69
+ return Qnil;
70
+ }
71
+ Data_Get_Struct(obj, inet, ip0);
72
+ ip1 = (inet *)palloc(VARSIZE(ip0));
73
+ memcpy(ip1, ip0, VARSIZE(ip0));
74
+ return plruby_datum_set(a, (Datum)ip1);
75
+ }
76
+
77
+ PL_MLOADVAR(pl_inet_mload, inet_recv, inet, VARSIZE);
78
+ PL_MDUMP(pl_inet_mdump, inet_send);
79
+
80
+ static VALUE
81
+ pl_inet_init(int argc, VALUE *argv, VALUE obj)
82
+ {
83
+ inet *inst;
84
+ void *v;
85
+ VALUE a, b;
86
+ int cidr = 0;
87
+
88
+ if (rb_scan_args(argc, argv, "11", &a, &b) == 2) {
89
+ cidr = RTEST(b);
90
+ }
91
+ a = plruby_to_s(a);
92
+ Data_Get_Struct(obj, inet, inst);
93
+ if (cidr) {
94
+ v = (void *)PLRUBY_DFC1(cidr_in, RSTRING_PTR(a));
95
+ }
96
+ else {
97
+ v = (void *)PLRUBY_DFC1(inet_in, RSTRING_PTR(a));
98
+ }
99
+ free(inst);
100
+ inst = (inet *)ALLOC_N(char, VARSIZE(v));
101
+ CPY_FREE(inst, v, VARSIZE(v));
102
+ RDATA(obj)->data = inst;
103
+ return obj;
104
+ }
105
+
106
+ static VALUE
107
+ pl_inet_cmp(VALUE a, VALUE b)
108
+ {
109
+ inet *inst0, *inst1;
110
+
111
+ if (!rb_obj_is_kind_of(b, rb_obj_class(a))) {
112
+ return Qnil;
113
+ }
114
+ Data_Get_Struct(a, inet, inst0);
115
+ Data_Get_Struct(b, inet, inst1);
116
+ if (PLRUBY_DFC2(network_eq, inst0, inst1)) return INT2NUM(0);
117
+ if (PLRUBY_DFC2(network_lt, inst0, inst1)) return INT2NUM(-1);
118
+ return INT2FIX(1);
119
+ }
120
+
121
+ #define NETWORK_BOOL(NAME_, FUNCTION_) \
122
+ static VALUE \
123
+ NAME_(VALUE obj, VALUE a) \
124
+ { \
125
+ inet *inst0, *inst1; \
126
+ \
127
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) { \
128
+ rb_raise(rb_eArgError, "expected a NetAddr object"); \
129
+ } \
130
+ Data_Get_Struct(obj, inet, inst0); \
131
+ Data_Get_Struct(a, inet, inst1); \
132
+ if (PLRUBY_DFC2(FUNCTION_, inst0, inst1)) return Qtrue; \
133
+ return Qfalse; \
134
+ }
135
+
136
+ NETWORK_BOOL(pl_inet_contained, network_sub);
137
+ NETWORK_BOOL(pl_inet_containedeq, network_subeq);
138
+ NETWORK_BOOL(pl_inet_contain, network_sup);
139
+ NETWORK_BOOL(pl_inet_containeq, network_supeq);
140
+
141
+ #define NETWORK_CALL(NAME_,FUNCTION_) \
142
+ static VALUE \
143
+ NAME_(VALUE obj) \
144
+ { \
145
+ inet *src; \
146
+ char *str; \
147
+ VALUE res; \
148
+ \
149
+ Data_Get_Struct(obj, inet, src); \
150
+ str = (char *)PLRUBY_DFC1(FUNCTION_, src); \
151
+ if (OBJ_TAINTED(obj)) { \
152
+ res = rb_tainted_str_new((char *)VARDATA(str), \
153
+ VARSIZE(str) - VARHDRSZ); \
154
+ } \
155
+ else { \
156
+ res = rb_str_new((char *)VARDATA(str), \
157
+ VARSIZE(str) - VARHDRSZ); \
158
+ } \
159
+ pfree(str); \
160
+ return res; \
161
+ }
162
+
163
+ NETWORK_CALL(pl_inet_host, network_host);
164
+
165
+ #if PG_PL_VERSION >= 82
166
+ NETWORK_CALL(pl_inet_abbrev, inet_abbrev);
167
+ #else
168
+ NETWORK_CALL(pl_inet_abbrev, network_abbrev);
169
+ #endif
170
+
171
+ static VALUE
172
+ pl_inet_to_s(VALUE obj)
173
+ {
174
+ inet *src;
175
+ char *str;
176
+ VALUE res;
177
+
178
+ Data_Get_Struct(obj, inet, src);
179
+ str = (char *)PLRUBY_DFC1(inet_out, src);
180
+ if (OBJ_TAINTED(obj)) {
181
+ res = rb_tainted_str_new2(str);
182
+ }
183
+ else {
184
+ res = rb_str_new2(str);
185
+ }
186
+ pfree(str);
187
+ return res;
188
+ }
189
+
190
+ static VALUE
191
+ pl_inet_masklen(VALUE obj)
192
+ {
193
+ inet *src;
194
+ Data_Get_Struct(obj, inet, src);
195
+ return INT2NUM(DatumGetInt32(PLRUBY_DFC1(network_masklen, src)));
196
+ }
197
+
198
+ static VALUE
199
+ pl_inet_setmasklen(VALUE obj, VALUE a)
200
+ {
201
+ inet *s0, *s1, *s2;
202
+ VALUE res;
203
+
204
+ Data_Get_Struct(obj, inet, s0);
205
+ s1 = (inet *)PLRUBY_DFC2(inet_set_masklen, s0, Int32GetDatum(NUM2INT(a)));
206
+ s2 = (inet *)ALLOC_N(char, VARSIZE(s1));
207
+ CPY_FREE(s2, s1, VARSIZE(s1));
208
+ res = Data_Wrap_Struct(rb_obj_class(obj), pl_inet_mark, free, s2);
209
+ if (OBJ_TAINTED(res) || OBJ_TAINTED(a)) OBJ_TAINT(res);
210
+ return res;
211
+ }
212
+
213
+ #if PG_PL_VERSION >= 74
214
+
215
+ static VALUE
216
+ pl_inet_family(VALUE obj)
217
+ {
218
+ inet *s;
219
+ VALUE str;
220
+
221
+ Data_Get_Struct(obj, inet, s);
222
+ switch (DatumGetInt32(PLRUBY_DFC1(network_family, s))) {
223
+ case 4:
224
+ str = rb_str_new2("AF_INET");
225
+ break;
226
+ case 6:
227
+ str = rb_str_new2("AF_INET6");
228
+ break;
229
+ default:
230
+ str = Qnil;
231
+ break;
232
+ }
233
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
234
+ return str;
235
+ }
236
+
237
+ #endif
238
+
239
+ #define NETWORK_INET(NAME_, FUNCTION_) \
240
+ static VALUE \
241
+ NAME_(VALUE obj) \
242
+ { \
243
+ inet *ip0, *ip1, *ip2; \
244
+ VALUE res; \
245
+ \
246
+ Data_Get_Struct(obj, inet, ip0); \
247
+ res = Data_Make_Struct(rb_obj_class(obj), inet, \
248
+ pl_inet_mark, free, ip1); \
249
+ ip2 = (inet *)PLRUBY_DFC1(FUNCTION_, ip0); \
250
+ ip1 = (inet *)ALLOC_N(char, VARSIZE(ip2)); \
251
+ CPY_FREE(ip1, ip2, VARSIZE(ip2)); \
252
+ res = Data_Wrap_Struct(rb_obj_class(obj), pl_inet_mark, free, ip1); \
253
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res); \
254
+ return res; \
255
+ }
256
+
257
+ NETWORK_INET(pl_inet_broadcast, network_broadcast);
258
+ NETWORK_INET(pl_inet_network, network_network);
259
+ NETWORK_INET(pl_inet_netmask, network_netmask);
260
+
261
+ #if PG_PL_VERSION >= 74
262
+
263
+ NETWORK_INET(pl_inet_hostmask, network_hostmask);
264
+
265
+ #endif
266
+
267
+ static VALUE
268
+ pl_inet_last(VALUE obj)
269
+ {
270
+ inet *ip0, *ip1, *ip2;
271
+ VALUE res;
272
+
273
+ Data_Get_Struct(obj, inet, ip0);
274
+ res = Data_Make_Struct(rb_obj_class(obj), inet,
275
+ pl_inet_mark, free, ip1);
276
+ ip2 = (inet *)network_scan_last((Datum)ip0);
277
+ ip1 = (inet *)ALLOC_N(char, VARSIZE(ip2));
278
+ CPY_FREE(ip1, ip2, VARSIZE(ip2));
279
+ res = Data_Wrap_Struct(rb_obj_class(obj), pl_inet_mark, free, ip1);
280
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
281
+ return res;
282
+ }
283
+
284
+ #if PG_PL_VERSION >= 75
285
+
286
+ static VALUE
287
+ pl_inet_s_caddr(VALUE obj)
288
+ {
289
+ inet *ip0, *ip1;
290
+ VALUE res;
291
+
292
+ ip0 = (inet *)PLRUBY_DFC0(inet_client_addr);
293
+ if (!ip0) {
294
+ return Qnil;
295
+ }
296
+ ip1 = (inet *)ALLOC_N(char, VARSIZE(ip0));
297
+ CPY_FREE(ip1, ip0, VARSIZE(ip0));
298
+ res = Data_Wrap_Struct(obj, pl_inet_mark, free, ip1);
299
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
300
+ return res;
301
+ }
302
+
303
+ static VALUE
304
+ pl_inet_s_cport(VALUE obj)
305
+ {
306
+ return INT2NUM(PLRUBY_DFC0(inet_client_port));
307
+ }
308
+
309
+ static VALUE
310
+ pl_inet_s_saddr(VALUE obj)
311
+ {
312
+ inet *ip0, *ip1;
313
+ VALUE res;
314
+
315
+ ip0 = (inet *)PLRUBY_DFC0(inet_server_addr);
316
+ if (!ip0) {
317
+ return Qnil;
318
+ }
319
+ ip1 = (inet *)ALLOC_N(char, VARSIZE(ip0));
320
+ CPY_FREE(ip1, ip0, VARSIZE(ip0));
321
+ res = Data_Wrap_Struct(obj, pl_inet_mark, free, ip1);
322
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
323
+ return res;
324
+ }
325
+
326
+ static VALUE
327
+ pl_inet_s_sport(VALUE obj)
328
+ {
329
+ return INT2NUM(PLRUBY_DFC0(inet_server_port));
330
+ }
331
+
332
+ #endif
333
+
334
+
335
+ static void pl_mac_mark(macaddr *mac) {}
336
+
337
+ static VALUE
338
+ pl_mac_s_alloc(VALUE obj)
339
+ {
340
+ macaddr *mac;
341
+ return Data_Make_Struct(obj, macaddr, pl_mac_mark, free, mac);
342
+ }
343
+
344
+ static VALUE
345
+ pl_mac_init_copy(VALUE copy, VALUE orig)
346
+ {
347
+ macaddr *t0, *t1;
348
+
349
+ if (copy == orig) return copy;
350
+ if (TYPE(orig) != T_DATA ||
351
+ RDATA(orig)->dmark != (RUBY_DATA_FUNC)pl_mac_mark) {
352
+ rb_raise(rb_eTypeError, "wrong argument type to clone");
353
+ }
354
+ Data_Get_Struct(orig, macaddr, t0);
355
+ Data_Get_Struct(copy, macaddr, t1);
356
+ MEMCPY(t1, t0, macaddr, 1);
357
+ return copy;
358
+ }
359
+
360
+ static VALUE
361
+ pl_mac_s_datum(VALUE obj, VALUE a)
362
+ {
363
+ macaddr *mac0, *mac1;
364
+ Oid typoid;
365
+ VALUE res;
366
+
367
+ mac0 = (macaddr *)plruby_datum_get(a, &typoid);
368
+ if (typoid != MACADDROID) {
369
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
370
+ }
371
+ mac1 = ALLOC_N(macaddr, 1);
372
+ memcpy(mac1, mac0, sizeof(macaddr));
373
+ res = Data_Wrap_Struct(obj, pl_mac_mark, free, mac1);
374
+ OBJ_TAINT(res);
375
+ return res;
376
+ }
377
+
378
+ static VALUE
379
+ pl_mac_to_datum(VALUE obj, VALUE a)
380
+ {
381
+ macaddr *mac0, *mac1;
382
+ Oid typoid;
383
+
384
+ typoid = plruby_datum_oid(a, 0);
385
+ if (typoid != MACADDROID) {
386
+ return Qnil;
387
+ }
388
+ Data_Get_Struct(obj, macaddr, mac0);
389
+ mac1 = (macaddr *)palloc(sizeof(macaddr));
390
+ memcpy(mac1, mac0, sizeof(macaddr));
391
+ return plruby_datum_set(a, (Datum)mac1);
392
+ }
393
+
394
+ PL_MLOAD(pl_mac_mload, macaddr_recv, macaddr);
395
+ PL_MDUMP(pl_mac_mdump, macaddr_send);
396
+
397
+ static VALUE
398
+ pl_mac_init(VALUE obj, VALUE a)
399
+ {
400
+ macaddr *m0, *m1;
401
+
402
+ a = plruby_to_s(a);
403
+ Data_Get_Struct(obj, struct macaddr, m0);
404
+ m1 = (macaddr *)PLRUBY_DFC1(macaddr_in, RSTRING_PTR(a));
405
+ CPY_FREE(m0, m1, sizeof(macaddr));
406
+ return obj;
407
+ }
408
+
409
+ static VALUE
410
+ pl_mac_cmp(VALUE obj, VALUE a)
411
+ {
412
+ macaddr *m0, *m1;
413
+ int res;
414
+
415
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) {
416
+ return Qnil;
417
+ }
418
+ Data_Get_Struct(obj, macaddr, m0);
419
+ Data_Get_Struct(a, macaddr, m1);
420
+ res = DatumGetInt32(PLRUBY_DFC2(macaddr_cmp, m0, m1));
421
+ return INT2NUM(res);
422
+ }
423
+
424
+ static VALUE
425
+ pl_mac_to_s(VALUE obj)
426
+ {
427
+ macaddr *m;
428
+ char *s;
429
+ VALUE res;
430
+
431
+ Data_Get_Struct(obj, macaddr, m);
432
+ s = (char *)PLRUBY_DFC1(macaddr_out, m);
433
+ res = rb_str_new2(s);
434
+ pfree(s);
435
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
436
+ return res;
437
+ }
438
+
439
+ static VALUE
440
+ pl_mac_truncate(VALUE obj)
441
+ {
442
+ macaddr *m0, *m1, *m2;
443
+ VALUE res;
444
+
445
+ Data_Get_Struct(obj, macaddr, m0);
446
+ m2 = (macaddr *)PLRUBY_DFC1(macaddr_trunc, m0);
447
+ res = Data_Make_Struct(rb_obj_class(obj), macaddr, pl_mac_mark, free, m1);
448
+ CPY_FREE(m1, m2, sizeof(macaddr));
449
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
450
+ return res;
451
+ }
452
+
453
+ void Init_plruby_network()
454
+ {
455
+ VALUE pl_cInet, pl_cMac;
456
+
457
+ pl_cInet = rb_define_class("NetAddr", rb_cObject);
458
+ rb_include_module(pl_cInet, rb_mComparable);
459
+ rb_undef_method(CLASS_OF(pl_cInet), "method_missing");
460
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
461
+ rb_define_alloc_func(pl_cInet, pl_inet_s_alloc);
462
+ #else
463
+ rb_define_singleton_method(pl_cInet, "allocate", pl_inet_s_alloc, 0);
464
+ #endif
465
+ rb_define_singleton_method(pl_cInet, "new", plruby_s_new, -1);
466
+ rb_define_singleton_method(pl_cInet, "from_string", plruby_s_new, -1);
467
+ rb_define_singleton_method(pl_cInet, "from_datum", pl_inet_s_datum, 1);
468
+ #if PG_PL_VERSION >= 75
469
+ rb_define_singleton_method(pl_cInet, "client_addr", pl_inet_s_caddr, 0);
470
+ rb_define_singleton_method(pl_cInet, "client_port", pl_inet_s_cport, 0);
471
+ rb_define_singleton_method(pl_cInet, "server_addr", pl_inet_s_saddr, 0);
472
+ rb_define_singleton_method(pl_cInet, "server_port", pl_inet_s_sport, 0);
473
+ #endif
474
+ rb_define_method(pl_cInet, "to_datum", pl_inet_to_datum, 1);
475
+ rb_define_method(pl_cInet, "initialize", pl_inet_init, -1);
476
+ #ifndef HAVE_RB_INITIALIZE_COPY
477
+ rb_define_method(pl_cInet, "clone", plruby_clone, 0);
478
+ #endif
479
+ rb_define_method(pl_cInet, "initialize_copy", pl_inet_init_copy, 1);
480
+ #if PG_PL_VERSION >= 74
481
+ rb_define_method(pl_cInet, "marshal_load", pl_inet_mload, 1);
482
+ rb_define_method(pl_cInet, "marshal_dump", pl_inet_mdump, -1);
483
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
484
+ rb_define_singleton_method(pl_cInet, "_load", plruby_s_load, 1);
485
+ rb_define_alias(pl_cInet, "_dump", "marshal_dump");
486
+ #endif
487
+ #endif
488
+ rb_define_method(pl_cInet, "<=>", pl_inet_cmp, 1);
489
+ rb_define_method(pl_cInet, "contained?", pl_inet_contained, 1);
490
+ rb_define_method(pl_cInet, "contained_or_equal?", pl_inet_containedeq, 1);
491
+ rb_define_method(pl_cInet, "contain?", pl_inet_contain, 1);
492
+ rb_define_method(pl_cInet, "contain_or_equal?", pl_inet_containeq, 1);
493
+ rb_define_method(pl_cInet, "host", pl_inet_host, 0);
494
+ rb_define_method(pl_cInet, "abbrev", pl_inet_abbrev, 0);
495
+ rb_define_method(pl_cInet, "masklen", pl_inet_masklen, 0);
496
+ rb_define_method(pl_cInet, "set_masklen", pl_inet_setmasklen, 1);
497
+ #if PG_PL_VERSION >= 74
498
+ rb_define_method(pl_cInet, "family", pl_inet_family, 0);
499
+ #endif
500
+ rb_define_method(pl_cInet, "broadcast", pl_inet_broadcast, 0);
501
+ rb_define_method(pl_cInet, "network", pl_inet_network, 0);
502
+ rb_define_method(pl_cInet, "netmask", pl_inet_netmask, 0);
503
+ #if PG_PL_VERSION >= 74
504
+ rb_define_method(pl_cInet, "hostmask", pl_inet_hostmask, 0);
505
+ #endif
506
+ rb_define_method(pl_cInet, "to_s", pl_inet_to_s, 0);
507
+ rb_define_method(pl_cInet, "first", pl_inet_network, 0);
508
+ rb_define_method(pl_cInet, "last", pl_inet_last, 0);
509
+ pl_cMac = rb_define_class("MacAddr", rb_cObject);
510
+ rb_include_module(pl_cMac, rb_mComparable);
511
+ rb_undef_method(CLASS_OF(pl_cMac), "method_missing");
512
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
513
+ rb_define_alloc_func(pl_cMac, pl_mac_s_alloc);
514
+ #else
515
+ rb_define_singleton_method(pl_cMac, "allocate", pl_mac_s_alloc, 0);
516
+ #endif
517
+ rb_define_singleton_method(pl_cMac, "new", plruby_s_new, -1);
518
+ rb_define_singleton_method(pl_cMac, "from_string", plruby_s_new, -1);
519
+ rb_define_singleton_method(pl_cMac, "from_datum", pl_mac_s_datum, 1);
520
+ rb_define_method(pl_cMac, "to_datum", pl_mac_to_datum, 1);
521
+ rb_define_method(pl_cMac, "initialize", pl_mac_init, 1);
522
+ #ifndef HAVE_RB_INITIALIZE_COPY
523
+ rb_define_method(pl_cMac, "clone", plruby_clone, 0);
524
+ #endif
525
+ rb_define_method(pl_cMac, "initialize_copy", pl_mac_init_copy, 1);
526
+ #if PG_PL_VERSION >= 74
527
+ rb_define_method(pl_cMac, "marshal_load", pl_mac_mload, 1);
528
+ rb_define_method(pl_cMac, "marshal_dump", pl_mac_mdump, -1);
529
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
530
+ rb_define_singleton_method(pl_cMac, "_load", plruby_s_load, 1);
531
+ rb_define_alias(pl_cMac, "_dump", "marshal_dump");
532
+ #endif
533
+ #endif
534
+ rb_define_method(pl_cMac, "<=>", pl_mac_cmp, 1);
535
+ rb_define_method(pl_cMac, "to_s", pl_mac_to_s, 0);
536
+ rb_define_method(pl_cMac, "truncate", pl_mac_truncate, 0);
537
+ }