Skip to content

Commit 0744895

Browse files
committed
PHPC-96 & PHPC-119 call the new bsonUnserialize method and optimize things a little
1 parent 2691047 commit 0744895

File tree

3 files changed

+54
-62
lines changed

3 files changed

+54
-62
lines changed

php_phongo_classes.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,17 @@
2424
/* PHP Core stuff */
2525
#include <php.h>
2626

27+
#define BSON_UNSERIALIZE_FUNC_NAME "bsonUnserialize"
28+
#define BSON_SERIALIZE_FUNC_NAME "bsonSerialize"
2729

2830
typedef struct {
2931
zend_object std;
3032
bson_t *bson;
3133
} php_phongo_command_t;
3234

3335
typedef struct {
34-
struct {
35-
char *classname;
36-
int classname_len;
37-
} document;
38-
struct {
39-
char *classname;
40-
int classname_len;
41-
} array;
36+
zend_class_entry *document;
37+
zend_class_entry *array;
4238
} php_phongo_bson_typemap;
4339

4440
typedef struct {
@@ -213,6 +209,8 @@ extern PHONGO_API zend_class_entry *php_phongo_duplicatekeyexception_ce;
213209
extern PHONGO_API zend_class_entry *php_phongo_writeexception_ce;
214210

215211
extern PHONGO_API zend_class_entry *php_phongo_type_ce;
212+
extern PHONGO_API zend_class_entry *php_phongo_unserializable_ce;
213+
extern PHONGO_API zend_class_entry *php_phongo_serializable_ce;
216214
extern PHONGO_API zend_class_entry *php_phongo_binary_ce;
217215
extern PHONGO_API zend_class_entry *php_phongo_int32_ce;
218216
extern PHONGO_API zend_class_entry *php_phongo_int64_ce;

src/bson.c

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -450,32 +450,25 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter __attribute__((unuse
450450
{
451451
zval *retval = ((php_phongo_bson_state *)data)->zchild;
452452
bson_iter_t child;
453-
zend_class_entry *ce = zend_standard_class_def;
454453
TSRMLS_FETCH();
455454

456455
if (bson_iter_init(&child, v_document)) {
457-
php_phongo_bson_state state = {NULL, {{NULL, 0}, {NULL, 0}}};
456+
php_phongo_bson_state state = {NULL, {NULL, NULL} };
458457

459458
state.map = ((php_phongo_bson_state *)data)->map;
460459

461460
MAKE_STD_ZVAL(state.zchild);
462461
array_init(state.zchild);
463462

464463
if (!bson_iter_visit_all(&child, &php_bson_visitors, &state)) {
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-
if (ce->type == ZEND_INTERNAL_CLASS && ce->constructor) {
468-
zval tmp_val = *state.zchild;
464+
if (state.map.document) {
465+
zval tmp_val = *state.zchild;
469466

470-
object_and_properties_init(state.zchild, ce, NULL);
471-
zend_call_method_with_1_params(&state.zchild, ce, &ce->constructor, "__construct", NULL, &tmp_val);
472-
473-
zval_dtor(&tmp_val);
474-
} else {
475-
object_and_properties_init(state.zchild, ce, Z_ARRVAL_P(state.zchild));
476-
}
467+
object_and_properties_init(state.zchild, state.map.document, NULL);
468+
zend_call_method_with_1_params(&state.zchild, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &tmp_val);
469+
zval_dtor(&tmp_val);
477470
} else {
478-
object_and_properties_init(state.zchild, ce, Z_ARRVAL_P(state.zchild));
471+
object_and_properties_init(state.zchild, zend_standard_class_def, Z_ARRVAL_P(state.zchild));
479472
}
480473

481474
add_assoc_zval(retval, key, state.zchild);
@@ -491,12 +484,11 @@ bool php_phongo_bson_visit_document(const bson_iter_t *iter __attribute__((unuse
491484
bool php_phongo_bson_visit_array(const bson_iter_t *iter __attribute__((unused)), const char *key, const bson_t *v_array, void *data)
492485
{
493486
zval *retval = ((php_phongo_bson_state *)data)->zchild;
494-
zend_class_entry *ce = zend_standard_class_def;
495487
bson_iter_t child;
496488
TSRMLS_FETCH();
497489

498490
if (bson_iter_init(&child, v_array)) {
499-
php_phongo_bson_state state = {NULL, {{NULL, 0}, {NULL, 0}}};
491+
php_phongo_bson_state state = {NULL, {NULL, NULL} };
500492

501493
state.map = ((php_phongo_bson_state *)data)->map;
502494

@@ -505,20 +497,12 @@ bool php_phongo_bson_visit_array(const bson_iter_t *iter __attribute__((unused))
505497

506498
if (!bson_iter_visit_all(&child, &php_bson_visitors, &state)) {
507499

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);
510-
if (ce->type == ZEND_INTERNAL_CLASS && ce->constructor) {
511-
zval tmp_val = *state.zchild;
512-
513-
object_and_properties_init(state.zchild, ce, NULL);
514-
zend_call_method_with_1_params(&state.zchild, ce, &ce->constructor, "__construct", NULL, &tmp_val);
500+
if (state.map.array) {
501+
zval tmp_val = *state.zchild;
515502

516-
zval_dtor(&tmp_val);
517-
} else {
518-
object_and_properties_init(state.zchild, ce, Z_ARRVAL_P(state.zchild));
519-
}
520-
} else {
521-
object_and_properties_init(state.zchild, ce, Z_ARRVAL_P(state.zchild));
503+
object_and_properties_init(state.zchild, state.map.array, NULL);
504+
zend_call_method_with_1_params(&state.zchild, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &tmp_val);
505+
zval_dtor(&tmp_val);
522506
}
523507

524508
add_assoc_zval(retval, key, state.zchild);
@@ -842,11 +826,12 @@ PHP_FUNCTION(fromArray)
842826
Returns the PHP representation of a BSON value, optionally converting them into custom types/classes */
843827
PHP_FUNCTION(toArray)
844828
{
845-
char *data, *document_classname, *array_classname;
846-
int data_len, document_classname_len, array_classname_len;
829+
char *data, *classname;
830+
int data_len, classname_len;
847831
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}}};
832+
zend_bool classname_free = 0;
833+
zend_class_entry *array_ce = NULL, *document_ce = NULL;
834+
php_phongo_bson_state state = {NULL, {NULL, NULL} };
850835

851836
(void)return_value_ptr; (void)this_ptr; (void)return_value_used; /* We don't use these */
852837

@@ -855,26 +840,30 @@ PHP_FUNCTION(toArray)
855840
}
856841

857842
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;
843+
classname = php_array_fetchl_string(typemap, "array", sizeof("array")-1, &classname_len, &classname_free);
844+
array_ce = zend_fetch_class(classname, classname_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
845+
846+
if (instanceof_function(array_ce, php_phongo_unserializable_ce TSRMLS_CC)) {
847+
state.map.array = array_ce;
848+
}
849+
if (classname_free) {
850+
efree(classname);
862851
}
863852

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;
853+
classname = php_array_fetchl_string(typemap, "document", sizeof("document")-1, &classname_len, &classname_free);
854+
document_ce = zend_fetch_class(classname, classname_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
855+
if (instanceof_function(document_ce, php_phongo_unserializable_ce TSRMLS_CC)) {
856+
state.map.document = document_ce;
857+
}
858+
if (classname_free) {
859+
efree(classname);
868860
}
869861
}
862+
870863
state.zchild = return_value;
871864
if (!bson_to_zval((const unsigned char *)data, data_len, &state)) {
872865
RETURN_NULL();
873866
}
874-
875-
if (document_classname_free) {
876-
efree(document_classname);
877-
}
878867
}
879868
/* }}} */
880869

tests/bson/bson-decode-002.phpt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ BSON encoding: Encoding object/arrays data into user specificied classes
66
<?php
77
require_once "tests/utils/basic.inc";
88

9+
class MyArrayObject extends ArrayObject implements BSON\Unserializable {
10+
function bsonUnserialize(array $data) {
11+
parent::__construct($data);
12+
}
13+
}
914
$tests = array(
1015
array(array("hello" => "world")),
1116
array((object)array("hello" => "world")),
@@ -18,7 +23,7 @@ $tests = array(
1823
foreach($tests as $n => $test) {
1924
$s = BSON\fromArray($test);
2025
echo "Test#{$n} ", BSON\toJSON($s), "\n";
21-
$val = BSON\toArray($s, array("document"=> "ArrayObject", "array" => "ArrayObject"));
26+
$val = BSON\toArray($s, array("document"=> "MyArrayObject", "array" => "MyArrayObject"));
2227
var_dump($val);
2328
}
2429
?>
@@ -28,7 +33,7 @@ foreach($tests as $n => $test) {
2833
Test#%d { "0" : { "hello" : "world" } }
2934
array(1) {
3035
[0]=>
31-
object(ArrayObject)#%d (1) {
36+
object(MyArrayObject)#%d (1) {
3237
[%s]=>
3338
array(1) {
3439
["hello"]=>
@@ -39,7 +44,7 @@ array(1) {
3944
Test#%d { "0" : { "hello" : "world" } }
4045
array(1) {
4146
[0]=>
42-
object(ArrayObject)#%d (1) {
47+
object(MyArrayObject)#%d (1) {
4348
[%s]=>
4449
array(1) {
4550
["hello"]=>
@@ -50,7 +55,7 @@ array(1) {
5055
Test#%d { "my" : { "hello" : "world" } }
5156
array(1) {
5257
["my"]=>
53-
object(ArrayObject)#%d (1) {
58+
object(MyArrayObject)#%d (1) {
5459
[%s]=>
5560
array(1) {
5661
["hello"]=>
@@ -61,7 +66,7 @@ array(1) {
6166
Test#%d { "my" : { "hello" : "world" } }
6267
array(1) {
6368
["my"]=>
64-
object(ArrayObject)#%d (1) {
69+
object(MyArrayObject)#%d (1) {
6570
[%s]=>
6671
array(1) {
6772
["hello"]=>
@@ -72,11 +77,11 @@ array(1) {
7277
Test#%d { "my" : [ [ "hello", "world" ] ] }
7378
array(1) {
7479
["my"]=>
75-
object(ArrayObject)#%d (1) {
80+
object(MyArrayObject)#%d (1) {
7681
[%s]=>
7782
array(1) {
7883
[0]=>
79-
object(ArrayObject)#%d (1) {
84+
object(MyArrayObject)#%d (1) {
8085
[%s]=>
8186
array(2) {
8287
[0]=>
@@ -91,11 +96,11 @@ array(1) {
9196
Test#%d { "my" : { "0" : [ "hello", "world" ] } }
9297
array(1) {
9398
["my"]=>
94-
object(ArrayObject)#%d (1) {
99+
object(MyArrayObject)#%d (1) {
95100
[%s]=>
96101
array(1) {
97102
[0]=>
98-
object(ArrayObject)#%d (1) {
103+
object(MyArrayObject)#%d (1) {
99104
[%s]=>
100105
array(2) {
101106
[0]=>

0 commit comments

Comments
 (0)