| {% from "templates/macros.tmpl" import license, source_files_for_generated_file %} |
| {{ license() }} |
| |
| {{source_files_for_generated_file(template_file, input_files)}} |
| |
| #include "{{this_include_path}}" |
| |
| #include <memory> |
| |
| #include "base/stl_util.h" // for base::size() |
| #include "third_party/blink/renderer/platform/wtf/static_constructors.h" |
| #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" |
| |
| namespace blink { |
| namespace {{cpp_namespace}} { |
| |
| DEFINE_GLOBAL(AtomicString, {{namespace_prefix}}NamespaceURI); |
| |
| {% if tags %} |
| // Tags |
| |
| void* tag_storage[kTagsCount * ((sizeof({{namespace}}QualifiedName) + sizeof(void *) - 1) / sizeof(void *))]; |
| {% for tag in tags|sort(attribute='name', case_sensitive=True) %} |
| const {{namespace}}QualifiedName& {{tag|symbol}}Tag = reinterpret_cast<{{namespace}}QualifiedName*>(&tag_storage)[{{loop.index0}}]; |
| {% endfor %} |
| |
| |
| std::unique_ptr<const {{namespace}}QualifiedName*[]> GetTags() { |
| auto tags = std::make_unique<const {{namespace}}QualifiedName*[]>(kTagsCount); |
| for (size_t i = 0; i < kTagsCount; ++i) |
| tags[i] = reinterpret_cast<{{namespace}}QualifiedName*>(&tag_storage) + i; |
| return tags; |
| } |
| |
| {% endif %} |
| // Attributes |
| |
| void* attr_storage[kAttrsCount * ((sizeof(QualifiedName) + sizeof(void *) - 1) / sizeof(void *))]; |
| |
| {% for attr in attrs|sort(attribute='name', case_sensitive=True) %} |
| const QualifiedName& {{attr|symbol}}Attr = reinterpret_cast<QualifiedName*>(&attr_storage)[{{loop.index0}}]; |
| {% endfor %} |
| |
| {% if namespace != 'HTML' %} |
| std::unique_ptr<const QualifiedName*[]> GetAttrs() { |
| auto attrs = std::make_unique<const QualifiedName*[]>(kAttrsCount); |
| for (size_t i = 0; i < kAttrsCount; ++i) |
| attrs[i] = reinterpret_cast<QualifiedName*>(&attr_storage) + i; |
| return attrs; |
| } |
| {% endif %} |
| |
| |
| void Init() { |
| struct NameEntry { |
| const char* name; |
| unsigned hash; |
| unsigned char length; |
| unsigned char is_tag; |
| unsigned char is_attr; |
| }; |
| |
| // Namespace |
| // Use placement new to initialize the globals. |
| AtomicString ns_uri("{{namespace_uri}}"); |
| new ((void*)&{{namespace_prefix}}NamespaceURI) AtomicString(ns_uri); |
| |
| {% set tagnames = tags|map(attribute='name')|list() %} |
| {% set attrnames = attrs|map(attribute='name')|list() %} |
| static const NameEntry kNames[] = { |
| {% for name, tag_list in (tags + attrs)|groupby('name')|sort(attribute=0, case_sensitive=True) %} |
| { "{{name}}", {{name.original|hash}}, {{name.original|length}}, {{ (name in tagnames)|int }}, {{ (name in attrnames)|int }} }, |
| {% endfor %} |
| }; |
| |
| {% if tags %} |
| size_t tag_i = 0; |
| {% endif %} |
| size_t attr_i = 0; |
| for (size_t i = 0; i < base::size(kNames); ++i) { |
| StringImpl* impl = StringImpl::CreateStatic(kNames[i].name, kNames[i].length, kNames[i].hash); |
| {% if tags %} |
| if (kNames[i].is_tag) { |
| void* address = reinterpret_cast<{{namespace}}QualifiedName*>(&tag_storage) + tag_i; |
| QualifiedName::CreateStatic(address, impl, ns_uri); |
| ++tag_i; |
| } |
| |
| if (!kNames[i].is_attr) |
| continue; |
| {% endif %} |
| void* address = reinterpret_cast<QualifiedName*>(&attr_storage) + attr_i; |
| {% if use_namespace_for_attrs %} |
| QualifiedName::CreateStatic(address, impl, ns_uri); |
| {% else %} |
| QualifiedName::CreateStatic(address, impl); |
| {% endif %} |
| ++attr_i; |
| } |
| {% if tags %} |
| DCHECK_EQ(tag_i, kTagsCount); |
| {% endif %} |
| DCHECK_EQ(attr_i, kAttrsCount); |
| } |
| |
| } // namespace {{cpp_namespace}} |
| } // namespace blink |