From 693aff1dce7d26388ff36794fe4b90a26b7f2ccd Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 5 Oct 2005 07:29:29 +0000 Subject: [PATCH 1/1] - new signature for the negotiator, which doesn't mix return value types, but fills the optional second argument with the negotiaton result array if desired --- http.c | 4 +- http_functions.c | 96 +++++++++++++++++++++----------------- http_util_object.c | 4 +- php_http_std_defs.h | 7 +++ tests/negotiation_001.phpt | 10 ++-- 5 files changed, 71 insertions(+), 50 deletions(-) diff --git a/http.c b/http.c index 2402ccb..26bcf0f 100644 --- a/http.c +++ b/http.c @@ -77,8 +77,8 @@ zend_function_entry http_functions[] = { PHP_FE(http_date, NULL) PHP_FE(http_build_uri, NULL) PHP_FALIAS(http_absolute_uri, http_build_uri, NULL) - PHP_FE(http_negotiate_language, NULL) - PHP_FE(http_negotiate_charset, NULL) + PHP_FE(http_negotiate_language, http_arg_pass_ref_2) + PHP_FE(http_negotiate_charset, http_arg_pass_ref_2) PHP_FE(http_redirect, NULL) PHP_FE(http_throttle, NULL) PHP_FE(http_send_status, NULL) diff --git a/http_functions.c b/http_functions.c index c7cc2b6..b0916b9 100644 --- a/http_functions.c +++ b/http_functions.c @@ -107,51 +107,50 @@ PHP_FUNCTION(http_build_uri) } /* }}} */ -#define HTTP_DO_NEGOTIATE(type, supported, as_array) \ +#define HTTP_DO_NEGOTIATE(type, supported, rs_array) \ { \ HashTable *result; \ if (result = http_negotiate_ ##type(supported)) { \ - if (as_array) { \ - Z_TYPE_P(return_value) = IS_ARRAY; \ - Z_ARRVAL_P(return_value) = result; \ + char *key; \ + uint key_len; \ + ulong idx; \ + \ + if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(result, &key, &key_len, &idx, 1, NULL)) { \ + RETVAL_STRINGL(key, key_len-1, 0); \ } else { \ - char *key; \ - uint key_len; \ - ulong idx; \ - \ - if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(result, &key, &key_len, &idx, 1, NULL)) { \ - RETVAL_STRINGL(key, key_len-1, 0); \ - } else { \ - RETVAL_NULL(); \ - } \ - zend_hash_destroy(result); \ - FREE_HASHTABLE(result); \ + RETVAL_NULL(); \ } \ + \ + if (rs_array) { \ + zend_hash_copy(Z_ARRVAL_P(rs_array), result, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); \ + } \ + \ + zend_hash_destroy(result); \ + FREE_HASHTABLE(result); \ + \ } else { \ - if (as_array) { \ + zval **value; \ + \ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(supported)); \ + if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(supported), (void **) &value)) { \ + RETVAL_ZVAL(*value, 1, 0); \ + } else { \ + RETVAL_NULL(); \ + } \ + \ + if (rs_array) { \ zval **value; \ \ - array_init(return_value); \ - \ FOREACH_VAL(supported, value) { \ convert_to_string_ex(value); \ - add_assoc_double(return_value, Z_STRVAL_PP(value), 1.0); \ - } \ - } else { \ - zval **value; \ - \ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(supported)); \ - if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(supported), (void **) &value)) { \ - RETVAL_ZVAL(*value, 1, 0); \ - } else { \ - RETVAL_NULL(); \ + add_assoc_double(rs_array, Z_STRVAL_PP(value), 1.0); \ } \ } \ } \ } -/* {{{ proto mixed http_negotiate_language(array supported[, array result]) +/* {{{ proto string http_negotiate_language(array supported[, array &result]) * * This function negotiates the clients preferred language based on its * Accept-Language HTTP header. The qualifier is recognized and languages @@ -186,18 +185,22 @@ PHP_FUNCTION(http_build_uri) */ PHP_FUNCTION(http_negotiate_language) { - zval *supported; - zend_bool as_array = 0; + zval *supported, *rs_array = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &supported, &as_array) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &supported, &rs_array) != SUCCESS) { RETURN_FALSE; } - HTTP_DO_NEGOTIATE(language, supported, as_array); + if (rs_array) { + zval_dtor(rs_array); + array_init(rs_array); + } + + HTTP_DO_NEGOTIATE(language, supported, rs_array); } /* }}} */ -/* {{{ proto string http_negotiate_charset(array supported[, array result]) +/* {{{ proto string http_negotiate_charset(array supported[, array &result]) * * This function negotiates the clients preferred charset based on its * Accept-Charset HTTP header. The qualifier is recognized and charsets @@ -234,14 +237,18 @@ PHP_FUNCTION(http_negotiate_language) */ PHP_FUNCTION(http_negotiate_charset) { - zval *supported; - zend_bool as_array = 0; + zval *supported, *rs_array = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &supported, &as_array) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &supported, &rs_array) != SUCCESS) { RETURN_FALSE; } + + if (rs_array) { + zval_dtor(rs_array); + array_init(rs_array); + } - HTTP_DO_NEGOTIATE(charset, supported, as_array); + HTTP_DO_NEGOTIATE(charset, supported, rs_array); } /* }}} */ @@ -308,7 +315,7 @@ PHP_FUNCTION(http_send_last_modified) PHP_FUNCTION(http_send_content_type) { char *ct = "application/x-octetstream"; - int ct_len = lenof("application/x-octetstream"; + int ct_len = lenof("application/x-octetstream"); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ct, &ct_len) != SUCCESS) { RETURN_FALSE; @@ -344,7 +351,7 @@ PHP_FUNCTION(http_send_content_disposition) } /* }}} */ -/* {{{ proto bool http_match_modified([int timestamp[, for_range = false]]) +/* {{{ proto bool http_match_modified([int timestamp[, bool for_range = false]]) * * Matches the given unix timestamp against the clients "If-Modified-Since" * resp. "If-Unmodified-Since" HTTP headers. @@ -378,7 +385,7 @@ PHP_FUNCTION(http_match_modified) } /* }}} */ -/* {{{ proto bool http_match_etag(string etag[, for_range = false]) +/* {{{ proto bool http_match_etag(string etag[, bool for_range = false]) * * Matches the given ETag against the clients "If-Match" resp. * "If-None-Match" HTTP headers. @@ -505,7 +512,7 @@ PHP_FUNCTION(ob_etaghandler) } /* }}} */ -/* {{{ proto void http_throttle(double sec[, long bytes = 2097152]) +/* {{{ proto void http_throttle(double sec[, int bytes = 2097152]) * * Sets the throttle delay and send buffer size for use with http_send() API. * Provides a basic throttling mechanism, which will yield the current process @@ -530,7 +537,7 @@ PHP_FUNCTION(ob_etaghandler) */ PHP_FUNCTION(http_throttle) { - long chunk_size = HTTP_SEND_BUFFERSIZE; + long chunk_size = HTTP_SENDBUF_SIZE; double interval; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|l", &interval, &chunk_size)) { @@ -668,6 +675,7 @@ PHP_FUNCTION(http_redirect) * * Sends raw data with support for (multiple) range requests. * + * Retursn TRUE on success, or FALSE on failure. */ PHP_FUNCTION(http_send_data) { @@ -868,6 +876,8 @@ PHP_FUNCTION(http_parse_headers) /* {{{ proto array http_get_request_headers(void) * * Get a list of incoming HTTP headers. + * + * Returns an associative array of incoming request headers. */ PHP_FUNCTION(http_get_request_headers) { diff --git a/http_util_object.c b/http_util_object.c index 024089d..ac87820 100644 --- a/http_util_object.c +++ b/http_util_object.c @@ -45,12 +45,12 @@ HTTP_END_ARGS; HTTP_BEGIN_ARGS(negotiateLanguage, 1) HTTP_ARG_VAL(supported, 0) - HTTP_ARG_VAL(default, 0) + HTTP_ARG_VAL(result, 1) HTTP_END_ARGS; HTTP_BEGIN_ARGS(negotiateCharset, 1) HTTP_ARG_VAL(supported, 0) - HTTP_ARG_VAL(default, 0) + HTTP_ARG_VAL(result, 1) HTTP_END_ARGS; HTTP_BEGIN_ARGS(matchModified, 1) diff --git a/php_http_std_defs.h b/php_http_std_defs.h index ce42260..79b69ae 100644 --- a/php_http_std_defs.h +++ b/php_http_std_defs.h @@ -322,6 +322,12 @@ typedef int STATUS; #ifdef HTTP_HAVE_CURL # ifdef ZEND_ENGINE_2 # define HTTP_DECLARE_ARG_PASS_INFO() \ + static \ + ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_2, 0) \ + ZEND_ARG_PASS_INFO(0) \ + ZEND_ARG_PASS_INFO(1) \ + ZEND_END_ARG_INFO(); \ + \ static \ ZEND_BEGIN_ARG_INFO(http_arg_pass_ref_3, 0) \ ZEND_ARG_PASS_INFO(0) \ @@ -348,6 +354,7 @@ typedef int STATUS; # else # define HTTP_DECLARE_ARG_PASS_INFO() \ + static unsigned char http_arg_pass_ref_2[] = {2, BYREF_NONE, BYREF_FORCE}; \ static unsigned char http_arg_pass_ref_3[] = {3, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \ static unsigned char http_arg_pass_ref_4[] = {4, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; \ static unsigned char http_arg_pass_ref_5[] = {5, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_NONE, BYREF_FORCE}; diff --git a/tests/negotiation_001.phpt b/tests/negotiation_001.phpt index 88e6ec4..cb11d43 100644 --- a/tests/negotiation_001.phpt +++ b/tests/negotiation_001.phpt @@ -17,19 +17,23 @@ $csets = array( array('utf-8', 'iso-8859-1'), ); var_dump(http_negotiate_language($langs[0])); -print_r(http_negotiate_language($langs[0], true)); +var_dump(http_negotiate_language($langs[0], $lresult)); var_dump(http_negotiate_charset($csets[0])); -print_r(http_negotiate_charset($csets[0], true)); +var_dump(http_negotiate_charset($csets[0], $cresult)); +print_r($lresult); +print_r($cresult); echo "Done\n"; --EXPECTF-- %sTEST string(2) "de" +string(2) "de" +string(10) "iso-8859-1" +string(10) "iso-8859-1" Array ( [de] => 500 [en] => 0.15 ) -string(10) "iso-8859-1" Array ( [iso-8859-1] => 1000 -- 2.30.2