globegit-postgresql-plruby 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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
+ }