couchbase 1.3.4-x64-mingw32
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +22 -0
- data/.yardopts +5 -0
- data/CONTRIBUTING.markdown +75 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/Makefile +3 -0
- data/README.markdown +649 -0
- data/RELEASE_NOTES.markdown +796 -0
- data/Rakefile +20 -0
- data/couchbase.gemspec +49 -0
- data/examples/chat-em/Gemfile +7 -0
- data/examples/chat-em/README.markdown +45 -0
- data/examples/chat-em/server.rb +82 -0
- data/examples/chat-goliath-grape/Gemfile +5 -0
- data/examples/chat-goliath-grape/README.markdown +50 -0
- data/examples/chat-goliath-grape/app.rb +67 -0
- data/examples/chat-goliath-grape/config/app.rb +20 -0
- data/examples/transcoders/Gemfile +3 -0
- data/examples/transcoders/README.markdown +59 -0
- data/examples/transcoders/cb-zcat +40 -0
- data/examples/transcoders/cb-zcp +45 -0
- data/examples/transcoders/gzip_transcoder.rb +49 -0
- data/examples/transcoders/options.rb +54 -0
- data/ext/couchbase_ext/.gitignore +4 -0
- data/ext/couchbase_ext/arguments.c +956 -0
- data/ext/couchbase_ext/arithmetic.c +307 -0
- data/ext/couchbase_ext/bucket.c +1370 -0
- data/ext/couchbase_ext/context.c +65 -0
- data/ext/couchbase_ext/couchbase_ext.c +1364 -0
- data/ext/couchbase_ext/couchbase_ext.h +644 -0
- data/ext/couchbase_ext/delete.c +163 -0
- data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
- data/ext/couchbase_ext/extconf.rb +168 -0
- data/ext/couchbase_ext/get.c +316 -0
- data/ext/couchbase_ext/gethrtime.c +129 -0
- data/ext/couchbase_ext/http.c +432 -0
- data/ext/couchbase_ext/multithread_plugin.c +1090 -0
- data/ext/couchbase_ext/observe.c +171 -0
- data/ext/couchbase_ext/plugin_common.c +171 -0
- data/ext/couchbase_ext/result.c +129 -0
- data/ext/couchbase_ext/stats.c +163 -0
- data/ext/couchbase_ext/store.c +542 -0
- data/ext/couchbase_ext/timer.c +192 -0
- data/ext/couchbase_ext/touch.c +186 -0
- data/ext/couchbase_ext/unlock.c +176 -0
- data/ext/couchbase_ext/utils.c +551 -0
- data/ext/couchbase_ext/version.c +142 -0
- data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
- data/lib/active_support/cache/couchbase_store.rb +430 -0
- data/lib/couchbase.rb +155 -0
- data/lib/couchbase/bucket.rb +457 -0
- data/lib/couchbase/cluster.rb +119 -0
- data/lib/couchbase/connection_pool.rb +58 -0
- data/lib/couchbase/constants.rb +12 -0
- data/lib/couchbase/result.rb +26 -0
- data/lib/couchbase/transcoder.rb +120 -0
- data/lib/couchbase/utils.rb +62 -0
- data/lib/couchbase/version.rb +21 -0
- data/lib/couchbase/view.rb +506 -0
- data/lib/couchbase/view_row.rb +272 -0
- data/lib/ext/multi_json_fix.rb +56 -0
- data/lib/rack/session/couchbase.rb +108 -0
- data/tasks/benchmark.rake +6 -0
- data/tasks/compile.rake +158 -0
- data/tasks/test.rake +100 -0
- data/tasks/util.rake +21 -0
- data/test/profile/.gitignore +1 -0
- data/test/profile/Gemfile +6 -0
- data/test/profile/benchmark.rb +195 -0
- data/test/setup.rb +178 -0
- data/test/test_arithmetic.rb +185 -0
- data/test/test_async.rb +316 -0
- data/test/test_bucket.rb +250 -0
- data/test/test_cas.rb +235 -0
- data/test/test_couchbase.rb +77 -0
- data/test/test_couchbase_connection_pool.rb +77 -0
- data/test/test_couchbase_rails_cache_store.rb +361 -0
- data/test/test_delete.rb +120 -0
- data/test/test_errors.rb +82 -0
- data/test/test_eventmachine.rb +70 -0
- data/test/test_format.rb +164 -0
- data/test/test_get.rb +407 -0
- data/test/test_stats.rb +57 -0
- data/test/test_store.rb +216 -0
- data/test/test_timer.rb +42 -0
- data/test/test_touch.rb +97 -0
- data/test/test_unlock.rb +119 -0
- data/test/test_utils.rb +58 -0
- data/test/test_version.rb +52 -0
- metadata +336 -0
@@ -0,0 +1,551 @@
|
|
1
|
+
/* vim: ft=c et ts=8 sts=4 sw=4 cino=
|
2
|
+
*
|
3
|
+
* Copyright 2011, 2012 Couchbase, Inc.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
|
18
|
+
#include "couchbase_ext.h"
|
19
|
+
|
20
|
+
void
|
21
|
+
cb_gc_protect_ptr(struct cb_bucket_st *bucket, void *ptr, mark_f mark_func)
|
22
|
+
{
|
23
|
+
st_insert(bucket->object_space, (st_index_t)ptr, (st_data_t)mark_func);
|
24
|
+
}
|
25
|
+
|
26
|
+
void
|
27
|
+
cb_gc_unprotect_ptr(struct cb_bucket_st *bucket, void *ptr)
|
28
|
+
{
|
29
|
+
st_delete(bucket->object_space, (st_index_t*)&ptr, NULL);
|
30
|
+
}
|
31
|
+
|
32
|
+
struct proc_params_st
|
33
|
+
{
|
34
|
+
struct cb_bucket_st *bucket;
|
35
|
+
VALUE recv;
|
36
|
+
ID mid;
|
37
|
+
int argc;
|
38
|
+
VALUE *argv;
|
39
|
+
VALUE exc;
|
40
|
+
};
|
41
|
+
|
42
|
+
static VALUE
|
43
|
+
do_async_error_notify(VALUE ptr)
|
44
|
+
{
|
45
|
+
struct proc_params_st *p = (struct proc_params_st *)ptr;
|
46
|
+
return rb_funcall(p->bucket->on_error_proc, cb_id_call, 1, p->exc);
|
47
|
+
}
|
48
|
+
|
49
|
+
void
|
50
|
+
cb_async_error_notify(struct cb_bucket_st *bucket, VALUE exc)
|
51
|
+
{
|
52
|
+
if (bucket->on_error_proc != Qnil) {
|
53
|
+
struct proc_params_st params;
|
54
|
+
int fail;
|
55
|
+
params.bucket = bucket;
|
56
|
+
params.exc = exc;
|
57
|
+
rb_protect(do_async_error_notify, (VALUE)¶ms, &fail);
|
58
|
+
if (fail) {
|
59
|
+
rb_warning("Couchbase::Bucket#on_error shouldn't raise exceptions");
|
60
|
+
}
|
61
|
+
} else {
|
62
|
+
if (NIL_P(bucket->exception)) {
|
63
|
+
bucket->exception = exc;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
int
|
69
|
+
cb_bucket_connected_bang(struct cb_bucket_st *bucket, VALUE operation)
|
70
|
+
{
|
71
|
+
if (bucket->type == LCB_TYPE_BUCKET &&
|
72
|
+
(bucket->handle == NULL || !bucket->connected)) {
|
73
|
+
VALUE exc = rb_exc_new2(cb_eConnectError, "not connected to the server");
|
74
|
+
rb_ivar_set(exc, cb_id_iv_operation, operation);
|
75
|
+
rb_ivar_set(exc, cb_id_iv_value, bucket->self);
|
76
|
+
if (bucket->async) {
|
77
|
+
cb_async_error_notify(bucket, exc);
|
78
|
+
} else {
|
79
|
+
rb_exc_raise(exc);
|
80
|
+
}
|
81
|
+
return 0;
|
82
|
+
}
|
83
|
+
return 1;
|
84
|
+
}
|
85
|
+
|
86
|
+
static VALUE
|
87
|
+
func_call_failed(VALUE ptr, VALUE exc)
|
88
|
+
{
|
89
|
+
struct proc_params_st *p = (struct proc_params_st *)ptr;
|
90
|
+
cb_async_error_notify(p->bucket, exc);
|
91
|
+
return Qnil;
|
92
|
+
}
|
93
|
+
|
94
|
+
static VALUE
|
95
|
+
do_func_call(VALUE ptr)
|
96
|
+
{
|
97
|
+
struct proc_params_st *p = (struct proc_params_st *)ptr;
|
98
|
+
return rb_funcall2(p->recv, p->mid, p->argc, p->argv);
|
99
|
+
}
|
100
|
+
|
101
|
+
VALUE
|
102
|
+
cb_proc_call(struct cb_bucket_st *bucket, VALUE recv, int argc, ...)
|
103
|
+
{
|
104
|
+
VALUE *argv;
|
105
|
+
va_list ar;
|
106
|
+
int arity;
|
107
|
+
int ii;
|
108
|
+
struct proc_params_st params;
|
109
|
+
|
110
|
+
arity = FIX2INT(rb_funcall(recv, cb_id_arity, 0));
|
111
|
+
if (arity < 0) {
|
112
|
+
arity = argc;
|
113
|
+
}
|
114
|
+
if (arity > 0) {
|
115
|
+
va_init_list(ar, argc);
|
116
|
+
argv = ALLOCA_N(VALUE, argc);
|
117
|
+
for (ii = 0; ii < arity; ++ii) {
|
118
|
+
if (ii < argc) {
|
119
|
+
argv[ii] = va_arg(ar, VALUE);
|
120
|
+
} else {
|
121
|
+
argv[ii] = Qnil;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
va_end(ar);
|
125
|
+
} else {
|
126
|
+
argv = NULL;
|
127
|
+
}
|
128
|
+
params.bucket = bucket;
|
129
|
+
params.recv = recv;
|
130
|
+
params.mid = cb_id_call;
|
131
|
+
params.argc = arity;
|
132
|
+
params.argv = argv;
|
133
|
+
return rb_rescue2(do_func_call, (VALUE)¶ms,
|
134
|
+
func_call_failed, (VALUE)¶ms,
|
135
|
+
rb_eException, (VALUE)0);
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE
|
139
|
+
cb_hash_delete(VALUE hash, VALUE key)
|
140
|
+
{
|
141
|
+
return rb_funcall(hash, cb_id_delete, 1, key);
|
142
|
+
}
|
143
|
+
|
144
|
+
/* Helper to convert return code from libcouchbase to meaningful exception.
|
145
|
+
* Returns nil if the code considering successful and exception object
|
146
|
+
* otherwise. Store given string to exceptions as message, and also
|
147
|
+
* initialize +error+ attribute with given return code. */
|
148
|
+
VALUE
|
149
|
+
cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
|
150
|
+
lcb_http_status_t status)
|
151
|
+
{
|
152
|
+
VALUE klass, exc, str;
|
153
|
+
char buf[300];
|
154
|
+
|
155
|
+
if ((rc == LCB_SUCCESS && (status == 0 || status / 100 == 2)) ||
|
156
|
+
rc == LCB_AUTH_CONTINUE) {
|
157
|
+
return Qnil;
|
158
|
+
}
|
159
|
+
switch (rc) {
|
160
|
+
case LCB_AUTH_ERROR:
|
161
|
+
klass = cb_eAuthError;
|
162
|
+
break;
|
163
|
+
case LCB_DELTA_BADVAL:
|
164
|
+
klass = cb_eDeltaBadvalError;
|
165
|
+
break;
|
166
|
+
case LCB_E2BIG:
|
167
|
+
klass = cb_eTooBigError;
|
168
|
+
break;
|
169
|
+
case LCB_EBUSY:
|
170
|
+
klass = cb_eBusyError;
|
171
|
+
break;
|
172
|
+
case LCB_EINTERNAL:
|
173
|
+
klass = cb_eInternalError;
|
174
|
+
break;
|
175
|
+
case LCB_EINVAL:
|
176
|
+
klass = cb_eInvalidError;
|
177
|
+
break;
|
178
|
+
case LCB_ENOMEM:
|
179
|
+
klass = cb_eNoMemoryError;
|
180
|
+
break;
|
181
|
+
case LCB_ERANGE:
|
182
|
+
klass = cb_eRangeError;
|
183
|
+
break;
|
184
|
+
case LCB_ETMPFAIL:
|
185
|
+
klass = cb_eTmpFailError;
|
186
|
+
break;
|
187
|
+
case LCB_KEY_EEXISTS:
|
188
|
+
klass = cb_eKeyExistsError;
|
189
|
+
break;
|
190
|
+
case LCB_KEY_ENOENT:
|
191
|
+
klass = cb_eNotFoundError;
|
192
|
+
break;
|
193
|
+
case LCB_DLOPEN_FAILED:
|
194
|
+
klass = cb_eDlopenFailedError;
|
195
|
+
break;
|
196
|
+
case LCB_DLSYM_FAILED:
|
197
|
+
klass = cb_eDlsymFailedError;
|
198
|
+
break;
|
199
|
+
case LCB_NETWORK_ERROR:
|
200
|
+
klass = cb_eNetworkError;
|
201
|
+
break;
|
202
|
+
case LCB_NOT_MY_VBUCKET:
|
203
|
+
klass = cb_eNotMyVbucketError;
|
204
|
+
break;
|
205
|
+
case LCB_NOT_STORED:
|
206
|
+
klass = cb_eNotStoredError;
|
207
|
+
break;
|
208
|
+
case LCB_NOT_SUPPORTED:
|
209
|
+
klass = cb_eNotSupportedError;
|
210
|
+
break;
|
211
|
+
case LCB_UNKNOWN_COMMAND:
|
212
|
+
klass = cb_eUnknownCommandError;
|
213
|
+
break;
|
214
|
+
case LCB_UNKNOWN_HOST:
|
215
|
+
klass = cb_eUnknownHostError;
|
216
|
+
break;
|
217
|
+
case LCB_PROTOCOL_ERROR:
|
218
|
+
klass = cb_eProtocolError;
|
219
|
+
break;
|
220
|
+
case LCB_ETIMEDOUT:
|
221
|
+
klass = cb_eTimeoutError;
|
222
|
+
break;
|
223
|
+
case LCB_CONNECT_ERROR:
|
224
|
+
klass = cb_eConnectError;
|
225
|
+
break;
|
226
|
+
case LCB_BUCKET_ENOENT:
|
227
|
+
klass = cb_eBucketNotFoundError;
|
228
|
+
break;
|
229
|
+
case LCB_CLIENT_ENOMEM:
|
230
|
+
klass = cb_eClientNoMemoryError;
|
231
|
+
break;
|
232
|
+
case LCB_CLIENT_ETMPFAIL:
|
233
|
+
klass = cb_eClientTmpFailError;
|
234
|
+
break;
|
235
|
+
case LCB_EBADHANDLE:
|
236
|
+
klass = cb_eBadHandleError;
|
237
|
+
break;
|
238
|
+
case LCB_SERVER_BUG:
|
239
|
+
klass = cb_eServerBug;
|
240
|
+
break;
|
241
|
+
case LCB_PLUGIN_VERSION_MISMATCH:
|
242
|
+
klass = cb_ePluginVersionMismatch;
|
243
|
+
break;
|
244
|
+
case LCB_INVALID_HOST_FORMAT:
|
245
|
+
klass = cb_eInvalidHostFormat;
|
246
|
+
break;
|
247
|
+
case LCB_INVALID_CHAR:
|
248
|
+
klass = cb_eInvalidChar;
|
249
|
+
break;
|
250
|
+
case LCB_DURABILITY_ETOOMANY:
|
251
|
+
klass = cb_eDurabilityTooMany;
|
252
|
+
break;
|
253
|
+
case LCB_DUPLICATE_COMMANDS:
|
254
|
+
klass = cb_eDuplicateCommands;
|
255
|
+
break;
|
256
|
+
case LCB_NO_MATCHING_SERVER:
|
257
|
+
klass = cb_eBadEnvironment;
|
258
|
+
break;
|
259
|
+
case LCB_BAD_ENVIRONMENT:
|
260
|
+
klass = cb_eBadEnvironment;
|
261
|
+
break;
|
262
|
+
case LCB_BUSY:
|
263
|
+
klass = cb_eBusyError;
|
264
|
+
break;
|
265
|
+
case LCB_INVALID_USERNAME:
|
266
|
+
klass = cb_eInvalidUsername;
|
267
|
+
break;
|
268
|
+
case LCB_ERROR:
|
269
|
+
/* fall through */
|
270
|
+
default:
|
271
|
+
klass = cb_eLibcouchbaseError;
|
272
|
+
}
|
273
|
+
|
274
|
+
str = rb_str_buf_new2(msg ? msg : "");
|
275
|
+
rb_str_buf_cat2(str, " (");
|
276
|
+
if (key != Qnil) {
|
277
|
+
snprintf(buf, 300, "key=\"%s\", ", RSTRING_PTR(key));
|
278
|
+
rb_str_buf_cat2(str, buf);
|
279
|
+
}
|
280
|
+
if (status > 0) {
|
281
|
+
const char *reason = NULL;
|
282
|
+
klass = cb_eHTTPError;
|
283
|
+
snprintf(buf, 300, "status=\"%d\"", status);
|
284
|
+
rb_str_buf_cat2(str, buf);
|
285
|
+
switch (status) {
|
286
|
+
case LCB_HTTP_STATUS_BAD_REQUEST:
|
287
|
+
reason = " (Bad Request)";
|
288
|
+
break;
|
289
|
+
case LCB_HTTP_STATUS_UNAUTHORIZED:
|
290
|
+
reason = " (Unauthorized)";
|
291
|
+
break;
|
292
|
+
case LCB_HTTP_STATUS_PAYMENT_REQUIRED:
|
293
|
+
reason = " (Payment Required)";
|
294
|
+
break;
|
295
|
+
case LCB_HTTP_STATUS_FORBIDDEN:
|
296
|
+
reason = " (Forbidden)";
|
297
|
+
break;
|
298
|
+
case LCB_HTTP_STATUS_NOT_FOUND:
|
299
|
+
reason = " (Not Found)";
|
300
|
+
break;
|
301
|
+
case LCB_HTTP_STATUS_METHOD_NOT_ALLOWED:
|
302
|
+
reason = " (Method Not Allowed)";
|
303
|
+
break;
|
304
|
+
case LCB_HTTP_STATUS_NOT_ACCEPTABLE:
|
305
|
+
reason = " (Not Acceptable)";
|
306
|
+
break;
|
307
|
+
case LCB_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED:
|
308
|
+
reason = " (Proxy Authentication Required)";
|
309
|
+
break;
|
310
|
+
case LCB_HTTP_STATUS_REQUEST_TIMEOUT:
|
311
|
+
reason = " (Request Timeout)";
|
312
|
+
break;
|
313
|
+
case LCB_HTTP_STATUS_CONFLICT:
|
314
|
+
reason = " (Conflict)";
|
315
|
+
break;
|
316
|
+
case LCB_HTTP_STATUS_GONE:
|
317
|
+
reason = " (Gone)";
|
318
|
+
break;
|
319
|
+
case LCB_HTTP_STATUS_LENGTH_REQUIRED:
|
320
|
+
reason = " (Length Required)";
|
321
|
+
break;
|
322
|
+
case LCB_HTTP_STATUS_PRECONDITION_FAILED:
|
323
|
+
reason = " (Precondition Failed)";
|
324
|
+
break;
|
325
|
+
case LCB_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE:
|
326
|
+
reason = " (Request Entity Too Large)";
|
327
|
+
break;
|
328
|
+
case LCB_HTTP_STATUS_REQUEST_URI_TOO_LONG:
|
329
|
+
reason = " (Request Uri Too Long)";
|
330
|
+
break;
|
331
|
+
case LCB_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE:
|
332
|
+
reason = " (Unsupported Media Type)";
|
333
|
+
break;
|
334
|
+
case LCB_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE:
|
335
|
+
reason = " (Requested Range Not Satisfiable)";
|
336
|
+
break;
|
337
|
+
case LCB_HTTP_STATUS_EXPECTATION_FAILED:
|
338
|
+
reason = " (Expectation Failed)";
|
339
|
+
break;
|
340
|
+
case LCB_HTTP_STATUS_UNPROCESSABLE_ENTITY:
|
341
|
+
reason = " (Unprocessable Entity)";
|
342
|
+
break;
|
343
|
+
case LCB_HTTP_STATUS_LOCKED:
|
344
|
+
reason = " (Locked)";
|
345
|
+
break;
|
346
|
+
case LCB_HTTP_STATUS_FAILED_DEPENDENCY:
|
347
|
+
reason = " (Failed Dependency)";
|
348
|
+
break;
|
349
|
+
case LCB_HTTP_STATUS_INTERNAL_SERVER_ERROR:
|
350
|
+
reason = " (Internal Server Error)";
|
351
|
+
break;
|
352
|
+
case LCB_HTTP_STATUS_NOT_IMPLEMENTED:
|
353
|
+
reason = " (Not Implemented)";
|
354
|
+
break;
|
355
|
+
case LCB_HTTP_STATUS_BAD_GATEWAY:
|
356
|
+
reason = " (Bad Gateway)";
|
357
|
+
break;
|
358
|
+
case LCB_HTTP_STATUS_SERVICE_UNAVAILABLE:
|
359
|
+
reason = " (Service Unavailable)";
|
360
|
+
break;
|
361
|
+
case LCB_HTTP_STATUS_GATEWAY_TIMEOUT:
|
362
|
+
reason = " (Gateway Timeout)";
|
363
|
+
break;
|
364
|
+
case LCB_HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED:
|
365
|
+
reason = " (Http Version Not Supported)";
|
366
|
+
break;
|
367
|
+
case LCB_HTTP_STATUS_INSUFFICIENT_STORAGE:
|
368
|
+
reason = " (Insufficient Storage)";
|
369
|
+
break;
|
370
|
+
default:
|
371
|
+
reason = "";
|
372
|
+
}
|
373
|
+
rb_str_buf_cat2(str, reason);
|
374
|
+
rb_str_buf_cat2(str, ", ");
|
375
|
+
|
376
|
+
}
|
377
|
+
snprintf(buf, 300, "error=0x%02x)", rc);
|
378
|
+
rb_str_buf_cat2(str, buf);
|
379
|
+
exc = rb_exc_new3(klass, str);
|
380
|
+
rb_ivar_set(exc, cb_id_iv_error, INT2FIX(rc));
|
381
|
+
rb_ivar_set(exc, cb_id_iv_key, key);
|
382
|
+
rb_ivar_set(exc, cb_id_iv_cas, Qnil);
|
383
|
+
rb_ivar_set(exc, cb_id_iv_operation, Qnil);
|
384
|
+
rb_ivar_set(exc, cb_id_iv_status, status ? INT2FIX(status) : Qnil);
|
385
|
+
return exc;
|
386
|
+
}
|
387
|
+
|
388
|
+
VALUE
|
389
|
+
cb_check_error(lcb_error_t rc, const char *msg, VALUE key)
|
390
|
+
{
|
391
|
+
return cb_check_error_with_status(rc, msg, key, 0);
|
392
|
+
}
|
393
|
+
|
394
|
+
static VALUE
|
395
|
+
do_encode(VALUE *args)
|
396
|
+
{
|
397
|
+
VALUE val = args[0];
|
398
|
+
uint32_t *flags = (uint32_t *)args[1];
|
399
|
+
VALUE transcoder = args[2];
|
400
|
+
VALUE options = args[3];
|
401
|
+
VALUE ret;
|
402
|
+
|
403
|
+
ret = rb_funcall(transcoder, cb_id_dump, 3, val, ULONG2NUM(*flags), options);
|
404
|
+
Check_Type(ret, T_ARRAY);
|
405
|
+
if (RARRAY_LEN(ret) != 2) {
|
406
|
+
rb_raise(rb_eArgError, "#dump method of transcoder should return two items");
|
407
|
+
}
|
408
|
+
*flags = NUM2ULONG(rb_ary_entry(ret, 1));
|
409
|
+
return rb_ary_entry(ret, 0);
|
410
|
+
}
|
411
|
+
|
412
|
+
static VALUE
|
413
|
+
do_decode(VALUE *args)
|
414
|
+
{
|
415
|
+
VALUE blob = args[0];
|
416
|
+
VALUE transcoder = args[2];
|
417
|
+
VALUE flags = args[1];
|
418
|
+
VALUE options = args[3];
|
419
|
+
|
420
|
+
return rb_funcall(transcoder, cb_id_load, 3, blob, ULONG2NUM(flags), options);
|
421
|
+
}
|
422
|
+
|
423
|
+
static VALUE
|
424
|
+
coding_failed(VALUE unused, VALUE exc)
|
425
|
+
{
|
426
|
+
(void)unused;
|
427
|
+
return exc;
|
428
|
+
}
|
429
|
+
|
430
|
+
VALUE
|
431
|
+
cb_encode_value(VALUE transcoder, VALUE val, uint32_t *flags, VALUE options)
|
432
|
+
{
|
433
|
+
VALUE args[4];
|
434
|
+
|
435
|
+
args[0] = val;
|
436
|
+
args[1] = (VALUE)flags;
|
437
|
+
args[2] = transcoder;
|
438
|
+
args[3] = options;
|
439
|
+
|
440
|
+
/* if nil, just pass value through */
|
441
|
+
if (NIL_P(args[2])) {
|
442
|
+
return val;
|
443
|
+
}
|
444
|
+
/* bytestring or exception object */
|
445
|
+
return rb_rescue(do_encode, (VALUE)args, coding_failed, 0);
|
446
|
+
}
|
447
|
+
|
448
|
+
VALUE
|
449
|
+
cb_decode_value(VALUE transcoder, VALUE blob, uint32_t flags, VALUE options)
|
450
|
+
{
|
451
|
+
VALUE args[4];
|
452
|
+
|
453
|
+
/* first it must be bytestring */
|
454
|
+
if (TYPE(blob) != T_STRING) {
|
455
|
+
return Qundef;
|
456
|
+
}
|
457
|
+
args[0] = blob;
|
458
|
+
args[1] = (VALUE)flags;
|
459
|
+
args[2] = transcoder;
|
460
|
+
args[3] = options;
|
461
|
+
|
462
|
+
/* if nil, just pass blob through */
|
463
|
+
if (NIL_P(args[2])) {
|
464
|
+
return blob;
|
465
|
+
}
|
466
|
+
/* the value or exception object */
|
467
|
+
return rb_rescue(do_decode, (VALUE)args, coding_failed, 0);
|
468
|
+
}
|
469
|
+
|
470
|
+
void
|
471
|
+
cb_strip_key_prefix(struct cb_bucket_st *bucket, VALUE key)
|
472
|
+
{
|
473
|
+
if (RTEST(bucket->key_prefix_val)) {
|
474
|
+
rb_str_update(key, 0, RSTRING_LEN(bucket->key_prefix_val), cb_vStrEmpty);
|
475
|
+
}
|
476
|
+
}
|
477
|
+
|
478
|
+
VALUE
|
479
|
+
cb_unify_key(struct cb_bucket_st *bucket, VALUE key, int apply_prefix)
|
480
|
+
{
|
481
|
+
VALUE ret = Qnil, tmp;
|
482
|
+
|
483
|
+
if (RTEST(bucket->key_prefix_val) && apply_prefix) {
|
484
|
+
ret = rb_str_dup(bucket->key_prefix_val);
|
485
|
+
}
|
486
|
+
switch (TYPE(key)) {
|
487
|
+
case T_STRING:
|
488
|
+
return NIL_P(ret) ? key : rb_str_concat(ret, key);
|
489
|
+
case T_SYMBOL:
|
490
|
+
tmp = STR_NEW_CSTR(rb_id2name(SYM2ID(key)));
|
491
|
+
return NIL_P(ret) ? tmp : rb_str_concat(ret, tmp);
|
492
|
+
default: /* call #to_str or raise error */
|
493
|
+
tmp = StringValue(key);
|
494
|
+
return NIL_P(ret) ? tmp : rb_str_concat(ret, tmp);
|
495
|
+
}
|
496
|
+
}
|
497
|
+
|
498
|
+
void
|
499
|
+
cb_build_headers(struct cb_context_st *ctx, const char * const *headers)
|
500
|
+
{
|
501
|
+
if (!ctx->headers_built) {
|
502
|
+
VALUE key = Qnil, val;
|
503
|
+
for (size_t ii = 1; *headers != NULL; ++ii, ++headers) {
|
504
|
+
if (ii % 2 == 0) {
|
505
|
+
if (key == Qnil) {
|
506
|
+
break;
|
507
|
+
}
|
508
|
+
val = rb_hash_aref(ctx->headers_val, key);
|
509
|
+
switch (TYPE(val)) {
|
510
|
+
case T_NIL:
|
511
|
+
rb_hash_aset(ctx->headers_val, key, STR_NEW_CSTR(*headers));
|
512
|
+
break;
|
513
|
+
case T_ARRAY:
|
514
|
+
rb_ary_push(val, STR_NEW_CSTR(*headers));
|
515
|
+
break;
|
516
|
+
default:
|
517
|
+
{
|
518
|
+
VALUE ary = rb_ary_new();
|
519
|
+
rb_ary_push(ary, val);
|
520
|
+
rb_ary_push(ary, STR_NEW_CSTR(*headers));
|
521
|
+
rb_hash_aset(ctx->headers_val, key, ary);
|
522
|
+
}
|
523
|
+
}
|
524
|
+
} else {
|
525
|
+
key = STR_NEW_CSTR(*headers);
|
526
|
+
}
|
527
|
+
}
|
528
|
+
ctx->headers_built = 1;
|
529
|
+
}
|
530
|
+
}
|
531
|
+
|
532
|
+
int
|
533
|
+
cb_first_value_i(VALUE key, VALUE value, VALUE arg)
|
534
|
+
{
|
535
|
+
VALUE *val = (VALUE *)arg;
|
536
|
+
|
537
|
+
*val = value;
|
538
|
+
(void)key;
|
539
|
+
return ST_STOP;
|
540
|
+
}
|
541
|
+
|
542
|
+
#ifndef HAVE_RB_HASH_LOOKUP2
|
543
|
+
VALUE
|
544
|
+
rb_hash_lookup2(VALUE hash, VALUE key, VALUE dflt)
|
545
|
+
{
|
546
|
+
if (RTEST(rb_funcall2(hash, cb_id_has_key_p, 1, &key))) {
|
547
|
+
dflt = rb_hash_aref(hash, key);
|
548
|
+
}
|
549
|
+
return dflt;
|
550
|
+
}
|
551
|
+
#endif
|