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 +--------------------------------------------------------------------+
13 #include "php_http_api.h"
15 static int php_http_negotiate_sort(const void *a
, const void *b TSRMLS_DC
)
17 zval result
, *first
, *second
;
19 first
= *((zval
**) (*((Bucket
**) a
))->pData
);
20 second
= *((zval
**) (*((Bucket
**) b
))->pData
);
22 if (numeric_compare_function(&result
, first
, second TSRMLS_CC
) != SUCCESS
) {
25 return (Z_LVAL(result
) > 0 ? -1 : (Z_LVAL(result
) < 0 ? 1 : 0));
28 static int php_http_negotiate_reduce(void *p TSRMLS_DC
, int num_args
, va_list args
, zend_hash_key
*hash_key
)
31 zval
**q
, *supported
= php_http_ztyp(IS_STRING
, *(zval
**)p
);
32 HashTable
*params
= va_arg(args
, HashTable
*);
33 HashTable
*result
= va_arg(args
, HashTable
*);
35 tmp
= php_strtolower(estrndup(Z_STRVAL_P(supported
), Z_STRLEN_P(supported
)), Z_STRLEN_P(supported
));
36 if (SUCCESS
== zend_symtable_find(params
, tmp
, Z_STRLEN_P(supported
) + 1, (void *) &q
)) {
38 zend_symtable_update(result
, Z_STRVAL_P(supported
), Z_STRLEN_P(supported
) + 1, (void *) q
, sizeof(zval
*), NULL
);
41 zval_ptr_dtor(&supported
);
42 return ZEND_HASH_APPLY_KEEP
;
45 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
)
47 HashTable
*result
= NULL
;
49 if (value_str
&& value_len
) {
51 zval arr
, **val
, **arg
, **zq
;
54 php_http_array_hashkey_t key
= php_http_array_hashkey_init(1);
55 php_http_params_opts_t opts
;
57 zend_hash_init(¶ms
, 10, NULL
, ZVAL_PTR_DTOR
, 0);
58 php_http_params_opts_default_get(&opts
);
59 opts
.input
.str
= estrndup(value_str
, value_len
);
60 opts
.input
.len
= value_len
;
61 php_http_params_parse(¶ms
, &opts TSRMLS_CC
);
62 efree(opts
.input
.str
);
67 FOREACH_HASH_KEYVAL(pos
, ¶ms
, key
, val
) {
70 if (SUCCESS
== zend_hash_find(Z_ARRVAL_PP(val
), ZEND_STRS("arguments"), (void *) &arg
)
71 && IS_ARRAY
== Z_TYPE_PP(arg
)
72 && SUCCESS
== zend_hash_find(Z_ARRVAL_PP(arg
), ZEND_STRS("q"), (void *) &zq
)) {
73 zval
*tmp
= php_http_ztyp(IS_DOUBLE
, *zq
);
83 q
= 1.0 - ++i
/ 100.0;
86 if (key
.type
== HASH_KEY_IS_STRING
) {
89 php_strtolower(key
.str
, key
.len
- 1);
90 add_assoc_double_ex(&arr
, key
.str
, key
.len
, q
);
92 if (primary_sep_str
&& primary_sep_len
&& (ptr
= php_http_locate_str(key
.str
, key
.len
- 1, primary_sep_str
, primary_sep_len
))) {
93 key
.str
[ptr
- key
.str
] = '\0';
94 add_assoc_double_ex(&arr
, key
.str
, ptr
- key
.str
+ 1, q
- i
/ 1000.0);
97 add_index_double(&arr
, key
.num
, q
);
103 ALLOC_HASHTABLE(result
);
104 zend_hash_init(result
, zend_hash_num_elements(supported
), NULL
, ZVAL_PTR_DTOR
, 0);
105 zend_hash_apply_with_arguments(supported TSRMLS_CC
, php_http_negotiate_reduce
, 2, Z_ARRVAL(arr
), result
);
106 zend_hash_destroy(¶ms
);
108 zend_hash_sort(result
, zend_qsort
, php_http_negotiate_sort
, 0 TSRMLS_CC
);
121 * vim600: noet sw=4 ts=4 fdm=marker
122 * vim<600: noet sw=4 ts=4