summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/standard/basic_functions.c4
-rw-r--r--ext/standard/file.c45
-rw-r--r--ext/standard/file.h2
-rw-r--r--ext/standard/php_string.h3
-rw-r--r--ext/standard/string.c84
5 files changed, 133 insertions, 5 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index e9abf4e749..c25f874a9e 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -607,6 +607,8 @@ function_entry basic_functions[] = {
PHP_FE(stream_context_set_params, NULL)
PHP_FE(stream_context_set_option, NULL)
PHP_FE(stream_context_get_options, NULL)
+ PHP_FE(stream_filter_prepend, NULL)
+ PHP_FE(stream_filter_append, NULL)
PHP_FE(fgetcsv, NULL)
PHP_FE(flock, NULL)
PHP_FE(get_meta_tags, NULL)
@@ -980,6 +982,7 @@ PHP_MINIT_FUNCTION(basic)
PHP_MINIT(file) (INIT_FUNC_ARGS_PASSTHRU);
PHP_MINIT(pack) (INIT_FUNC_ARGS_PASSTHRU);
PHP_MINIT(browscap) (INIT_FUNC_ARGS_PASSTHRU);
+ PHP_MINIT(string_filters) (INIT_FUNC_ARGS_PASSTHRU);
#if defined(HAVE_LOCALECONV) && defined(ZTS)
PHP_MINIT(localeconv) (INIT_FUNC_ARGS_PASSTHRU);
@@ -1043,6 +1046,7 @@ PHP_MSHUTDOWN_FUNCTION(basic)
PHP_MSHUTDOWN(assert) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
PHP_MSHUTDOWN(url_scanner_ex) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
PHP_MSHUTDOWN(file) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ PHP_MSHUTDOWN(string_filters) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
#if defined(HAVE_LOCALECONV) && defined(ZTS)
PHP_MSHUTDOWN(localeconv) (SHUTDOWN_FUNC_ARGS_PASSTHRU);
#endif
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 0404fa0a1b..bd0202f018 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -724,7 +724,7 @@ PHP_FUNCTION(stream_context_set_option)
zval *options = NULL, *zcontext = NULL, *zvalue = NULL;
php_stream_context *context;
char *wrappername, *optionname;
- long wrapperlen, optionlen;
+ int wrapperlen, optionlen;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"rssz", &zcontext, &wrappername, &wrapperlen,
@@ -791,6 +791,49 @@ PHP_FUNCTION(stream_context_create)
}
/* }}} */
+static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *zstream;
+ php_stream *stream;
+ char *filtername, *filterparams = NULL;
+ int filternamelen, filterparamslen = 0;
+ php_stream_filter *filter;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &zstream,
+ &filtername, &filternamelen, &filterparams, &filterparamslen) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ ZEND_FETCH_RESOURCE(stream, php_stream*, &zstream, -1, "stream", le_stream);
+
+ filter = php_stream_filter_create(filtername, filterparams, filterparamslen, php_stream_is_persistent(stream) TSRMLS_CC);
+ if (filter == NULL)
+ RETURN_FALSE;
+
+ if (append)
+ php_stream_filter_append(stream, filter);
+ else
+ php_stream_filter_prepend(stream, filter);
+
+ RETURN_TRUE;
+}
+
+/* {{{ proto bool stream_filter_prepend(resource stream, string filtername[, string filterparams])
+ Prepend a filter to a stream */
+PHP_FUNCTION(stream_filter_prepend)
+{
+ apply_filter_to_stream(0, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto bool stream_filter_append(resource stream, string filtername[, string filterparams])
+ Append a filter to a stream */
+PHP_FUNCTION(stream_filter_append)
+{
+ apply_filter_to_stream(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
/* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]])
Open a file or a URL and return a file pointer */
PHP_NAMED_FUNCTION(php_if_fopen)
diff --git a/ext/standard/file.h b/ext/standard/file.h
index 0ea36c7907..c2af165679 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -77,6 +77,8 @@ PHP_FUNCTION(stream_context_create);
PHP_FUNCTION(stream_context_set_params);
PHP_FUNCTION(stream_context_set_option);
PHP_FUNCTION(stream_context_get_options);
+PHP_FUNCTION(stream_filter_prepend);
+PHP_FUNCTION(stream_filter_append);
PHP_MINIT_FUNCTION(user_streams);
PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC);
diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h
index d63f91b254..6fbc57bd42 100644
--- a/ext/standard/php_string.h
+++ b/ext/standard/php_string.h
@@ -89,6 +89,9 @@ PHP_FUNCTION(strcoll);
PHP_FUNCTION(money_format);
#endif
+PHP_MINIT_FUNCTION(string_filters);
+PHP_MSHUTDOWN_FUNCTION(string_filters);
+
#if defined(HAVE_LOCALECONV) && defined(ZTS)
PHP_MINIT_FUNCTION(localeconv);
PHP_MSHUTDOWN_FUNCTION(localeconv);
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 0940eab539..3b62ea00c4 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -3883,15 +3883,15 @@ PHP_FUNCTION(sscanf)
}
/* }}} */
+static char rot13_from[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static char rot13_to[] = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
+
/* {{{ proto string str_rot13(string str)
Perform the rot13 transform on a string */
PHP_FUNCTION(str_rot13)
{
zval **arg;
- static char xfrom[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- static char xto[] = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
-
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg)) {
WRONG_PARAM_COUNT;
}
@@ -3899,7 +3899,7 @@ PHP_FUNCTION(str_rot13)
*return_value = **arg;
zval_copy_ctor(return_value);
- php_strtr(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), xfrom, xto, 52);
+ php_strtr(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), rot13_from, rot13_to, 52);
}
/* }}} */
@@ -3926,6 +3926,82 @@ PHP_FUNCTION(money_format) {
/* }}} */
#endif
+/* {{{ rot13 stream filter implementation */
+static size_t strfilter_rot13_write(php_stream *stream, php_stream_filter *thisfilter,
+ const char *buf, size_t count TSRMLS_DC)
+{
+ char rotbuf[1024];
+ size_t chunk;
+ size_t wrote = 0;
+
+ while (count > 0) {
+ chunk = count;
+ if (chunk > sizeof(rotbuf))
+ chunk = sizeof(rotbuf);
+
+ PHP_STRLCPY(rotbuf, buf, sizeof(rotbuf), chunk);
+ buf += chunk;
+ count -= chunk;
+
+ php_strtr(rotbuf, chunk, rot13_from, rot13_to, 52);
+ wrote += php_stream_filter_write_next(stream, thisfilter, rotbuf, chunk);
+ }
+
+ return wrote;
+}
+
+static size_t strfilter_rot13_read(php_stream *stream, php_stream_filter *thisfilter,
+ char *buf, size_t count TSRMLS_DC)
+{
+ size_t read;
+
+ read = php_stream_filter_read_next(stream, thisfilter, buf, count);
+ php_strtr(buf, read, rot13_from, rot13_to, 52);
+
+ return read;
+}
+
+static int strfilter_rot13_flush(php_stream *stream, php_stream_filter *thisfilter TSRMLS_DC)
+{
+ return php_stream_filter_flush_next(stream, thisfilter);
+}
+
+static int strfilter_rot13_eof(php_stream *stream, php_stream_filter *thisfilter TSRMLS_DC)
+{
+ return php_stream_filter_eof_next(stream, thisfilter);
+}
+
+
+static php_stream_filter_ops strfilter_rot13_ops = {
+ strfilter_rot13_write,
+ strfilter_rot13_read,
+ strfilter_rot13_flush,
+ strfilter_rot13_eof,
+ NULL,
+ "string.rot13"
+};
+
+static php_stream_filter *strfilter_rot13_create(const char *filtername, const char *filterparams,
+ int filterparamslen, int persistent TSRMLS_DC)
+{
+ return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent);
+}
+
+static php_stream_filter_factory strfilter_rot13_factory = {
+ strfilter_rot13_create
+};
+
+PHP_MINIT_FUNCTION(string_filters)
+{
+ return php_stream_filter_register_factory("string.rot13", &strfilter_rot13_factory);
+}
+
+PHP_MSHUTDOWN_FUNCTION(string_filters)
+{
+ return php_stream_filter_unregister_factory("string.rot13");
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4