From 24488f376260d3fe3ea69b59d4d82702d9aa492c Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Thu, 19 Jul 2012 16:59:04 +0100 Subject: Cleanup: Remove two UNUSED()s which are not true --- bindings/hubbub/parser.c | 2 -- src/core/node.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/bindings/hubbub/parser.c b/bindings/hubbub/parser.c index a4a9a2e..4a90511 100644 --- a/bindings/hubbub/parser.c +++ b/bindings/hubbub/parser.c @@ -459,8 +459,6 @@ static hubbub_error has_children(void *parser, void *node, bool *result) dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; - UNUSED(parser); - err = dom_node_has_child_nodes((struct dom_node *) node, result); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, diff --git a/src/core/node.c b/src/core/node.c index 628c7c6..9ddac0c 100644 --- a/src/core/node.c +++ b/src/core/node.c @@ -1666,8 +1666,6 @@ dom_exception _dom_node_get_feature(dom_node_internal *node, { bool has; - UNUSED(node); - dom_implementation_has_feature(dom_string_data(feature), dom_string_data(version), &has); -- cgit v1.2.3 From 0b32f2dd635c7c770a685eaa05837729c08debc1 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 21 Jul 2012 18:20:29 +0100 Subject: DOMString: Add toupper and tolower methods --- include/dom/core/string.h | 8 ++++ src/core/string.c | 116 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/include/dom/core/string.h b/include/dom/core/string.h index b9b41a9..f2a6122 100644 --- a/include/dom/core/string.h +++ b/include/dom/core/string.h @@ -102,6 +102,14 @@ dom_exception dom_string_replace(dom_string *target, dom_string *source, uint32_t i1, uint32_t i2, dom_string **result); +/* Generate an uppercase version of the given string */ +dom_exception dom_string_toupper(dom_string *source, bool ascii_only, + dom_string **upper); + +/* Generate an lowercase version of the given string */ +dom_exception dom_string_tolower(dom_string *source, bool ascii_only, + dom_string **lower); + /* Calculate a hash value from a dom string */ uint32_t dom_string_hash(dom_string *str); diff --git a/src/core/string.c b/src/core/string.c index aa046ad..0cadd77 100644 --- a/src/core/string.c +++ b/src/core/string.c @@ -890,7 +890,7 @@ const char *dom_string_data(const dom_string *str) } } -/* Get the byte length of this dom_string +/** Get the byte length of this dom_string * * \param str The dom_string object */ @@ -904,3 +904,117 @@ size_t dom_string_byte_length(const dom_string *str) } } +/** Convert the given string to uppercase + * + * \param source + * \param ascii_only Whether to only convert [a-z] to [A-Z] + * \param upper Result pointer for uppercase string. Caller owns ref + * + * \return DOM_NO_ERR on success. + * + * \note Right now, will return DOM_NOT_SUPPORTED_ERR if ascii_only is false. + */ +dom_exception +dom_string_toupper(dom_string *source, bool ascii_only, dom_string **upper) +{ + const uint8_t *orig_s = (const uint8_t *) dom_string_data(source); + const size_t nbytes = dom_string_byte_length(source); + uint8_t *copy_s; + size_t index = 0, clen; + parserutils_error err; + dom_exception exc; + + if (ascii_only == false) + return DOM_NOT_SUPPORTED_ERR; + + copy_s = malloc(nbytes); + if (copy_s == NULL) + return DOM_NO_MEM_ERR; + memcpy(copy_s, orig_s, nbytes); + + while (index < nbytes) { + err = parserutils_charset_utf8_char_byte_length(orig_s + index, + &clen); + if (err != PARSERUTILS_OK) { + free(copy_s); + /** \todo Find a better exception */ + return DOM_NO_MEM_ERR; + } + + if (clen == 1) { + if (orig_s[index] >= 'a' && + orig_s[index] <= 'z') + copy_s[index] -= 'a' - 'A'; + } + + index += clen; + } + + if (((dom_string_internal*)source)->type == DOM_STRING_CDATA) { + exc = dom_string_create(copy_s, nbytes, upper); + } else { + exc = dom_string_create_interned(copy_s, nbytes, upper); + } + + free(copy_s); + + return exc; +} + +/** Convert the given string to lowercase + * + * \param source + * \param ascii_only Whether to only convert [a-z] to [A-Z] + * \param lower Result pointer for lowercase string. Caller owns ref + * + * \return DOM_NO_ERR on success. + * + * \note Right now, will return DOM_NOT_SUPPORTED_ERR if ascii_only is false. + */ +dom_exception +dom_string_tolower(dom_string *source, bool ascii_only, dom_string **lower) +{ + const uint8_t *orig_s = (const uint8_t *) dom_string_data(source); + const size_t nbytes = dom_string_byte_length(source); + uint8_t *copy_s; + size_t index = 0, clen; + parserutils_error err; + dom_exception exc; + + if (ascii_only == false) + return DOM_NOT_SUPPORTED_ERR; + + copy_s = malloc(nbytes); + if (copy_s == NULL) + return DOM_NO_MEM_ERR; + memcpy(copy_s, orig_s, nbytes); + + while (index < nbytes) { + err = parserutils_charset_utf8_char_byte_length(orig_s + index, + &clen); + if (err != PARSERUTILS_OK) { + free(copy_s); + /** \todo Find a better exception */ + return DOM_NO_MEM_ERR; + } + + if (clen == 1) { + if (orig_s[index] >= 'A' && + orig_s[index] <= 'Z') + copy_s[index] += 'a' - 'A'; + } + + index += clen; + } + + if (((dom_string_internal*)source)->type == DOM_STRING_CDATA) { + exc = dom_string_create(copy_s, nbytes, lower); + } else { + exc = dom_string_create_interned(copy_s, nbytes, lower); + } + + free(copy_s); + + return exc; +} + -- cgit v1.2.3 From 96f79bd294bb6d31e8c495b5ad3cbccb0cd57c54 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 21 Jul 2012 18:29:12 +0100 Subject: HTMLDocument: Uppercase all tag names for HTMLElement and derivatives --- src/html/html_document.c | 67 ++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/html/html_document.c b/src/html/html_document.c index a2a7ed5..ddb8196 100644 --- a/src/html/html_document.c +++ b/src/html/html_document.c @@ -163,58 +163,53 @@ dom_exception _dom_html_document_copy(dom_node_internal *old, /** Internal method to support both kinds of create method */ static dom_exception _dom_html_document_create_element_internal(dom_html_document *html, - dom_string *tag_name, + dom_string *in_tag_name, dom_string *namespace, dom_string *prefix, dom_html_element **result) { + dom_exception exc; + dom_string *tag_name; + + exc = dom_string_toupper(in_tag_name, true, &tag_name); + if (exc != DOM_NO_ERR) + return exc; + if (dom_string_caseless_isequal(tag_name, html->memoised[hds_HTML])) { - return _dom_html_html_element_create(html, namespace, prefix, + exc = _dom_html_html_element_create(html, namespace, prefix, (dom_html_html_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_HEAD])) { - return _dom_html_head_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_HEAD])) { + exc = _dom_html_head_element_create(html, namespace, prefix, (dom_html_head_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_TITLE])) { - return _dom_html_title_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_TITLE])) { + exc = _dom_html_title_element_create(html, namespace, prefix, (dom_html_title_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_FORM])) { - return _dom_html_form_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_FORM])) { + exc = _dom_html_form_element_create(html, namespace, prefix, (dom_html_form_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_LINK])) { - return _dom_html_link_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_LINK])) { + exc = _dom_html_link_element_create(html, namespace, prefix, (dom_html_link_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_BUTTON])) { - return _dom_html_button_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_BUTTON])) { + exc = _dom_html_button_element_create(html, namespace, prefix, (dom_html_button_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_INPUT])) { - return _dom_html_input_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_INPUT])) { + exc = _dom_html_input_element_create(html, namespace, prefix, (dom_html_input_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_TEXTAREA])) { - return _dom_html_text_area_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_TEXTAREA])) { + exc = _dom_html_text_area_element_create(html, namespace, prefix, (dom_html_text_area_element **) result); - } - - if (dom_string_caseless_isequal(tag_name, html->memoised[hds_OPTGROUP])) { - return _dom_html_opt_group_element_create(html, namespace, prefix, + } else if (dom_string_caseless_isequal(tag_name, html->memoised[hds_OPTGROUP])) { + exc = _dom_html_opt_group_element_create(html, namespace, prefix, (dom_html_opt_group_element **) result); + } else { + exc = _dom_html_element_create(html, tag_name, namespace, + prefix, result); } - return _dom_html_element_create(html, tag_name, namespace, prefix, - result); + dom_string_unref(tag_name); + + return exc; } dom_exception _dom_html_document_create_element(dom_document *doc, -- cgit v1.2.3 From 9374dc45e2967484f2e689cc3b9e27b997f4dcb1 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 21 Jul 2012 18:30:11 +0100 Subject: HTMLElement: Ensure HTMLElement.get_elements_by_tag_name{,_ns} are caseless --- src/html/html_element.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++- src/html/html_element.h | 34 +++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/html/html_element.c b/src/html/html_element.c index 21f3d1e..c2a4899 100644 --- a/src/html/html_element.c +++ b/src/html/html_element.c @@ -26,7 +26,7 @@ struct dom_html_element_vtable _dom_html_element_vtable = { }, DOM_NODE_VTABLE_ELEMENT, }, - DOM_ELEMENT_VTABLE + DOM_ELEMENT_VTABLE_HTML_ELEMENT, }, DOM_HTML_ELEMENT_VTABLE }; @@ -142,6 +142,71 @@ SIMPLE_GET_SET(lang,lang) SIMPLE_GET_SET(dir,dir) SIMPLE_GET_SET(class_name,class) +/** + * Retrieve a list of descendant elements of an element which match a given + * tag name (caselessly) + * + * \param element The root of the subtree to search + * \param name The tag name to match (or "*" for all tags) + * \param result Pointer to location to receive result + * \return DOM_NO_ERR. + * + * The returned nodelist will have its reference count increased. It is + * the responsibility of the caller to unref the nodelist once it has + * finished with it. + */ +dom_exception _dom_html_element_get_elements_by_tag_name( + struct dom_element *element, dom_string *name, + struct dom_nodelist **result) +{ + dom_exception err; + dom_node_internal *base = (dom_node_internal *) element; + + assert(base->owner != NULL); + + err = _dom_document_get_nodelist(base->owner, + DOM_NODELIST_BY_NAME_CASELESS, + (struct dom_node_internal *) element, name, NULL, + NULL, result); + + return err; +} + +/** + * Retrieve a list of descendant elements of an element which match a given + * namespace/localname pair, caselessly. + * + * \param element The root of the subtree to search + * \param namespace The namespace URI to match (or "*" for all) + * \param localname The local name to match (or "*" for all) + * \param result Pointer to location to receive result + * \return DOM_NO_ERR on success, + * DOM_NOT_SUPPORTED_ERR if the implementation does not support + * the feature "XML" and the language exposed + * through the Document does not support + * Namespaces. + * + * The returned nodelist will have its reference count increased. It is + * the responsibility of the caller to unref the nodelist once it has + * finished with it. + */ +dom_exception _dom_html_element_get_elements_by_tag_name_ns( + struct dom_element *element, dom_string *namespace, + dom_string *localname, struct dom_nodelist **result) +{ + dom_exception err; + + /** \todo ensure XML feature is supported */ + + err = _dom_document_get_nodelist(element->base.owner, + DOM_NODELIST_BY_NAMESPACE_CASELESS, + (struct dom_node_internal *) element, NULL, + namespace, localname, + result); + + return err; +} + /*-----------------------------------------------------------------------*/ /* Common functions */ diff --git a/src/html/html_element.h b/src/html/html_element.h index ebf47ba..2ac4b17 100644 --- a/src/html/html_element.h +++ b/src/html/html_element.h @@ -33,11 +33,45 @@ dom_exception _dom_html_element_initialise(struct dom_html_document *doc, void _dom_html_element_finalise(struct dom_html_element *ele); +/* Virtual functions */ +dom_exception _dom_html_element_get_elements_by_tag_name( + struct dom_element *element, dom_string *name, + struct dom_nodelist **result); + +dom_exception _dom_html_element_get_elements_by_tag_name_ns( + struct dom_element *element, dom_string *namespace, + dom_string *localname, struct dom_nodelist **result); + + /* The protected virtual functions */ void _dom_html_element_destroy(dom_node_internal *node); dom_exception _dom_html_element_copy(dom_node_internal *old, dom_node_internal **copy); +#define DOM_ELEMENT_VTABLE_HTML_ELEMENT \ + _dom_element_get_tag_name, \ + _dom_element_get_attribute, \ + _dom_element_set_attribute, \ + _dom_element_remove_attribute, \ + _dom_element_get_attribute_node, \ + _dom_element_set_attribute_node, \ + _dom_element_remove_attribute_node, \ + _dom_html_element_get_elements_by_tag_name, \ + _dom_element_get_attribute_ns, \ + _dom_element_set_attribute_ns, \ + _dom_element_remove_attribute_ns, \ + _dom_element_get_attribute_node_ns, \ + _dom_element_set_attribute_node_ns, \ + _dom_html_element_get_elements_by_tag_name_ns, \ + _dom_element_has_attribute, \ + _dom_element_has_attribute_ns, \ + _dom_element_get_schema_type_info, \ + _dom_element_set_id_attribute, \ + _dom_element_set_id_attribute_ns, \ + _dom_element_set_id_attribute_node, \ + _dom_element_get_classes, \ + _dom_element_has_class + #define DOM_HTML_ELEMENT_PROTECT_VTABLE \ _dom_html_element_destroy, \ _dom_html_element_copy -- cgit v1.2.3 From cc4a5d9ccf3367966a8be9fe0721b0bee0c3a5af Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 21 Jul 2012 20:16:26 +0100 Subject: HTMLDocument: If finalise is hung, don't free us underneath ourselves --- src/html/html_document.c | 24 ++++++++++++++---------- src/html/html_document.h | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/html/html_document.c b/src/html/html_document.c index ddb8196..7644fde 100644 --- a/src/html/html_document.c +++ b/src/html/html_document.c @@ -116,15 +116,20 @@ out: } /* Finalise a HTMLDocument */ -void _dom_html_document_finalise(dom_html_document *doc) +bool _dom_html_document_finalise(dom_html_document *doc) { int sidx; - dom_string_unref(doc->cookie); - dom_string_unref(doc->url); - dom_string_unref(doc->domain); - dom_string_unref(doc->referrer); - dom_string_unref(doc->title); + if (doc->cookie != NULL) + dom_string_unref(doc->cookie); + if (doc->url != NULL) + dom_string_unref(doc->url); + if (doc->domain != NULL) + dom_string_unref(doc->domain); + if (doc->referrer != NULL) + dom_string_unref(doc->referrer); + if (doc->title != NULL) + dom_string_unref(doc->title); if (doc->memoised != NULL) { for(sidx = 0; sidx < hds_COUNT; ++sidx) { @@ -136,7 +141,7 @@ void _dom_html_document_finalise(dom_html_document *doc) doc->memoised = NULL; } - _dom_document_finalise(&doc->base); + return _dom_document_finalise(&doc->base); } /* Destroy a HTMLDocument */ @@ -144,9 +149,8 @@ void _dom_html_document_destroy(dom_node_internal *node) { dom_html_document *doc = (dom_html_document *) node; - _dom_html_document_finalise(doc); - - free(doc); + if (_dom_html_document_finalise(doc) == true) + free(doc); } dom_exception _dom_html_document_copy(dom_node_internal *old, diff --git a/src/html/html_document.h b/src/html/html_document.h index fbe7155..bb1a0d2 100644 --- a/src/html/html_document.h +++ b/src/html/html_document.h @@ -38,7 +38,7 @@ dom_exception _dom_html_document_create( dom_exception _dom_html_document_initialise(dom_html_document *doc, dom_events_default_action_fetcher daf); /* Finalise a HTMLDocument */ -void _dom_html_document_finalise(dom_html_document *doc); +bool _dom_html_document_finalise(dom_html_document *doc); void _dom_html_document_destroy(dom_node_internal *node); dom_exception _dom_html_document_copy(dom_node_internal *old, -- cgit v1.2.3 From d0499715bb2184a48ee7f2fdfc093fbf3fcf3286 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 21 Jul 2012 20:16:42 +0100 Subject: DOMDocument: Actually free the empty memoised string --- src/core/document.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/document.c b/src/core/document.c index c43f0bc..456d906 100644 --- a/src/core/document.c +++ b/src/core/document.c @@ -143,7 +143,7 @@ dom_exception _dom_document_initialise(dom_document *doc, /* Intern the empty string. The use of a space in the constant * is to prevent the compiler warning about an empty string. */ - err = dom_string_create_interned((const uint8_t *) ' ', 0, + err = dom_string_create_interned((const uint8_t *) " ", 0, &doc->_memo_empty); if (err != DOM_NO_ERR) { dom_string_unref(doc->class_string); @@ -184,6 +184,7 @@ bool _dom_document_finalise(dom_document *doc) dom_string_unref(doc->id_name); dom_string_unref(doc->class_string); + dom_string_unref(doc->_memo_empty); _dom_document_event_internal_finalise(doc, &doc->dei); -- cgit v1.2.3