summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2016-01-31 12:04:11 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2016-01-31 12:04:11 +0000
commitd49ce7364ef8d6b577a077c9883f251acb5a3f99 (patch)
tree7d53ef02e40473849ff5154b830911f8ac9860b8
parent2e707ef487896b68494ecb07f0047be164e4ae8e (diff)
downloadlibdom-d49ce7364ef8d6b577a077c9883f251acb5a3f99.tar.gz
libdom-d49ce7364ef8d6b577a077c9883f251acb5a3f99.tar.bz2
Optimise dom_string_tolower where interned string was already lower case.
Now we detect that the string was lower case, and return a new ref to the same dom_string.
-rw-r--r--src/core/string.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/src/core/string.c b/src/core/string.c
index 9af2e74..1f0fdd5 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -978,36 +978,58 @@ dom_string_toupper(dom_string *source, bool ascii_only, dom_string **upper)
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;
- dom_exception exc;
-
+ dom_string_internal *isource = (dom_string_internal *)source;
+ dom_exception exc = DOM_NO_ERR;
+
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) {
- if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
- copy_s[index] += 'a' - 'A';
- }
- index++;
- }
-
- if (((dom_string_internal*)source)->type == DOM_STRING_CDATA) {
+ if (isource->type == DOM_STRING_CDATA) {
+ const uint8_t *orig_s = (const uint8_t *)
+ dom_string_data(source);
+ const size_t nbytes = dom_string_byte_length(source);
+ size_t index = 0;
+ uint8_t *copy_s;
+
+ copy_s = malloc(nbytes);
+ if (copy_s == NULL)
+ return DOM_NO_MEM_ERR;
+ memcpy(copy_s, orig_s, nbytes);
+
+ while (index < nbytes) {
+ if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
+ copy_s[index] += 'a' - 'A';
+ }
+
+ index++;
+ }
exc = dom_string_create(copy_s, nbytes, lower);
+
+ free(copy_s);
} else {
- exc = dom_string_create_interned(copy_s, nbytes, lower);
+ bool equal;
+ lwc_error err;
+ lwc_string *l;
+
+ err = lwc_string_tolower(isource->data.intern, &l);
+ if (err != lwc_error_ok) {
+ return DOM_NO_MEM_ERR;
+ }
+
+ if (lwc_string_isequal(isource->data.intern, l, &equal) ==
+ lwc_error_ok && equal == true) {
+ /* String is already lower case. */
+ *lower = dom_string_ref(source);
+ } else {
+ /* TODO: create dom_string wrapper around existing
+ * lwc string. */
+ exc = dom_string_create_interned(
+ (const uint8_t *)lwc_string_data(l),
+ lwc_string_length(l), lower);
+ }
+ lwc_string_unref(l);
}
- free(copy_s);
-
return exc;
}