faststep 0.0.8.1 → 0.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/faststep/bson.c +193 -101
- data/ext/faststep/bson.h +715 -33
- data/ext/faststep/connection.c +6 -6
- data/ext/faststep/connection.h +1 -1
- data/ext/faststep/cursor.c +1 -1
- data/ext/faststep/encoding.c +136 -0
- data/ext/faststep/encoding.h +54 -0
- data/ext/faststep/gridfs.c +7 -8
- data/ext/faststep/gridfs.h +8 -2
- data/ext/faststep/md5.h +2 -0
- data/ext/faststep/mongo.c +545 -209
- data/ext/faststep/mongo.h +373 -36
- data/ext/faststep/platform_hacks.h +3 -2
- data/lib/faststep/version.rb +1 -1
- metadata +10 -6
data/ext/faststep/bson.c
CHANGED
@@ -15,12 +15,14 @@
|
|
15
15
|
* limitations under the License.
|
16
16
|
*/
|
17
17
|
|
18
|
-
#include "bson.h"
|
19
18
|
#include <stdlib.h>
|
20
19
|
#include <string.h>
|
21
20
|
#include <stdio.h>
|
22
21
|
#include <time.h>
|
23
22
|
|
23
|
+
#include "bson.h"
|
24
|
+
#include "encoding.h"
|
25
|
+
|
24
26
|
const int initialBufferSize = 128;
|
25
27
|
|
26
28
|
/* only need one of these */
|
@@ -32,7 +34,8 @@ static const int zero = 0;
|
|
32
34
|
|
33
35
|
bson * bson_empty(bson * obj){
|
34
36
|
static char * data = "\005\0\0\0\0";
|
35
|
-
|
37
|
+
bson_init(obj, data, 0);
|
38
|
+
return obj;
|
36
39
|
}
|
37
40
|
|
38
41
|
void bson_copy(bson* out, const bson* in){
|
@@ -42,15 +45,18 @@ void bson_copy(bson* out, const bson* in){
|
|
42
45
|
memcpy(out->data, in->data, bson_size(in));
|
43
46
|
}
|
44
47
|
|
45
|
-
|
46
|
-
|
48
|
+
int bson_from_buffer(bson * b, bson_buffer * buf){
|
49
|
+
b->err = buf->err;
|
50
|
+
bson_buffer_finish(buf);
|
51
|
+
return bson_init(b, buf->buf, 1);
|
47
52
|
}
|
48
53
|
|
49
|
-
|
54
|
+
int bson_init( bson * b, char * data, bson_bool_t mine ){
|
50
55
|
b->data = data;
|
51
56
|
b->owned = mine;
|
52
|
-
return
|
57
|
+
return BSON_OK;
|
53
58
|
}
|
59
|
+
|
54
60
|
int bson_size(const bson * b ){
|
55
61
|
int i;
|
56
62
|
if ( ! b || ! b->data )
|
@@ -58,6 +64,7 @@ int bson_size(const bson * b ){
|
|
58
64
|
bson_little_endian32(&i, b->data);
|
59
65
|
return i;
|
60
66
|
}
|
67
|
+
|
61
68
|
void bson_destroy( bson * b ){
|
62
69
|
if ( b->owned && b->data )
|
63
70
|
free( b->data );
|
@@ -204,7 +211,7 @@ bson_type bson_iterator_next( bson_iterator * i ){
|
|
204
211
|
i->first = 0;
|
205
212
|
return (bson_type)(*i->cur);
|
206
213
|
}
|
207
|
-
|
214
|
+
|
208
215
|
switch ( bson_iterator_type(i) ){
|
209
216
|
case bson_eoo: return bson_eoo; /* don't advance */
|
210
217
|
case bson_undefined:
|
@@ -399,42 +406,49 @@ void bson_iterator_subiterator(const bson_iterator * i, bson_iterator * sub){
|
|
399
406
|
BUILDING
|
400
407
|
------------------------------ */
|
401
408
|
|
402
|
-
|
409
|
+
int bson_buffer_init( bson_buffer * b ){
|
403
410
|
b->buf = (char*)bson_malloc( initialBufferSize );
|
404
411
|
b->bufSize = initialBufferSize;
|
405
412
|
b->cur = b->buf + 4;
|
406
413
|
b->finished = 0;
|
407
414
|
b->stackPos = 0;
|
408
|
-
|
415
|
+
b->err = 0;
|
416
|
+
b->errstr = NULL;
|
417
|
+
return 0;
|
409
418
|
}
|
410
419
|
|
411
|
-
void bson_append_byte( bson_buffer * b
|
420
|
+
void bson_append_byte( bson_buffer * b, char c ){
|
412
421
|
b->cur[0] = c;
|
413
422
|
b->cur++;
|
414
423
|
}
|
415
|
-
|
424
|
+
|
425
|
+
void bson_append( bson_buffer * b, const void * data, int len ){
|
416
426
|
memcpy( b->cur , data , len );
|
417
427
|
b->cur += len;
|
418
428
|
}
|
429
|
+
|
419
430
|
void bson_append32(bson_buffer * b, const void * data){
|
420
431
|
bson_little_endian32(b->cur, data);
|
421
432
|
b->cur += 4;
|
422
433
|
}
|
434
|
+
|
423
435
|
void bson_append64(bson_buffer * b, const void * data){
|
424
436
|
bson_little_endian64(b->cur, data);
|
425
437
|
b->cur += 8;
|
426
438
|
}
|
427
439
|
|
428
|
-
|
440
|
+
int bson_ensure_space( bson_buffer * b, const int bytesNeeded ){
|
429
441
|
int pos = b->cur - b->buf;
|
430
442
|
char * orig = b->buf;
|
431
443
|
int new_size;
|
432
444
|
|
433
|
-
if (b->finished)
|
434
|
-
|
445
|
+
if (b->finished) {
|
446
|
+
b->err = BSON_OBJECT_FINISHED;
|
447
|
+
return BSON_ERROR;
|
448
|
+
}
|
435
449
|
|
436
450
|
if (pos + bytesNeeded <= b->bufSize)
|
437
|
-
return
|
451
|
+
return BSON_OK;
|
438
452
|
|
439
453
|
new_size = 1.5 * (b->bufSize + bytesNeeded);
|
440
454
|
b->buf = realloc(b->buf, new_size);
|
@@ -444,140 +458,206 @@ bson_buffer * bson_ensure_space( bson_buffer * b , const int bytesNeeded ){
|
|
444
458
|
b->bufSize = new_size;
|
445
459
|
b->cur += b->buf - orig;
|
446
460
|
|
447
|
-
return
|
461
|
+
return BSON_OK;
|
448
462
|
}
|
449
463
|
|
450
|
-
|
464
|
+
/**
|
465
|
+
* Add null byte, mark as finished, and return buffer.
|
466
|
+
* Note that the buffer will now be owned by the bson
|
467
|
+
* object created from a call to bson_from_buffer.
|
468
|
+
* This buffer is then deallocated by calling
|
469
|
+
* bson_destroy().
|
470
|
+
*/
|
471
|
+
int bson_buffer_finish( bson_buffer * b ){
|
451
472
|
int i;
|
452
473
|
if ( ! b->finished ){
|
453
|
-
if (
|
454
|
-
bson_append_byte( b
|
474
|
+
if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
|
475
|
+
bson_append_byte( b, 0 );
|
455
476
|
i = b->cur - b->buf;
|
456
477
|
bson_little_endian32(b->buf, &i);
|
457
478
|
b->finished = 1;
|
458
479
|
}
|
459
|
-
|
480
|
+
|
481
|
+
return BSON_OK;
|
460
482
|
}
|
461
483
|
|
462
484
|
void bson_buffer_destroy( bson_buffer * b ){
|
463
485
|
free( b->buf );
|
486
|
+
b->err = 0;
|
464
487
|
b->buf = 0;
|
465
488
|
b->cur = 0;
|
466
489
|
b->finished = 1;
|
467
490
|
}
|
468
491
|
|
469
|
-
static
|
470
|
-
const int
|
471
|
-
if (
|
472
|
-
return
|
473
|
-
|
474
|
-
|
475
|
-
|
492
|
+
static int bson_append_estart( bson_buffer * b, int type, const char * name, const int dataSize ){
|
493
|
+
const int len = strlen(name) + 1;
|
494
|
+
if ( bson_ensure_space( b, 1 + len + dataSize ) == BSON_ERROR ) {
|
495
|
+
return BSON_ERROR;
|
496
|
+
}
|
497
|
+
|
498
|
+
if( bson_check_field_name( b, (unsigned char* )name, len - 1 ) == BSON_ERROR ) {
|
499
|
+
bson_builder_error( b );
|
500
|
+
return BSON_ERROR;
|
501
|
+
}
|
502
|
+
|
503
|
+
bson_append_byte( b, (char)type );
|
504
|
+
bson_append( b, name, len );
|
505
|
+
return BSON_OK;
|
476
506
|
}
|
477
507
|
|
478
508
|
/* ----------------------------
|
479
509
|
BUILDING TYPES
|
480
510
|
------------------------------ */
|
481
511
|
|
482
|
-
|
483
|
-
if (
|
512
|
+
int bson_append_int( bson_buffer * b, const char * name, const int i ) {
|
513
|
+
if ( bson_append_estart( b, bson_int, name, 4 ) == BSON_ERROR )
|
514
|
+
return BSON_ERROR;
|
484
515
|
bson_append32( b , &i );
|
485
|
-
return
|
516
|
+
return BSON_OK;
|
486
517
|
}
|
487
|
-
|
488
|
-
|
518
|
+
|
519
|
+
int bson_append_long( bson_buffer * b, const char * name, const int64_t i ) {
|
520
|
+
if ( bson_append_estart( b , bson_long, name, 8 ) == BSON_ERROR )
|
521
|
+
return BSON_ERROR;
|
489
522
|
bson_append64( b , &i );
|
490
|
-
return
|
523
|
+
return BSON_OK;
|
491
524
|
}
|
492
|
-
|
493
|
-
|
525
|
+
|
526
|
+
int bson_append_double( bson_buffer * b, const char * name, const double d ) {
|
527
|
+
if ( bson_append_estart( b, bson_double, name, 8 ) == BSON_ERROR )
|
528
|
+
return BSON_ERROR;
|
494
529
|
bson_append64( b , &d );
|
495
|
-
return
|
530
|
+
return BSON_OK;
|
496
531
|
}
|
497
|
-
|
498
|
-
|
532
|
+
|
533
|
+
int bson_append_bool( bson_buffer * b, const char * name, const bson_bool_t i ) {
|
534
|
+
if ( bson_append_estart( b, bson_bool, name, 1 ) == BSON_ERROR )
|
535
|
+
return BSON_ERROR;
|
499
536
|
bson_append_byte( b , i != 0 );
|
500
|
-
return
|
537
|
+
return BSON_OK;
|
501
538
|
}
|
502
|
-
|
503
|
-
|
504
|
-
|
539
|
+
|
540
|
+
int bson_append_null( bson_buffer * b, const char * name ) {
|
541
|
+
if ( bson_append_estart( b , bson_null, name, 0 ) == BSON_ERROR )
|
542
|
+
return BSON_ERROR;
|
543
|
+
return BSON_OK;
|
505
544
|
}
|
506
|
-
|
507
|
-
|
508
|
-
|
545
|
+
|
546
|
+
int bson_append_undefined( bson_buffer * b, const char * name ) {
|
547
|
+
if ( bson_append_estart( b, bson_undefined, name, 0 ) == BSON_ERROR )
|
548
|
+
return BSON_ERROR;
|
549
|
+
return BSON_OK;
|
509
550
|
}
|
510
|
-
|
511
|
-
|
512
|
-
|
551
|
+
|
552
|
+
int bson_append_string_base( bson_buffer * b, const char * name,
|
553
|
+
const char * value, int len, bson_type type) {
|
554
|
+
|
555
|
+
int sl = len + 1;
|
556
|
+
if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
|
557
|
+
return BSON_ERROR;
|
558
|
+
}
|
559
|
+
if ( bson_check_string( b, value, sl - 1 ) == BSON_ERROR )
|
560
|
+
return BSON_ERROR;
|
513
561
|
bson_append32( b , &sl);
|
514
|
-
bson_append( b , value , sl );
|
515
|
-
|
562
|
+
bson_append( b , value , sl - 1 );
|
563
|
+
bson_append( b , "\0" , 1 );
|
564
|
+
return BSON_OK;
|
565
|
+
}
|
566
|
+
|
567
|
+
int bson_append_string( bson_buffer * b, const char * name, const char * value ) {
|
568
|
+
return bson_append_string_base(b, name, value, strlen ( value ), bson_string);
|
516
569
|
}
|
517
|
-
|
518
|
-
|
570
|
+
|
571
|
+
int bson_append_symbol( bson_buffer * b, const char * name, const char * value ) {
|
572
|
+
return bson_append_string_base(b, name, value, strlen ( value ), bson_symbol);
|
573
|
+
}
|
574
|
+
|
575
|
+
int bson_append_code( bson_buffer * b, const char * name, const char * value ) {
|
576
|
+
return bson_append_string_base(b, name, value, strlen ( value ), bson_code);
|
577
|
+
}
|
578
|
+
|
579
|
+
int bson_append_string_n( bson_buffer * b, const char * name, const char * value, int len ) {
|
580
|
+
return bson_append_string_base(b, name, value, len, bson_string);
|
519
581
|
}
|
520
|
-
|
521
|
-
|
582
|
+
|
583
|
+
int bson_append_symbol_n( bson_buffer * b, const char * name, const char * value, int len ) {
|
584
|
+
return bson_append_string_base(b, name, value, len, bson_symbol);
|
522
585
|
}
|
523
|
-
|
524
|
-
|
586
|
+
|
587
|
+
int bson_append_code_n( bson_buffer * b, const char * name, const char * value, int len ) {
|
588
|
+
return bson_append_string_base(b, name, value, len, bson_code);
|
525
589
|
}
|
526
590
|
|
527
|
-
|
528
|
-
int
|
591
|
+
int bson_append_code_w_scope_n( bson_buffer * b, const char * name,
|
592
|
+
const char * code, int len, const bson * scope) {
|
593
|
+
|
594
|
+
int sl = len + 1;
|
529
595
|
int size = 4 + 4 + sl + bson_size(scope);
|
530
|
-
if (
|
596
|
+
if ( bson_append_estart(b, bson_codewscope, name, size) == BSON_ERROR )
|
597
|
+
return BSON_ERROR;
|
531
598
|
bson_append32(b, &size);
|
532
599
|
bson_append32(b, &sl);
|
533
600
|
bson_append(b, code, sl);
|
534
601
|
bson_append(b, scope->data, bson_size(scope));
|
535
|
-
return
|
602
|
+
return BSON_OK;
|
536
603
|
}
|
537
604
|
|
538
|
-
|
605
|
+
int bson_append_code_w_scope( bson_buffer * b, const char * name, const char * code, const bson * scope){
|
606
|
+
return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
|
607
|
+
}
|
608
|
+
|
609
|
+
int bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len ){
|
539
610
|
if ( type == 2 ){
|
540
611
|
int subtwolen = len + 4;
|
541
|
-
if (
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
612
|
+
if ( bson_append_estart( b, bson_bindata, name, 4+1+4+len ) == BSON_ERROR )
|
613
|
+
return BSON_ERROR;
|
614
|
+
bson_append32(b, &subtwolen);
|
615
|
+
bson_append_byte(b, type);
|
616
|
+
bson_append32(b, &len);
|
617
|
+
bson_append(b, str, len);
|
618
|
+
} else {
|
619
|
+
if ( bson_append_estart( b, bson_bindata, name, 4+1+len ) == BSON_ERROR )
|
620
|
+
return BSON_ERROR;
|
621
|
+
bson_append32(b, &len);
|
622
|
+
bson_append_byte(b, type);
|
623
|
+
bson_append(b, str, len);
|
551
624
|
}
|
552
|
-
return
|
625
|
+
return BSON_OK;
|
553
626
|
}
|
554
|
-
|
555
|
-
|
627
|
+
|
628
|
+
int bson_append_oid( bson_buffer * b, const char * name, const bson_oid_t * oid ){
|
629
|
+
if ( bson_append_estart( b, bson_oid, name, 12 ) == BSON_ERROR )
|
630
|
+
return BSON_ERROR;
|
556
631
|
bson_append( b , oid , 12 );
|
557
|
-
return
|
632
|
+
return BSON_OK;
|
558
633
|
}
|
559
|
-
|
634
|
+
|
635
|
+
int bson_append_new_oid( bson_buffer * b, const char * name ){
|
560
636
|
bson_oid_t oid;
|
561
637
|
bson_oid_gen(&oid);
|
562
638
|
return bson_append_oid(b, name, &oid);
|
563
639
|
}
|
564
640
|
|
565
|
-
|
641
|
+
int bson_append_regex( bson_buffer * b, const char * name, const char * pattern, const char * opts ){
|
566
642
|
const int plen = strlen(pattern)+1;
|
567
643
|
const int olen = strlen(opts)+1;
|
568
|
-
if (
|
644
|
+
if ( bson_append_estart( b, bson_regex, name, plen + olen ) == BSON_ERROR )
|
645
|
+
return BSON_ERROR;
|
646
|
+
if ( bson_check_string( b, pattern, plen - 1 ) == BSON_ERROR )
|
647
|
+
return BSON_ERROR;
|
569
648
|
bson_append( b , pattern , plen );
|
570
649
|
bson_append( b , opts , olen );
|
571
|
-
return
|
650
|
+
return BSON_OK;
|
572
651
|
}
|
573
652
|
|
574
|
-
|
575
|
-
if (
|
653
|
+
int bson_append_bson( bson_buffer * b, const char * name, const bson* bson){
|
654
|
+
if ( bson_append_estart( b, bson_object, name, bson_size(bson) ) == BSON_ERROR )
|
655
|
+
return BSON_ERROR;
|
576
656
|
bson_append( b , bson->data , bson_size(bson) );
|
577
|
-
return
|
657
|
+
return BSON_OK;
|
578
658
|
}
|
579
659
|
|
580
|
-
|
660
|
+
int bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem){
|
581
661
|
bson_iterator next = *elem;
|
582
662
|
int size;
|
583
663
|
|
@@ -585,7 +665,8 @@ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, c
|
|
585
665
|
size = next.cur - elem->cur;
|
586
666
|
|
587
667
|
if (name_or_null == NULL){
|
588
|
-
bson_ensure_space(b, size)
|
668
|
+
if( bson_ensure_space(b, size) == BSON_ERROR )
|
669
|
+
return BSON_ERROR;
|
589
670
|
bson_append(b, elem->cur, size);
|
590
671
|
}else{
|
591
672
|
int data_size = size - 2 - strlen(bson_iterator_key(elem));
|
@@ -593,53 +674,53 @@ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, c
|
|
593
674
|
bson_append(b, bson_iterator_value(elem), data_size);
|
594
675
|
}
|
595
676
|
|
596
|
-
return
|
677
|
+
return BSON_OK;
|
597
678
|
}
|
598
679
|
|
599
|
-
|
600
|
-
if (
|
680
|
+
int bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts ){
|
681
|
+
if ( bson_append_estart( b, bson_timestamp, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
|
601
682
|
|
602
683
|
bson_append32( b , &(ts->i) );
|
603
684
|
bson_append32( b , &(ts->t) );
|
604
685
|
|
605
|
-
return
|
686
|
+
return BSON_OK;
|
606
687
|
}
|
607
688
|
|
608
|
-
|
609
|
-
if (
|
689
|
+
int bson_append_date( bson_buffer * b, const char * name, bson_date_t millis ) {
|
690
|
+
if ( bson_append_estart( b, bson_date, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
|
610
691
|
bson_append64( b , &millis );
|
611
|
-
return
|
692
|
+
return BSON_OK;
|
612
693
|
}
|
613
694
|
|
614
|
-
|
695
|
+
int bson_append_time_t( bson_buffer * b, const char * name, time_t secs) {
|
615
696
|
return bson_append_date(b, name, (bson_date_t)secs * 1000);
|
616
697
|
}
|
617
698
|
|
618
|
-
|
619
|
-
if (
|
699
|
+
int bson_append_start_object( bson_buffer * b, const char * name ) {
|
700
|
+
if ( bson_append_estart( b, bson_object, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
|
620
701
|
b->stack[ b->stackPos++ ] = b->cur - b->buf;
|
621
702
|
bson_append32( b , &zero );
|
622
|
-
return
|
703
|
+
return BSON_OK;
|
623
704
|
}
|
624
705
|
|
625
|
-
|
626
|
-
if (
|
706
|
+
int bson_append_start_array( bson_buffer * b, const char * name ) {
|
707
|
+
if ( bson_append_estart( b, bson_array, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
|
627
708
|
b->stack[ b->stackPos++ ] = b->cur - b->buf;
|
628
709
|
bson_append32( b , &zero );
|
629
|
-
return
|
710
|
+
return BSON_OK;
|
630
711
|
}
|
631
712
|
|
632
|
-
|
713
|
+
int bson_append_finish_object( bson_buffer * b ){
|
633
714
|
char * start;
|
634
715
|
int i;
|
635
|
-
if (
|
716
|
+
if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
|
636
717
|
bson_append_byte( b , 0 );
|
637
718
|
|
638
719
|
start = b->buf + b->stack[ --b->stackPos ];
|
639
720
|
i = b->cur - start;
|
640
721
|
bson_little_endian32(start, &i);
|
641
722
|
|
642
|
-
return
|
723
|
+
return BSON_OK;
|
643
724
|
}
|
644
725
|
|
645
726
|
void* bson_malloc(int size){
|
@@ -662,6 +743,17 @@ bson_err_handler set_bson_err_handler(bson_err_handler func){
|
|
662
743
|
return old;
|
663
744
|
}
|
664
745
|
|
746
|
+
/**
|
747
|
+
* This method is invoked when a non-fatal bson error is encountered.
|
748
|
+
* Calls the error handler if available.
|
749
|
+
*
|
750
|
+
* @param
|
751
|
+
*/
|
752
|
+
void bson_builder_error( bson_buffer* b ) {
|
753
|
+
if( err_handler )
|
754
|
+
err_handler( "BSON error." );
|
755
|
+
}
|
756
|
+
|
665
757
|
void bson_fatal( int ok ){
|
666
758
|
bson_fatal_msg(ok, "");
|
667
759
|
}
|