45
45
#undef MONGOC_LOG_DOMAIN
46
46
#define MONGOC_LOG_DOMAIN "PHONGO-BSON"
47
47
48
+ /* Forwards declarations */
49
+ static void php_phongo_zval_to_bson_internal (zval * data , php_phongo_field_path * field_path , php_phongo_bson_flags_t flags , bson_t * bson , bson_t * * bson_out TSRMLS_DC );
50
+
48
51
/* Determines whether the argument should be serialized as a BSON array or
49
52
* document. IS_ARRAY is returned if the argument's keys are a sequence of
50
53
* integers starting at zero; otherwise, IS_OBJECT is returned. */
@@ -113,7 +116,7 @@ static int php_phongo_is_array_or_document(zval* val TSRMLS_DC) /* {{{ */
113
116
* will be appended as an embedded document. Other MongoDB\BSON\Type instances
114
117
* will be appended as the appropriate BSON type. Other array or object values
115
118
* will be appended as an embedded document. */
116
- static void php_phongo_bson_append_object (bson_t * bson , php_phongo_bson_flags_t flags , const char * key , long key_len , zval * object TSRMLS_DC ) /* {{{ */
119
+ static void php_phongo_bson_append_object (bson_t * bson , php_phongo_field_path * field_path , php_phongo_bson_flags_t flags , const char * key , long key_len , zval * object TSRMLS_DC ) /* {{{ */
117
120
{
118
121
if (Z_TYPE_P (object ) == IS_OBJECT && instanceof_function (Z_OBJCE_P (object ), php_phongo_cursorid_ce TSRMLS_CC )) {
119
122
bson_append_int64 (bson , key , key_len , Z_CURSORID_OBJ_P (object )-> id );
@@ -178,17 +181,17 @@ static void php_phongo_bson_append_object(bson_t* bson, php_phongo_bson_flags_t
178
181
#endif
179
182
}
180
183
#if PHP_VERSION_ID >= 70000
181
- php_phongo_zval_to_bson (& obj_data , flags , & child , NULL TSRMLS_CC );
184
+ php_phongo_zval_to_bson_internal (& obj_data , field_path , flags , & child , NULL TSRMLS_CC );
182
185
#else
183
- php_phongo_zval_to_bson (obj_data , flags , & child , NULL TSRMLS_CC );
186
+ php_phongo_zval_to_bson_internal (obj_data , field_path , flags , & child , NULL TSRMLS_CC );
184
187
#endif
185
188
bson_append_document_end (bson , & child );
186
189
} else {
187
190
bson_append_array_begin (bson , key , key_len , & child );
188
191
#if PHP_VERSION_ID >= 70000
189
- php_phongo_zval_to_bson (& obj_data , flags , & child , NULL TSRMLS_CC );
192
+ php_phongo_zval_to_bson_internal (& obj_data , field_path , flags , & child , NULL TSRMLS_CC );
190
193
#else
191
- php_phongo_zval_to_bson (obj_data , flags , & child , NULL TSRMLS_CC );
194
+ php_phongo_zval_to_bson_internal (obj_data , field_path , flags , & child , NULL TSRMLS_CC );
192
195
#endif
193
196
bson_append_array_end (bson , & child );
194
197
}
@@ -294,16 +297,18 @@ static void php_phongo_bson_append_object(bson_t* bson, php_phongo_bson_flags_t
294
297
295
298
mongoc_log (MONGOC_LOG_LEVEL_TRACE , MONGOC_LOG_DOMAIN , "encoding document" );
296
299
bson_append_document_begin (bson , key , key_len , & child );
297
- php_phongo_zval_to_bson (object , flags , & child , NULL TSRMLS_CC );
300
+ php_phongo_zval_to_bson_internal (object , field_path , flags , & child , NULL TSRMLS_CC );
298
301
bson_append_document_end (bson , & child );
299
302
}
300
303
} /* }}} */
301
304
302
305
/* Appends the zval argument to the BSON document. If the argument is an object,
303
306
* or an array that should be serialized as an embedded document, this function
304
307
* will defer to php_phongo_bson_append_object(). */
305
- static void php_phongo_bson_append (bson_t * bson , php_phongo_bson_flags_t flags , const char * key , long key_len , zval * entry TSRMLS_DC ) /* {{{ */
308
+ static void php_phongo_bson_append (bson_t * bson , php_phongo_field_path * field_path , php_phongo_bson_flags_t flags , const char * key , long key_len , zval * entry TSRMLS_DC ) /* {{{ */
306
309
{
310
+ php_phongo_field_path_write_item_at_current_level (field_path , key );
311
+
307
312
#if PHP_VERSION_ID >= 70000
308
313
try_again :
309
314
#endif
@@ -337,7 +342,9 @@ static void php_phongo_bson_append(bson_t* bson, php_phongo_bson_flags_t flags,
337
342
if (bson_utf8_validate (Z_STRVAL_P (entry ), Z_STRLEN_P (entry ), true)) {
338
343
bson_append_utf8 (bson , key , key_len , Z_STRVAL_P (entry ), Z_STRLEN_P (entry ));
339
344
} else {
340
- phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected invalid UTF-8 for fieldname \"%s\": %s" , key , Z_STRVAL_P (entry ));
345
+ char * path_string = php_phongo_field_path_as_string (field_path );
346
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected invalid UTF-8 for field path \"%s\": %s" , path_string , Z_STRVAL_P (entry ));
347
+ efree (path_string );
341
348
}
342
349
break ;
343
350
@@ -347,7 +354,9 @@ static void php_phongo_bson_append(bson_t* bson, php_phongo_bson_flags_t flags,
347
354
HashTable * tmp_ht = HASH_OF (entry );
348
355
349
356
if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT (tmp_ht ) > 0 ) {
350
- phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for fieldname \"%s\"" , key );
357
+ char * path_string = php_phongo_field_path_as_string (field_path );
358
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for field path \"%s\"" , path_string );
359
+ efree (path_string );
351
360
break ;
352
361
}
353
362
@@ -356,7 +365,9 @@ static void php_phongo_bson_append(bson_t* bson, php_phongo_bson_flags_t flags,
356
365
}
357
366
358
367
bson_append_array_begin (bson , key , key_len , & child );
359
- php_phongo_zval_to_bson (entry , flags , & child , NULL TSRMLS_CC );
368
+ field_path -> current_level ++ ;
369
+ php_phongo_zval_to_bson_internal (entry , field_path , flags , & child , NULL TSRMLS_CC );
370
+ field_path -> current_level -- ;
360
371
bson_append_array_end (bson , & child );
361
372
362
373
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
@@ -370,15 +381,19 @@ static void php_phongo_bson_append(bson_t* bson, php_phongo_bson_flags_t flags,
370
381
HashTable * tmp_ht = HASH_OF (entry );
371
382
372
383
if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT (tmp_ht ) > 0 ) {
373
- phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for fieldname \"%s\"" , key );
384
+ char * path_string = php_phongo_field_path_as_string (field_path );
385
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected recursion for field path \"%s\"" , path_string );
386
+ efree (path_string );
374
387
break ;
375
388
}
376
389
377
390
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
378
391
ZEND_HASH_INC_APPLY_COUNT (tmp_ht );
379
392
}
380
393
381
- php_phongo_bson_append_object (bson , flags , key , key_len , entry TSRMLS_CC );
394
+ field_path -> current_level ++ ;
395
+ php_phongo_bson_append_object (bson , field_path , flags , key , key_len , entry TSRMLS_CC );
396
+ field_path -> current_level -- ;
382
397
383
398
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION (tmp_ht )) {
384
399
ZEND_HASH_DEC_APPLY_COUNT (tmp_ht );
@@ -388,23 +403,23 @@ static void php_phongo_bson_append(bson_t* bson, php_phongo_bson_flags_t flags,
388
403
389
404
#if PHP_VERSION_ID >= 70000
390
405
case IS_INDIRECT :
391
- php_phongo_bson_append (bson , flags , key , key_len , Z_INDIRECT_P (entry ) TSRMLS_DC );
406
+ php_phongo_bson_append (bson , field_path , flags , key , key_len , Z_INDIRECT_P (entry ) TSRMLS_DC );
392
407
break ;
393
408
394
409
case IS_REFERENCE :
395
410
ZVAL_DEREF (entry );
396
411
goto try_again ;
397
412
#endif
398
413
399
- default :
400
- phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected unsupported PHP type for fieldname \"%s\": %d (%s)" , key , Z_TYPE_P (entry ), zend_get_type_by_const (Z_TYPE_P (entry )));
414
+ default : {
415
+ char * path_string = php_phongo_field_path_as_string (field_path );
416
+ phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "Detected unsupported PHP type for field path \"%s\": %d (%s)" , path_string , Z_TYPE_P (entry ), zend_get_type_by_const (Z_TYPE_P (entry )));
417
+ efree (path_string );
418
+ }
401
419
}
402
420
} /* }}} */
403
421
404
- /* Converts the array or object argument to a BSON document. If the object is an
405
- * instance of MongoDB\BSON\Serializable, the return value of bsonSerialize()
406
- * will be used. */
407
- void php_phongo_zval_to_bson (zval * data , php_phongo_bson_flags_t flags , bson_t * bson , bson_t * * bson_out TSRMLS_DC ) /* {{{ */
422
+ static void php_phongo_zval_to_bson_internal (zval * data , php_phongo_field_path * field_path , php_phongo_bson_flags_t flags , bson_t * bson , bson_t * * bson_out TSRMLS_DC ) /* {{{ */
408
423
{
409
424
HashTable * ht_data = NULL ;
410
425
#if PHP_VERSION_ID >= 70000
@@ -482,7 +497,6 @@ void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t*
482
497
483
498
if (instanceof_function (Z_OBJCE_P (data ), php_phongo_type_ce TSRMLS_CC )) {
484
499
phongo_throw_exception (PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC , "%s instance %s cannot be serialized as a root element" , ZSTR_VAL (php_phongo_type_ce -> name ), ZSTR_VAL (Z_OBJCE_P (data )-> name ));
485
-
486
500
return ;
487
501
}
488
502
@@ -538,7 +552,7 @@ void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t*
538
552
zend_string_addref (string_key );
539
553
}
540
554
541
- php_phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , ZSTR_VAL (string_key ), strlen (ZSTR_VAL (string_key )), value TSRMLS_CC );
555
+ php_phongo_bson_append (bson , field_path , flags & ~PHONGO_BSON_ADD_ID , ZSTR_VAL (string_key ), strlen (ZSTR_VAL (string_key )), value TSRMLS_CC );
542
556
543
557
zend_string_release (string_key );
544
558
}
@@ -593,7 +607,7 @@ void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t*
593
607
spprintf (& string_key , 0 , "%ld" , num_key );
594
608
}
595
609
596
- php_phongo_bson_append (bson , flags & ~PHONGO_BSON_ADD_ID , string_key , strlen (string_key ), * value TSRMLS_CC );
610
+ php_phongo_bson_append (bson , field_path , flags & ~PHONGO_BSON_ADD_ID , string_key , strlen (string_key ), * value TSRMLS_CC );
597
611
598
612
if (hash_type == HASH_KEY_IS_LONG ) {
599
613
efree (string_key );
@@ -629,6 +643,18 @@ void php_phongo_zval_to_bson(zval* data, php_phongo_bson_flags_t flags, bson_t*
629
643
}
630
644
} /* }}} */
631
645
646
+ /* Converts the array or object argument to a BSON document. If the object is an
647
+ * instance of MongoDB\BSON\Serializable, the return value of bsonSerialize()
648
+ * will be used. */
649
+ void php_phongo_zval_to_bson (zval * data , php_phongo_bson_flags_t flags , bson_t * bson , bson_t * * bson_out TSRMLS_DC ) /* {{{ */
650
+ {
651
+ php_phongo_field_path * field_path = php_phongo_field_path_alloc ();
652
+
653
+ php_phongo_zval_to_bson_internal (data , field_path , flags , bson , bson_out TSRMLS_CC );
654
+
655
+ php_phongo_field_path_free (field_path );
656
+ } /* }}} */
657
+
632
658
/*
633
659
* Local variables:
634
660
* tab-width: 4
0 commit comments