36
36
/* Our stuffz */
37
37
#include "php_phongo.h"
38
38
#include "php_bson.h"
39
+ #include "php_array.h"
39
40
40
41
41
42
#define BSON_APPEND_INT32 (b ,key ,val ) \
@@ -453,17 +454,16 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter __attribute__((unuse
453
454
TSRMLS_FETCH ();
454
455
455
456
if (bson_iter_init (& child , v_document )) {
456
- php_phongo_bson_state state = {NULL , NULL , 0 };
457
+ php_phongo_bson_state state = {NULL , {{ NULL , 0 }, { NULL , 0 }} };
457
458
458
- state .classname = ((php_phongo_bson_state * )data )-> classname ;
459
- state .classname_len = ((php_phongo_bson_state * )data )-> classname_len ;
459
+ state .map = ((php_phongo_bson_state * )data )-> map ;
460
460
461
461
MAKE_STD_ZVAL (state .zchild );
462
462
array_init (state .zchild );
463
463
464
464
if (!bson_iter_visit_all (& child , & php_bson_visitors , & state )) {
465
- if (state .classname_len ) {
466
- ce = zend_fetch_class (state .classname , state .classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
465
+ if (state .map . document . classname_len ) {
466
+ ce = zend_fetch_class (state .map . document . classname , state . map . document .classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
467
467
if (ce -> type == ZEND_INTERNAL_CLASS && ce -> constructor ) {
468
468
zval tmp_val = * state .zchild ;
469
469
@@ -490,25 +490,23 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter __attribute__((unuse
490
490
491
491
bool php_phongo_bson_visit_array (const bson_iter_t * iter __attribute__((unused )), const char * key , const bson_t * v_array , void * data )
492
492
{
493
- php_phongo_bson_state * parent_state = data ;
494
- zval * retval = parent_state -> zchild ;
493
+ zval * retval = ((php_phongo_bson_state * )data )-> zchild ;
495
494
zend_class_entry * ce = zend_standard_class_def ;
496
495
bson_iter_t child ;
497
496
TSRMLS_FETCH ();
498
497
499
498
if (bson_iter_init (& child , v_array )) {
500
- php_phongo_bson_state state = {NULL , NULL , 0 };
499
+ php_phongo_bson_state state = {NULL , {{ NULL , 0 }, { NULL , 0 }} };
501
500
502
- state .classname = parent_state -> classname ;
503
- state .classname_len = parent_state -> classname_len ;
501
+ state .map = ((php_phongo_bson_state * )data )-> map ;
504
502
505
503
MAKE_STD_ZVAL (state .zchild );
506
504
array_init (state .zchild );
507
505
508
506
if (!bson_iter_visit_all (& child , & php_bson_visitors , & state )) {
509
507
510
- if (state .classname_len ) {
511
- ce = zend_fetch_class (state .classname , state .classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
508
+ if (state .map . array . classname_len ) {
509
+ ce = zend_fetch_class (state .map . array . classname , state . map . array .classname_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC );
512
510
if (ce -> type == ZEND_INTERNAL_CLASS && ce -> constructor ) {
513
511
zval tmp_val = * state .zchild ;
514
512
@@ -840,26 +838,43 @@ PHP_FUNCTION(fromArray)
840
838
}
841
839
/* }}} */
842
840
843
- /* {{{ proto string BSON\toArray(string data)
844
- Returns the PHP representation of a BSON value */
841
+ /* {{{ proto string BSON\toArray(string data [, array $typemap = array()] )
842
+ Returns the PHP representation of a BSON value, optionally converting them into custom types/classes */
845
843
PHP_FUNCTION (toArray )
846
844
{
847
- char * data , * classname = NULL ;
848
- int data_len , classname_len = 0 ;
849
- php_phongo_bson_state state = {NULL , NULL , 0 };
845
+ char * data , * document_classname , * array_classname ;
846
+ int data_len , document_classname_len , array_classname_len ;
847
+ zval * typemap = NULL ;
848
+ zend_bool document_classname_free = 0 , array_classname_free = 0 ;
849
+ php_phongo_bson_state state = {NULL , {{NULL , 0 }, {NULL , 0 }}};
850
850
851
851
(void )return_value_ptr ; (void )this_ptr ; (void )return_value_used ; /* We don't use these */
852
852
853
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "s|s !" , & data , & data_len , & classname , & classname_len ) == FAILURE ) {
853
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "s|a !" , & data , & data_len , & typemap ) == FAILURE ) {
854
854
return ;
855
855
}
856
856
857
- state .classname_len = classname_len ;
858
- state .classname = classname ;
857
+ if (typemap ) {
858
+ array_classname = php_array_fetchl_string (typemap , "array" , sizeof ("array" )- 1 , & array_classname_len , & array_classname_free );
859
+ if (array_classname_len ) {
860
+ state .map .array .classname_len = array_classname_len ;
861
+ state .map .array .classname = array_classname ;
862
+ }
863
+
864
+ document_classname = php_array_fetchl_string (typemap , "document" , sizeof ("document" )- 1 , & document_classname_len , & document_classname_free );
865
+ if (document_classname_len ) {
866
+ state .map .document .classname_len = document_classname_len ;
867
+ state .map .document .classname = document_classname ;
868
+ }
869
+ }
859
870
state .zchild = return_value ;
860
871
if (!bson_to_zval ((const unsigned char * )data , data_len , & state )) {
861
872
RETURN_NULL ();
862
873
}
874
+
875
+ if (document_classname_free ) {
876
+ efree (document_classname );
877
+ }
863
878
}
864
879
/* }}} */
865
880
0 commit comments