durable_rules 0.31.1

Sign up to get free protection for your applications and to get access to all the features.
data/src/rules/state.h ADDED
@@ -0,0 +1,57 @@
1
+
2
+ #define HASH_ID 5863474
3
+ #define HASH_SID 193505797
4
+ #define UNDEFINED_INDEX 0xFFFFFFFF
5
+ #define MAX_STATE_PROPERTIES 64
6
+ #define UNDEFINED_HASH_OFFSET 0xFFFFFFFF
7
+
8
+ typedef struct jsonProperty {
9
+ unsigned int hash;
10
+ unsigned char type;
11
+ unsigned char isMaterial;
12
+ unsigned short valueOffset;
13
+ unsigned short valueLength;
14
+ unsigned short nameOffset;
15
+ unsigned short nameLength;
16
+ union {
17
+ long i;
18
+ double d;
19
+ unsigned char b;
20
+ } value;
21
+ } jsonProperty;
22
+
23
+ typedef struct stateEntry {
24
+ unsigned int nextHashOffset;
25
+ unsigned int nextLruOffset;
26
+ unsigned int prevLruOffset;
27
+ unsigned int sidHash;
28
+ unsigned int bindingIndex;
29
+ unsigned int lastRefresh;
30
+ unsigned int propertiesLength;
31
+ jsonProperty properties[MAX_STATE_PROPERTIES];
32
+ char *state;
33
+ char *sid;
34
+ } stateEntry;
35
+
36
+ unsigned int djbHash(char *str, unsigned int len);
37
+ void rehydrateProperty(jsonProperty *property, char *state);
38
+ unsigned int refreshState(void *tree, char *sid);
39
+ unsigned int constructObject(char *parentName,
40
+ char *object,
41
+ char createHashtable,
42
+ unsigned int maxProperties,
43
+ jsonProperty *properties,
44
+ unsigned int *propertiesLength,
45
+ unsigned int *midIndex,
46
+ unsigned int *sidIndex,
47
+ char **next);
48
+ unsigned int resolveBinding(void *tree,
49
+ char *sid,
50
+ void **rulesBinding);
51
+ unsigned int fetchStateProperty(void *tree,
52
+ char *sid,
53
+ unsigned int propertyHash,
54
+ unsigned int maxTime,
55
+ unsigned char ignoreStaleState,
56
+ char **state,
57
+ jsonProperty **property);
@@ -0,0 +1,37 @@
1
+ require 'mkmf'
2
+
3
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
4
+
5
+ rules_include = File.join(File.dirname(__FILE__), %w{.. .. src rules})
6
+ rules_lib = File.join(File.dirname(__FILE__), %w{.. .. src rules})
7
+ hiredis_lib = File.join(File.dirname(__FILE__), %w{.. .. deps hiredis})
8
+
9
+ RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
10
+ make_program = $1 || ENV['make']
11
+ make_program ||= case RUBY_PLATFORM
12
+ when /mswin/
13
+ 'nmake'
14
+ when /(bsd|solaris)/
15
+ 'gmake'
16
+ else
17
+ 'make'
18
+ end
19
+
20
+ # Make sure hiredis is built...
21
+ Dir.chdir(hiredis_lib) do
22
+ success = system("#{make_program} static")
23
+ raise "Building hiredis failed" if !success
24
+ end
25
+
26
+ # Make sure rules is built...
27
+ Dir.chdir(rules_lib) do
28
+ success = system("#{make_program} static")
29
+ raise "Building rules failed" if !success
30
+ end
31
+
32
+ # Statically link to hiredis (mkmf can't do this for us)
33
+ $CFLAGS << " -I#{rules_lib} "
34
+ $LDFLAGS << " #{hiredis_lib}/libhiredis.a #{rules_lib}/rules.a"
35
+
36
+ have_func("rb_thread_fd_select")
37
+ create_makefile('src/rulesrb/rules')
@@ -0,0 +1,644 @@
1
+ #include <ruby.h>
2
+ #include <rules.h>
3
+
4
+ VALUE rulesModule = Qnil;
5
+
6
+ static VALUE rbCreateRuleset(VALUE self, VALUE name, VALUE rules, VALUE stateCacheSize) {
7
+ Check_Type(name, T_STRING);
8
+ Check_Type(rules, T_STRING);
9
+
10
+ void *output = NULL;
11
+ unsigned int result = createRuleset(&output, RSTRING_PTR(name), RSTRING_PTR(rules), FIX2INT(stateCacheSize));
12
+ if (result != RULES_OK) {
13
+ if (result == ERR_OUT_OF_MEMORY) {
14
+ rb_raise(rb_eNoMemError, "Out of memory");
15
+ } else {
16
+ rb_raise(rb_eException, "Could not create ruleset, error code: %d", result);
17
+ }
18
+ }
19
+
20
+ return INT2FIX(output);
21
+ }
22
+
23
+ static VALUE rbDeleteRuleset(VALUE self, VALUE handle) {
24
+ Check_Type(handle, T_FIXNUM);
25
+
26
+ unsigned int result = deleteRuleset((void *)FIX2LONG(handle));
27
+ if (result != RULES_OK) {
28
+ if (result == ERR_OUT_OF_MEMORY) {
29
+ rb_raise(rb_eNoMemError, "Out of memory");
30
+ } else {
31
+ rb_raise(rb_eException, "Could not delete ruleset, error code: %d", result);
32
+ }
33
+ }
34
+
35
+ return Qnil;
36
+ }
37
+
38
+ static VALUE rbBindRuleset(VALUE self, VALUE handle, VALUE host, VALUE port, VALUE password) {
39
+ Check_Type(handle, T_FIXNUM);
40
+ Check_Type(host, T_STRING);
41
+ Check_Type(port, T_FIXNUM);
42
+
43
+ unsigned int result;
44
+ if (TYPE(password) == T_STRING) {
45
+ result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), RSTRING_PTR(password));
46
+ } else if (TYPE(password) == T_NIL) {
47
+ result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), NULL);
48
+ } else {
49
+ rb_raise(rb_eTypeError, "Wrong argument type for password");
50
+ }
51
+
52
+ if (result != RULES_OK) {
53
+ if (result == ERR_OUT_OF_MEMORY) {
54
+ rb_raise(rb_eNoMemError, "Out of memory");
55
+ } else {
56
+ rb_raise(rb_eException, "Could not create connection, error code: %d", result);
57
+ }
58
+ }
59
+
60
+ return Qnil;
61
+ }
62
+
63
+ static VALUE rbComplete(VALUE self, VALUE rulesBinding, VALUE replyCount) {
64
+ Check_Type(rulesBinding, T_FIXNUM);
65
+ Check_Type(replyCount, T_FIXNUM);
66
+
67
+ unsigned int result = complete((void *)FIX2LONG(rulesBinding), FIX2LONG(replyCount));
68
+ if (result != RULES_OK) {
69
+ if (result == ERR_OUT_OF_MEMORY) {
70
+ rb_raise(rb_eNoMemError, "Out of memory");
71
+ } else {
72
+ rb_raise(rb_eException, "Could not complete action, error code: %d", result);
73
+ }
74
+ }
75
+
76
+ return Qnil;
77
+ }
78
+
79
+ static VALUE rbStartAssertEvent(VALUE self, VALUE handle, VALUE event) {
80
+ Check_Type(handle, T_FIXNUM);
81
+ Check_Type(event, T_STRING);
82
+
83
+ unsigned int replyCount;
84
+ void *rulesBinding = NULL;
85
+ unsigned int result = startAssertEvent((void *)FIX2LONG(handle), RSTRING_PTR(event), &rulesBinding, &replyCount);
86
+ if (result == RULES_OK) {
87
+ VALUE output = rb_ary_new();
88
+ rb_ary_push(output, INT2FIX(rulesBinding));
89
+ rb_ary_push(output, INT2FIX(replyCount));
90
+ return output;
91
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
92
+ VALUE output = rb_ary_new();
93
+ rb_ary_push(output, INT2FIX(0));
94
+ rb_ary_push(output, INT2FIX(0));
95
+ return output;
96
+ } else {
97
+ if (result == ERR_OUT_OF_MEMORY) {
98
+ rb_raise(rb_eNoMemError, "Out of memory");
99
+ } else {
100
+ rb_raise(rb_eException, "Could not assert event, error code: %d", result);
101
+ }
102
+ }
103
+
104
+ return Qnil;
105
+ }
106
+
107
+ static VALUE rbAssertEvent(VALUE self, VALUE handle, VALUE event) {
108
+ Check_Type(handle, T_FIXNUM);
109
+ Check_Type(event, T_STRING);
110
+
111
+ unsigned int result = assertEvent((void *)FIX2LONG(handle), RSTRING_PTR(event));
112
+ if (result == RULES_OK) {
113
+ return INT2FIX(1);
114
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
115
+ return INT2FIX(0);
116
+ } else {
117
+ if (result == ERR_OUT_OF_MEMORY) {
118
+ rb_raise(rb_eNoMemError, "Out of memory");
119
+ } else {
120
+ rb_raise(rb_eException, "Could not assert event, error code: %d", result);
121
+ }
122
+ }
123
+
124
+ return Qnil;
125
+ }
126
+
127
+ static VALUE rbStartAssertEvents(VALUE self, VALUE handle, VALUE events) {
128
+ Check_Type(handle, T_FIXNUM);
129
+ Check_Type(events, T_STRING);
130
+
131
+ unsigned int *results = NULL;
132
+ unsigned int resultsLength = 0;
133
+ unsigned int replyCount;
134
+ void *rulesBinding = NULL;
135
+ unsigned int result = startAssertEvents((void *)FIX2LONG(handle), RSTRING_PTR(events), &resultsLength, &results, &rulesBinding, &replyCount);
136
+ if (result == RULES_OK) {
137
+ if (results) {
138
+ free(results);
139
+ }
140
+ VALUE output = rb_ary_new();
141
+ rb_ary_push(output, INT2FIX(rulesBinding));
142
+ rb_ary_push(output, INT2FIX(replyCount));
143
+ return output;
144
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
145
+ VALUE output = rb_ary_new();
146
+ rb_ary_push(output, INT2FIX(0));
147
+ rb_ary_push(output, INT2FIX(0));
148
+ return output;
149
+ } else {
150
+ if (result == ERR_OUT_OF_MEMORY) {
151
+ rb_raise(rb_eNoMemError, "Out of memory");
152
+ } else {
153
+ if (results) {
154
+ free(results);
155
+ }
156
+ rb_raise(rb_eException, "Could not assert events, error code: %d", result);
157
+ }
158
+ }
159
+
160
+ return Qnil;
161
+ }
162
+
163
+ static VALUE rbAssertEvents(VALUE self, VALUE handle, VALUE events) {
164
+ Check_Type(handle, T_FIXNUM);
165
+ Check_Type(events, T_STRING);
166
+
167
+ unsigned int *results = NULL;
168
+ unsigned int resultsLength = 0;
169
+ unsigned int result = assertEvents((void *)FIX2LONG(handle), RSTRING_PTR(events), &resultsLength, &results);
170
+ if (result == RULES_OK) {
171
+ if (results) {
172
+ free(results);
173
+ }
174
+ return INT2FIX(resultsLength);
175
+ } else {
176
+ if (result == ERR_OUT_OF_MEMORY) {
177
+ rb_raise(rb_eNoMemError, "Out of memory");
178
+ } else {
179
+ if (results) {
180
+ free(results);
181
+ }
182
+ rb_raise(rb_eException, "Could not assert events, error code: %d", result);
183
+ }
184
+ }
185
+
186
+ return Qnil;
187
+ }
188
+
189
+ static VALUE rbRetractEvent(VALUE self, VALUE handle, VALUE event) {
190
+ Check_Type(handle, T_FIXNUM);
191
+ Check_Type(event, T_STRING);
192
+
193
+ unsigned int result = retractEvent((void *)FIX2LONG(handle), RSTRING_PTR(event));
194
+ if (result == RULES_OK) {
195
+ return INT2FIX(1);
196
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
197
+ return INT2FIX(0);
198
+ } else {
199
+ if (result == ERR_OUT_OF_MEMORY) {
200
+ rb_raise(rb_eNoMemError, "Out of memory");
201
+ } else {
202
+ rb_raise(rb_eException, "Could not retract event, error code: %d", result);
203
+ }
204
+ }
205
+
206
+ return Qnil;
207
+ }
208
+
209
+ static VALUE rbStartAssertFact(VALUE self, VALUE handle, VALUE fact) {
210
+ Check_Type(handle, T_FIXNUM);
211
+ Check_Type(fact, T_STRING);
212
+
213
+ unsigned int replyCount;
214
+ void *rulesBinding = NULL;
215
+ unsigned int result = startAssertFact((void *)FIX2LONG(handle), RSTRING_PTR(fact), &rulesBinding, &replyCount);
216
+ if (result == RULES_OK) {
217
+ VALUE output = rb_ary_new();
218
+ rb_ary_push(output, INT2FIX(rulesBinding));
219
+ rb_ary_push(output, INT2FIX(replyCount));
220
+ return output;
221
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
222
+ VALUE output = rb_ary_new();
223
+ rb_ary_push(output, INT2FIX(0));
224
+ rb_ary_push(output, INT2FIX(0));
225
+ return output;
226
+ } else {
227
+ if (result == ERR_OUT_OF_MEMORY) {
228
+ rb_raise(rb_eNoMemError, "Out of memory");
229
+ } else {
230
+ rb_raise(rb_eException, "Could not assert fact, error code: %d", result);
231
+ }
232
+ }
233
+
234
+ return Qnil;
235
+ }
236
+
237
+ static VALUE rbAssertFact(VALUE self, VALUE handle, VALUE fact) {
238
+ Check_Type(handle, T_FIXNUM);
239
+ Check_Type(fact, T_STRING);
240
+
241
+ unsigned int result = assertFact((void *)FIX2LONG(handle), RSTRING_PTR(fact));
242
+ if (result == RULES_OK) {
243
+ return INT2FIX(1);
244
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
245
+ return INT2FIX(0);
246
+ } else {
247
+ if (result == ERR_OUT_OF_MEMORY) {
248
+ rb_raise(rb_eNoMemError, "Out of memory");
249
+ } else {
250
+ rb_raise(rb_eException, "Could not assert fact, error code: %d", result);
251
+ }
252
+ }
253
+
254
+ return Qnil;
255
+ }
256
+
257
+ static VALUE rbStartAssertFacts(VALUE self, VALUE handle, VALUE facts) {
258
+ Check_Type(handle, T_FIXNUM);
259
+ Check_Type(facts, T_STRING);
260
+
261
+ unsigned int *results = NULL;
262
+ unsigned int resultsLength = 0;
263
+ unsigned int replyCount;
264
+ void *rulesBinding = NULL;
265
+ unsigned int result = startAssertFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results, &rulesBinding, &replyCount);
266
+ if (result == RULES_OK) {
267
+ if (results) {
268
+ free(results);
269
+ }
270
+ VALUE output = rb_ary_new();
271
+ rb_ary_push(output, INT2FIX(rulesBinding));
272
+ rb_ary_push(output, INT2FIX(replyCount));
273
+ return output;
274
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
275
+ VALUE output = rb_ary_new();
276
+ rb_ary_push(output, INT2FIX(0));
277
+ rb_ary_push(output, INT2FIX(0));
278
+ return output;
279
+ } else {
280
+ if (result == ERR_OUT_OF_MEMORY) {
281
+ rb_raise(rb_eNoMemError, "Out of memory");
282
+ } else {
283
+ if (results) {
284
+ free(results);
285
+ }
286
+ rb_raise(rb_eException, "Could not assert facts, error code: %d", result);
287
+ }
288
+ }
289
+
290
+ return Qnil;
291
+ }
292
+
293
+ static VALUE rbAssertFacts(VALUE self, VALUE handle, VALUE facts) {
294
+ Check_Type(handle, T_FIXNUM);
295
+ Check_Type(facts, T_STRING);
296
+
297
+ unsigned int *results = NULL;
298
+ unsigned int resultsLength = 0;
299
+ unsigned int result = assertFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results);
300
+ if (result == RULES_OK) {
301
+ if (results) {
302
+ free(results);
303
+ }
304
+ return INT2FIX(resultsLength);
305
+ } else {
306
+ if (result == ERR_OUT_OF_MEMORY) {
307
+ rb_raise(rb_eNoMemError, "Out of memory");
308
+ } else {
309
+ if (results) {
310
+ free(results);
311
+ }
312
+ rb_raise(rb_eException, "Could not assert facts, error code: %d", result);
313
+ }
314
+ }
315
+
316
+ return Qnil;
317
+ }
318
+
319
+ static VALUE rbStartRetractFact(VALUE self, VALUE handle, VALUE fact) {
320
+ Check_Type(handle, T_FIXNUM);
321
+ Check_Type(fact, T_STRING);
322
+
323
+ unsigned int replyCount;
324
+ void *rulesBinding = NULL;
325
+ unsigned int result = startRetractFact((void *)FIX2LONG(handle), RSTRING_PTR(fact), &rulesBinding, &replyCount);
326
+ if (result == RULES_OK) {
327
+ VALUE output = rb_ary_new();
328
+ rb_ary_push(output, INT2FIX(rulesBinding));
329
+ rb_ary_push(output, INT2FIX(replyCount));
330
+ return output;
331
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
332
+ VALUE output = rb_ary_new();
333
+ rb_ary_push(output, INT2FIX(0));
334
+ rb_ary_push(output, INT2FIX(0));
335
+ return output;
336
+ } else {
337
+ if (result == ERR_OUT_OF_MEMORY) {
338
+ rb_raise(rb_eNoMemError, "Out of memory");
339
+ } else {
340
+ rb_raise(rb_eException, "Could not retract fact, error code: %d", result);
341
+ }
342
+ }
343
+
344
+ return Qnil;
345
+ }
346
+
347
+ static VALUE rbRetractFact(VALUE self, VALUE handle, VALUE fact) {
348
+ Check_Type(handle, T_FIXNUM);
349
+ Check_Type(fact, T_STRING);
350
+
351
+ unsigned int result = retractFact((void *)FIX2LONG(handle), RSTRING_PTR(fact));
352
+ if (result == RULES_OK) {
353
+ return INT2FIX(1);
354
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
355
+ return INT2FIX(0);
356
+ } else {
357
+ if (result == ERR_OUT_OF_MEMORY) {
358
+ rb_raise(rb_eNoMemError, "Out of memory");
359
+ } else {
360
+ rb_raise(rb_eException, "Could not retract fact, error code: %d", result);
361
+ }
362
+ }
363
+
364
+ return Qnil;
365
+ }
366
+
367
+ static VALUE rbStartRetractFacts(VALUE self, VALUE handle, VALUE facts) {
368
+ Check_Type(handle, T_FIXNUM);
369
+ Check_Type(facts, T_STRING);
370
+
371
+ unsigned int *results = NULL;
372
+ unsigned int resultsLength = 0;
373
+ unsigned int replyCount;
374
+ void *rulesBinding = NULL;
375
+ unsigned int result = startRetractFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results, &rulesBinding, &replyCount);
376
+ if (result == RULES_OK) {
377
+ if (results) {
378
+ free(results);
379
+ }
380
+ VALUE output = rb_ary_new();
381
+ rb_ary_push(output, INT2FIX(rulesBinding));
382
+ rb_ary_push(output, INT2FIX(replyCount));
383
+ return output;
384
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
385
+ VALUE output = rb_ary_new();
386
+ rb_ary_push(output, INT2FIX(0));
387
+ rb_ary_push(output, INT2FIX(0));
388
+ return output;
389
+ } else {
390
+ if (result == ERR_OUT_OF_MEMORY) {
391
+ rb_raise(rb_eNoMemError, "Out of memory");
392
+ } else {
393
+ if (results) {
394
+ free(results);
395
+ }
396
+ rb_raise(rb_eException, "Could not retract facts, error code: %d", result);
397
+ }
398
+ }
399
+
400
+ return Qnil;
401
+ }
402
+
403
+ static VALUE rbRetractFacts(VALUE self, VALUE handle, VALUE facts) {
404
+ Check_Type(handle, T_FIXNUM);
405
+ Check_Type(facts, T_STRING);
406
+
407
+ unsigned int *results = NULL;
408
+ unsigned int resultsLength = 0;
409
+ unsigned int result = retractFacts((void *)FIX2LONG(handle), RSTRING_PTR(facts), &resultsLength, &results);
410
+ if (result == RULES_OK) {
411
+ if (results) {
412
+ free(results);
413
+ }
414
+ return INT2FIX(resultsLength);
415
+ } else {
416
+ if (result == ERR_OUT_OF_MEMORY) {
417
+ rb_raise(rb_eNoMemError, "Out of memory");
418
+ } else {
419
+ if (results) {
420
+ free(results);
421
+ }
422
+ rb_raise(rb_eException, "Could not retract facts, error code: %d", result);
423
+ }
424
+ }
425
+
426
+ return Qnil;
427
+ }
428
+
429
+ static VALUE rbAssertState(VALUE self, VALUE handle, VALUE state) {
430
+ Check_Type(handle, T_FIXNUM);
431
+ Check_Type(state, T_STRING);
432
+
433
+ unsigned int result = assertState((void *)FIX2LONG(handle), RSTRING_PTR(state));
434
+ if (result == RULES_OK) {
435
+ return INT2FIX(1);
436
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
437
+ return INT2FIX(0);
438
+ } else {
439
+ if (result == ERR_OUT_OF_MEMORY) {
440
+ rb_raise(rb_eNoMemError, "Out of memory");
441
+ } else {
442
+ rb_raise(rb_eException, "Could not assert event, error code: %d", result);
443
+ }
444
+ }
445
+
446
+ return Qnil;
447
+ }
448
+
449
+ static VALUE rbStartUpdateState(VALUE self, VALUE handle, VALUE actionHandle, VALUE state) {
450
+ Check_Type(handle, T_FIXNUM);
451
+ Check_Type(actionHandle, T_FIXNUM);
452
+ Check_Type(state, T_STRING);
453
+
454
+ unsigned int replyCount;
455
+ void *rulesBinding = NULL;
456
+ unsigned int result = startUpdateState((void *)FIX2LONG(handle), (void *)FIX2LONG(actionHandle), RSTRING_PTR(state), &rulesBinding, &replyCount);
457
+ if (result == RULES_OK) {
458
+ VALUE output = rb_ary_new();
459
+ rb_ary_push(output, INT2FIX(rulesBinding));
460
+ rb_ary_push(output, INT2FIX(replyCount));
461
+ return output;
462
+ } else if (result == ERR_EVENT_NOT_HANDLED) {
463
+ VALUE output = rb_ary_new();
464
+ rb_ary_push(output, INT2FIX(0));
465
+ rb_ary_push(output, INT2FIX(0));
466
+ return output;
467
+ } else {
468
+ if (result == ERR_OUT_OF_MEMORY) {
469
+ rb_raise(rb_eNoMemError, "Out of memory");
470
+ } else {
471
+ rb_raise(rb_eException, "Could not start update state, error code: %d", result);
472
+ }
473
+ }
474
+
475
+ return Qnil;
476
+ }
477
+
478
+ static VALUE rbStartAction(VALUE self, VALUE handle) {
479
+ Check_Type(handle, T_FIXNUM);
480
+
481
+ char *state;
482
+ char *messages;
483
+ void *actionHandle;
484
+ void *actionBinding;
485
+ unsigned int result = startAction((void *)FIX2LONG(handle), &state, &messages, &actionHandle, &actionBinding);
486
+ if (result == ERR_NO_ACTION_AVAILABLE) {
487
+ return Qnil;
488
+ } else if (result != RULES_OK) {
489
+ if (result == ERR_OUT_OF_MEMORY) {
490
+ rb_raise(rb_eNoMemError, "Out of memory");
491
+ } else {
492
+ rb_raise(rb_eException, "Could not start action, error code: %d", result);
493
+ }
494
+ }
495
+
496
+ VALUE output = rb_ary_new();
497
+ rb_ary_push(output, rb_str_new2(state));
498
+ rb_ary_push(output, rb_str_new2(messages));
499
+ rb_ary_push(output, INT2FIX(actionHandle));
500
+ rb_ary_push(output, INT2FIX(actionBinding));
501
+ return output;
502
+ }
503
+
504
+ static VALUE rbCompleteAction(VALUE self, VALUE handle, VALUE actionHandle, VALUE state) {
505
+ Check_Type(handle, T_FIXNUM);
506
+ Check_Type(actionHandle, T_FIXNUM);
507
+ Check_Type(state, T_STRING);
508
+
509
+ unsigned int result = completeAction((void *)FIX2LONG(handle), (void *)FIX2LONG(actionHandle), RSTRING_PTR(state));
510
+ if (result != RULES_OK) {
511
+ if (result == ERR_OUT_OF_MEMORY) {
512
+ rb_raise(rb_eNoMemError, "Out of memory");
513
+ } else {
514
+ rb_raise(rb_eException, "Could not complete action, error code: %d", result);
515
+ }
516
+ }
517
+
518
+ return Qnil;
519
+ }
520
+
521
+ static VALUE rbCompleteAndStartAction(VALUE self, VALUE handle, VALUE expectedReplies, VALUE actionHandle) {
522
+ Check_Type(handle, T_FIXNUM);
523
+ Check_Type(expectedReplies, T_FIXNUM);
524
+ Check_Type(actionHandle, T_FIXNUM);
525
+
526
+ char *messages;
527
+ unsigned int result = completeAndStartAction((void *)FIX2LONG(handle), FIX2LONG(expectedReplies), (void *)FIX2LONG(actionHandle), &messages);
528
+ if (result == ERR_NO_ACTION_AVAILABLE) {
529
+ return Qnil;
530
+ } else if (result != RULES_OK) {
531
+ if (result == ERR_OUT_OF_MEMORY) {
532
+ rb_raise(rb_eNoMemError, "Out of memory");
533
+ } else {
534
+ rb_raise(rb_eException, "Could not complete and start action, error code: %d", result);
535
+ }
536
+ }
537
+
538
+ return rb_str_new2(messages);
539
+ }
540
+
541
+
542
+ static VALUE rbAbandonAction(VALUE self, VALUE handle, VALUE actionHandle) {
543
+ Check_Type(handle, T_FIXNUM);
544
+ Check_Type(actionHandle, T_FIXNUM);
545
+
546
+ unsigned int result = abandonAction((void *)FIX2LONG(handle), (void *)FIX2LONG(actionHandle));
547
+ if (result != RULES_OK) {
548
+ if (result == ERR_OUT_OF_MEMORY) {
549
+ rb_raise(rb_eNoMemError, "Out of memory");
550
+ } else {
551
+ rb_raise(rb_eException, "Could not abandon action, error code: %d", result);
552
+ }
553
+ }
554
+
555
+ return Qnil;
556
+ }
557
+
558
+ static VALUE rbStartTimer(VALUE self, VALUE handle, VALUE sid, VALUE duration, VALUE timer) {
559
+ Check_Type(handle, T_FIXNUM);
560
+ Check_Type(sid, T_STRING);
561
+ Check_Type(duration, T_FIXNUM);
562
+ Check_Type(timer, T_STRING);
563
+
564
+ unsigned int result = startTimer((void *)FIX2LONG(handle), RSTRING_PTR(sid), FIX2UINT(duration), RSTRING_PTR(timer));
565
+ if (result != RULES_OK) {
566
+ if (result == ERR_OUT_OF_MEMORY) {
567
+ rb_raise(rb_eNoMemError, "Out of memory");
568
+ } else {
569
+ rb_raise(rb_eException, "Could not start timer, error code: %d", result);
570
+ }
571
+ }
572
+
573
+ return Qnil;
574
+ }
575
+
576
+ static VALUE rbAssertTimers(VALUE self, VALUE handle) {
577
+ Check_Type(handle, T_FIXNUM);
578
+
579
+ unsigned int result = assertTimers((void *)FIX2LONG(handle));
580
+ if (result == RULES_OK) {
581
+ return INT2FIX(1);
582
+ } else if (result == ERR_NO_TIMERS_AVAILABLE) {
583
+ return INT2FIX(0);
584
+ } else {
585
+ if (result == ERR_OUT_OF_MEMORY) {
586
+ rb_raise(rb_eNoMemError, "Out of memory");
587
+ } else {
588
+ rb_raise(rb_eException, "Could not assert timers, error code: %d", result);
589
+ }
590
+ }
591
+
592
+ return Qnil;
593
+ }
594
+
595
+ static VALUE rbGetState(VALUE self, VALUE handle, VALUE sid) {
596
+ Check_Type(handle, T_FIXNUM);
597
+ Check_Type(sid, T_STRING);
598
+
599
+ char *state;
600
+ unsigned int result = getState((void *)FIX2LONG(handle), RSTRING_PTR(sid), &state);
601
+ if (result != RULES_OK) {
602
+ if (result == ERR_OUT_OF_MEMORY) {
603
+ rb_raise(rb_eNoMemError, "Out of memory");
604
+ } else {
605
+ rb_raise(rb_eException, "Could not get state, error code: %d", result);
606
+ }
607
+ }
608
+
609
+ VALUE output = rb_str_new2(state);
610
+ free(state);
611
+ return output;
612
+ }
613
+
614
+ void Init_rules() {
615
+ rulesModule = rb_define_module("Rules");
616
+ rb_define_singleton_method(rulesModule, "create_ruleset", rbCreateRuleset, 3);
617
+ rb_define_singleton_method(rulesModule, "delete_ruleset", rbDeleteRuleset, 1);
618
+ rb_define_singleton_method(rulesModule, "bind_ruleset", rbBindRuleset, 4);
619
+ rb_define_singleton_method(rulesModule, "complete", rbComplete, 2);
620
+ rb_define_singleton_method(rulesModule, "assert_event", rbAssertEvent, 2);
621
+ rb_define_singleton_method(rulesModule, "start_assert_event", rbStartAssertEvent, 2);
622
+ rb_define_singleton_method(rulesModule, "assert_events", rbAssertEvents, 2);
623
+ rb_define_singleton_method(rulesModule, "start_assert_events", rbStartAssertEvents, 2);
624
+ rb_define_singleton_method(rulesModule, "retract_event", rbRetractEvent, 2);
625
+ rb_define_singleton_method(rulesModule, "start_assert_fact", rbStartAssertFact, 2);
626
+ rb_define_singleton_method(rulesModule, "assert_fact", rbAssertFact, 2);
627
+ rb_define_singleton_method(rulesModule, "start_assert_facts", rbStartAssertFacts, 2);
628
+ rb_define_singleton_method(rulesModule, "assert_facts", rbAssertFacts, 2);
629
+ rb_define_singleton_method(rulesModule, "start_retract_fact", rbStartRetractFact, 2);
630
+ rb_define_singleton_method(rulesModule, "retract_fact", rbRetractFact, 2);
631
+ rb_define_singleton_method(rulesModule, "start_retract_facts", rbStartRetractFacts, 2);
632
+ rb_define_singleton_method(rulesModule, "retract_facts", rbRetractFacts, 2);
633
+ rb_define_singleton_method(rulesModule, "assert_state", rbAssertState, 2);
634
+ rb_define_singleton_method(rulesModule, "start_update_state", rbStartUpdateState, 3);
635
+ rb_define_singleton_method(rulesModule, "start_action", rbStartAction, 1);
636
+ rb_define_singleton_method(rulesModule, "complete_action", rbCompleteAction, 3);
637
+ rb_define_singleton_method(rulesModule, "complete_and_start_action", rbCompleteAndStartAction, 3);
638
+ rb_define_singleton_method(rulesModule, "abandon_action", rbAbandonAction, 2);
639
+ rb_define_singleton_method(rulesModule, "start_timer", rbStartTimer, 4);
640
+ rb_define_singleton_method(rulesModule, "assert_timers", rbAssertTimers, 1);
641
+ rb_define_singleton_method(rulesModule, "get_state", rbGetState, 2);
642
+ }
643
+
644
+