rubywmq 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/wmq.h CHANGED
@@ -1,350 +1,367 @@
1
- /* --------------------------------------------------------------------------
2
- * Copyright 2006 J. Reid Morrison. Dimension Solutions, Inc.
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- * --------------------------------------------------------------------------*/
16
-
17
- #include <ruby.h>
18
- #include <version.h>
19
- #include <cmqc.h>
20
- #include <cmqxc.h>
21
-
22
- /* Todo: Add a #ifdef here to exclude the following includes when applicable */
23
- #include <cmqcfc.h> /* PCF */
24
- #include <cmqbc.h> /* MQAI */
25
-
26
- #ifdef _WIN32
27
- #define WMQ_EXPORT __declspec(dllexport)
28
- #else
29
- #define WMQ_EXPORT
30
- #endif
31
-
32
- void QueueManager_id_init();
33
- void QueueManager_selector_id_init();
34
- void QueueManager_command_id_init();
35
- VALUE QUEUE_MANAGER_alloc(VALUE klass);
36
- VALUE QueueManager_singleton_connect(int argc, VALUE *argv, VALUE self);
37
- VALUE QueueManager_open_queue(int argc, VALUE *argv, VALUE self);
38
- VALUE QueueManager_initialize(VALUE self, VALUE parms);
39
- VALUE QueueManager_connect(VALUE self);
40
- VALUE QueueManager_disconnect(VALUE self);
41
- VALUE QueueManager_begin(VALUE self);
42
- VALUE QueueManager_commit(VALUE self);
43
- VALUE QueueManager_backout(VALUE self);
44
- VALUE QueueManager_put(VALUE self, VALUE parms);
45
- VALUE QueueManager_reason_code(VALUE self);
46
- VALUE QueueManager_comp_code(VALUE self);
47
- VALUE QueueManager_reason(VALUE self);
48
- VALUE QueueManager_exception_on_error(VALUE self);
49
- VALUE QueueManager_connected_q(VALUE self);
50
- VALUE QueueManager_name(VALUE self);
51
- VALUE QueueManager_execute(VALUE self, VALUE hash);
52
-
53
- void Queue_id_init();
54
- VALUE QUEUE_alloc(VALUE klass);
55
- VALUE Queue_initialize(VALUE self, VALUE parms);
56
- VALUE Queue_singleton_open(int argc, VALUE *argv, VALUE self);
57
- VALUE Queue_open(VALUE self);
58
- VALUE Queue_close(VALUE self);
59
- VALUE Queue_put(VALUE self, VALUE parms);
60
- VALUE Queue_get(VALUE self, VALUE parms);
61
- VALUE Queue_each(int argc, VALUE *argv, VALUE self);
62
- VALUE Queue_name(VALUE self);
63
- VALUE Queue_reason_code(VALUE self);
64
- VALUE Queue_comp_code(VALUE self);
65
- VALUE Queue_reason(VALUE self);
66
- VALUE Queue_open_q(VALUE self);
67
-
68
- void Queue_extract_put_message_options(VALUE hash, PMQPMO ppmo);
69
-
70
- extern VALUE wmq_queue;
71
- extern VALUE wmq_queue_manager;
72
- extern VALUE wmq_message;
73
- extern VALUE wmq_exception;
74
-
75
- #define WMQ_EXEC_STRING_INQ_BUFFER_SIZE 32768 /* Todo: Should we make the mqai string return buffer dynamic? */
76
-
77
- /* Internal C Structures for holding MQ data types */
78
- typedef struct tagQUEUE_MANAGER QUEUE_MANAGER;
79
- typedef QUEUE_MANAGER MQPOINTER PQUEUE_MANAGER;
80
-
81
- struct tagQUEUE_MANAGER {
82
- MQHCONN hcon; /* connection handle */
83
- MQLONG comp_code; /* completion code */
84
- MQLONG reason_code; /* reason code for MQCONN */
85
- MQLONG exception_on_error; /* Non-Zero means throw exception*/
86
- MQLONG already_connected; /* Already connected means don't disconnect */
87
- MQLONG trace_level; /* Trace level. 0==None, 1==Info 2==Debug ..*/
88
- MQCNO connect_options; /* MQCONNX Connection Options */
89
- #ifdef MQCNO_VERSION_2
90
- MQCD client_conn; /* Client Connection */
91
- #endif
92
- #ifdef MQCNO_VERSION_4
93
- MQSCO ssl_config_opts; /* Security options */
94
- #endif
95
- #ifdef MQCD_VERSION_6
96
- MQPTR long_remote_user_id_ptr;
97
- #endif
98
- #ifdef MQCD_VERSION_7
99
- MQPTR ssl_peer_name_ptr;
100
- #endif
101
- #ifdef MQHB_UNUSABLE_HBAG
102
- MQHBAG admin_bag;
103
- MQHBAG reply_bag;
104
- #endif
105
- PMQBYTE p_buffer; /* message buffer */
106
- MQLONG buffer_size; /* Allocated size of buffer */
107
-
108
- MQLONG is_client_conn; /* Is this a Client Connection? */
109
- void* mq_lib_handle; /* Handle to MQ library */
110
-
111
- void(*MQCONNX)(PMQCHAR,PMQCNO,PMQHCONN,PMQLONG,PMQLONG);
112
- void(*MQCONN) (PMQCHAR,PMQHCONN,PMQLONG,PMQLONG);
113
- void(*MQDISC) (PMQHCONN,PMQLONG,PMQLONG);
114
- void(*MQBEGIN)(MQHCONN,PMQVOID,PMQLONG,PMQLONG);
115
- void(*MQBACK) (MQHCONN,PMQLONG,PMQLONG);
116
- void(*MQCMIT) (MQHCONN,PMQLONG,PMQLONG);
117
- void(*MQPUT1) (MQHCONN,PMQVOID,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG);
118
-
119
- void(*MQOPEN) (MQHCONN,PMQVOID,MQLONG,PMQHOBJ,PMQLONG,PMQLONG);
120
- void(*MQCLOSE)(MQHCONN,PMQHOBJ,MQLONG,PMQLONG,PMQLONG);
121
- void(*MQGET) (MQHCONN,MQHOBJ,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG,PMQLONG);
122
- void(*MQPUT) (MQHCONN,MQHOBJ,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG);
123
-
124
- void(*MQINQ) (MQHCONN,MQHOBJ,MQLONG,PMQLONG,MQLONG,PMQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
125
- void(*MQSET) (MQHCONN,MQHOBJ,MQLONG,PMQLONG,MQLONG,PMQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
126
-
127
- void(*mqCreateBag)(MQLONG,PMQHBAG,PMQLONG,PMQLONG);
128
- void(*mqDeleteBag)(PMQHBAG,PMQLONG,PMQLONG);
129
- void(*mqClearBag)(MQHBAG,PMQLONG,PMQLONG);
130
- void(*mqExecute)(MQHCONN,MQLONG,MQHBAG,MQHBAG,MQHBAG,MQHOBJ,MQHOBJ,PMQLONG,PMQLONG);
131
- void(*mqCountItems)(MQHBAG,MQLONG,PMQLONG,PMQLONG,PMQLONG);
132
- void(*mqInquireBag)(MQHBAG,MQLONG,MQLONG,PMQHBAG,PMQLONG,PMQLONG);
133
- void(*mqInquireItemInfo)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG,PMQLONG,PMQLONG);
134
- void(*mqInquireInteger)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG,PMQLONG);
135
- void(*mqInquireString)(MQHBAG,MQLONG,MQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG,PMQLONG,PMQLONG);
136
- void(*mqAddInquiry)(MQHBAG,MQLONG,PMQLONG,PMQLONG);
137
- void(*mqAddInteger)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG);
138
- void(*mqAddString)(MQHBAG,MQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
139
- };
140
-
141
- void Queue_manager_mq_load(PQUEUE_MANAGER pqm);
142
- void Queue_manager_mq_free(PQUEUE_MANAGER pqm);
143
-
144
-
145
- /*
146
- * Message
147
- */
148
- struct Message_build_header_arg {
149
- PMQBYTE* pp_buffer; /* Autosize: Pointer to start of total buffer */
150
- PMQLONG p_buffer_size; /* Autosize: Size of total buffer */
151
- MQLONG data_length; /* Autosize: Length of the data being written */
152
- PMQLONG p_data_offset; /* Current offset of data portion in total buffer */
153
- MQLONG trace_level; /* Trace level. 0==None, 1==Info 2==Debug ..*/
154
- ID next_header_id; /* Used for setting MQ Format to next header */
155
- PMQBYTE data_format; /* Format of data. Used when next_header_id == 0 */
156
- };
157
-
158
- void Message_id_init();
159
- VALUE Message_initialize(int argc, VALUE *argv, VALUE self);
160
- VALUE Message_clear(VALUE self);
161
- PMQBYTE Message_autogrow_data_buffer(struct Message_build_header_arg* parg, MQLONG additional_size);
162
- void Message_build_rf_header (VALUE hash, struct Message_build_header_arg* parg);
163
- MQLONG Message_deblock_rf_header (VALUE hash, PMQBYTE p_data, MQLONG data_len);
164
- void Message_build_rf_header_2 (VALUE hash, struct Message_build_header_arg* parg);
165
- MQLONG Message_deblock_rf_header_2 (VALUE hash, PMQBYTE p_data, MQLONG data_len);
166
-
167
- void Message_build_set_format(ID header_type, PMQBYTE p_format);
168
- void Message_build(PMQBYTE* pq_pp_buffer, PMQLONG pq_p_buffer_size, MQLONG trace_level,
169
- VALUE parms, PPMQVOID pp_buffer, PMQLONG p_total_length, PMQMD pmqmd);
170
- void Message_build_mqmd(VALUE self, PMQMD pmqmd);
171
- void Message_deblock(VALUE message, PMQMD pmqmd, PMQBYTE p_buffer, MQLONG total_length, MQLONG trace_level);
172
-
173
- int Message_build_header(VALUE hash, struct Message_build_header_arg* parg);
174
-
175
- /* Utility methods */
176
-
177
- /* --------------------------------------------------
178
- * Set internal variable based on value passed in from
179
- * a hash
180
- * --------------------------------------------------*/
181
- void setFromHashString(VALUE self, VALUE hash, char* pKey, char* pAttribute, char* pDefault);
182
- void setFromHashValue(VALUE self, VALUE hash, char* pKey, char* pAttribute, VALUE valDefault);
183
-
184
- void to_mqmd(VALUE hash, MQMD* pmqmd);
185
- void from_mqmd(VALUE hash, MQMD* pmqmd);
186
-
187
- void to_mqdlh(VALUE hash, MQDLH* pmqdlh);
188
- void from_mqdlh(VALUE hash, MQDLH* pmqdlh);
189
-
190
- void wmq_structs_id_init();
191
- void Message_to_mqmd(VALUE hash, MQMD* pmqmd);
192
- void Message_to_mqmd1(VALUE hash, MQMD1* pmqmd1);
193
- void Message_to_mqrfh2(VALUE hash, MQRFH2* pmqrfh2);
194
- void Message_to_mqrfh(VALUE hash, MQRFH* pmqrfh);
195
- void Message_to_mqdlh(VALUE hash, MQDLH* pmqdlh);
196
- void Message_to_mqcih(VALUE hash, MQCIH* pmqcih);
197
- void Message_to_mqdh(VALUE hash, MQDH* pmqdh);
198
- void Message_to_mqiih(VALUE hash, MQIIH* pmqiih);
199
- void Message_to_mqrmh(VALUE hash, MQRMH* pmqrmh);
200
- void Message_to_mqtm(VALUE hash, MQTM* pmqtm);
201
- void Message_to_mqtmc2(VALUE hash, MQTMC2* pmqtmc2);
202
- void Message_to_mqwih(VALUE hash, MQWIH* pmqwih);
203
- void Message_to_mqxqh(VALUE hash, MQXQH* pmqxqh);
204
- void Message_from_mqmd(VALUE hash, MQMD* pmqmd);
205
- void Message_from_mqmd1(VALUE hash, MQMD1* pmqmd1);
206
- void Message_from_mqrfh2(VALUE hash, MQRFH2* pmqrfh2);
207
- void Message_from_mqrfh(VALUE hash, MQRFH* pmqrfh);
208
- void Message_from_mqdlh(VALUE hash, MQDLH* pmqdlh);
209
- void Message_from_mqcih(VALUE hash, MQCIH* pmqcih);
210
- void Message_from_mqdh(VALUE hash, MQDH* pmqdh);
211
- void Message_from_mqiih(VALUE hash, MQIIH* pmqiih);
212
- void Message_from_mqrmh(VALUE hash, MQRMH* pmqrmh);
213
- void Message_from_mqtm(VALUE hash, MQTM* pmqtm);
214
- void Message_from_mqtmc2(VALUE hash, MQTMC2* pmqtmc2);
215
- void Message_from_mqwih(VALUE hash, MQWIH* pmqwih);
216
- void Message_from_mqxqh(VALUE hash, MQXQH* pmqxqh);
217
-
218
- char* wmq_reason(MQLONG reason_code);
219
- ID wmq_selector_id(MQLONG selector);
220
- MQLONG wmq_command_lookup(ID command_id);
221
- void wmq_selector(ID selector_id, PMQLONG selector_type, PMQLONG selector);
222
-
223
- /* --------------------------------------------------
224
- * MACROS for moving data between Ruby and MQ
225
- * --------------------------------------------------*/
226
- #define WMQ_STR2MQLONG(STR,ELEMENT) \
227
- ELEMENT = NUM2LONG(STR);
228
-
229
- #define WMQ_STR2MQCHAR(STR,ELEMENT) \
230
- ELEMENT = NUM2LONG(STR);
231
-
232
- #define WMQ_STR2MQCHARS(STR,ELEMENT) \
233
- str = StringValue(STR); \
234
- length = RSTRING(STR)->len; \
235
- size = sizeof(ELEMENT); \
236
- strncpy(ELEMENT, RSTRING(STR)->ptr, length > size ? size : length);
237
-
238
- #define WMQ_STR2MQBYTES(STR,ELEMENT) \
239
- str = StringValue(STR); \
240
- length = RSTRING(str)->len; \
241
- size = sizeof(ELEMENT); \
242
- if (length >= size) \
243
- { \
244
- memcpy(ELEMENT, RSTRING(str)->ptr, size); \
245
- } \
246
- else \
247
- { \
248
- memcpy(ELEMENT, RSTRING(str)->ptr, length); \
249
- memset(ELEMENT+length, 0, size-length); \
250
- }
251
-
252
- #define WMQ_HASH2MQLONG(HASH,KEY,ELEMENT) \
253
- val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
254
- if (!NIL_P(val)) { WMQ_STR2MQLONG(val,ELEMENT) }
255
-
256
- #define WMQ_HASH2MQCHARS(HASH,KEY,ELEMENT) \
257
- val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
258
- if (!NIL_P(val)) \
259
- { \
260
- WMQ_STR2MQCHARS(val,ELEMENT) \
261
- }
262
-
263
- #define WMQ_HASH2MQCHAR(HASH,KEY,ELEMENT) \
264
- val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
265
- if (!NIL_P(val)) { WMQ_STR2MQCHAR(val,ELEMENT); } \
266
-
267
- #define WMQ_HASH2MQBYTES(HASH,KEY,ELEMENT) \
268
- val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
269
- if (!NIL_P(val)) \
270
- { \
271
- WMQ_STR2MQBYTES(val,ELEMENT) \
272
- }
273
-
274
- #define WMQ_HASH2BOOL(HASH,KEY,ELEMENT) \
275
- val = rb_hash_aref(hash, ID2SYM(ID_##KEY)); \
276
- if (!NIL_P(val)) \
277
- { \
278
- if(TYPE(val) == T_TRUE) ELEMENT = 1; \
279
- else if(TYPE(val) == T_FALSE) ELEMENT = 0; \
280
- else \
281
- rb_raise(rb_eTypeError, ":" #KEY \
282
- " must be true or false"); \
283
- }
284
-
285
- #define IF_TRUE(KEY,DEFAULT) \
286
- val = rb_hash_aref(hash, ID2SYM(ID_##KEY)); \
287
- if (NIL_P(val)) \
288
- { \
289
- flag = DEFAULT; \
290
- } \
291
- else \
292
- { \
293
- if(TYPE(val) == T_TRUE) flag = 1; \
294
- else if(TYPE(val) == T_FALSE) flag = 0; \
295
- else \
296
- rb_raise(rb_eTypeError, ":" #KEY \
297
- " must be true or false"); \
298
- } \
299
- if (flag)
300
-
301
- /* --------------------------------------------------
302
- * Strip trailing nulls and spaces
303
- * --------------------------------------------------*/
304
- #define WMQ_MQCHARS2STR(ELEMENT, TARGET) \
305
- size = sizeof(ELEMENT); \
306
- length = 0; \
307
- pChar = ELEMENT + size-1; \
308
- for (i = size; i > 0; i--) \
309
- { \
310
- if (*pChar != ' ' && *pChar != 0) \
311
- { \
312
- length = i; \
313
- break; \
314
- } \
315
- pChar--; \
316
- } \
317
- TARGET = rb_str_new(ELEMENT,length);
318
-
319
- #define WMQ_MQCHARS2HASH(HASH,KEY,ELEMENT) \
320
- WMQ_MQCHARS2STR(ELEMENT, str) \
321
- rb_hash_aset(HASH, ID2SYM(ID_##KEY), str);
322
-
323
- #define WMQ_MQLONG2HASH(HASH,KEY,ELEMENT) \
324
- rb_hash_aset(HASH, ID2SYM(ID_##KEY), LONG2NUM(ELEMENT));
325
-
326
- #define WMQ_MQCHAR2HASH(HASH,KEY,ELEMENT) \
327
- rb_hash_aset(HASH, ID2SYM(ID_##KEY), LONG2NUM(ELEMENT));
328
-
329
- /* --------------------------------------------------
330
- * Trailing Spaces are important with binary fields
331
- * --------------------------------------------------*/
332
- #define WMQ_MQBYTES2STR(ELEMENT,TARGET) \
333
- size = sizeof(ELEMENT); \
334
- length = 0; \
335
- pChar = ELEMENT + size-1; \
336
- for (i = size; i > 0; i--) \
337
- { \
338
- if (*pChar != 0) \
339
- { \
340
- length = i; \
341
- break; \
342
- } \
343
- pChar--; \
344
- } \
345
- TARGET = rb_str_new(ELEMENT,length);
346
-
347
- #define WMQ_MQBYTES2HASH(HASH,KEY,ELEMENT) \
348
- WMQ_MQBYTES2STR(ELEMENT, str) \
349
- rb_hash_aset(HASH, ID2SYM(ID_##KEY), str);
350
-
1
+ /* --------------------------------------------------------------------------
2
+ * Copyright 2006 J. Reid Morrison. Dimension Solutions, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ * --------------------------------------------------------------------------*/
16
+
17
+ #include <ruby.h>
18
+
19
+ /* New with Ruby 1.9, define for prior Ruby versions */
20
+ #ifndef RSTRING_PTR
21
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
22
+ #endif
23
+ #ifndef RSTRING_LEN
24
+ #define RSTRING_LEN(str) RSTRING(str)->len
25
+ #endif
26
+ #ifndef RARRAY_PTR
27
+ #define RARRAY_PTR(ary) RARRAY(ary)->ptr
28
+ #endif
29
+ #ifndef RARRAY_LEN
30
+ #define RARRAY_LEN(ary) RARRAY(ary)->len
31
+ #endif
32
+ #ifndef HAVE_RB_STR_SET_LEN
33
+ #define rb_str_set_len(str, length) (RSTRING_LEN(str) = (length))
34
+ #endif
35
+
36
+ #include <cmqc.h>
37
+ #include <cmqxc.h>
38
+
39
+ /* Todo: Add a #ifdef here to exclude the following includes when applicable */
40
+ #include <cmqcfc.h> /* PCF */
41
+ #include <cmqbc.h> /* MQAI */
42
+
43
+ #ifdef _WIN32
44
+ #define WMQ_EXPORT __declspec(dllexport)
45
+ #else
46
+ #define WMQ_EXPORT
47
+ #endif
48
+
49
+ void QueueManager_id_init();
50
+ void QueueManager_selector_id_init();
51
+ void QueueManager_command_id_init();
52
+ VALUE QUEUE_MANAGER_alloc(VALUE klass);
53
+ VALUE QueueManager_singleton_connect(int argc, VALUE *argv, VALUE self);
54
+ VALUE QueueManager_open_queue(int argc, VALUE *argv, VALUE self);
55
+ VALUE QueueManager_initialize(VALUE self, VALUE parms);
56
+ VALUE QueueManager_connect(VALUE self);
57
+ VALUE QueueManager_disconnect(VALUE self);
58
+ VALUE QueueManager_begin(VALUE self);
59
+ VALUE QueueManager_commit(VALUE self);
60
+ VALUE QueueManager_backout(VALUE self);
61
+ VALUE QueueManager_put(VALUE self, VALUE parms);
62
+ VALUE QueueManager_reason_code(VALUE self);
63
+ VALUE QueueManager_comp_code(VALUE self);
64
+ VALUE QueueManager_reason(VALUE self);
65
+ VALUE QueueManager_exception_on_error(VALUE self);
66
+ VALUE QueueManager_connected_q(VALUE self);
67
+ VALUE QueueManager_name(VALUE self);
68
+ VALUE QueueManager_execute(VALUE self, VALUE hash);
69
+
70
+ void Queue_id_init();
71
+ VALUE QUEUE_alloc(VALUE klass);
72
+ VALUE Queue_initialize(VALUE self, VALUE parms);
73
+ VALUE Queue_singleton_open(int argc, VALUE *argv, VALUE self);
74
+ VALUE Queue_open(VALUE self);
75
+ VALUE Queue_close(VALUE self);
76
+ VALUE Queue_put(VALUE self, VALUE parms);
77
+ VALUE Queue_get(VALUE self, VALUE parms);
78
+ VALUE Queue_each(int argc, VALUE *argv, VALUE self);
79
+ VALUE Queue_name(VALUE self);
80
+ VALUE Queue_reason_code(VALUE self);
81
+ VALUE Queue_comp_code(VALUE self);
82
+ VALUE Queue_reason(VALUE self);
83
+ VALUE Queue_open_q(VALUE self);
84
+
85
+ void Queue_extract_put_message_options(VALUE hash, PMQPMO ppmo);
86
+
87
+ extern VALUE wmq_queue;
88
+ extern VALUE wmq_queue_manager;
89
+ extern VALUE wmq_message;
90
+ extern VALUE wmq_exception;
91
+
92
+ #define WMQ_EXEC_STRING_INQ_BUFFER_SIZE 32768 /* Todo: Should we make the mqai string return buffer dynamic? */
93
+
94
+ /* Internal C Structures for holding MQ data types */
95
+ typedef struct tagQUEUE_MANAGER QUEUE_MANAGER;
96
+ typedef QUEUE_MANAGER MQPOINTER PQUEUE_MANAGER;
97
+
98
+ struct tagQUEUE_MANAGER {
99
+ MQHCONN hcon; /* connection handle */
100
+ MQLONG comp_code; /* completion code */
101
+ MQLONG reason_code; /* reason code for MQCONN */
102
+ MQLONG exception_on_error; /* Non-Zero means throw exception*/
103
+ MQLONG already_connected; /* Already connected means don't disconnect */
104
+ MQLONG trace_level; /* Trace level. 0==None, 1==Info 2==Debug ..*/
105
+ MQCNO connect_options; /* MQCONNX Connection Options */
106
+ #ifdef MQCNO_VERSION_2
107
+ MQCD client_conn; /* Client Connection */
108
+ #endif
109
+ #ifdef MQCNO_VERSION_4
110
+ MQSCO ssl_config_opts; /* Security options */
111
+ #endif
112
+ #ifdef MQCD_VERSION_6
113
+ MQPTR long_remote_user_id_ptr;
114
+ #endif
115
+ #ifdef MQCD_VERSION_7
116
+ MQPTR ssl_peer_name_ptr;
117
+ #endif
118
+ #ifdef MQHB_UNUSABLE_HBAG
119
+ MQHBAG admin_bag;
120
+ MQHBAG reply_bag;
121
+ #endif
122
+ PMQBYTE p_buffer; /* message buffer */
123
+ MQLONG buffer_size; /* Allocated size of buffer */
124
+
125
+ MQLONG is_client_conn; /* Is this a Client Connection? */
126
+ void* mq_lib_handle; /* Handle to MQ library */
127
+
128
+ void(*MQCONNX)(PMQCHAR,PMQCNO,PMQHCONN,PMQLONG,PMQLONG);
129
+ void(*MQCONN) (PMQCHAR,PMQHCONN,PMQLONG,PMQLONG);
130
+ void(*MQDISC) (PMQHCONN,PMQLONG,PMQLONG);
131
+ void(*MQBEGIN)(MQHCONN,PMQVOID,PMQLONG,PMQLONG);
132
+ void(*MQBACK) (MQHCONN,PMQLONG,PMQLONG);
133
+ void(*MQCMIT) (MQHCONN,PMQLONG,PMQLONG);
134
+ void(*MQPUT1) (MQHCONN,PMQVOID,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG);
135
+
136
+ void(*MQOPEN) (MQHCONN,PMQVOID,MQLONG,PMQHOBJ,PMQLONG,PMQLONG);
137
+ void(*MQCLOSE)(MQHCONN,PMQHOBJ,MQLONG,PMQLONG,PMQLONG);
138
+ void(*MQGET) (MQHCONN,MQHOBJ,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG,PMQLONG);
139
+ void(*MQPUT) (MQHCONN,MQHOBJ,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG);
140
+
141
+ void(*MQINQ) (MQHCONN,MQHOBJ,MQLONG,PMQLONG,MQLONG,PMQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
142
+ void(*MQSET) (MQHCONN,MQHOBJ,MQLONG,PMQLONG,MQLONG,PMQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
143
+
144
+ void(*mqCreateBag)(MQLONG,PMQHBAG,PMQLONG,PMQLONG);
145
+ void(*mqDeleteBag)(PMQHBAG,PMQLONG,PMQLONG);
146
+ void(*mqClearBag)(MQHBAG,PMQLONG,PMQLONG);
147
+ void(*mqExecute)(MQHCONN,MQLONG,MQHBAG,MQHBAG,MQHBAG,MQHOBJ,MQHOBJ,PMQLONG,PMQLONG);
148
+ void(*mqCountItems)(MQHBAG,MQLONG,PMQLONG,PMQLONG,PMQLONG);
149
+ void(*mqInquireBag)(MQHBAG,MQLONG,MQLONG,PMQHBAG,PMQLONG,PMQLONG);
150
+ void(*mqInquireItemInfo)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG,PMQLONG,PMQLONG);
151
+ void(*mqInquireInteger)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG,PMQLONG);
152
+ void(*mqInquireString)(MQHBAG,MQLONG,MQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG,PMQLONG,PMQLONG);
153
+ void(*mqAddInquiry)(MQHBAG,MQLONG,PMQLONG,PMQLONG);
154
+ void(*mqAddInteger)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG);
155
+ void(*mqAddString)(MQHBAG,MQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
156
+ };
157
+
158
+ void Queue_manager_mq_load(PQUEUE_MANAGER pqm);
159
+ void Queue_manager_mq_free(PQUEUE_MANAGER pqm);
160
+
161
+
162
+ /*
163
+ * Message
164
+ */
165
+ struct Message_build_header_arg {
166
+ PMQBYTE* pp_buffer; /* Autosize: Pointer to start of total buffer */
167
+ PMQLONG p_buffer_size; /* Autosize: Size of total buffer */
168
+ MQLONG data_length; /* Autosize: Length of the data being written */
169
+ PMQLONG p_data_offset; /* Current offset of data portion in total buffer */
170
+ MQLONG trace_level; /* Trace level. 0==None, 1==Info 2==Debug ..*/
171
+ ID next_header_id; /* Used for setting MQ Format to next header */
172
+ PMQBYTE data_format; /* Format of data. Used when next_header_id == 0 */
173
+ };
174
+
175
+ void Message_id_init();
176
+ VALUE Message_initialize(int argc, VALUE *argv, VALUE self);
177
+ VALUE Message_clear(VALUE self);
178
+ PMQBYTE Message_autogrow_data_buffer(struct Message_build_header_arg* parg, MQLONG additional_size);
179
+ void Message_build_rf_header (VALUE hash, struct Message_build_header_arg* parg);
180
+ MQLONG Message_deblock_rf_header (VALUE hash, PMQBYTE p_data, MQLONG data_len);
181
+ void Message_build_rf_header_2 (VALUE hash, struct Message_build_header_arg* parg);
182
+ MQLONG Message_deblock_rf_header_2 (VALUE hash, PMQBYTE p_data, MQLONG data_len);
183
+
184
+ void Message_build_set_format(ID header_type, PMQBYTE p_format);
185
+ void Message_build(PMQBYTE* pq_pp_buffer, PMQLONG pq_p_buffer_size, MQLONG trace_level,
186
+ VALUE parms, PPMQVOID pp_buffer, PMQLONG p_total_length, PMQMD pmqmd);
187
+ void Message_build_mqmd(VALUE self, PMQMD pmqmd);
188
+ void Message_deblock(VALUE message, PMQMD pmqmd, PMQBYTE p_buffer, MQLONG total_length, MQLONG trace_level);
189
+
190
+ int Message_build_header(VALUE hash, struct Message_build_header_arg* parg);
191
+
192
+ /* Utility methods */
193
+
194
+ /* --------------------------------------------------
195
+ * Set internal variable based on value passed in from
196
+ * a hash
197
+ * --------------------------------------------------*/
198
+ void setFromHashString(VALUE self, VALUE hash, char* pKey, char* pAttribute, char* pDefault);
199
+ void setFromHashValue(VALUE self, VALUE hash, char* pKey, char* pAttribute, VALUE valDefault);
200
+
201
+ void to_mqmd(VALUE hash, MQMD* pmqmd);
202
+ void from_mqmd(VALUE hash, MQMD* pmqmd);
203
+
204
+ void to_mqdlh(VALUE hash, MQDLH* pmqdlh);
205
+ void from_mqdlh(VALUE hash, MQDLH* pmqdlh);
206
+
207
+ void wmq_structs_id_init();
208
+ void Message_to_mqmd(VALUE hash, MQMD* pmqmd);
209
+ void Message_to_mqmd1(VALUE hash, MQMD1* pmqmd1);
210
+ void Message_to_mqrfh2(VALUE hash, MQRFH2* pmqrfh2);
211
+ void Message_to_mqrfh(VALUE hash, MQRFH* pmqrfh);
212
+ void Message_to_mqdlh(VALUE hash, MQDLH* pmqdlh);
213
+ void Message_to_mqcih(VALUE hash, MQCIH* pmqcih);
214
+ void Message_to_mqdh(VALUE hash, MQDH* pmqdh);
215
+ void Message_to_mqiih(VALUE hash, MQIIH* pmqiih);
216
+ void Message_to_mqrmh(VALUE hash, MQRMH* pmqrmh);
217
+ void Message_to_mqtm(VALUE hash, MQTM* pmqtm);
218
+ void Message_to_mqtmc2(VALUE hash, MQTMC2* pmqtmc2);
219
+ void Message_to_mqwih(VALUE hash, MQWIH* pmqwih);
220
+ void Message_to_mqxqh(VALUE hash, MQXQH* pmqxqh);
221
+ void Message_from_mqmd(VALUE hash, MQMD* pmqmd);
222
+ void Message_from_mqmd1(VALUE hash, MQMD1* pmqmd1);
223
+ void Message_from_mqrfh2(VALUE hash, MQRFH2* pmqrfh2);
224
+ void Message_from_mqrfh(VALUE hash, MQRFH* pmqrfh);
225
+ void Message_from_mqdlh(VALUE hash, MQDLH* pmqdlh);
226
+ void Message_from_mqcih(VALUE hash, MQCIH* pmqcih);
227
+ void Message_from_mqdh(VALUE hash, MQDH* pmqdh);
228
+ void Message_from_mqiih(VALUE hash, MQIIH* pmqiih);
229
+ void Message_from_mqrmh(VALUE hash, MQRMH* pmqrmh);
230
+ void Message_from_mqtm(VALUE hash, MQTM* pmqtm);
231
+ void Message_from_mqtmc2(VALUE hash, MQTMC2* pmqtmc2);
232
+ void Message_from_mqwih(VALUE hash, MQWIH* pmqwih);
233
+ void Message_from_mqxqh(VALUE hash, MQXQH* pmqxqh);
234
+
235
+ char* wmq_reason(MQLONG reason_code);
236
+ ID wmq_selector_id(MQLONG selector);
237
+ MQLONG wmq_command_lookup(ID command_id);
238
+ void wmq_selector(ID selector_id, PMQLONG selector_type, PMQLONG selector);
239
+
240
+ /* --------------------------------------------------
241
+ * MACROS for moving data between Ruby and MQ
242
+ * --------------------------------------------------*/
243
+ #define WMQ_STR2MQLONG(STR,ELEMENT) \
244
+ ELEMENT = NUM2LONG(STR);
245
+
246
+ #define WMQ_STR2MQCHAR(STR,ELEMENT) \
247
+ ELEMENT = NUM2LONG(STR);
248
+
249
+ #define WMQ_STR2MQCHARS(STR,ELEMENT) \
250
+ str = StringValue(STR); \
251
+ length = RSTRING_LEN(STR); \
252
+ size = sizeof(ELEMENT); \
253
+ strncpy(ELEMENT, RSTRING_PTR(STR), length > size ? size : length);
254
+
255
+ #define WMQ_STR2MQBYTES(STR,ELEMENT) \
256
+ str = StringValue(STR); \
257
+ length = RSTRING_LEN(str); \
258
+ size = sizeof(ELEMENT); \
259
+ if (length >= size) \
260
+ { \
261
+ memcpy(ELEMENT, RSTRING_PTR(str), size); \
262
+ } \
263
+ else \
264
+ { \
265
+ memcpy(ELEMENT, RSTRING_PTR(str), length); \
266
+ memset(ELEMENT+length, 0, size-length); \
267
+ }
268
+
269
+ #define WMQ_HASH2MQLONG(HASH,KEY,ELEMENT) \
270
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
271
+ if (!NIL_P(val)) { WMQ_STR2MQLONG(val,ELEMENT) }
272
+
273
+ #define WMQ_HASH2MQCHARS(HASH,KEY,ELEMENT) \
274
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
275
+ if (!NIL_P(val)) \
276
+ { \
277
+ WMQ_STR2MQCHARS(val,ELEMENT) \
278
+ }
279
+
280
+ #define WMQ_HASH2MQCHAR(HASH,KEY,ELEMENT) \
281
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
282
+ if (!NIL_P(val)) { WMQ_STR2MQCHAR(val,ELEMENT); } \
283
+
284
+ #define WMQ_HASH2MQBYTES(HASH,KEY,ELEMENT) \
285
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
286
+ if (!NIL_P(val)) \
287
+ { \
288
+ WMQ_STR2MQBYTES(val,ELEMENT) \
289
+ }
290
+
291
+ #define WMQ_HASH2BOOL(HASH,KEY,ELEMENT) \
292
+ val = rb_hash_aref(hash, ID2SYM(ID_##KEY)); \
293
+ if (!NIL_P(val)) \
294
+ { \
295
+ if(TYPE(val) == T_TRUE) ELEMENT = 1; \
296
+ else if(TYPE(val) == T_FALSE) ELEMENT = 0; \
297
+ else \
298
+ rb_raise(rb_eTypeError, ":" #KEY \
299
+ " must be true or false"); \
300
+ }
301
+
302
+ #define IF_TRUE(KEY,DEFAULT) \
303
+ val = rb_hash_aref(hash, ID2SYM(ID_##KEY)); \
304
+ if (NIL_P(val)) \
305
+ { \
306
+ flag = DEFAULT; \
307
+ } \
308
+ else \
309
+ { \
310
+ if(TYPE(val) == T_TRUE) flag = 1; \
311
+ else if(TYPE(val) == T_FALSE) flag = 0; \
312
+ else \
313
+ rb_raise(rb_eTypeError, ":" #KEY \
314
+ " must be true or false"); \
315
+ } \
316
+ if (flag)
317
+
318
+ /* --------------------------------------------------
319
+ * Strip trailing nulls and spaces
320
+ * --------------------------------------------------*/
321
+ #define WMQ_MQCHARS2STR(ELEMENT, TARGET) \
322
+ size = sizeof(ELEMENT); \
323
+ length = 0; \
324
+ pChar = ELEMENT + size-1; \
325
+ for (i = size; i > 0; i--) \
326
+ { \
327
+ if (*pChar != ' ' && *pChar != 0) \
328
+ { \
329
+ length = i; \
330
+ break; \
331
+ } \
332
+ pChar--; \
333
+ } \
334
+ TARGET = rb_str_new(ELEMENT,length);
335
+
336
+ #define WMQ_MQCHARS2HASH(HASH,KEY,ELEMENT) \
337
+ WMQ_MQCHARS2STR(ELEMENT, str) \
338
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), str);
339
+
340
+ #define WMQ_MQLONG2HASH(HASH,KEY,ELEMENT) \
341
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), LONG2NUM(ELEMENT));
342
+
343
+ #define WMQ_MQCHAR2HASH(HASH,KEY,ELEMENT) \
344
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), LONG2NUM(ELEMENT));
345
+
346
+ /* --------------------------------------------------
347
+ * Trailing Spaces are important with binary fields
348
+ * --------------------------------------------------*/
349
+ #define WMQ_MQBYTES2STR(ELEMENT,TARGET) \
350
+ size = sizeof(ELEMENT); \
351
+ length = 0; \
352
+ pChar = ELEMENT + size-1; \
353
+ for (i = size; i > 0; i--) \
354
+ { \
355
+ if (*pChar != 0) \
356
+ { \
357
+ length = i; \
358
+ break; \
359
+ } \
360
+ pChar--; \
361
+ } \
362
+ TARGET = rb_str_new(ELEMENT,length);
363
+
364
+ #define WMQ_MQBYTES2HASH(HASH,KEY,ELEMENT) \
365
+ WMQ_MQBYTES2STR(ELEMENT, str) \
366
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), str);
367
+