WireAPI 0.3
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.
- data/amq_connection.c +232 -0
- data/amq_connection.h +5 -0
- data/amq_content.c +533 -0
- data/amq_content.h +7 -0
- data/amq_field_list.c +318 -0
- data/amq_field_list.h +13 -0
- data/amq_session.c +954 -0
- data/amq_session.h +5 -0
- data/amq_types.c +273 -0
- data/amq_types.h +128 -0
- data/amq_wireapi.c +195 -0
- data/extconf.rb +30 -0
- metadata +64 -0
data/amq_field_list.c
ADDED
@@ -0,0 +1,318 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <st.h>
|
3
|
+
#include <string.h>
|
4
|
+
#include "amq_field_list.h"
|
5
|
+
#include "amq_types.h"
|
6
|
+
#include <limits.h>
|
7
|
+
|
8
|
+
/* used for converting float to fixpoint */
|
9
|
+
const long FIXPOINT_MAX=LONG_MAX/100;
|
10
|
+
|
11
|
+
VALUE amqp_field_list;
|
12
|
+
|
13
|
+
/* receives a AMQ_FieldList or a Hash */
|
14
|
+
icl_longstr_t* get_optional_field_list(VALUE val) {
|
15
|
+
amq_field_list_cls *obj=0;
|
16
|
+
if (TYPE(val)==T_DATA && rb_obj_is_instance_of(val, amqp_field_list)) {
|
17
|
+
obj=get_amq_field_list_cls(val,1);
|
18
|
+
}
|
19
|
+
if (TYPE(val)==T_HASH) {
|
20
|
+
VALUE fld_list=rb_funcall(amqp_field_list,rb_intern("new"),1,val);
|
21
|
+
obj= get_amq_field_list_cls(fld_list,1);
|
22
|
+
}
|
23
|
+
|
24
|
+
if (obj && obj->field_list) {
|
25
|
+
return asl_field_list_flatten(obj->field_list);
|
26
|
+
}
|
27
|
+
return 0;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
/* try to convert val to a string when it is not a string yet */
|
32
|
+
VALUE get_as_string(VALUE val) {
|
33
|
+
if (TYPE(val)==T_STRING)
|
34
|
+
return val;
|
35
|
+
return rb_funcall(val,rb_intern("to_s"),0,0);
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
static VALUE field_value_to_ruby(asl_field_t *field) {
|
42
|
+
switch (field->type) {
|
43
|
+
case 'D': {
|
44
|
+
long double val=field->integer;
|
45
|
+
int d=field->decimals;
|
46
|
+
while (--d>=0)
|
47
|
+
val/=10;
|
48
|
+
return rb_float_new(val);
|
49
|
+
break;
|
50
|
+
}
|
51
|
+
case 'T': {
|
52
|
+
VALUE argv[1];
|
53
|
+
argv[0]=LONG2NUM(asl_field_integer(field));
|
54
|
+
VALUE time=rb_funcall2(rb_cTime,rb_intern("at"),1,argv);
|
55
|
+
return time;
|
56
|
+
break;
|
57
|
+
}
|
58
|
+
case 'S': {
|
59
|
+
return rb_str_new2(asl_field_string(field));
|
60
|
+
break;
|
61
|
+
}
|
62
|
+
case 'I': {
|
63
|
+
return INT2NUM(asl_field_integer(field));
|
64
|
+
break;
|
65
|
+
}
|
66
|
+
default:
|
67
|
+
return Qnil;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
|
72
|
+
static int add_ruby_value_to_field_list(asl_field_list_t *field_list,char *name,VALUE val) {
|
73
|
+
int res=0;
|
74
|
+
switch (TYPE(val)) {
|
75
|
+
case T_NIL:
|
76
|
+
{
|
77
|
+
asl_field_new_void(field_list,name);
|
78
|
+
res=1;
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
case T_DATA:
|
82
|
+
{
|
83
|
+
if (rb_obj_is_instance_of(val, rb_cTime)) {
|
84
|
+
VALUE _time=rb_funcall(val,rb_intern("tv_sec"),0,0);
|
85
|
+
long t=NUM2LONG(_time);
|
86
|
+
asl_field_new_time(field_list,name,t);
|
87
|
+
res=1;
|
88
|
+
break;
|
89
|
+
}
|
90
|
+
|
91
|
+
}
|
92
|
+
case T_FLOAT:
|
93
|
+
{
|
94
|
+
long double v=NUM2DBL(val);
|
95
|
+
int dec=0;
|
96
|
+
// make sure the integer doesn't roll over
|
97
|
+
while ((((long)v)-v)!=0 && abs(v)<FIXPOINT_MAX && dec<255) {
|
98
|
+
v*=10;
|
99
|
+
dec++;
|
100
|
+
}
|
101
|
+
asl_field_new_decimal(field_list,name,(long)v,dec);
|
102
|
+
res=1;
|
103
|
+
break;
|
104
|
+
}
|
105
|
+
case T_STRING:
|
106
|
+
{
|
107
|
+
char *str_val= StringValuePtr(val);
|
108
|
+
asl_field_new_string(field_list,name,str_val);
|
109
|
+
res=1;
|
110
|
+
break;
|
111
|
+
}
|
112
|
+
case T_FIXNUM:
|
113
|
+
{
|
114
|
+
long int_val= NUM2LONG(val);
|
115
|
+
asl_field_new_integer(field_list,name,int_val);
|
116
|
+
res=1;
|
117
|
+
break;
|
118
|
+
}
|
119
|
+
}
|
120
|
+
return res;
|
121
|
+
}
|
122
|
+
|
123
|
+
|
124
|
+
static VALUE field_list_new(int argc,VALUE *argv,VALUE klass)
|
125
|
+
{
|
126
|
+
VALUE self=create_amq_field_list_cls(asl_field_list_new (0));
|
127
|
+
rb_obj_call_init(self, argc, argv);
|
128
|
+
return self;
|
129
|
+
}
|
130
|
+
|
131
|
+
|
132
|
+
static VALUE field_list_initialize(int argc,VALUE *argv,VALUE self)
|
133
|
+
{
|
134
|
+
VALUE param;
|
135
|
+
rb_scan_args(argc,argv,"01",¶m);
|
136
|
+
if (param==Qnil) {
|
137
|
+
return self;
|
138
|
+
}
|
139
|
+
|
140
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
141
|
+
if (TYPE(param)==T_HASH) {
|
142
|
+
return rb_funcall(self,rb_intern("add_hash"),1,param);
|
143
|
+
}
|
144
|
+
if (TYPE(param)==T_DATA && rb_obj_is_instance_of(param, amqp_field_list)) {
|
145
|
+
amq_field_list_cls *obj=get_amq_field_list_cls(param,1);
|
146
|
+
asl_field_t *field = 0;
|
147
|
+
field=asl_field_list_first (obj->field_list);
|
148
|
+
while (field) {
|
149
|
+
VALUE val_arg=field_value_to_ruby(field);
|
150
|
+
add_ruby_value_to_field_list(fieldlst->field_list,field->name,val_arg);
|
151
|
+
field = asl_field_list_next (&field);
|
152
|
+
}
|
153
|
+
return self;
|
154
|
+
}
|
155
|
+
return self;
|
156
|
+
}
|
157
|
+
|
158
|
+
|
159
|
+
static VALUE field_list_destroy(VALUE self)
|
160
|
+
{
|
161
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
162
|
+
if (fieldlst->field_list) {
|
163
|
+
asl_field_list_destroy(&(fieldlst->field_list));
|
164
|
+
fieldlst->field_list=0;
|
165
|
+
}
|
166
|
+
return Qnil;
|
167
|
+
}
|
168
|
+
|
169
|
+
|
170
|
+
static VALUE field_list_to_hash(VALUE self) {
|
171
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
172
|
+
VALUE result=rb_hash_new();
|
173
|
+
VALUE key;
|
174
|
+
VALUE val;
|
175
|
+
asl_field_t *field = 0;
|
176
|
+
field=asl_field_list_first (fieldlst->field_list);
|
177
|
+
while (field) {
|
178
|
+
key=rb_str_new2(field->name);
|
179
|
+
val=field_value_to_ruby(field);
|
180
|
+
rb_hash_aset(result,key,val);
|
181
|
+
field = asl_field_list_next (&field);
|
182
|
+
}
|
183
|
+
return result;
|
184
|
+
}
|
185
|
+
|
186
|
+
static VALUE field_list_each_pair(VALUE self) {
|
187
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
188
|
+
VALUE result=rb_hash_new();
|
189
|
+
VALUE key_arg;
|
190
|
+
VALUE val_arg;
|
191
|
+
asl_field_t *field = 0;
|
192
|
+
field=asl_field_list_first (fieldlst->field_list);
|
193
|
+
|
194
|
+
while (field) {
|
195
|
+
key_arg=rb_str_new2(field->name);
|
196
|
+
val_arg=field_value_to_ruby(field);
|
197
|
+
if (rb_block_given_p()==Qtrue) {
|
198
|
+
rb_yield_values(2,key_arg,val_arg);
|
199
|
+
} else {
|
200
|
+
rb_raise(rb_eArgError, "need block with 2 arguments");
|
201
|
+
}
|
202
|
+
field = asl_field_list_next (&field);
|
203
|
+
}
|
204
|
+
return result;
|
205
|
+
}
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
static VALUE field_list_get_key(VALUE self,VALUE name_val) {
|
211
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
212
|
+
VALUE name=get_as_string(name_val);
|
213
|
+
Check_Type(name,T_STRING);
|
214
|
+
char *_name = StringValuePtr(name);
|
215
|
+
asl_field_t *field = 0;
|
216
|
+
field=asl_field_list_first (fieldlst->field_list);
|
217
|
+
VALUE result=Qnil;
|
218
|
+
while (field && result==Qnil) {
|
219
|
+
if (strcmp(field->name,_name)==0) {
|
220
|
+
result=field_value_to_ruby(field);
|
221
|
+
}
|
222
|
+
field = asl_field_list_next (&field);
|
223
|
+
}
|
224
|
+
return result;
|
225
|
+
}
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
static VALUE field_list_put_key(VALUE self,VALUE name_val,VALUE val) {
|
230
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
231
|
+
VALUE name=get_as_string(name_val);
|
232
|
+
Check_Type(name,T_STRING);
|
233
|
+
char *_name = StringValuePtr(name);
|
234
|
+
int res=add_ruby_value_to_field_list(fieldlst->field_list,_name,val);
|
235
|
+
if (res==0) {
|
236
|
+
rb_raise(rb_amq_error,"Can't handle value type");
|
237
|
+
}
|
238
|
+
return self;
|
239
|
+
}
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
/* utility */
|
244
|
+
static int push_hash_key(VALUE key, VALUE value, VALUE buf) {
|
245
|
+
rb_ary_push(buf,key);
|
246
|
+
return ST_CONTINUE;
|
247
|
+
}
|
248
|
+
|
249
|
+
|
250
|
+
static VALUE field_list_keys(VALUE self) {
|
251
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
252
|
+
VALUE result=rb_ary_new();
|
253
|
+
asl_field_t *field = 0;
|
254
|
+
field=asl_field_list_first(fieldlst->field_list);
|
255
|
+
while (field) {
|
256
|
+
VALUE key_str=rb_str_new2(field->name);
|
257
|
+
rb_ary_push(result,key_str);
|
258
|
+
field = asl_field_list_next (&field);
|
259
|
+
}
|
260
|
+
return result;
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
static VALUE field_list_keys_unique(VALUE self) {
|
265
|
+
VALUE key_array=field_list_keys(self);
|
266
|
+
ID include_method=rb_intern("include?");
|
267
|
+
|
268
|
+
while (RARRAY_LEN(key_array)>0) {
|
269
|
+
VALUE elem=rb_ary_pop(key_array);
|
270
|
+
if (Qtrue==rb_funcall(key_array,include_method,1,elem)) {
|
271
|
+
return Qfalse;
|
272
|
+
}
|
273
|
+
}
|
274
|
+
return Qtrue;
|
275
|
+
}
|
276
|
+
|
277
|
+
|
278
|
+
static VALUE field_list_add_hash(VALUE self,VALUE hash) {
|
279
|
+
amq_field_list_cls* const fieldlst=get_amq_field_list_cls(self,1);
|
280
|
+
Check_Type(hash,T_HASH);
|
281
|
+
VALUE key_arr=rb_ary_new();
|
282
|
+
rb_hash_foreach(hash, push_hash_key, key_arr);
|
283
|
+
|
284
|
+
VALUE key=rb_ary_shift(key_arr);
|
285
|
+
while (key!=Qnil) {
|
286
|
+
VALUE key_name=get_as_string(key);
|
287
|
+
char *_key = StringValuePtr(key_name);
|
288
|
+
VALUE val=rb_hash_aref(hash,key);
|
289
|
+
int res=add_ruby_value_to_field_list(fieldlst->field_list,_key,val);
|
290
|
+
if (res==0) {
|
291
|
+
rb_raise(rb_amq_error,"Can't handle value type for ",key);
|
292
|
+
}
|
293
|
+
key=rb_ary_shift(key_arr);
|
294
|
+
}
|
295
|
+
return self;
|
296
|
+
}
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
|
302
|
+
void init_field_list() {
|
303
|
+
amqp_field_list = rb_define_class_under(rb_wireapi,"AMQ_FieldList",rb_cObject);
|
304
|
+
rb_define_singleton_method(amqp_field_list , "new", field_list_new , -1);
|
305
|
+
rb_define_method(amqp_field_list,"initialize" , field_list_initialize ,-1);
|
306
|
+
rb_define_method(amqp_field_list,"to_hash" , field_list_to_hash ,0);
|
307
|
+
rb_define_method(amqp_field_list,"keys" , field_list_keys ,0);
|
308
|
+
rb_define_method(amqp_field_list,"destroy" , field_list_destroy ,0);
|
309
|
+
rb_define_method(amqp_field_list,"each_pair" , field_list_each_pair,0);
|
310
|
+
rb_define_method(amqp_field_list,"[]" , field_list_get_key ,1);
|
311
|
+
rb_define_method(amqp_field_list,"get" , field_list_get_key ,1);
|
312
|
+
rb_define_method(amqp_field_list,"put" , field_list_put_key ,2);
|
313
|
+
rb_define_method(amqp_field_list,"[]=" , field_list_put_key ,2);
|
314
|
+
rb_define_method(amqp_field_list,"add_hash" , field_list_add_hash,1);
|
315
|
+
rb_define_method(amqp_field_list,"keys_unique?", field_list_keys_unique,0);
|
316
|
+
|
317
|
+
}
|
318
|
+
|