]> granicus.if.org Git - php/commitdiff
- New Interface Serializeable
authorMarcus Boerger <helly@php.net>
Mon, 7 Mar 2005 22:23:14 +0000 (22:23 +0000)
committerMarcus Boerger <helly@php.net>
Mon, 7 Mar 2005 22:23:14 +0000 (22:23 +0000)
- Change signature of unserialize() callback to ease inheritance and
  support code reuse of handlers

Zend/zend.h
Zend/zend_compile.c
Zend/zend_interfaces.c
Zend/zend_interfaces.h

index 0583c09cb5126a2153e2b508aec8c737fae98ae3..248e7d02330e42e29156d03e8d74ffc3debc1046 100644 (file)
@@ -331,6 +331,8 @@ struct _zend_class_entry {
        union _zend_function *__get;
        union _zend_function *__set;
        union _zend_function *__call;
+       union _zend_function *serialize_func;
+       union _zend_function *unserialize_func;
 
        zend_class_iterator_funcs iterator_funcs;
 
@@ -341,7 +343,7 @@ struct _zend_class_entry {
 
        /* serializer callbacks */
        int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
-       int (*unserialize)(zval **object, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
+       int (*unserialize)(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
 
        zend_class_entry **interfaces;
        zend_uint num_interfaces;
index 3309608b51ca9eecdbe5f9bcbf10a717895475e3..a2741faa427cac402ec903789920df8c0a2f9bae 100644 (file)
@@ -3848,6 +3848,8 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
                ce->module = NULL;
                ce->serialize = NULL;
                ce->unserialize = NULL;
+               ce->serialize_func = NULL;
+               ce->unserialize_func = NULL;
        }
 }
 
index cb79742ad35a155c1aad8639bf13994b4e7f40b5..8e1b6038016367a303747d0e54ded292d23bc6d4 100755 (executable)
@@ -27,6 +27,7 @@ ZEND_API zend_class_entry *zend_ce_traversable;
 ZEND_API zend_class_entry *zend_ce_aggregate;
 ZEND_API zend_class_entry *zend_ce_iterator;
 ZEND_API zend_class_entry *zend_ce_arrayaccess;
+ZEND_API zend_class_entry *zend_ce_serializeable;
 
 /* {{{ zend_call_method 
  Only returns the returned zval if retval_ptr != NULL */
@@ -392,6 +393,79 @@ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_en
 }
 /* }}}*/
 
+/* {{{ zend_user_serialize */
+int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
+{
+       zend_class_entry * ce = Z_OBJCE_P(object);
+       zval *retval;
+       int result;
+
+       zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
+
+
+       if (!retval || EG(exception)) {
+               result = FAILURE;
+       } else {
+               switch(Z_TYPE_P(retval)) {
+               case IS_NULL:
+                       /* we could also make this '*buf_len = 0' but this allows to skip variables */
+                       result = FAILURE;
+                       break;
+               case IS_STRING:
+                       *buffer = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
+                       *buf_len = Z_STRLEN_P(retval);
+                       result = SUCCESS;
+                       break;
+               default: /* failure */
+                       result = FAILURE;
+                       break;
+               }
+               zval_ptr_dtor(&retval);
+       }
+
+       if (result == FAILURE) {
+               zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name);
+       }
+       return result;
+}
+/* }}} */
+
+/* {{{ zend_user_unserialize */
+int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
+{
+       zval * zdata;
+
+       object_init_ex(*object, ce);
+       
+       MAKE_STD_ZVAL(zdata);
+       ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
+
+       zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
+       
+       zval_ptr_dtor(&zdata);
+       
+       if (EG(exception)) {
+               return FAILURE;
+       } else {
+               return SUCCESS;
+       }
+}
+/* }}} */
+
+/* {{{ zend_implement_serializeable */
+static int zend_implement_serializeable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
+{
+       if ((class_type->serialize   && class_type->serialize   != zend_user_serialize)
+       ||  (class_type->unserialize && class_type->unserialize != zend_user_unserialize)
+       ) {
+               return FAILURE;
+       }
+       class_type->serialize = zend_user_serialize;
+       class_type->unserialize = zend_user_unserialize;
+       return SUCCESS;
+}
+/* }}}*/
+
 /* {{{ function tables */
 zend_function_entry zend_funcs_aggregate[] = {
        ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
@@ -428,6 +502,16 @@ zend_function_entry zend_funcs_arrayaccess[] = {
        {NULL, NULL, NULL}
 };
 
+static
+ZEND_BEGIN_ARG_INFO(arginfo_serializeable_serialize, 0)
+       ZEND_ARG_INFO(0, serialized)
+ZEND_END_ARG_INFO();
+
+zend_function_entry zend_funcs_serializeable[] = {
+       ZEND_ABSTRACT_ME(serializeable, serialize,   NULL)
+       ZEND_FENTRY(unserialize, NULL, arginfo_serializeable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR) 
+       {NULL, NULL, NULL}
+};
 /* }}} */
 
 #define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
@@ -453,6 +537,8 @@ ZEND_API void zend_register_interfaces(TSRMLS_D)
        REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
        
        REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
+       
+       REGISTER_ITERATOR_INTERFACE(serializeable, Serializeable)
 }
 /* }}} */
 
index 78674cc62701b2328feca0c49874f31555d95c06..a720f44a74f1b46beb61a22b8e7fe903af9b06ca 100755 (executable)
@@ -30,6 +30,7 @@ extern ZEND_API zend_class_entry *zend_ce_traversable;
 extern ZEND_API zend_class_entry *zend_ce_aggregate;
 extern ZEND_API zend_class_entry *zend_ce_iterator;
 extern ZEND_API zend_class_entry *zend_ce_arrayaccess;
+extern ZEND_API zend_class_entry *zend_ce_serializeable;
 
 typedef struct _zend_user_iterator {
        zend_object_iterator     it;