cvs: php4 /ext/standard basic_functions.c file.h ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c php_fopen_wrappers.h /ext/zlib zlib.c
/main php_streams.h streams.c user_streams.c

From: Date: Tue, 19 Mar 2002 03:51:02 +0000
Subject: cvs: php4 /ext/standard basic_functions.c file.h ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c php_fopen_wrappers.h /ext/zlib zlib.c
/main php_streams.h streams.c user_streams.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-10399@lists.php.net to get a copy of this message
wez Mon Mar 18 22:51:02 2002 EDT Added files: /php4/main user_streams.c Modified files: /php4/ext/standard basic_functions.c file.h ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c php_fopen_wrappers.h /php4/ext/zlib zlib.c /php4/main php_streams.h streams.c Log: Implement user-space streams. There's probably room for improvement, docs will following some time this week.

Index: php4/ext/standard/basic_functions.c diff -u php4/ext/standard/basic_functions.c:1.458 php4/ext/standard/basic_functions.c:1.459 --- php4/ext/standard/basic_functions.c:1.458 Mon Mar 18 05:44:39 2002 +++ php4/ext/standard/basic_functions.c Mon Mar 18 22:51:01 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.458 2002/03/18 10:44:39 wez Exp $ */ +/* $Id: basic_functions.c,v 1.459 2002/03/19 03:51:01 wez Exp $ */ #include "php.h" #include "php_streams.h" @@ -624,6 +624,7 @@ PHP_FE(socket_set_blocking, NULL) PHP_FE(fgetwrapperdata, NULL) + PHP_FE(file_register_wrapper, NULL) #if HAVE_SYS_TIME_H PHP_FE(socket_set_timeout, NULL) Index: php4/ext/standard/file.h diff -u php4/ext/standard/file.h:1.51 php4/ext/standard/file.h:1.52 --- php4/ext/standard/file.h:1.51 Mon Mar 18 13:54:27 2002 +++ php4/ext/standard/file.h Mon Mar 18 22:51:01 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.h,v 1.51 2002/03/18 18:54:27 wez Exp $ */ +/* $Id: file.h,v 1.52 2002/03/19 03:51:01 wez Exp $ */ /* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */ @@ -71,6 +71,7 @@ PHP_NAMED_FUNCTION(php_if_fstat); PHP_FUNCTION(fgetwrapperdata); +PHP_FUNCTION(file_register_wrapper); PHPAPI int php_set_sock_blocking(int socketd, int block); PHPAPI int php_file_le_stream(void); Index: php4/ext/standard/ftp_fopen_wrapper.c diff -u php4/ext/standard/ftp_fopen_wrapper.c:1.18 php4/ext/standard/ftp_fopen_wrapper.c:1.19 --- php4/ext/standard/ftp_fopen_wrapper.c:1.18 Mon Mar 18 13:54:28 2002 +++ php4/ext/standard/ftp_fopen_wrapper.c Mon Mar 18 22:51:01 2002 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholzgra@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: ftp_fopen_wrapper.c,v 1.18 2002/03/18 18:54:28 wez Exp $ */ +/* $Id: ftp_fopen_wrapper.c,v 1.19 2002/03/19 03:51:01 wez Exp $ */ #include "php.h" #include "php_globals.h" @@ -79,13 +79,14 @@ php_stream_wrapper php_stream_ftp_wrapper = { php_stream_url_wrap_ftp, + NULL, NULL }; /* {{{ php_fopen_url_wrap_ftp */ -php_stream * php_stream_url_wrap_ftp(char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) +php_stream * php_stream_url_wrap_ftp(char *path, char *mode, int options, char **opened_path, void *wrappercontext STREAMS_DC TSRMLS_DC) { php_stream *stream=NULL; php_url *resource=NULL; Index: php4/ext/standard/http_fopen_wrapper.c diff -u php4/ext/standard/http_fopen_wrapper.c:1.27 php4/ext/standard/http_fopen_wrapper.c:1.28 --- php4/ext/standard/http_fopen_wrapper.c:1.27 Mon Mar 18 13:54:28 2002 +++ php4/ext/standard/http_fopen_wrapper.c Mon Mar 18 22:51:01 2002 @@ -18,7 +18,7 @@ | Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: http_fopen_wrapper.c,v 1.27 2002/03/18 18:54:28 wez Exp $ */ +/* $Id: http_fopen_wrapper.c,v 1.28 2002/03/19 03:51:01 wez Exp $ */ #include "php.h" #include "php_globals.h" @@ -71,7 +71,7 @@ #define HTTP_HEADER_BLOCK_SIZE 1024 -php_stream *php_stream_url_wrap_http(char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) +php_stream *php_stream_url_wrap_http(char *path, char *mode, int options, char **opened_path, void *wrappercontext STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; php_url *resource = NULL; @@ -268,7 +268,7 @@ else { strlcpy(new_path, location, sizeof(new_path)); } - stream = php_stream_url_wrap_http(new_path, mode, options, opened_path STREAMS_CC TSRMLS_CC); + stream = php_stream_url_wrap_http(new_path, mode, options, opened_path, NULL STREAMS_CC TSRMLS_CC); if (stream->wrapperdata) { entryp = &entry; MAKE_STD_ZVAL(entry); @@ -311,6 +311,7 @@ php_stream_wrapper php_stream_http_wrapper = { php_stream_url_wrap_http, + NULL, NULL }; Index: php4/ext/standard/php_fopen_wrapper.c diff -u php4/ext/standard/php_fopen_wrapper.c:1.14 php4/ext/standard/php_fopen_wrapper.c:1.15 --- php4/ext/standard/php_fopen_wrapper.c:1.14 Mon Mar 18 13:54:28 2002 +++ php4/ext/standard/php_fopen_wrapper.c Mon Mar 18 22:51:01 2002 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholzgra@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrapper.c,v 1.14 2002/03/18 18:54:28 wez Exp $ */ +/* $Id: php_fopen_wrapper.c,v 1.15 2002/03/19 03:51:01 wez Exp $ */ #include <stdio.h> #include <stdlib.h> @@ -30,7 +30,7 @@ #include "php_standard.h" #include "php_fopen_wrappers.h" -php_stream * php_stream_url_wrap_php(char * path, char * mode, int options, char ** opened_path STREAMS_DC TSRMLS_DC) +php_stream * php_stream_url_wrap_php(char * path, char * mode, int options, char ** opened_path, void *wrappercontext STREAMS_DC TSRMLS_DC) { FILE * fp = NULL; php_stream * stream = NULL; @@ -54,6 +54,7 @@ php_stream_wrapper php_stream_php_wrapper = { php_stream_url_wrap_php, + NULL, NULL }; Index: php4/ext/standard/php_fopen_wrappers.h diff -u php4/ext/standard/php_fopen_wrappers.h:1.10 php4/ext/standard/php_fopen_wrappers.h:1.11 --- php4/ext/standard/php_fopen_wrappers.h:1.10 Mon Mar 18 13:54:28 2002 +++ php4/ext/standard/php_fopen_wrappers.h Mon Mar 18 22:51:01 2002 @@ -18,13 +18,13 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrappers.h,v 1.10 2002/03/18 18:54:28 wez Exp $ */ +/* $Id: php_fopen_wrappers.h,v 1.11 2002/03/19 03:51:01 wez Exp $ */ #ifndef PHP_FOPEN_WRAPPERS_H #define PHP_FOPEN_WRAPPERS_H -php_stream *php_stream_url_wrap_http(char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC); -php_stream *php_stream_url_wrap_ftp(char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC); +php_stream *php_stream_url_wrap_http(char *path, char *mode, int options, char **opened_path, void *wrappercontext STREAMS_DC TSRMLS_DC); +php_stream *php_stream_url_wrap_ftp(char *path, char *mode, int options, char **opened_path, void *wrappercontext STREAMS_DC TSRMLS_DC); php_stream_wrapper php_stream_http_wrapper; php_stream_wrapper php_stream_ftp_wrapper; php_stream_wrapper php_stream_php_wrapper; Index: php4/ext/zlib/zlib.c diff -u php4/ext/zlib/zlib.c:1.114 php4/ext/zlib/zlib.c:1.115 --- php4/ext/zlib/zlib.c:1.114 Mon Mar 18 13:54:29 2002 +++ php4/ext/zlib/zlib.c Mon Mar 18 22:51:01 2002 @@ -18,7 +18,7 @@ | Jade Nicoletti <nicoletti@nns.ch> | +----------------------------------------------------------------------+ */ -/* $Id: zlib.c,v 1.114 2002/03/18 18:54:29 wez Exp $ */ +/* $Id: zlib.c,v 1.115 2002/03/19 03:51:01 wez Exp $ */ #define IS_EXT_MODULE #ifdef HAVE_CONFIG_H @@ -237,9 +237,7 @@ { php_info_print_table_start(); php_info_print_table_row(2, "ZLib Support", "enabled"); -#if HAVE_FOPENCOOKIE php_info_print_table_row(2, "'zlib:' fopen wrapper", "enabled"); -#endif php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION ); php_info_print_table_row(2, "Linked Version", (char *)zlibVersion() ); php_info_print_table_end(); Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.18 php4/main/php_streams.h:1.19 --- php4/main/php_streams.h:1.18 Mon Mar 18 14:47:50 2002 +++ php4/main/php_streams.h Mon Mar 18 22:51:01 2002 @@ -101,12 +101,13 @@ } php_stream_ops; /* options uses the IGNORE_URL family of defines from fopen_wrappers.h */ -typedef php_stream *(*php_stream_factory_func_t)(char *filename, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC); +typedef php_stream *(*php_stream_factory_func_t)(char *filename, char *mode, int options, char **opened_path, void * wrappercontext STREAMS_DC TSRMLS_DC); typedef void (*php_stream_wrapper_dtor_func_t)(php_stream *stream TSRMLS_DC); typedef struct _php_stream_wrapper { php_stream_factory_func_t create; php_stream_wrapper_dtor_func_t destroy; + void * wrappercontext; } php_stream_wrapper; struct _php_stream { @@ -253,6 +254,7 @@ # define IGNORE_URL_WIN 0 #endif +int php_init_user_streams(TSRMLS_D); int php_init_stream_wrappers(TSRMLS_D); int php_shutdown_stream_wrappers(TSRMLS_D); PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); @@ -267,6 +269,11 @@ /* DO NOT call this on streams that are referenced by resources! */ PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream STREAMS_DC TSRMLS_DC); #define php_stream_make_seekable(origstream, newstream) _php_stream_make_seekable(origstream, newstream STREAMS_CC TSRMLS_CC) + + +/* for user-space streams */ +extern php_stream_ops php_stream_userspace_ops; +#define PHP_STREAM_IS_USERSPACE &php_stream_userspace_ops #endif Index: php4/main/streams.c diff -u php4/main/streams.c:1.32 php4/main/streams.c:1.33 --- php4/main/streams.c:1.32 Mon Mar 18 14:47:50 2002 +++ php4/main/streams.c Mon Mar 18 22:51:01 2002 @@ -891,7 +891,9 @@ int php_init_stream_wrappers(TSRMLS_D) { if (PG(allow_url_fopen)) { - return zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1); + if (zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS) + return php_init_user_streams(TSRMLS_C); + return FAILURE; } return SUCCESS; } @@ -940,7 +942,7 @@ protocol = NULL; } if (wrapper) { - php_stream *stream = wrapper->create(path, mode, options, opened_path STREAMS_REL_CC TSRMLS_CC); + php_stream *stream = wrapper->create(path, mode, options, opened_path, wrapper->wrappercontext STREAMS_REL_CC TSRMLS_CC); if (stream) stream->wrapper = wrapper; return stream; Index: php4/main/user_streams.c +++ php4/main/user_streams.c /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: | | Wez Furlong (wez@thebrainroom.com) | +----------------------------------------------------------------------+ */ #include "php.h" #include "php_globals.h" static int le_protocols; struct php_user_stream_wrapper { char * protoname; char * classname; zend_class_entry *ce; php_stream_wrapper wrapper; }; static php_stream *user_wrapper_factory(char *filename, char *mode, int options, char **opened_path, void * wrappercontext STREAMS_DC TSRMLS_DC); static void stream_wrapper_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) { struct php_user_stream_wrapper * uwrap = (struct php_user_stream_wrapper*)rsrc->ptr; php_unregister_url_stream_wrapper(uwrap->protoname TSRMLS_CC); efree(uwrap->protoname); efree(uwrap->classname); efree(uwrap); } int php_init_user_streams(TSRMLS_D) { le_protocols = zend_register_list_destructors_ex(stream_wrapper_dtor, NULL, "stream factory", 0); return le_protocols == FAILURE ? FAILURE : SUCCESS; } struct _php_userstream_data { struct php_user_stream_wrapper * wrapper; zval * object; }; typedef struct _php_userstream_data php_userstream_data_t; /* names of methods */ #define USERSTREAM_OPEN "stream_open" #define USERSTREAM_CLOSE "stream_close" #define USERSTREAM_READ "stream_read" #define USERSTREAM_WRITE "stream_write" #define USERSTREAM_FLUSH "stream_flush" #define USERSTREAM_SEEK "stream_seek" #define USERSTREAM_GETS "stream_gets" #define USERSTREAM_TELL "stream_tell" #define USERSTREAM_EOF "stream_eof" /* class should have methods like these: function stream_open($path, $mode, $options, &$opened_path) { return true/false; } function stream_read($count) { return false on error; else return string; } function stream_write($data) { return false on error; else return count written; } function stream_close() { } function stream_flush() { } function stream_seek($offset, $whence) { } function stream_gets($size) { return false on error; else return string; } * */ static php_stream *user_wrapper_factory(char *filename, char *mode, int options, char **opened_path, void *wrappercontext STREAMS_DC TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrappercontext; php_userstream_data_t *us; zval *zfilename, *zmode, *zopened, *zoptions, *zretval = NULL, *zfuncname; zval **args[4]; int call_result; php_stream *stream = NULL; us = emalloc(sizeof(*us)); us->wrapper = uwrap; /* create an instance of our class */ ALLOC_ZVAL(us->object); object_init_ex(us->object, uwrap->ce); ZVAL_REFCOUNT(us->object) = 1; PZVAL_IS_REF(us->object) = 1; /* call it's stream_open method - set up params first */ MAKE_STD_ZVAL(zfilename); ZVAL_STRING(zfilename, filename, 1); args[0] = &zfilename; MAKE_STD_ZVAL(zmode); ZVAL_STRING(zmode, mode, 1); args[1] = &zmode; MAKE_STD_ZVAL(zoptions); ZVAL_LONG(zoptions, options); args[2] = &zoptions; MAKE_STD_ZVAL(zopened); ZVAL_REFCOUNT(zopened) = 1; PZVAL_IS_REF(zopened) = 1; ZVAL_NULL(zopened); args[3] = &zopened; MAKE_STD_ZVAL(zfuncname); ZVAL_STRING(zfuncname, USERSTREAM_OPEN, 1); call_result = call_user_function_ex(NULL, &us->object, zfuncname, &zretval, 4, args, 0, NULL TSRMLS_CC); if (call_result == SUCCESS && zretval != NULL) { /* the stream is now open! */ stream = php_stream_alloc_rel(&php_stream_userspace_ops, us, 0, mode); /* if the opened path is set, copy it out */ if (Z_TYPE_P(zopened) == IS_STRING && opened_path) { *opened_path = estrndup(Z_STRVAL_P(zopened), Z_STRLEN_P(zopened)); } } else { /* destroy the object */ zval_ptr_dtor(&us->object); efree(us); } /* destroy everything else */ if (zretval) zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); zval_ptr_dtor(&zopened); zval_ptr_dtor(&zoptions); zval_ptr_dtor(&zmode); zval_ptr_dtor(&zfilename); return stream; } /* {{{ proto bool file_register_wrapper(string protocol, string classname) Registers a custom URL protocol handler class */ PHP_FUNCTION(file_register_wrapper) { char *protocol, *classname; int protocol_len, classname_len; struct php_user_stream_wrapper * uwrap; int rsrc_id; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &protocol, &protocol_len, &classname, &classname_len) == FAILURE) { RETURN_FALSE; } if (!PG(allow_url_fopen)) { zend_error(E_WARNING, "%s(): fopen wrappers have been disabled", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap)); uwrap->protoname = estrndup(protocol, protocol_len); uwrap->classname = estrndup(classname, classname_len); uwrap->wrapper.create = user_wrapper_factory; uwrap->wrapper.wrappercontext = uwrap; zend_str_tolower(uwrap->classname, classname_len); rsrc_id = ZEND_REGISTER_RESOURCE(NULL, uwrap, le_protocols); if (zend_hash_find(EG(class_table), uwrap->classname, classname_len + 1, (void**)&uwrap->ce) == SUCCESS) { #ifdef ZEND_ENGINE_2 uwrap->ce = *(zend_class_entry**)uwrap->ce; #endif if (php_register_url_stream_wrapper(protocol, &uwrap->wrapper TSRMLS_CC) == SUCCESS) { RETURN_TRUE; } } else { zend_error(E_WARNING, "%s(): class '%s' is undefined", get_active_function_name(TSRMLS_C), classname); } zend_list_delete(rsrc_id); RETURN_FALSE; } /* }}} */ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { zval func_name; zval *retval = NULL; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; zval **args[1]; zval zbuff, *zbufptr; size_t didwrite = 0; assert(us != NULL); ZVAL_STRINGL(&func_name, USERSTREAM_WRITE, sizeof(USERSTREAM_WRITE)-1, 0); ZVAL_STRINGL(&zbuff, (char*)buf, count, 0); zbufptr = &zbuff; args[0] = &zbufptr; call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 1, args, 0, NULL TSRMLS_CC); if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_LONG) didwrite = Z_LVAL_P(retval); else didwrite = 0; if (retval) zval_ptr_dtor(&retval); return didwrite; } static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { zval func_name; zval *retval = NULL; zval **args[1]; int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); if (buf == NULL && count == 0) { ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1, 0); call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 0, NULL, 0, NULL TSRMLS_CC); if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) didread = 0; else didread = EOF; } else { zval *zcount; ZVAL_STRINGL(&func_name, USERSTREAM_READ, sizeof(USERSTREAM_READ)-1, 0); MAKE_STD_ZVAL(zcount); ZVAL_LONG(zcount, count); args[0] = &zcount; call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 1, args, 0, NULL TSRMLS_CC); if (retval && Z_TYPE_P(retval) == IS_STRING) { didread = Z_STRLEN_P(retval); if (didread > count) { zend_error(E_WARNING, "%s::" USERSTREAM_READ " - read more data than requested; some data will be lost", us->wrapper->classname); didread = count; } if (didread > 0) memcpy(buf, Z_STRVAL_P(retval), didread); } zval_ptr_dtor(&zcount); } if (retval) zval_ptr_dtor(&retval); return didread; } static int php_userstreamop_close(php_stream *stream, int close_handle TSRMLS_DC) { zval func_name; zval *retval = NULL; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1, 0); call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 0, NULL, 0, NULL TSRMLS_CC); if (retval) zval_ptr_dtor(&retval); zval_ptr_dtor(&us->object); efree(us); return 0; } static int php_userstreamop_flush(php_stream *stream TSRMLS_DC) { zval func_name; zval *retval = NULL; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); ZVAL_STRINGL(&func_name, USERSTREAM_FLUSH, sizeof(USERSTREAM_FLUSH)-1, 0); call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 0, NULL, 0, NULL TSRMLS_CC); if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) call_result = 0; else call_result = -1; if (retval) zval_ptr_dtor(&retval); return call_result; } static int php_userstreamop_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) { zval func_name; zval *retval = NULL; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); if (offset == 0 && whence == SEEK_CUR) { ZVAL_STRINGL(&func_name, USERSTREAM_TELL, sizeof(USERSTREAM_TELL)-1, 0); call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 0, NULL, 0, NULL TSRMLS_CC); } else { zval **args[2]; zval *zoffs, *zwhence; ZVAL_STRINGL(&func_name, USERSTREAM_SEEK, sizeof(USERSTREAM_SEEK)-1, 0); MAKE_STD_ZVAL(zoffs); ZVAL_LONG(zoffs, offset); args[0] = &zoffs; MAKE_STD_ZVAL(zwhence); ZVAL_LONG(zwhence, whence); args[1] = &zwhence; call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 2, args, 0, NULL TSRMLS_CC); zval_ptr_dtor(&zoffs); zval_ptr_dtor(&zwhence); } if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_LONG) call_result = Z_LVAL_P(retval); else call_result = -1; if (retval) zval_ptr_dtor(&retval); return 0; } static char *php_userstreamop_gets(php_stream *stream, char *buf, size_t size TSRMLS_DC) { zval func_name; zval *retval = NULL; zval *zcount; zval **args[2]; int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); /* TODO: when the gets method is not available, fall back on emulated version using read */ ZVAL_STRINGL(&func_name, USERSTREAM_GETS, sizeof(USERSTREAM_GETS)-1, 0); MAKE_STD_ZVAL(zcount); ZVAL_LONG(zcount, size); args[0] = &zcount; call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 1, args, 0, NULL TSRMLS_CC); if (retval && Z_TYPE_P(retval) == IS_STRING) { didread = Z_STRLEN_P(retval); if (didread > size) { zend_error(E_WARNING, "%s::" USERSTREAM_GETS " - read more data than requested; some data will be lost", us->wrapper->classname); didread = size; } if (didread > 0) memcpy(buf, Z_STRVAL_P(retval), didread); zval_ptr_dtor(&retval); } if (retval) zval_ptr_dtor(&zcount); if (didread) return buf; return 0; } php_stream_ops php_stream_userspace_ops = { php_userstreamop_write, php_userstreamop_read, php_userstreamop_close, php_userstreamop_flush, php_userstreamop_seek, php_userstreamop_gets, NULL, /* cast */ "user-space" };
« previous php.cvs (#10399) next »