php_ion_serializer_php *obj = php_ion_obj(serializer_php, Z_OBJ_P(ZEND_THIS));
PTR_CHECK(obj);
+ obj->serializer.call_magic = true;
+
ZEND_PARSE_PARAMETERS_START(0, 3)
Z_PARAM_OPTIONAL
Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->opt, ce_Writer_Options)
+ Z_PARAM_BOOL(obj->serializer.multi_seq)
Z_PARAM_BOOL(obj->serializer.call_magic)
Z_PARAM_STR_OR_NULL(obj->serializer.call_custom)
ZEND_PARSE_PARAMETERS_END();
ZEND_METHOD(ion_Unserializer_PHP, __construct)
{
php_ion_unserializer_php *obj = php_ion_obj(unserializer_php, Z_OBJ_P(ZEND_THIS));
+ PTR_CHECK(obj);
+
+ obj->unserializer.call_magic = true;
ZEND_PARSE_PARAMETERS_START(0, 3)
Z_PARAM_OPTIONAL
Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->opt, ce_Reader_Options)
+ Z_PARAM_BOOL(obj->unserializer.multi_seq)
Z_PARAM_BOOL(obj->unserializer.call_magic)
Z_PARAM_STR_OR_NULL(obj->unserializer.call_custom)
ZEND_PARSE_PARAMETERS_END();
class PHP implements \ion\Serializer {
public function __construct(
public readonly ?\ion\Writer\Options $writerOptions = null,
+ public readonly bool $multiSequence = false,
public readonly bool $callMagicSerialize = true,
public readonly ?string $callCustomSerialize = null,
) {}
class PHP implements \ion\Unserializer {
public function __construct(
public readonly ?\ion\Reader\Options $readerOptions = null,
+ public readonly bool $multiSequence = true,
public readonly bool $callMagicUnserialize = true,
public readonly ?string $callCustomUnserialize = null,
){}
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 5dc8abb809cd14ed4c542ca5114bd4ceda42d70b */
+ * Stub hash: 4c467ccb7b924c30cc5471b9212f4bffe0b0ba31 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ion_serialize, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, data, IS_MIXED, 0)
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Serializer_PHP___construct, 0, 0, 0)
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, writerOptions, ion\\Writer\\Options, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, multiSequence, _IS_BOOL, 0, "false")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callMagicSerialize, _IS_BOOL, 0, "true")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callCustomSerialize, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Unserializer_PHP___construct, 0, 0, 0)
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, readerOptions, ion\\Reader\\Options, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, multiSequence, _IS_BOOL, 0, "true")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callMagicUnserialize, _IS_BOOL, 0, "true")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callCustomUnserialize, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
zend_declare_typed_property(class_entry, property_writerOptions_name, &property_writerOptions_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_writerOptions_class_ion_Writer_Options, 0, MAY_BE_NULL));
zend_string_release(property_writerOptions_name);
+ zval property_multiSequence_default_value;
+ ZVAL_UNDEF(&property_multiSequence_default_value);
+ zend_string *property_multiSequence_name = zend_string_init("multiSequence", sizeof("multiSequence") - 1, 1);
+ zend_declare_typed_property(class_entry, property_multiSequence_name, &property_multiSequence_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_multiSequence_name);
+
zval property_callMagicSerialize_default_value;
ZVAL_UNDEF(&property_callMagicSerialize_default_value);
zend_string *property_callMagicSerialize_name = zend_string_init("callMagicSerialize", sizeof("callMagicSerialize") - 1, 1);
zend_declare_typed_property(class_entry, property_readerOptions_name, &property_readerOptions_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_readerOptions_class_ion_Reader_Options, 0, MAY_BE_NULL));
zend_string_release(property_readerOptions_name);
+ zval property_multiSequence_default_value;
+ ZVAL_UNDEF(&property_multiSequence_default_value);
+ zend_string *property_multiSequence_name = zend_string_init("multiSequence", sizeof("multiSequence") - 1, 1);
+ zend_declare_typed_property(class_entry, property_multiSequence_name, &property_multiSequence_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
+ zend_string_release(property_multiSequence_name);
+
zval property_callMagicUnserialize_default_value;
ZVAL_UNDEF(&property_callMagicUnserialize_default_value);
zend_string *property_callMagicUnserialize_name = zend_string_init("callMagicUnserialize", sizeof("callMagicUnserialize") - 1, 1);
zend_string *call_custom;
zend_bool call_magic;
+ zend_bool multi_seq;
uint32_t level;
HashTable *ids;
zend_string *call_custom;
zend_bool call_magic;
+ zend_bool multi_seq;
uint32_t level;
HashTable *ids;
php_ion_decl(serializer_php, Serializer_PHP, php_ion_serializer_php_dtor(obj));
+static inline void php_ion_serialize_ex(php_ion_serializer *ser, zval *zv)
+{
+ HashPosition pos;
+ HashTable *arr = NULL;
+
+ if (ser->multi_seq) {
+ if (Z_TYPE_P(zv) != IS_ARRAY || !zend_array_is_list(Z_ARRVAL_P(zv))) {
+ zend_throw_exception_ex(spl_ce_InvalidArgumentException, IERR_INVALID_ARG,
+ "Expected a packed, consecutively numerically indexed array as argument to the multi sequence serializer");
+ return;
+ }
+
+ arr = Z_ARRVAL_P(zv);
+
+ zend_hash_internal_pointer_reset_ex(arr, &pos);
+ zv = zend_hash_get_current_data_ex(arr, &pos);
+ }
+
+ while (zv) {
+ /* start off with a global PHP annotation instead of repeating it all over the place */
+ if (0 == php_ion_globals_serializer_step()) {
+ ION_STRING is;
+ ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("PHP"))));
+ }
+ php_ion_serialize_zval(ser, zv);
+ php_ion_globals_serializer_exit();
+
+ if (!ser->multi_seq) {
+ break;
+ }
+ zend_hash_move_forward_ex(arr, &pos);
+ zv = zend_hash_get_current_data_ex(arr, &pos);
+ }
+}
+
void php_ion_serialize(php_ion_serializer *ser, zval *zv, zval *return_value)
{
zend_object *zo_opt = NULL, *zo_ser = NULL;
ser->writer = writer->writer;
ser->buffer = &writer->buffer.str;
- /* start off with a global PHP annotation instead of repeating it all over the place */
- if (0 == php_ion_globals_serializer_step()) {
- ION_STRING is;
- ION_CHECK(ion_writer_add_annotation(ser->writer, ion_string_assign_cstr(&is, ZEND_STRL("PHP"))),
- if (zo_ser) OBJ_RELEASE(zo_ser));
+ if (!EG(exception)) {
+ php_ion_serialize_ex(ser, zv);
}
- php_ion_serialize_zval(ser, zv);
- php_ion_globals_serializer_exit();
/* make sure to flush when done, else str.s might not contain everything until the writer is closed */
ion_writer_flush(ser->writer, NULL);
php_ion_decl(unserializer_php, Unserializer_PHP, php_ion_unserializer_php_dtor(obj));
+static inline void php_ion_unserialize_ex(php_ion_unserializer *ser, zval *return_value)
+{
+ if (ser->multi_seq) {
+ array_init(return_value);
+ }
+
+ do {
+ zval tmp;
+ ZVAL_NULL(&tmp);
+ php_ion_globals_unserializer_step();
+ php_ion_unserialize_zval(ser, &tmp, NULL);
+ php_ion_globals_unserializer_exit();
+ ION_CATCH(zval_ptr_dtor(&tmp));
+
+ if (!ser->multi_seq) {
+ RETURN_COPY_VALUE(&tmp);
+ } else if (ser->type != tid_EOF) {
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
+ }
+ } while (ser->type != tid_EOF);
+}
+
void php_ion_unserialize(php_ion_unserializer *ser, zval *zdata, zval *return_value)
{
zend_object *zo_opt = NULL, *zo_ser = NULL;
php_ion_reader_ctor(reader);
ser->reader = reader->reader;
- ION_CATCH();
- php_ion_globals_unserializer_step();
- php_ion_unserialize_zval(ser, return_value, NULL);
- php_ion_globals_unserializer_exit();
+ if (!EG(exception)) {
+ php_ion_unserialize_ex(ser, return_value);
+ }
OBJ_RELEASE(zo_reader);
if (zo_opt) {