bson_ext 1.1.5 → 1.2.rc0
Sign up to get free protection for your applications and to get access to all the features.
- data/bson_ext.gemspec +1 -1
- data/ext/cbson/cbson.c +42 -22
- data/ext/cbson/version.h +1 -1
- metadata +13 -11
data/bson_ext.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require './lib/bson'
|
2
2
|
VERSION_HEADER = File.open(File.join(File.dirname(__FILE__), 'ext', 'cbson', 'version.h'), "r")
|
3
|
-
VERSION = VERSION_HEADER.read.scan(/VERSION\s+"(\d+\.\d+(
|
3
|
+
VERSION = VERSION_HEADER.read.scan(/VERSION\s+"(\d+\.\d+(\.[\w\d]+\w*)?)\"/)[0][0]
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'bson_ext'
|
6
6
|
|
data/ext/cbson/cbson.c
CHANGED
@@ -30,10 +30,16 @@
|
|
30
30
|
#ifndef RSTRING_LEN
|
31
31
|
# define RSTRING_LEN(v) RSTRING(v)->len
|
32
32
|
#endif
|
33
|
+
#ifndef RSTRING_LENINT
|
34
|
+
# define RSTRING_LENINT(v) (int)(RSTRING_LEN(v))
|
35
|
+
#endif
|
33
36
|
|
34
37
|
#ifndef RARRAY_LEN
|
35
38
|
# define RARRAY_LEN(v) RARRAY(v)->len
|
36
39
|
#endif
|
40
|
+
#ifndef RARRAY_LENINT
|
41
|
+
# define RARRAY_LENINT(v) (int)(RARRAY_LEN(v))
|
42
|
+
#endif
|
37
43
|
|
38
44
|
#if HAVE_RUBY_ST_H
|
39
45
|
#include "ruby/st.h"
|
@@ -88,6 +94,8 @@ static VALUE InvalidDocument;
|
|
88
94
|
static VALUE DigestMD5;
|
89
95
|
static VALUE RB_HASH;
|
90
96
|
|
97
|
+
static int max_bson_size;
|
98
|
+
|
91
99
|
#if HAVE_RUBY_ENCODING_H
|
92
100
|
#include "ruby/encoding.h"
|
93
101
|
#define STR_NEW(p,n) \
|
@@ -102,13 +110,13 @@ static VALUE RB_HASH;
|
|
102
110
|
/* MUST call TO_UTF8 before calling write_utf8. */
|
103
111
|
#define TO_UTF8(string) rb_str_export_to_enc((string), rb_utf8_encoding())
|
104
112
|
static void write_utf8(buffer_t buffer, VALUE string, char check_null) {
|
105
|
-
result_t status = check_string(RSTRING_PTR(string),
|
113
|
+
result_t status = check_string(RSTRING_PTR(string), RSTRING_LENINT(string),
|
106
114
|
0, check_null);
|
107
115
|
if (status == HAS_NULL) {
|
108
116
|
buffer_free(buffer);
|
109
117
|
rb_raise(InvalidDocument, "Key names / regex patterns must not contain the NULL byte");
|
110
118
|
}
|
111
|
-
SAFE_WRITE(buffer, RSTRING_PTR(string),
|
119
|
+
SAFE_WRITE(buffer, RSTRING_PTR(string), RSTRING_LENINT(string));
|
112
120
|
}
|
113
121
|
#else
|
114
122
|
#define STR_NEW(p,n) rb_str_new((p), (n))
|
@@ -147,7 +155,7 @@ static void write_utf8(buffer_t buffer, VALUE string, char check_null) {
|
|
147
155
|
* either use _scprintf and _snprintf on for Windows or
|
148
156
|
* use snprintf for solaris. */
|
149
157
|
#ifndef HAVE_ASPRINTF
|
150
|
-
#ifdef _MSC_VER
|
158
|
+
#ifdef _WIN32 || _MSC_VER
|
151
159
|
#define INT2STRING(buffer, i) \
|
152
160
|
{ \
|
153
161
|
int vslength = _scprintf("%d", i) + 1; \
|
@@ -255,7 +263,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
255
263
|
} else {
|
256
264
|
int int_value;
|
257
265
|
write_name_and_type(buffer, key, 0x10);
|
258
|
-
int_value = ll_value;
|
266
|
+
int_value = (int)ll_value;
|
259
267
|
SAFE_WRITE(buffer, (char*)&int_value, 4);
|
260
268
|
}
|
261
269
|
break;
|
@@ -305,7 +313,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
305
313
|
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
|
306
314
|
}
|
307
315
|
|
308
|
-
items =
|
316
|
+
items = RARRAY_LENINT(value);
|
309
317
|
for(i = 0; i < items; i++) {
|
310
318
|
char* name;
|
311
319
|
VALUE key;
|
@@ -326,7 +334,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
326
334
|
int length;
|
327
335
|
write_name_and_type(buffer, key, 0x02);
|
328
336
|
value = TO_UTF8(value);
|
329
|
-
length =
|
337
|
+
length = RSTRING_LENINT(value) + 1;
|
330
338
|
SAFE_WRITE(buffer, (char*)&length, 4);
|
331
339
|
write_utf8(buffer, value, 0);
|
332
340
|
SAFE_WRITE(buffer, &zero, 1);
|
@@ -335,7 +343,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
335
343
|
case T_SYMBOL:
|
336
344
|
{
|
337
345
|
const char* str_value = rb_id2name(SYM2ID(value));
|
338
|
-
int length = strlen(str_value) + 1;
|
346
|
+
int length = (int)strlen(str_value) + 1;
|
339
347
|
write_name_and_type(buffer, key, 0x0E);
|
340
348
|
SAFE_WRITE(buffer, (char*)&length, 4);
|
341
349
|
SAFE_WRITE(buffer, str_value, length);
|
@@ -350,7 +358,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
350
358
|
const char subtype = strcmp(cls, "ByteBuffer") ?
|
351
359
|
(const char)FIX2INT(rb_funcall(value, rb_intern("subtype"), 0)) : 2;
|
352
360
|
VALUE string_data = rb_funcall(value, rb_intern("to_s"), 0);
|
353
|
-
int length =
|
361
|
+
int length = RSTRING_LENINT(string_data);
|
354
362
|
write_name_and_type(buffer, key, 0x05);
|
355
363
|
if (subtype == 2) {
|
356
364
|
const int other_length = length + 4;
|
@@ -401,6 +409,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
401
409
|
if (strcmp(cls, "BSON::Code") == 0) {
|
402
410
|
buffer_position length_location, start_position, total_length;
|
403
411
|
int length;
|
412
|
+
VALUE code_str;
|
404
413
|
write_name_and_type(buffer, key, 0x0F);
|
405
414
|
|
406
415
|
start_position = buffer_get_position(buffer);
|
@@ -409,8 +418,8 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
409
418
|
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
|
410
419
|
}
|
411
420
|
|
412
|
-
|
413
|
-
length =
|
421
|
+
code_str = rb_funcall(value, rb_intern("code"), 0);
|
422
|
+
length = RSTRING_LENINT(code_str) + 1;
|
414
423
|
SAFE_WRITE(buffer, (char*)&length, 4);
|
415
424
|
SAFE_WRITE(buffer, RSTRING_PTR(code_str), length - 1);
|
416
425
|
SAFE_WRITE(buffer, &zero, 1);
|
@@ -490,7 +499,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
490
499
|
if (TYPE(has_extra) == T_TRUE) {
|
491
500
|
VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0);
|
492
501
|
buffer_position old_position = buffer_get_position(buffer);
|
493
|
-
SAFE_WRITE(buffer, RSTRING_PTR(extra),
|
502
|
+
SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LENINT(extra));
|
494
503
|
qsort(buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
|
495
504
|
}
|
496
505
|
SAFE_WRITE(buffer, &zero, 1);
|
@@ -573,8 +582,7 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
|
|
573
582
|
rb_hash_foreach(hash, write_function, pack_extra(buffer, check_keys));
|
574
583
|
} else {
|
575
584
|
buffer_free(buffer);
|
576
|
-
|
577
|
-
rb_raise(InvalidDocument, "BSON.serialize takes a Hash but got a %s", cls);
|
585
|
+
rb_raise(InvalidDocument, "BSON.serialize takes a Hash but got a %s", rb_obj_classname(hash));
|
578
586
|
}
|
579
587
|
|
580
588
|
// write null byte and fill in length
|
@@ -582,9 +590,9 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
|
|
582
590
|
length = buffer_get_position(buffer) - start_position;
|
583
591
|
|
584
592
|
// make sure that length doesn't exceed 4MB
|
585
|
-
if (length >
|
593
|
+
if (length > max_bson_size) {
|
586
594
|
buffer_free(buffer);
|
587
|
-
rb_raise(InvalidDocument, "Document too large: BSON documents are limited to
|
595
|
+
rb_raise(InvalidDocument, "Document too large: BSON documents are limited to %d bytes.", max_bson_size);
|
588
596
|
return;
|
589
597
|
}
|
590
598
|
SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&length, 4);
|
@@ -665,7 +673,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
|
|
665
673
|
value = rb_ary_new();
|
666
674
|
while (*position < end) {
|
667
675
|
int type = (int)buffer[(*position)++];
|
668
|
-
int key_size = strlen(buffer + *position);
|
676
|
+
int key_size = (int)strlen(buffer + *position);
|
669
677
|
VALUE to_append;
|
670
678
|
|
671
679
|
*position += key_size + 1; // just skip the key, they're in order.
|
@@ -729,13 +737,13 @@ static VALUE get_value(const char* buffer, int* position, int type) {
|
|
729
737
|
}
|
730
738
|
case 11:
|
731
739
|
{
|
732
|
-
int pattern_length = strlen(buffer + *position);
|
740
|
+
int pattern_length = (int)strlen(buffer + *position);
|
733
741
|
VALUE pattern = STR_NEW(buffer + *position, pattern_length);
|
734
742
|
int flags_length, flags = 0, i = 0;
|
735
743
|
VALUE argv[3];
|
736
744
|
*position += pattern_length + 1;
|
737
745
|
|
738
|
-
flags_length = strlen(buffer + *position);
|
746
|
+
flags_length = (int)strlen(buffer + *position);
|
739
747
|
for (i = 0; i < flags_length; i++) {
|
740
748
|
char flag = buffer[*position + i];
|
741
749
|
if (flag == 'i') {
|
@@ -845,7 +853,7 @@ static VALUE elements_to_hash(const char* buffer, int max) {
|
|
845
853
|
int position = 0;
|
846
854
|
while (position < max) {
|
847
855
|
int type = (int)buffer[position++];
|
848
|
-
int name_length = strlen(buffer + position);
|
856
|
+
int name_length = (int)strlen(buffer + position);
|
849
857
|
VALUE name = STR_NEW(buffer + position, name_length);
|
850
858
|
VALUE value;
|
851
859
|
position += name_length + 1;
|
@@ -857,7 +865,7 @@ static VALUE elements_to_hash(const char* buffer, int max) {
|
|
857
865
|
|
858
866
|
static VALUE method_deserialize(VALUE self, VALUE bson) {
|
859
867
|
const char* buffer = RSTRING_PTR(bson);
|
860
|
-
int remaining =
|
868
|
+
int remaining = RSTRING_LENINT(bson);
|
861
869
|
|
862
870
|
// NOTE we just swallow the size and end byte here
|
863
871
|
buffer += 4;
|
@@ -874,7 +882,7 @@ static VALUE objectid_generate(VALUE self)
|
|
874
882
|
unsigned short pid;
|
875
883
|
int i;
|
876
884
|
|
877
|
-
t = htonl(time(NULL));
|
885
|
+
t = htonl((int)time(NULL));
|
878
886
|
MEMCPY(&oid_bytes, &t, unsigned char, 4);
|
879
887
|
|
880
888
|
MEMCPY(&oid_bytes[4], hostname_digest, unsigned char, 3);
|
@@ -902,11 +910,19 @@ static VALUE objectid_generate(VALUE self)
|
|
902
910
|
return oid;
|
903
911
|
}
|
904
912
|
|
913
|
+
static VALUE method_update_max_bson_size(VALUE self, VALUE connection) {
|
914
|
+
max_bson_size = FIX2INT(rb_funcall(connection, rb_intern("max_bson_size"), 0));
|
915
|
+
return INT2FIX(max_bson_size);
|
916
|
+
}
|
917
|
+
|
918
|
+
static VALUE method_max_bson_size(VALUE self) {
|
919
|
+
return INT2FIX(max_bson_size);
|
920
|
+
}
|
905
921
|
|
906
922
|
void Init_cbson() {
|
907
923
|
VALUE bson, CBson, Digest, ext_version, digest;
|
908
924
|
static char hostname[MAX_HOSTNAME_LENGTH];
|
909
|
-
|
925
|
+
|
910
926
|
element_assignment_method = rb_intern("[]=");
|
911
927
|
unpack_method = rb_intern("unpack");
|
912
928
|
utc_method = rb_intern("utc");
|
@@ -939,6 +955,8 @@ void Init_cbson() {
|
|
939
955
|
rb_define_const(CBson, "VERSION", ext_version);
|
940
956
|
rb_define_module_function(CBson, "serialize", method_serialize, 3);
|
941
957
|
rb_define_module_function(CBson, "deserialize", method_deserialize, 1);
|
958
|
+
rb_define_module_function(CBson, "max_bson_size", method_max_bson_size, 0);
|
959
|
+
rb_define_module_function(CBson, "update_max_bson_size", method_update_max_bson_size, 1);
|
942
960
|
|
943
961
|
rb_require("digest/md5");
|
944
962
|
Digest = rb_const_get(rb_cObject, rb_intern("Digest"));
|
@@ -953,4 +971,6 @@ void Init_cbson() {
|
|
953
971
|
rb_str_new2(hostname));
|
954
972
|
memcpy(hostname_digest, RSTRING_PTR(digest), 16);
|
955
973
|
hostname_digest[16] = '\0';
|
974
|
+
|
975
|
+
max_bson_size = 4 * 1024 * 1024;
|
956
976
|
}
|
data/ext/cbson/version.h
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bson_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 977940448
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 2
|
9
|
+
- rc0
|
10
|
+
version: 1.2.rc0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mike Dirolf
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-05 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -37,7 +37,7 @@ files:
|
|
37
37
|
- ext/cbson/encoding_helpers.h
|
38
38
|
- ext/cbson/version.h
|
39
39
|
- ext/cbson/buffer.h
|
40
|
-
has_rdoc:
|
40
|
+
has_rdoc: false
|
41
41
|
homepage: http://www.mongodb.org
|
42
42
|
licenses: []
|
43
43
|
|
@@ -58,12 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
58
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
59
|
none: false
|
60
60
|
requirements:
|
61
|
-
- - "
|
61
|
+
- - ">"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
hash:
|
63
|
+
hash: 25
|
64
64
|
segments:
|
65
|
-
-
|
66
|
-
|
65
|
+
- 1
|
66
|
+
- 3
|
67
|
+
- 1
|
68
|
+
version: 1.3.1
|
67
69
|
requirements: []
|
68
70
|
|
69
71
|
rubyforge_project:
|