2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2010, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
13 /* $Id: php_http_headers_api.h 300300 2010-06-09 07:29:35Z mike $ */
17 #include <ext/standard/php_string.h>
19 #ifndef PHP_HTTP_DBG_NEG
20 # define PHP_HTTP_DBG_NEG 0
23 char *php_http_negotiate_language_func(const char *test
, double *quality
, HashTable
*supported TSRMLS_DC
)
27 const char *dash_test
;
29 FOREACH_HASH_VAL(pos
, supported
, value
) {
31 fprintf(stderr
, "strcasecmp('%s', '%s')\n", Z_STRVAL_PP(value
), test
);
33 if (!strcasecmp(Z_STRVAL_PP(value
), test
)) {
34 return Z_STRVAL_PP(value
);
38 /* no distinct match found, so try primaries */
39 if ((dash_test
= strchr(test
, '-'))) {
40 FOREACH_HASH_VAL(pos
, supported
, value
) {
41 int len
= dash_test
- test
;
43 fprintf(stderr
, "strncasecmp('%s', '%s', %d)\n", Z_STRVAL_PP(value
), test
, len
);
45 if ( (!strncasecmp(Z_STRVAL_PP(value
), test
, len
)) &&
46 ( (Z_STRVAL_PP(value
)[len
] == '\0') ||
47 (Z_STRVAL_PP(value
)[len
] == '-'))) {
49 return Z_STRVAL_PP(value
);
58 char *php_http_negotiate_default_func(const char *test
, double *quality
, HashTable
*supported TSRMLS_DC
)
64 FOREACH_HASH_VAL(pos
, supported
, value
) {
66 fprintf(stderr
, "strcasecmp('%s', '%s')\n", Z_STRVAL_PP(value
), test
);
68 if (!strcasecmp(Z_STRVAL_PP(value
), test
)) {
69 return Z_STRVAL_PP(value
);
77 static int php_http_negotiate_sort(const void *a
, const void *b TSRMLS_DC
)
79 zval result
, *first
, *second
;
81 first
= *((zval
**) (*((Bucket
**) a
))->pData
);
82 second
= *((zval
**) (*((Bucket
**) b
))->pData
);
84 if (numeric_compare_function(&result
, first
, second TSRMLS_CC
) != SUCCESS
) {
87 return (Z_LVAL(result
) > 0 ? -1 : (Z_LVAL(result
) < 0 ? 1 : 0));
91 PHP_HTTP_API HashTable
*php_http_negotiate(const char *value
, HashTable
*supported
, php_http_negotiate_func_t neg TSRMLS_DC
)
93 HashTable
*result
= NULL
;
96 zval ex_arr
, ex_del
, ex_val
;
101 ZVAL_STRINGL(&ex_del
, ",", 1, 0);
102 ZVAL_STRING(&ex_val
, value
, 1);
105 php_explode(&ex_del
, &ex_val
, &ex_arr
, INT_MAX
);
107 if (zend_hash_num_elements(Z_ARRVAL(ex_arr
)) > 0) {
116 neg
= php_http_negotiate_default_func
;
119 FOREACH_HASH_VAL(pos
, Z_ARRVAL(ex_arr
), entry
) {
122 char *selected
, *identifier
, *freeme
;
123 const char *separator
;
126 fprintf(stderr
, "Checking %s\n", Z_STRVAL_PP(entry
));
129 if ((separator
= strchr(Z_STRVAL_PP(entry
), ';'))) {
130 const char *ptr
= separator
;
132 while (*++ptr
&& !PHP_HTTP_IS_CTYPE(digit
, *ptr
) && '.' != *ptr
);
134 quality
= zend_strtod(ptr
, NULL
);
135 identifier
= estrndup(Z_STRVAL_PP(entry
), ident_len
= separator
- Z_STRVAL_PP(entry
));
137 quality
= 1000.0 - i
++;
138 identifier
= estrndup(Z_STRVAL_PP(entry
), ident_len
= Z_STRLEN_PP(entry
));
142 while (PHP_HTTP_IS_CTYPE(space
, *identifier
)) {
146 while (ident_len
&& PHP_HTTP_IS_CTYPE(space
, identifier
[ident_len
- 1])) {
147 identifier
[--ident_len
] = '\0';
150 if ((selected
= neg(identifier
, &quality
, supported TSRMLS_CC
))) {
151 /* don't overwrite previously set with higher quality */
152 if (!zend_hash_exists(Z_ARRVAL(array
), selected
, strlen(selected
) + 1)) {
153 add_assoc_double(&array
, selected
, quality
);
160 result
= Z_ARRVAL(array
);
161 zend_hash_sort(result
, zend_qsort
, php_http_negotiate_sort
, 0 TSRMLS_CC
);
178 * vim600: noet sw=4 ts=4 fdm=marker
179 * vim<600: noet sw=4 ts=4