Hi,

I'm facing an issue I don't know how to overcome.

Short story:
I've an object which properties are connected to the internal struct
whith get_property() and write_property() object handlers.

Now if BP_VAR_W is used to access a property with read_prop() the
following works fine:

        // $this->body is a string
        $this->body{0} = 'X';

... but the following does nothing than producing a memleak:

        $body = &$this->body;
        $body = 'X';

Also, it seems impossible to connect *values* (longs or string lengths for 
instance) through 
that interface, because I cannot tell the zval that the value should point 
elsewhere...

Any advice very much appreciated :)
Do I have to disallow referenced writing access?

Long story (sorry):

static zval *_http_message_object_read_prop(zval *object, zval *member, int 
type TSRMLS_DC)
{
        getObjectEx(http_message_object, obj, object);
        http_message *msg = obj->message;
        zval *return_value;
#ifdef WONKY
        ulong h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member)+1);
#else
        zend_property_info *pinfo = zend_get_property_info(obj->zo.ce, member, 
1 TSRMLS_CC);
        
        if (!pinfo || ACC_PROP_PUBLIC(pinfo->flags)) {
                return zend_get_std_object_handlers()->read_property(object, 
member, type TSRMLS_CC);
        }
#endif

        if (type == BP_VAR_W) {
                return_value = &EG(uninitialized_zval);
                return_value->refcount = 1;
                return_value->is_ref = 1;
        } else {
                ALLOC_ZVAL(return_value);
                return_value->refcount = 0;
                return_value->is_ref = 0;
        }

#ifdef WONKY
        switch (h)
#else
        switch (pinfo->h)
#endif
        {
                case HTTP_MSG_PROPHASH_TYPE:
                case HTTP_MSG_CHILD_PROPHASH_TYPE:
                        RETVAL_LONG(msg->type);
                break;

                case HTTP_MSG_PROPHASH_HTTP_VERSION:
                case HTTP_MSG_CHILD_PROPHASH_HTTP_VERSION:
                        RETVAL_DOUBLE(msg->http.version);
                break;

                case HTTP_MSG_PROPHASH_BODY:
                case HTTP_MSG_CHILD_PROPHASH_BODY:
                        phpstr_fix(PHPSTR(msg));
                        RETVAL_PHPSTR(PHPSTR(msg), 0, !return_value->is_ref);
                break;

                case HTTP_MSG_PROPHASH_HEADERS:
                case HTTP_MSG_CHILD_PROPHASH_HEADERS:
                        if (return_value->is_ref) {
                                Z_TYPE_P(return_value) = IS_ARRAY;
                                Z_ARRVAL_P(return_value) = &msg->hdrs;
                        } else {
                                array_init(return_value);
                                zend_hash_copy(Z_ARRVAL_P(return_value), 
&msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
                        }
                break;

                case HTTP_MSG_PROPHASH_PARENT_MESSAGE:
                case HTTP_MSG_CHILD_PROPHASH_PARENT_MESSAGE:
                        if (msg->parent) {
                                RETVAL_OBJVAL(obj->parent);
                        } else {
                                RETVAL_NULL();
                        }
                break;

                case HTTP_MSG_PROPHASH_REQUEST_METHOD:
                case HTTP_MSG_CHILD_PROPHASH_REQUEST_METHOD:
                        if (HTTP_MSG_TYPE(REQUEST, msg) && 
msg->http.info.request.method) {
                                RETVAL_STRING(msg->http.info.request.method, 1);
                        } else {
                                RETVAL_NULL();
                        }
                break;

                case HTTP_MSG_PROPHASH_REQUEST_URI:
                        if (HTTP_MSG_TYPE(REQUEST, msg) && 
msg->http.info.request.URI) {
                                RETVAL_STRING(msg->http.info.request.URI, 
!return_value->is_ref);
                        } else {
                                RETVAL_NULL();
                        }
                break;

                case HTTP_MSG_PROPHASH_RESPONSE_CODE:
                case HTTP_MSG_CHILD_PROPHASH_RESPONSE_CODE:
                        if (HTTP_MSG_TYPE(RESPONSE, msg)) {
                                RETVAL_LONG(msg->http.info.response.code);
                        } else {
                                RETVAL_NULL();
                        }
                break;
                
                case HTTP_MSG_PROPHASH_RESPONSE_STATUS:
                case HTTP_MSG_CHILD_PROPHASH_RESPONSE_STATUS:
                        if (HTTP_MSG_TYPE(RESPONSE, msg) && 
msg->http.info.response.status) {
                                RETVAL_STRING(msg->http.info.response.status, 
!return_value->is_ref);
                        } else {
                                RETVAL_NULL();
                        }
                break;
                
                default:
#ifdef WONKY
                        return 
zend_get_std_object_handlers()->read_property(object, member, type TSRMLS_CC);
#else
                        RETVAL_NULL();
#endif
                break;
        }

        return return_value;
}

-- 
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to