From 9acb291f49419a1ebe0235f6622ef4e2976f9f33 Mon Sep 17 00:00:00 2001 From: Andrew Sidwell Date: Thu, 26 Jun 2008 09:19:59 +0000 Subject: Add code to adjust foreign attributes, as per spec. svn path=/trunk/hubbub/; revision=4454 --- src/treebuilder/internal.h | 3 ++ src/treebuilder/treebuilder.c | 71 ++++++++++++++++++++++++++++++++++++++++++- src/utils/Makefile | 2 +- src/utils/string.c | 62 +++++++++++++++++++++++++++++++++++++ src/utils/string.h | 16 ++++++++++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 src/utils/string.c create mode 100644 src/utils/string.h diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h index ba69660..6a35632 100644 --- a/src/treebuilder/internal.h +++ b/src/treebuilder/internal.h @@ -155,6 +155,9 @@ bool formatting_list_replace(hubbub_treebuilder *treebuilder, element_type type, void *node, uint32_t stack_index, element_type *otype, void **onode, uint32_t *ostack_index); +void adjust_foreign_attributes(hubbub_treebuilder *treebuilder, + hubbub_tag *tag); + #ifndef NDEBUG #include diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c index 2ca2132..28621bd 100644 --- a/src/treebuilder/treebuilder.c +++ b/src/treebuilder/treebuilder.c @@ -12,7 +12,7 @@ #include "treebuilder/internal.h" #include "treebuilder/treebuilder.h" #include "utils/utils.h" - +#include "utils/string.h" static const struct { const char *name; @@ -1242,6 +1242,75 @@ bool formatting_list_replace(hubbub_treebuilder *treebuilder, return true; } +/** + * Adjust foreign attributes. + * + * \param treebuilder Treebuilder instance + * \param tag Tag to adjust the attributes of + */ +void adjust_foreign_attributes(hubbub_treebuilder *treebuilder, + hubbub_tag *tag) +{ + for (size_t i = 0; i < tag->n_attributes; i++) { + hubbub_attribute *attr = &tag->attributes[i]; + const uint8_t *name = treebuilder->input_buffer + + attr->name.data.off; + +#define S(s) (uint8_t *) s, SLEN(s) + + /* 10 == strlen("xlink:href") */ + if (attr->name.len >= 10 && + strncmp((char *) name, "xlink:", + SLEN("xlink:")) == 0) { + size_t len = attr->name.len - 6; + name += 6; + + if (hubbub_string_match(name, len, S("actutate")) || + hubbub_string_match(name, len, + S("arcrole")) || + hubbub_string_match(name, len, + S("href")) || + hubbub_string_match(name, len, + S("role")) || + hubbub_string_match(name, len, + S("show")) || + hubbub_string_match(name, len, + S("title")) || + hubbub_string_match(name, len, + S("type"))) { + attr->ns = HUBBUB_NS_XLINK; + attr->name.data.off += 6; + attr->name.len -= 6; + } + /* 8 == strlen("xml:base") */ + } else if (attr->name.len >= 8 && + strncmp((char *) name, "xml:", SLEN("xml:")) == 0) { + size_t len = attr->name.len - 4; + name += 4; + + if (hubbub_string_match(name, len, S("base")) || + hubbub_string_match(name, len, + S("lang")) || + hubbub_string_match(name, len, + S("space"))) { + attr->ns = HUBBUB_NS_XML; + attr->name.data.off += 4; + attr->name.len -= 4; + } + } else if (hubbub_string_match(name, attr->name.len, + S("xmlns")) || + hubbub_string_match(name, attr->name.len, + S("xmlns:xlink"))) { + attr->ns = HUBBUB_NS_XMLNS; + attr->name.data.off += 6; + attr->name.len -= 6; + } + +#undef S + } +} + + #ifndef NDEBUG static const char *element_type_to_name(element_type type); diff --git a/src/utils/Makefile b/src/utils/Makefile index c9cd076..1910dc0 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -32,7 +32,7 @@ dirstack_$(sp) := $(d) d := $(DIR) # Sources -SRCS_$(d) := dict.c errors.c utf8.c utf16.c +SRCS_$(d) := dict.c errors.c utf8.c utf16.c string.c # Append to sources for component SOURCES += $(addprefix $(d), $(SRCS_$(d))) diff --git a/src/utils/string.c b/src/utils/string.c new file mode 100644 index 0000000..ea588f7 --- /dev/null +++ b/src/utils/string.c @@ -0,0 +1,62 @@ +/* + * This file is part of Hubbub. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2008 Andrew Sidwell + */ + +#include +#include +#include +#include "utils/string.h" + + +/** + * Check if one string starts with another. + * + * \param a String to compare + * \param a_len Length of first string + * \param b String to compare + * \param b_len Length of second string + */ +bool hubbub_string_starts(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len) +{ + uint8_t z1, z2; + + if (a_len < b_len) + return false; + + for (const uint8_t *s1 = a, *s2 = b; b_len > 0; s1++, s2++, b_len--) + { + z1 = *s1; + z2 = *s2; + if (z1 != z2) return false; + if (!z1) return true; + } + + return true; +} + +/** + * Check that one string is exactly equal to another + * + * \param a String to compare + * \param a_len Length of first string + * \param b String to compare + * \param b_len Length of second string + */ +bool hubbub_string_match(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len) +{ + if (a_len != b_len) + return false; + + for (const uint8_t *s1 = a, *s2 = b; b_len > 0; s1++, s2++, b_len--) + { + if (*s1 != *s2) return false; + } + + return true; +} + diff --git a/src/utils/string.h b/src/utils/string.h new file mode 100644 index 0000000..d6bfe42 --- /dev/null +++ b/src/utils/string.h @@ -0,0 +1,16 @@ +/* + * This file is part of Hubbub. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2008 Andrew Sidwell + */ + +#ifndef hubbub_string_h_ +#define hubbub_string_h_ + +bool hubbub_string_starts(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len); +bool hubbub_string_match(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len); + +#endif -- cgit v1.2.3