1 /*
2  * Copyright (C) 2018-2021 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #include "lexbor/dom/interfaces/document_type.h"
8 #include "lexbor/dom/interfaces/document.h"
9 
10 
11 LXB_API lxb_dom_attr_data_t *
12 lxb_dom_attr_qualified_name_append(lexbor_hash_t *hash, const lxb_char_t *name,
13                                    size_t length);
14 
15 
16 lxb_dom_document_type_t *
lxb_dom_document_type_interface_create(lxb_dom_document_t * document)17 lxb_dom_document_type_interface_create(lxb_dom_document_t *document)
18 {
19     lxb_dom_document_type_t *element;
20 
21     element = lexbor_mraw_calloc(document->mraw,
22                                  sizeof(lxb_dom_document_type_t));
23     if (element == NULL) {
24         return NULL;
25     }
26 
27     lxb_dom_node_t *node = lxb_dom_interface_node(element);
28 
29     node->owner_document = lxb_dom_document_owner(document);
30     node->type = LXB_DOM_NODE_TYPE_DOCUMENT_TYPE;
31 
32     return element;
33 }
34 
35 lxb_dom_document_type_t *
lxb_dom_document_type_interface_clone(lxb_dom_document_t * document,const lxb_dom_document_type_t * dtype)36 lxb_dom_document_type_interface_clone(lxb_dom_document_t *document,
37                                       const lxb_dom_document_type_t *dtype)
38 {
39     lxb_status_t status;
40     lxb_dom_document_type_t *new;
41     const lxb_dom_attr_data_t *data;
42 
43     new = lxb_dom_document_type_interface_create(document);
44     if (new == NULL) {
45         return NULL;
46     }
47 
48     status = lxb_dom_node_interface_copy(&new->node, &dtype->node, false);
49     if (status != LXB_STATUS_OK) {
50         return lxb_dom_document_type_interface_destroy(new);
51     }
52 
53     if (document == dtype->node.owner_document) {
54         new->name = dtype->name;
55     }
56     else {
57         data = lxb_dom_attr_data_by_id(dtype->node.owner_document->attrs,
58                                        dtype->name);
59         if (data == NULL) {
60             return lxb_dom_document_type_interface_destroy(new);
61         }
62 
63         data = lxb_dom_attr_qualified_name_append(document->attrs,
64                                                   lexbor_hash_entry_str(&data->entry),
65                                                   data->entry.length);
66         if (data == NULL) {
67             return lxb_dom_document_type_interface_destroy(new);
68         }
69 
70         new->name = (lxb_dom_attr_id_t) data;
71     }
72 
73     if (lexbor_str_copy(&new->public_id,
74                         &dtype->public_id, document->text) == NULL)
75     {
76         return lxb_dom_document_type_interface_destroy(new);
77     }
78 
79     if (lexbor_str_copy(&new->system_id,
80                         &dtype->system_id, document->text) == NULL)
81     {
82         return lxb_dom_document_type_interface_destroy(new);
83     }
84 
85     return new;
86 }
87 
88 
89 lxb_dom_document_type_t *
lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t * document_type)90 lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t *document_type)
91 {
92     lexbor_mraw_t *text;
93     lexbor_str_t public_id;
94     lexbor_str_t system_id;
95 
96     text = lxb_dom_interface_node(document_type)->owner_document->text;
97     public_id = document_type->public_id;
98     system_id = document_type->system_id;
99 
100     (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(document_type));
101 
102     (void) lexbor_str_destroy(&public_id, text, false);
103     (void) lexbor_str_destroy(&system_id, text, false);
104 
105     return NULL;
106 }
107 
108 /*
109  * No inline functions for ABI.
110  */
111 const lxb_char_t *
lxb_dom_document_type_name_noi(lxb_dom_document_type_t * doc_type,size_t * len)112 lxb_dom_document_type_name_noi(lxb_dom_document_type_t *doc_type, size_t *len)
113 {
114     return lxb_dom_document_type_name(doc_type, len);
115 }
116 
117 const lxb_char_t *
lxb_dom_document_type_public_id_noi(lxb_dom_document_type_t * doc_type,size_t * len)118 lxb_dom_document_type_public_id_noi(lxb_dom_document_type_t *doc_type,
119                                     size_t *len)
120 {
121     return lxb_dom_document_type_public_id(doc_type, len);
122 }
123 
124 const lxb_char_t *
lxb_dom_document_type_system_id_noi(lxb_dom_document_type_t * doc_type,size_t * len)125 lxb_dom_document_type_system_id_noi(lxb_dom_document_type_t *doc_type,
126                                     size_t *len)
127 {
128     return lxb_dom_document_type_system_id(doc_type, len);
129 }
130