bson_ext 1.0.7 → 1.0.9
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/cbson/cbson.c +56 -48
- data/ext/cbson/version.h +1 -1
- metadata +4 -4
data/ext/cbson/cbson.c
CHANGED
@@ -31,10 +31,6 @@
|
|
31
31
|
# define RSTRING_LEN(v) RSTRING(v)->len
|
32
32
|
#endif
|
33
33
|
|
34
|
-
#ifndef RARRAY_PTR
|
35
|
-
# define RARRAY_PTR(v) RARRAY(v)->ptr
|
36
|
-
#endif
|
37
|
-
|
38
34
|
#ifndef RARRAY_LEN
|
39
35
|
# define RARRAY_LEN(v) RARRAY(v)->len
|
40
36
|
#endif
|
@@ -72,6 +68,12 @@
|
|
72
68
|
|
73
69
|
#define MAX_HOSTNAME_LENGTH 256
|
74
70
|
|
71
|
+
static ID element_assignment_method;
|
72
|
+
static ID unpack_method;
|
73
|
+
static ID utc_method;
|
74
|
+
static ID lt_operator;
|
75
|
+
static ID gt_operator;
|
76
|
+
|
75
77
|
static VALUE Binary;
|
76
78
|
static VALUE ObjectID;
|
77
79
|
static VALUE ObjectId;
|
@@ -177,6 +179,9 @@ static void write_utf8(buffer_t buffer, VALUE string, char check_null) {
|
|
177
179
|
static char zero = 0;
|
178
180
|
static char one = 1;
|
179
181
|
|
182
|
+
static char hostname_digest[17];
|
183
|
+
static unsigned int object_id_inc = 0;
|
184
|
+
|
180
185
|
static int cmp_char(const void* a, const void* b) {
|
181
186
|
return *(char*)a - *(char*)b;
|
182
187
|
}
|
@@ -231,23 +236,27 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
231
236
|
|
232
237
|
switch(TYPE(value)) {
|
233
238
|
case T_BIGNUM:
|
234
|
-
case T_FIXNUM:
|
235
239
|
{
|
236
|
-
if (rb_funcall(value,
|
237
|
-
rb_funcall(value,
|
240
|
+
if (rb_funcall(value, gt_operator, 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
|
241
|
+
rb_funcall(value, lt_operator, 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) {
|
238
242
|
buffer_free(buffer);
|
239
243
|
rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints");
|
240
244
|
}
|
241
|
-
|
242
|
-
|
243
|
-
|
245
|
+
}
|
246
|
+
// NOTE: falls through to T_FIXNUM code
|
247
|
+
case T_FIXNUM:
|
248
|
+
{
|
249
|
+
long long ll_value;
|
250
|
+
ll_value = NUM2LL(value);
|
251
|
+
|
252
|
+
if (ll_value > 2147483647L ||
|
253
|
+
ll_value < -2147483648L) {
|
244
254
|
write_name_and_type(buffer, key, 0x12);
|
245
|
-
ll_value = NUM2LL(value);
|
246
255
|
SAFE_WRITE(buffer, (char*)&ll_value, 8);
|
247
256
|
} else {
|
248
257
|
int int_value;
|
249
258
|
write_name_and_type(buffer, key, 0x10);
|
250
|
-
int_value =
|
259
|
+
int_value = ll_value;
|
251
260
|
SAFE_WRITE(buffer, (char*)&int_value, 4);
|
252
261
|
}
|
253
262
|
break;
|
@@ -298,13 +307,12 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
298
307
|
}
|
299
308
|
|
300
309
|
items = RARRAY_LEN(value);
|
301
|
-
values = RARRAY_PTR(value);
|
302
310
|
for(i = 0; i < items; i++) {
|
303
311
|
char* name;
|
304
312
|
VALUE key;
|
305
313
|
INT2STRING(&name, i);
|
306
314
|
key = rb_str_new2(name);
|
307
|
-
write_element_with_id(key,
|
315
|
+
write_element_with_id(key, rb_ary_entry(value, i), pack_extra(buffer, check_keys));
|
308
316
|
free(name);
|
309
317
|
}
|
310
318
|
|
@@ -385,7 +393,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
|
|
385
393
|
int i;
|
386
394
|
write_name_and_type(buffer, key, 0x07);
|
387
395
|
for (i = 0; i < 12; i++) {
|
388
|
-
char byte = (char)FIX2INT(
|
396
|
+
char byte = (char)FIX2INT(rb_ary_entry(as_array, i));
|
389
397
|
SAFE_WRITE(buffer, &byte, 1);
|
390
398
|
}
|
391
399
|
break;
|
@@ -558,7 +566,7 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
|
|
558
566
|
VALUE keys = rb_funcall(hash, rb_intern("keys"), 0);
|
559
567
|
int i;
|
560
568
|
for(i = 0; i < RARRAY_LEN(keys); i++) {
|
561
|
-
VALUE key =
|
569
|
+
VALUE key = rb_ary_entry(keys, i);
|
562
570
|
VALUE value = rb_hash_aref(hash, key);
|
563
571
|
|
564
572
|
write_function(key, value, pack_extra(buffer, check_keys));
|
@@ -696,7 +704,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
|
|
696
704
|
case 7:
|
697
705
|
{
|
698
706
|
VALUE str = rb_str_new(buffer + *position, 12);
|
699
|
-
VALUE oid = rb_funcall(str,
|
707
|
+
VALUE oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
|
700
708
|
value = rb_class_new_instance(1, &oid, ObjectId);
|
701
709
|
*position += 12;
|
702
710
|
break;
|
@@ -712,7 +720,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
|
|
712
720
|
memcpy(&millis, buffer + *position, 8);
|
713
721
|
|
714
722
|
value = rb_time_new(millis / 1000, (millis % 1000) * 1000);
|
715
|
-
value = rb_funcall(value,
|
723
|
+
value = rb_funcall(value, utc_method, 0);
|
716
724
|
*position += 8;
|
717
725
|
break;
|
718
726
|
}
|
@@ -758,7 +766,7 @@ static VALUE get_value(const char* buffer, int* position, int type) {
|
|
758
766
|
*position += collection_length + 1;
|
759
767
|
|
760
768
|
str = rb_str_new(buffer + *position, 12);
|
761
|
-
oid = rb_funcall(str,
|
769
|
+
oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
|
762
770
|
id = rb_class_new_instance(1, &oid, ObjectId);
|
763
771
|
*position += 12;
|
764
772
|
|
@@ -844,7 +852,7 @@ static VALUE elements_to_hash(const char* buffer, int max) {
|
|
844
852
|
VALUE value;
|
845
853
|
position += name_length + 1;
|
846
854
|
value = get_value(buffer, &position, type);
|
847
|
-
rb_funcall(hash,
|
855
|
+
rb_funcall(hash, element_assignment_method, 2, name, value);
|
848
856
|
}
|
849
857
|
return hash;
|
850
858
|
}
|
@@ -860,28 +868,9 @@ static VALUE method_deserialize(VALUE self, VALUE bson) {
|
|
860
868
|
return elements_to_hash(buffer, remaining);
|
861
869
|
}
|
862
870
|
|
863
|
-
|
864
|
-
static VALUE fast_pack(VALUE self)
|
865
|
-
{
|
866
|
-
VALUE res;
|
867
|
-
long i;
|
868
|
-
char c;
|
869
|
-
|
870
|
-
res = rb_str_buf_new(0);
|
871
|
-
|
872
|
-
for (i = 0; i < RARRAY_LEN(self); i++) {
|
873
|
-
c = FIX2LONG(RARRAY_PTR(self)[i]);
|
874
|
-
rb_str_buf_cat(res, &c, sizeof(char));
|
875
|
-
}
|
876
|
-
|
877
|
-
return res;
|
878
|
-
}
|
879
|
-
|
880
|
-
|
881
871
|
static VALUE objectid_generate(VALUE self)
|
882
872
|
{
|
883
|
-
VALUE oid
|
884
|
-
char hostname[MAX_HOSTNAME_LENGTH];
|
873
|
+
VALUE oid;
|
885
874
|
unsigned char oid_bytes[12];
|
886
875
|
unsigned long t, inc;
|
887
876
|
unsigned short pid;
|
@@ -890,16 +879,22 @@ static VALUE objectid_generate(VALUE self)
|
|
890
879
|
t = htonl(time(NULL));
|
891
880
|
MEMCPY(&oid_bytes, &t, unsigned char, 4);
|
892
881
|
|
893
|
-
|
894
|
-
rb_raise(rb_eRuntimeError, "failed to get hostname");
|
895
|
-
}
|
896
|
-
digest = rb_funcall(DigestMD5, rb_intern("digest"), 1, rb_str_new2(hostname));
|
897
|
-
MEMCPY(&oid_bytes[4], RSTRING_PTR(digest), unsigned char, 3);
|
882
|
+
MEMCPY(&oid_bytes[4], hostname_digest, unsigned char, 3);
|
898
883
|
|
899
884
|
pid = htons(getpid());
|
900
885
|
MEMCPY(&oid_bytes[7], &pid, unsigned char, 2);
|
901
886
|
|
902
|
-
|
887
|
+
/* No need to synchronize modification of this counter between threads;
|
888
|
+
* MRI global interpreter lock guarantees serializaility.
|
889
|
+
*
|
890
|
+
* Compiler should optimize out impossible branch.
|
891
|
+
*/
|
892
|
+
if (sizeof(unsigned int) == 4) {
|
893
|
+
object_id_inc++;
|
894
|
+
} else {
|
895
|
+
object_id_inc = (object_id_inc + 1) % 0xFFFFFF;
|
896
|
+
}
|
897
|
+
inc = htonl(object_id_inc);
|
903
898
|
MEMCPY(&oid_bytes[9], ((unsigned char*)&inc + 1), unsigned char, 3);
|
904
899
|
|
905
900
|
oid = rb_ary_new2(12);
|
@@ -911,7 +906,14 @@ static VALUE objectid_generate(VALUE self)
|
|
911
906
|
|
912
907
|
|
913
908
|
void Init_cbson() {
|
914
|
-
VALUE bson, CBson, Digest, ext_version;
|
909
|
+
VALUE bson, CBson, Digest, ext_version, digest;
|
910
|
+
static char hostname[MAX_HOSTNAME_LENGTH];
|
911
|
+
|
912
|
+
element_assignment_method = rb_intern("[]=");
|
913
|
+
unpack_method = rb_intern("unpack");
|
914
|
+
utc_method = rb_intern("utc");
|
915
|
+
lt_operator = rb_intern("<");
|
916
|
+
gt_operator = rb_intern(">");
|
915
917
|
|
916
918
|
bson = rb_const_get(rb_cObject, rb_intern("BSON"));
|
917
919
|
rb_require("bson/types/binary");
|
@@ -949,5 +951,11 @@ void Init_cbson() {
|
|
949
951
|
rb_define_method(ObjectID, "generate", objectid_generate, 0);
|
950
952
|
rb_define_method(ObjectId, "generate", objectid_generate, 0);
|
951
953
|
|
952
|
-
|
954
|
+
if (gethostname(hostname, MAX_HOSTNAME_LENGTH) != 0) {
|
955
|
+
rb_raise(rb_eRuntimeError, "failed to get hostname");
|
956
|
+
}
|
957
|
+
digest = rb_funcall(DigestMD5, rb_intern("digest"), 1,
|
958
|
+
rb_str_new2(hostname));
|
959
|
+
memcpy(hostname_digest, RSTRING_PTR(digest), 16);
|
960
|
+
hostname_digest[16] = '\0';
|
953
961
|
}
|
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:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 9
|
10
|
+
version: 1.0.9
|
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: 2010-
|
18
|
+
date: 2010-09-20 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|