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-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
15 #include <ext/standard/php_string.h>
17 static int php_http_negotiate_sort(const void *a
, const void *b TSRMLS_DC
)
19 zval result
, *first
, *second
;
21 first
= *((zval
**) (*((Bucket
**) a
))->pData
);
22 second
= *((zval
**) (*((Bucket
**) b
))->pData
);
24 if (numeric_compare_function(&result
, first
, second TSRMLS_CC
) != SUCCESS
) {
27 return (Z_LVAL(result
) > 0 ? -1 : (Z_LVAL(result
) < 0 ? 1 : 0));
30 static int php_http_negotiate_reduce(void *p TSRMLS_DC
, int num_args
, va_list args
, zend_hash_key
*hash_key
)
33 zval
**q
, *supported
= php_http_ztyp(IS_STRING
, *(zval
**)p
);
34 HashTable
*params
= va_arg(args
, HashTable
*);
35 HashTable
*result
= va_arg(args
, HashTable
*);
37 tmp
= php_strtolower(estrndup(Z_STRVAL_P(supported
), Z_STRLEN_P(supported
)), Z_STRLEN_P(supported
));
38 if (SUCCESS
== zend_symtable_find(params
, tmp
, Z_STRLEN_P(supported
) + 1, (void *) &q
)) {
40 zend_symtable_update(result
, Z_STRVAL_P(supported
), Z_STRLEN_P(supported
) + 1, (void *) q
, sizeof(zval
*), NULL
);
43 zval_ptr_dtor(&supported
);
44 return ZEND_HASH_APPLY_KEEP
;
47 PHP_HTTP_API HashTable
*php_http_negotiate(const char *value_str
, size_t value_len
, HashTable
*supported
, const char *primary_sep_str
, size_t primary_sep_len TSRMLS_DC
)
49 HashTable
*result
= NULL
;
51 if (value_str
&& value_len
) {
53 zval arr
, **val
, **arg
, **zq
;
56 php_http_array_hashkey_t key
= php_http_array_hashkey_init(1);
57 php_http_params_opts_t opts
;
59 zend_hash_init(¶ms
, 10, NULL
, ZVAL_PTR_DTOR
, 0);
60 php_http_params_opts_default_get(&opts
);
61 opts
.input
.str
= estrndup(value_str
, value_len
);
62 opts
.input
.len
= value_len
;
63 php_http_params_parse(¶ms
, &opts TSRMLS_CC
);
64 efree(opts
.input
.str
);
69 FOREACH_HASH_KEYVAL(pos
, ¶ms
, key
, val
) {
72 if (SUCCESS
== zend_hash_find(Z_ARRVAL_PP(val
), ZEND_STRS("arguments"), (void *) &arg
)
73 && IS_ARRAY
== Z_TYPE_PP(arg
)
74 && SUCCESS
== zend_hash_find(Z_ARRVAL_PP(arg
), ZEND_STRS("q"), (void *) &zq
)) {
75 zval
*tmp
= php_http_ztyp(IS_DOUBLE
, *zq
);
80 q
= 1.0 - ++i
/ 100.0;
83 if (key
.type
== HASH_KEY_IS_STRING
) {
86 php_strtolower(key
.str
, key
.len
- 1);
87 add_assoc_double_ex(&arr
, key
.str
, key
.len
, q
);
89 if (primary_sep_str
&& primary_sep_len
&& (ptr
= php_http_locate_str(key
.str
, key
.len
- 1, primary_sep_str
, primary_sep_len
))) {
90 key
.str
[ptr
- key
.str
] = '\0';
91 add_assoc_double_ex(&arr
, key
.str
, ptr
- key
.str
+ 1, q
- i
/ 1000.0);
94 add_index_double(&arr
, key
.num
, q
);
100 ALLOC_HASHTABLE(result
);
101 zend_hash_init(result
, zend_hash_num_elements(supported
), NULL
, ZVAL_PTR_DTOR
, 0);
102 zend_hash_apply_with_arguments(supported TSRMLS_CC
, php_http_negotiate_reduce
, 2, Z_ARRVAL(arr
), result
);
103 zend_hash_destroy(¶ms
);
105 zend_hash_sort(result
, zend_qsort
, php_http_negotiate_sort
, 0 TSRMLS_CC
);
118 * vim600: noet sw=4 ts=4 fdm=marker
119 * vim<600: noet sw=4 ts=4