1 /*
2  * Copyright (C) 2018-2021 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #include "lexbor/dom/interfaces/character_data.h"
8 #include "lexbor/dom/interfaces/document.h"
9 
10 
11 lxb_dom_character_data_t *
lxb_dom_character_data_interface_create(lxb_dom_document_t * document)12 lxb_dom_character_data_interface_create(lxb_dom_document_t *document)
13 {
14     lxb_dom_character_data_t *element;
15 
16     element = lexbor_mraw_calloc(document->mraw,
17                                  sizeof(lxb_dom_character_data_t));
18     if (element == NULL) {
19         return NULL;
20     }
21 
22     lxb_dom_node_t *node = lxb_dom_interface_node(element);
23 
24     node->owner_document = lxb_dom_document_owner(document);
25     node->type = LXB_DOM_NODE_TYPE_UNDEF;
26 
27     return element;
28 }
29 
30 lxb_dom_character_data_t *
lxb_dom_character_data_interface_clone(lxb_dom_document_t * document,const lxb_dom_character_data_t * ch_data)31 lxb_dom_character_data_interface_clone(lxb_dom_document_t *document,
32                                        const lxb_dom_character_data_t *ch_data)
33 {
34     lxb_dom_character_data_t *new;
35 
36     new = lxb_dom_character_data_interface_create(document);
37     if (new == NULL) {
38         return NULL;
39     }
40 
41     if (lxb_dom_character_data_interface_copy(new, ch_data) != LXB_STATUS_OK) {
42         return lxb_dom_character_data_interface_destroy(new);
43     }
44 
45     return new;
46 }
47 
48 lxb_dom_character_data_t *
lxb_dom_character_data_interface_destroy(lxb_dom_character_data_t * character_data)49 lxb_dom_character_data_interface_destroy(lxb_dom_character_data_t *character_data)
50 {
51     lxb_dom_node_t *node;
52     lxb_dom_document_t *doc;
53     lexbor_str_t data;
54 
55     data = character_data->data;
56     node = lxb_dom_interface_node(character_data);
57     doc = node->owner_document;
58 
59     (void) lxb_dom_node_interface_destroy(node);
60 
61     lexbor_str_destroy(&data, doc->text, false);
62 
63     return NULL;
64 }
65 
66 lxb_status_t
lxb_dom_character_data_interface_copy(lxb_dom_character_data_t * dst,const lxb_dom_character_data_t * src)67 lxb_dom_character_data_interface_copy(lxb_dom_character_data_t *dst,
68                                       const lxb_dom_character_data_t *src)
69 {
70     lxb_status_t status;
71 
72     status = lxb_dom_node_interface_copy(&dst->node, &src->node, false);
73     if (status != LXB_STATUS_OK) {
74         return status;
75     }
76 
77     dst->data.length = 0;
78 
79     if (lexbor_str_copy(&dst->data, &src->data,
80                         lxb_dom_interface_node(dst)->owner_document->text) == NULL)
81     {
82         return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
83     }
84 
85     return LXB_STATUS_OK;
86 }
87 
88 /* TODO: oh, need to... https://dom.spec.whatwg.org/#concept-cd-replace */
89 lxb_status_t
lxb_dom_character_data_replace(lxb_dom_character_data_t * ch_data,const lxb_char_t * data,size_t len,size_t offset,size_t count)90 lxb_dom_character_data_replace(lxb_dom_character_data_t *ch_data,
91                                const lxb_char_t *data, size_t len,
92                                size_t offset, size_t count)
93 {
94     if (ch_data->data.data == NULL) {
95         lexbor_str_init(&ch_data->data, ch_data->node.owner_document->text, len);
96         if (ch_data->data.data == NULL) {
97             return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
98         }
99     }
100     else if (lexbor_str_size(&ch_data->data) < len) {
101         const lxb_char_t *data;
102 
103         data = lexbor_str_realloc(&ch_data->data,
104                                   ch_data->node.owner_document->text, (len + 1));
105         if (data == NULL) {
106             return LXB_STATUS_ERROR_MEMORY_ALLOCATION;
107         }
108     }
109 
110     memcpy(ch_data->data.data, data, sizeof(lxb_char_t) * len);
111 
112     ch_data->data.data[len] = 0x00;
113     ch_data->data.length = len;
114 
115     return LXB_STATUS_OK;
116 }
117