faststep 0.0.8.1 → 0.1.0.beta1
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/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
|
}
|