WPBDC 2013.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/WPBDC/WPBDC.c ADDED
@@ -0,0 +1,237 @@
1
+ #include "internal.h"
2
+
3
+ #define INIT_STRING_FROM_VALUE(String, Value) \
4
+ STRING String[1] = {{ RSTRING_PTR(Value), RSTRING_LEN(Value) }}
5
+
6
+ static VALUE rb_api_endecrypt(VALUE self, VALUE bridge_as_string)
7
+ #define ARGC_endecrypt 1
8
+ {
9
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
10
+ endecrypt(bridge_internal_string);
11
+ return bridge_as_string;
12
+ }
13
+
14
+ /*
15
+ struct analysis_result_t {
16
+ TVersion version; // WPBDC version of parsed bridge.
17
+ char scenario_id[SCENARIO_ID_SIZE]; // WPBDC scenario ID.
18
+ char scenario_number[SCENARIO_NUMBER_SIZE]; // WPBDC scenario number.
19
+ TTestStatus test_status; // Load test flag from uploaded file.
20
+ int status; // Summary status
21
+ TBridgeError error; // Bridge error condition.
22
+ double cost; // Cost in dollars.
23
+ char hash[HASH_SIZE]; // Bridge hash value.
24
+ };
25
+ */
26
+
27
+ static VALUE symbol(char *name)
28
+ {
29
+ return ID2SYM(rb_intern(name));
30
+ }
31
+
32
+ static void add_analysis_to_hash(VALUE hash, struct analysis_result_t *result)
33
+ {
34
+ char hex_hash[2 * HASH_SIZE + 1];
35
+
36
+ rb_hash_aset(hash, symbol("version"), INT2FIX(result->version));
37
+ rb_hash_aset(hash, symbol("scenario"), rb_str_new(result->scenario_id, SCENARIO_ID_SIZE));
38
+ rb_hash_aset(hash, symbol("scenario_number"), rb_str_new(result->scenario_number, SCENARIO_NUMBER_SIZE));
39
+ rb_hash_aset(hash, symbol("test_status"), INT2FIX(result->test_status));
40
+ rb_hash_aset(hash, symbol("status"), INT2FIX(result->status));
41
+ rb_hash_aset(hash, symbol("error"), INT2FIX(result->error));
42
+ rb_hash_aset(hash, symbol("score"), rb_float_new(result->cost));
43
+ if (result->status == BRIDGE_OK || result->status == BRIDGE_FAILEDTEST) {
44
+ rb_hash_aset(hash, symbol("hash"),
45
+ rb_str_new(hex_str(result->hash, HASH_SIZE, hex_hash), 2 * HASH_SIZE));
46
+ }
47
+ }
48
+
49
+ static VALUE rb_api_analyze(VALUE self, VALUE bridge_as_string)
50
+ #define ARGC_analyze 1
51
+ {
52
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
53
+ struct analysis_result_t result[1];
54
+ VALUE hash = rb_hash_new();
55
+ analyze(bridge_internal_string, result);
56
+ add_analysis_to_hash(hash, result);
57
+ return hash;
58
+ }
59
+
60
+ static VALUE rb_api_are_same(VALUE self, VALUE bridge_as_string_a, VALUE bridge_as_string_b)
61
+ #define ARGC_are_same 2
62
+ {
63
+ INIT_STRING_FROM_VALUE(bridge_internal_string_a, bridge_as_string_a);
64
+ INIT_STRING_FROM_VALUE(bridge_internal_string_b, bridge_as_string_b);
65
+ int cmp = compare(bridge_internal_string_a, bridge_internal_string_b);
66
+ return (cmp < 0) ? Qnil : (cmp > 0) ? Qtrue : Qfalse;
67
+ }
68
+
69
+ static VALUE c_str_to_value(char *s)
70
+ {
71
+ if (s) {
72
+ VALUE value = rb_str_new2(s);
73
+ Safefree(s);
74
+ return value;
75
+ }
76
+ return Qnil;
77
+ }
78
+
79
+ static VALUE rb_api_variant(VALUE self, VALUE bridge_as_string, VALUE seed)
80
+ #define ARGC_variant 2
81
+ {
82
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
83
+ char *result = variant(bridge_internal_string, FIX2INT(seed));
84
+ return c_str_to_value(result);
85
+ }
86
+
87
+ static VALUE rb_api_failed_variant(VALUE self, VALUE bridge_as_string, VALUE seed)
88
+ #define ARGC_failed_variant 2
89
+ {
90
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
91
+ char *result = failed_variant(bridge_internal_string, FIX2INT(seed));
92
+ return c_str_to_value(result);
93
+ }
94
+
95
+ static VALUE rb_api_perturbation(VALUE self, VALUE bridge_as_string, VALUE seed, VALUE n_joints, VALUE n_members)
96
+ #define ARGC_perturbation 4
97
+ {
98
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
99
+ char *result = perturbation(bridge_internal_string, FIX2INT(seed), FIX2INT(n_joints), FIX2INT(n_members));
100
+ return c_str_to_value(result);
101
+ }
102
+
103
+ static VALUE rb_api_sketch(VALUE self, VALUE bridge_as_string, VALUE width, VALUE height)
104
+ #define ARGC_sketch 3
105
+ {
106
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
107
+ COMPRESSED_IMAGE compressed_image[1];
108
+ struct analysis_result_t result[1];
109
+ VALUE hash = rb_hash_new();
110
+
111
+ init_compressed_image(compressed_image);
112
+ sketch(bridge_internal_string, width, height, compressed_image, result);
113
+
114
+ /*
115
+ struct analysis_result_t {
116
+ TVersion version; // WPBDC version of parsed bridge.
117
+ char scenario_id[SCENARIO_ID_SIZE]; // WPBDC scenario ID.
118
+ char scenario_number[SCENARIO_NUMBER_SIZE]; // WPBDC scenario number.
119
+ TTestStatus test_status; // Load test flag from uploaded file.
120
+ int status; // Summary status
121
+ TBridgeError error; // Bridge error condition.
122
+ double cost; // Cost in dollars.
123
+ char hash[HASH_SIZE]; // Bridge hash value.
124
+ };
125
+ */
126
+ add_analysis_to_hash(hash, result);
127
+ if (result->status == BRIDGE_OK) {
128
+ rb_hash_aset(hash, rb_str_new2("image"), rb_str_new(compressed_image->data, compressed_image->filled));
129
+ clear_compressed_image(compressed_image);
130
+ }
131
+ return hash;
132
+ }
133
+
134
+ static VALUE rb_api_analysis_table(VALUE self, VALUE bridge_as_string)
135
+ #define ARGC_analysis_table 1
136
+ {
137
+ INIT_STRING_FROM_VALUE(bridge_internal_string, bridge_as_string);
138
+ char *result = analysis_table(bridge_internal_string);
139
+ return c_str_to_value(result);
140
+ }
141
+
142
+ static VALUE rb_api_local_contest_number_to_id(VALUE self, VALUE number_as_string)
143
+ #define ARGC_local_contest_number_to_id 1
144
+ {
145
+ INIT_STRING_FROM_VALUE(number_internal_string, number_as_string);
146
+ char * result = get_local_contest_number(number_internal_string);
147
+ // Don't use c_str_to_value here because result is static.
148
+ return result ? rb_str_new2(result) : Qnil;
149
+ }
150
+
151
+
152
+ #define FUNCTION(Name) { #Name, rb_api_ ## Name, ARGC_ ## Name }
153
+
154
+ static struct ft_entry {
155
+ char *name;
156
+ VALUE (*func)();
157
+ int argc;
158
+ } function_table[] = {
159
+ FUNCTION(endecrypt),
160
+ FUNCTION(analyze),
161
+ FUNCTION(are_same),
162
+ FUNCTION(variant),
163
+ FUNCTION(failed_variant),
164
+ FUNCTION(perturbation),
165
+ FUNCTION(sketch),
166
+ FUNCTION(analysis_table),
167
+ FUNCTION(local_contest_number_to_id),
168
+ };
169
+
170
+ #define INT_CONST(Name) { #Name, Name }
171
+
172
+ static struct ict_entry {
173
+ char *name;
174
+ int val;
175
+ } int_const_table[] = {
176
+ INT_CONST(BRIDGE_OK),
177
+ INT_CONST(BRIDGE_MALFORMED),
178
+ INT_CONST(BRIDGE_WRONGVERSION),
179
+ INT_CONST(BRIDGE_FAILEDTEST),
180
+
181
+ INT_CONST(MAX_JOINTS),
182
+ INT_CONST(MAX_MEMBERS),
183
+
184
+ // Size of hash value in bytes.
185
+ INT_CONST(HASH_SIZE),
186
+
187
+ // Possible errors during bridge parsing.
188
+ INT_CONST(BridgeNoError),
189
+ INT_CONST(BridgeMissingData),
190
+ INT_CONST(BridgeSyntax),
191
+ INT_CONST(BridgeMissingHeader),
192
+ INT_CONST(BridgeBadHeader),
193
+ INT_CONST(BridgeMissingTestStatus),
194
+ INT_CONST(BridgeBadTestStatus),
195
+ INT_CONST(BridgeBadScenario),
196
+ INT_CONST(BridgeBadNDesignIterations),
197
+ INT_CONST(BridgeTooManyElements),
198
+ INT_CONST(BridgeBadJointBanner),
199
+ INT_CONST(BridgeTooFewJoints),
200
+ INT_CONST(BridgeWrongPrescribedJoints),
201
+ INT_CONST(BridgeBadMemberBanner),
202
+ INT_CONST(BridgeTooFewMembers),
203
+ INT_CONST(BridgeBadLabelPos),
204
+ INT_CONST(BridgeExtraJunk),
205
+ INT_CONST(BridgeDupJoints),
206
+ INT_CONST(BridgeDupMembers),
207
+ INT_CONST(BridgeJointOnMember),
208
+ INT_CONST(BridgeBadLoadScenario),
209
+ INT_CONST(BridgeBadChar),
210
+
211
+ // Test status flag values read from bridge file.
212
+ INT_CONST(NullTestStatus),
213
+ INT_CONST(Unrecorded),
214
+ INT_CONST(Untested),
215
+ INT_CONST(Failed),
216
+ INT_CONST(Passed),
217
+
218
+ INT_CONST(SCENARIO_ID_SIZE),
219
+ INT_CONST(SCENARIO_NUMBER_SIZE),
220
+ };
221
+
222
+ void Init_WPBDC(void)
223
+ {
224
+ int i;
225
+ VALUE module;
226
+
227
+ module = rb_define_module("WPBDC");
228
+
229
+ for (i = 0; i < STATIC_ARRAY_SIZE(function_table); i++) {
230
+ struct ft_entry *e = function_table + i;
231
+ rb_define_module_function(module, e->name, e->func, e->argc);
232
+ }
233
+ for (i = 0; i < STATIC_ARRAY_SIZE(int_const_table); i++) {
234
+ struct ict_entry *e = int_const_table + i;
235
+ rb_define_const(module, e->name, INT2FIX(e->val));
236
+ }
237
+ }