22#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
28#define TOKEN_LIST_GET_INTERNAL() php_dom_token_list_from_obj(Z_OBJ_P(ZEND_THIS))
29#define TOKEN_LIST_GET_SET(intern) (&(intern)->token_set)
30#define Z_TOKEN_LIST_P(zv) php_dom_token_list_from_obj(Z_OBJ_P(zv))
32typedef struct dom_token_list_it {
36 php_libxml_cache_tag cache_tag;
54static void dom_ordered_set_parser(
HashTable *token_set,
const char *position)
67 while (*position !=
'\0') {
69 const char *
start = position;
71 size_t length = position -
start;
75 dom_add_token(token_set, token);
87static char *dom_ordered_set_serializer(
HashTable *token_set)
92 size_t needed_size =
ZSTR_LEN(token) + 1;
98 length += needed_size;
120 php_libxml_node_ptr *element_ptr = intern->
dom.
ptr;
121 return element_ptr->node;
126 const xmlNode *element_node = dom_token_list_get_element(intern);
127 return xmlHasNsProp(element_node, BAD_CAST
"class",
NULL);
133 const xmlAttr *
attr = dom_token_list_get_attr(intern);
134 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
136 php_libxml_invalidate_cache_tag(&intern->
cache_tag);
139 if (
attr ==
NULL && zend_hash_num_elements(token_set) == 0) {
145 char *
value = dom_ordered_set_serializer(token_set);
146 xmlSetNsProp(dom_token_list_get_element(intern),
NULL, BAD_CAST
"class", BAD_CAST
value);
151static xmlChar *dom_token_list_get_class_value(
const xmlAttr *
attr,
bool *should_free)
154 return php_libxml_attr_value(
attr, should_free);
156 *should_free =
false;
164 const xmlAttr *
attr = dom_token_list_get_attr(intern);
166 xmlChar *
value = dom_token_list_get_class_value(
attr, &should_free);
169 dom_ordered_set_parser(token_set, (
const char *)
value);
183 const xmlAttr *
attr = dom_token_list_get_attr(intern);
184 xmlChar *
value = dom_token_list_get_class_value(
attr, &should_free);
188 php_libxml_invalidate_cache_tag(&intern->
cache_tag);
190 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
193 dom_token_list_update_set(intern, token_set);
203 php_libxml_node_ptr *
ptr = element_obj->
ptr;
211 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
214 dom_token_list_update_set(intern, token_set);
224 xmlNodePtr node = dom_token_list_get_element(intern);
225 if (php_libxml_decrement_node_ptr_ref(intern->
dom.
ptr) == 0) {
226 php_libxml_node_free_resource(node);
228 php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->
dom);
229 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
237 dom_token_list_ensure_set_up_to_date(token_list);
239 HashTable *token_set = TOKEN_LIST_GET_SET(token_list);
240 return index >= 0 && index < zend_hash_num_elements(token_set);
245 dom_token_list_ensure_set_up_to_date(token_list);
247 HashTable *token_set = TOKEN_LIST_GET_SET(token_list);
248 if (index >= 0 && index < zend_hash_num_elements(token_set)) {
321 zend_long index = dom_token_list_offset_convert_to_long(
offset, &failed);
326 dom_token_list_item_read(php_dom_token_list_from_obj(
object),
rv, index);
334 zend_long index = dom_token_list_offset_convert_to_long(
offset, &failed);
343 dom_token_list_item_read(token_list, &
rv, index);
345 zval_ptr_dtor_nogc(&
rv);
348 return dom_token_list_item_exists(token_list, index);
357 dom_token_list_ensure_set_up_to_date(token_list);
358 ZVAL_LONG(
retval, zend_hash_num_elements(TOKEN_LIST_GET_SET(token_list)));
368 const xmlAttr *
attr = dom_token_list_get_attr(intern);
369 xmlChar *
value = dom_token_list_get_class_value(
attr, &should_free);
385 xmlSetNsProp(dom_token_list_get_element(intern),
NULL, BAD_CAST
"class", BAD_CAST
Z_STRVAL_P(newval));
400 dom_token_list_item_read(TOKEN_LIST_GET_INTERNAL(),
return_value, index);
412 dom_token_list_ensure_set_up_to_date(token_list);
413 HashTable *token_set = TOKEN_LIST_GET_SET(token_list);
418static
bool dom_validate_token(const
zend_string *str)
427 if (dom_contains_ascii_whitespace(
ZSTR_VAL(str))) {
435static bool dom_validate_tokens_varargs(
const zval *
args, uint32_t argc)
437 for (uint32_t i = 0; i < argc; i++) {
443 if (zend_str_has_nul_byte(
Z_STR(
args[i]))) {
448 if (!dom_validate_token(
Z_STR(
args[i]))) {
466 if (!dom_validate_tokens_varargs(
args, argc)) {
472 dom_token_list_ensure_set_up_to_date(intern);
473 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
474 for (uint32_t i = 0; i < argc; i++) {
475 dom_add_token(token_set,
Z_STR(
args[i]));
479 dom_token_list_update(intern);
492 if (!dom_validate_tokens_varargs(
args, argc)) {
498 dom_token_list_ensure_set_up_to_date(intern);
499 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
500 for (uint32_t i = 0; i < argc; i++) {
505 dom_token_list_update(intern);
512 bool force, force_not_given =
true;
520 if (!dom_validate_token(token)) {
526 dom_token_list_ensure_set_up_to_date(intern);
527 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
529 if (found_token !=
NULL) {
535 if (force_not_given || !force) {
537 dom_token_list_update(intern);
546 else if (force_not_given || force) {
547 dom_add_token(token_set, token);
548 dom_token_list_update(intern);
566 if (!dom_validate_token(token) || !dom_validate_token(new_token)) {
572 dom_token_list_ensure_set_up_to_date(intern);
573 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
575 if (found_token ==
NULL) {
591 dom_token_list_update(intern);
615 dom_token_list_ensure_set_up_to_date(intern);
616 RETURN_LONG(zend_hash_num_elements(TOKEN_LIST_GET_SET(intern)));
632 dom_token_list_it *iterator = (dom_token_list_it *) iter;
639 dom_token_list_it *iterator = (dom_token_list_it *) iter;
641 HashTable *token_set = TOKEN_LIST_GET_SET(
object);
643 dom_token_list_ensure_set_up_to_date(
object);
652 dom_token_list_it *iterator = (dom_token_list_it *) iter;
654 dom_token_list_ensure_set_up_to_date(
object);
661 dom_token_list_it *iterator = (dom_token_list_it *) iter;
664 dom_token_list_ensure_set_up_to_date(
object);
666 if (
UNEXPECTED(php_libxml_is_cache_tag_stale(&
object->cache_tag, &iterator->cache_tag))) {
669 HashTable *token_set = TOKEN_LIST_GET_SET(
object);
671 while (
pos != iterator->pos) {
682 dom_token_list_it *iterator = (dom_token_list_it *) iter;
684 HashTable *token_set = TOKEN_LIST_GET_SET(
object);
686 dom_token_list_ensure_set_up_to_date(
object);
694 iterator->pos = validated;
701 dom_token_list_it_dtor,
702 dom_token_list_it_valid,
703 dom_token_list_it_get_current_data,
704 dom_token_list_it_get_current_key,
705 dom_token_list_it_move_forward,
706 dom_token_list_it_rewind,
719 dom_token_list_ensure_set_up_to_date(intern);
720 HashTable *token_set = TOKEN_LIST_GET_SET(intern);
722 dom_token_list_it *iterator =
emalloc(
sizeof(*iterator));
727 iterator->it.funcs = &dom_token_list_it_funcs;
730 return &iterator->it;
strspn(string $string, string $characters, int $offset=0, ?int $length=null)
strpbrk(string $string, string $characters)
count(Countable|array $value, int $mode=COUNT_NORMAL)
strcspn(string $string, string $characters, int $offset=0, ?int $length=null)
zend_result dom_token_list_value_write(dom_object *obj, zval *newval)
zend_result dom_token_list_value_read(dom_object *obj, zval *retval)
zend_result dom_token_list_length_read(dom_object *obj, zval *retval)
void php_dom_throw_error_with_message(dom_exception_code error_code, const char *error_message, bool strict_error)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
const char * ascii_whitespace
unsigned const char * pos
unsigned char key[REFLECTION_KEY_LEN]
php_libxml_ref_obj * document
php_libxml_cache_tag cache_tag
zend_object_iterator * dom_token_list_get_iterator(zend_class_entry *ce, zval *object, int by_ref)
void dom_token_list_free_obj(zend_object *object)
void dom_token_list_ctor(dom_token_list_object *intern, dom_object *element_obj)
int dom_token_list_has_dimension(zend_object *object, zval *offset, int check_empty)
zval * dom_token_list_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
struct _dom_object dom_object
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *container, const zval *offset, int type)
ZEND_API const char * zend_zval_value_name(const zval *arg)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
#define Z_PARAM_PATH_STR(dest)
#define ZEND_PARSE_PARAMETERS_END()
#define ZEND_PARSE_PARAMETERS_NONE()
#define ZVAL_STRING(z, s)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define Z_PARAM_BOOL_OR_NULL(dest, is_null)
#define Z_PARAM_LONG(dest)
#define Z_PARAM_VARIADIC(spec, dest, dest_num)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zend_class_entry * zend_ce_type_error
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_use_resource_as_offset(const zval *dim)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_set_bucket_key(HashTable *ht, Bucket *b, zend_string *key)
ZEND_API zend_result ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p)
ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos_ex(const HashTable *ht, HashPosition pos)
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HANDLE_NUMERIC(key, idx)
#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key)
#define ZEND_HASH_FOREACH_END()
ZEND_API zend_result zend_create_internal_iterator_zval(zval *return_value, zval *obj)
ZEND_API void zend_iterator_init(zend_object_iterator *iter)
struct _zend_object_iterator zend_object_iterator
struct _zend_object_iterator_funcs zend_object_iterator_funcs
struct _zend_string zend_string
ZEND_API void zend_object_std_dtor(zend_object *object)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
#define EXPECTED(condition)
#define zend_always_inline
#define XtOffsetOf(s_type, field)
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define Z_REFVAL_P(zval_p)
#define Z_STRVAL_P(zval_p)
#define ZVAL_STR_COPY(z, s)
struct _zend_array HashTable
#define Z_RES_HANDLE_P(zval_p)
#define ZVAL_OBJ_COPY(z, o)
ZEND_RESULT_CODE zend_result
ZEND_API void zval_ptr_dtor(zval *zval_ptr)