WPBDC 2013.1.1

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/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
+ }