bson_ext 1.1.5 → 1.2.rc0
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/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:
|