bson_ext 1.0.7 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|