1 /*
2 Copyright (C) 2016-2017 Alexander Borisov
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18 Author: lex.borisov@gmail.com (Alexander Borisov)
19 */
20
21 #include "mycss/namespace/init.h"
22
mycss_namespace_create(void)23 mycss_namespace_t * mycss_namespace_create(void)
24 {
25 return (mycss_namespace_t*)mycore_calloc(1, sizeof(mycss_namespace_t));
26 }
27
mycss_namespace_init(mycss_entry_t * entry,mycss_namespace_t * ns)28 mystatus_t mycss_namespace_init(mycss_entry_t* entry, mycss_namespace_t* ns)
29 {
30 /* Objects Namespace */
31 ns->mcobject_entries = mcobject_create();
32 if(ns->mcobject_entries == NULL)
33 return MyCSS_STATUS_ERROR_NAMESPACE_ENTRIES_CREATE;
34
35 mystatus_t myhtml_status = mcobject_init(ns->mcobject_entries, 256, sizeof(mycss_namespace_entry_t));
36 if(myhtml_status)
37 return MyCSS_STATUS_ERROR_NAMESPACE_ENTRIES_INIT;
38
39 return MyCSS_STATUS_OK;
40 }
41
mycss_namespace_clean(mycss_namespace_t * ns)42 void mycss_namespace_clean(mycss_namespace_t* ns)
43 {
44 ns->entry = NULL;
45 }
46
mycss_namespace_clean_all(mycss_namespace_t * ns)47 mystatus_t mycss_namespace_clean_all(mycss_namespace_t* ns)
48 {
49 mcobject_clean(ns->mcobject_entries);
50 ns->entry = NULL;
51
52 return MyCSS_STATUS_OK;
53 }
54
mycss_namespace_destroy(mycss_namespace_t * ns,bool self_destroy)55 mycss_namespace_t * mycss_namespace_destroy(mycss_namespace_t* ns, bool self_destroy)
56 {
57 if(ns == NULL)
58 return NULL;
59
60 ns->mcobject_entries = mcobject_destroy(ns->mcobject_entries, true);
61
62 if(self_destroy) {
63 mycore_free(ns);
64 return NULL;
65 }
66
67 return ns;
68 }
69
mycss_namespace_entry_create(mycss_namespace_t * ns)70 mycss_namespace_entry_t * mycss_namespace_entry_create(mycss_namespace_t* ns)
71 {
72 return mcobject_malloc(ns->mcobject_entries, NULL);
73 }
74
mycss_namespace_entry_clean(mycss_namespace_entry_t * ns_entry)75 void mycss_namespace_entry_clean(mycss_namespace_entry_t* ns_entry)
76 {
77 memset(ns_entry, 0, sizeof(mycss_namespace_entry_t));
78 }
79
mycss_namespace_entry_destroy(mycss_namespace_entry_t * ns_entry,mycss_entry_t * entry,bool self_destroy)80 mycss_namespace_entry_t * mycss_namespace_entry_destroy(mycss_namespace_entry_t* ns_entry, mycss_entry_t* entry, bool self_destroy)
81 {
82 if(ns_entry->name) {
83 mycore_string_destroy(ns_entry->name, false);
84 mcobject_free(entry->mcobject_string_entries, ns_entry->name);
85 }
86
87 if(ns_entry->url) {
88 mycore_string_destroy(ns_entry->url, false);
89 mcobject_free(entry->mcobject_string_entries, ns_entry->url);
90 }
91
92 if(self_destroy) {
93 mycore_free(ns_entry);
94 return NULL;
95 }
96
97 return ns_entry;
98 }
99
mycss_namespace_entry_append_to_current(mycss_namespace_t * ns,mycss_namespace_entry_t * ns_entry)100 void mycss_namespace_entry_append_to_current(mycss_namespace_t* ns, mycss_namespace_entry_t* ns_entry)
101 {
102 if(ns->entry_last) {
103 ns->entry_last->next = ns_entry;
104 ns_entry->prev = ns->entry_last;
105 }
106 else {
107 (*ns->entry) = ns_entry;
108 }
109
110 ns->entry_last = ns_entry;
111 }
112
mycss_namespace_stylesheet_init(mycss_namespace_stylesheet_t * ns_stylesheet,mycss_entry_t * entry)113 mystatus_t mycss_namespace_stylesheet_init(mycss_namespace_stylesheet_t* ns_stylesheet, mycss_entry_t* entry)
114 {
115 ns_stylesheet->name_tree = mctree_create(14);
116 if(ns_stylesheet->name_tree == NULL)
117 return MyCSS_STATUS_ERROR_NAMESPACE_CREATE;
118
119 ns_stylesheet->ns_id_counter = 0;
120
121 ns_stylesheet->entry_default = mycss_namespace_entry_create(entry->ns);
122 if(ns_stylesheet->entry_default == NULL)
123 return MyCSS_STATUS_ERROR_NAMESPACE_ENTRIES_CREATE;
124
125 mycss_namespace_entry_clean(ns_stylesheet->entry_default);
126 mycss_namespace_entry_clean(&ns_stylesheet->entry_undef);
127 mycss_namespace_entry_clean(&ns_stylesheet->entry_any);
128
129 /* init name for basic namespace entry; for default namespace entry name = NULL */
130 ns_stylesheet->entry_undef.name = mycss_entry_string_create_and_init(entry, 2);
131 if(ns_stylesheet->entry_undef.name == NULL)
132 return MyCSS_STATUS_ERROR_STRING_CREATE;
133
134 ns_stylesheet->entry_any.name = mycss_entry_string_create_and_init(entry, 2);
135 if(ns_stylesheet->entry_any.name == NULL)
136 return MyCSS_STATUS_ERROR_STRING_CREATE;
137
138 mycore_string_append(ns_stylesheet->entry_any.name, "*", 1);
139 ns_stylesheet->entry_any.ns_id = MyHTML_NAMESPACE_ANY;
140
141 mycss_namespace_stylesheet_init_default(ns_stylesheet, entry, NULL, 0, MyHTML_NAMESPACE_ANY);
142
143 return MyCSS_STATUS_OK;
144 }
145
mycss_namespace_stylesheet_clean(mycss_namespace_stylesheet_t * ns_stylesheet,mycss_entry_t * entry)146 mystatus_t mycss_namespace_stylesheet_clean(mycss_namespace_stylesheet_t* ns_stylesheet, mycss_entry_t* entry)
147 {
148 mctree_clean(ns_stylesheet->name_tree);
149 ns_stylesheet->ns_id_counter = 0;
150
151 mycss_namespace_stylesheet_init_default(ns_stylesheet, entry, NULL, 0, MyHTML_NAMESPACE_ANY);
152
153 return MyCSS_STATUS_OK;
154 }
155
mycss_namespace_stylesheet_destroy(mycss_namespace_stylesheet_t * ns_stylesheet,mycss_entry_t * entry,bool self_destroy)156 mycss_namespace_stylesheet_t * mycss_namespace_stylesheet_destroy(mycss_namespace_stylesheet_t* ns_stylesheet, mycss_entry_t* entry, bool self_destroy)
157 {
158 mycss_namespace_entry_t* ns_entry = ns_stylesheet->entry_default;
159
160 while(ns_entry) {
161 mycss_namespace_entry_t* ns_entry_next = ns_entry->next;
162
163 mycss_namespace_entry_destroy(ns_entry, entry, false);
164 mcobject_free(entry->ns->mcobject_entries, ns_entry);
165
166 ns_entry = ns_entry_next;
167 }
168
169 ns_stylesheet->name_tree = mctree_destroy(ns_stylesheet->name_tree);
170 ns_stylesheet->entry_undef.name = mycore_string_destroy(ns_stylesheet->entry_undef.name, false);
171 ns_stylesheet->entry_any.name = mycore_string_destroy(ns_stylesheet->entry_any.name, false);
172
173 if(self_destroy) {
174 mycore_free(ns_stylesheet);
175 return NULL;
176 }
177
178 return ns_stylesheet;
179 }
180
mycss_namespace_stylesheet_init_default(mycss_namespace_stylesheet_t * ns_stylesheet,mycss_entry_t * entry,const char * url,size_t url_length,myhtml_namespace_t def_ns)181 mystatus_t mycss_namespace_stylesheet_init_default(mycss_namespace_stylesheet_t* ns_stylesheet, mycss_entry_t* entry, const char* url, size_t url_length, myhtml_namespace_t def_ns)
182 {
183 mycore_string_t *str = ns_stylesheet->entry_default->url;
184
185 if(str == NULL) {
186 str = mcobject_malloc(entry->mcobject_string_entries, NULL);
187 mycore_string_init(entry->mchar, entry->mchar_node_id, str, (url_length + 1));
188
189 ns_stylesheet->entry_default->url = str;
190 }
191 else
192 mycore_string_clean(str);
193
194 if(url && url_length) {
195 mycore_string_append(str, url, url_length);
196 ns_stylesheet->entry_default->ns_id = myhtml_namespace_id_by_url(url, url_length);
197 }
198 else
199 ns_stylesheet->entry_default->ns_id = def_ns;
200
201 ns_stylesheet->entry_default->mctree_id = 0;
202 ns_stylesheet->entry_default->name = NULL;
203 ns_stylesheet->entry_default->next = NULL;
204 ns_stylesheet->entry_default->prev = NULL;
205
206 return MyCSS_STATUS_OK;
207 }
208
mycss_namespace_stylesheet_append_default(mycss_namespace_stylesheet_t * ns_stylesheet,mycss_namespace_entry_t * ns_entry)209 void mycss_namespace_stylesheet_append_default(mycss_namespace_stylesheet_t* ns_stylesheet, mycss_namespace_entry_t* ns_entry)
210 {
211 if(ns_stylesheet->entry_default == NULL) {
212 ns_stylesheet->entry_default = ns_entry;
213 return;
214 }
215
216 mycss_namespace_entry_t* ns_entry_cur = ns_stylesheet->entry_default;
217
218 while(ns_entry_cur->next)
219 ns_entry_cur = ns_entry_cur->next;
220
221 ns_entry_cur->next = ns_entry;
222 ns_entry->prev = ns_entry_cur;
223
224 ns_stylesheet->entry_default = ns_entry;
225 }
226
mycss_namespace_stylesheet_destroy_default(mycss_namespace_stylesheet_t * ns_stylesheet,mycss_entry_t * entry)227 void mycss_namespace_stylesheet_destroy_default(mycss_namespace_stylesheet_t* ns_stylesheet, mycss_entry_t* entry)
228 {
229 mycore_string_t *str = ns_stylesheet->entry_default->url;
230
231 if(str) {
232 mycore_string_destroy(str, false);
233 mcobject_free(entry->mcobject_string_entries, str);
234
235 ns_stylesheet->entry_default->url = NULL;
236 }
237 }
238
mycss_namespace_name_by_id(mycss_namespace_t * ns,mctree_t * name_tree,size_t ns_id,size_t * length)239 const char * mycss_namespace_name_by_id(mycss_namespace_t* ns, mctree_t* name_tree, size_t ns_id, size_t* length)
240 {
241 if(ns_id < MyHTML_NAMESPACE_LAST_ENTRY)
242 return myhtml_namespace_name_by_id((myhtml_namespace_t)ns_id, length);
243
244 ns_id -= MyHTML_NAMESPACE_LAST_ENTRY;
245
246 mycss_namespace_entry_t *entry = (mycss_namespace_entry_t*)(name_tree->nodes[ ns_id ].value);
247
248 if(length)
249 *length = entry->name->length;
250
251 return entry->name->data;
252 }
253
mycss_namespace_name_by_entry(mycss_namespace_entry_t * ns_entry,mctree_t * name_tree,size_t * length,bool * is_default)254 const char * mycss_namespace_name_by_entry(mycss_namespace_entry_t* ns_entry, mctree_t* name_tree, size_t* length, bool* is_default)
255 {
256 if(ns_entry->name == NULL) {
257 if(is_default)
258 *is_default = true;
259
260 if(length)
261 *length = 0;
262
263 if(ns_entry->ns_id <= MyHTML_NAMESPACE_LAST_ENTRY)
264 return myhtml_namespace_name_by_id(ns_entry->ns_id, length);
265
266 return NULL;
267 }
268
269 if(is_default)
270 *is_default = false;
271
272 if(length)
273 *length = ns_entry->name->length;
274
275 return ns_entry->name->data;
276 }
277
mycss_namespace_entry_by_name(mycss_namespace_t * ns,mctree_t * name_tree,const char * ns_name,size_t length,bool case_insensitive)278 mycss_namespace_entry_t * mycss_namespace_entry_by_name(mycss_namespace_t *ns, mctree_t* name_tree, const char* ns_name, size_t length, bool case_insensitive)
279 {
280 if(ns == NULL)
281 return NULL;
282
283 mctree_index_t idx;
284 if(case_insensitive)
285 idx = mctree_search_lowercase(name_tree, ns_name, length);
286 else
287 idx = mctree_search(name_tree, ns_name, length);
288
289 if(idx == 0)
290 return 0;
291
292 return (mycss_namespace_entry_t*)(name_tree->nodes[ idx ].value);
293 }
294
295
296