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