mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
DOM: Allocate all node strings when doing incremental rendering
This changes init_dom_node_() to take an allocated argument saying whether to allocate or not. If the value is -1, node->allocated will be set to the value of node->parent->allocated. This way the value is inherited like we do it in the menu code. It should be a sane default since we eventually want not to rely on the 'underlying' source of the document and there will be less variables to pass around.
This commit is contained in:
parent
24a9d103b4
commit
b6b6d3c67e
@ -314,7 +314,7 @@ get_dom_node_child(struct dom_node *parent, enum dom_node_type type,
|
||||
struct dom_node *
|
||||
init_dom_node_(unsigned char *file, int line,
|
||||
struct dom_node *parent, enum dom_node_type type,
|
||||
struct dom_string *string)
|
||||
struct dom_string *string, int allocated)
|
||||
{
|
||||
#ifdef DEBUG_MEMLEAK
|
||||
struct dom_node *node = debug_mem_calloc(file, line, 1, sizeof(*node));
|
||||
@ -326,7 +326,6 @@ init_dom_node_(unsigned char *file, int line,
|
||||
|
||||
node->type = type;
|
||||
node->parent = parent;
|
||||
copy_dom_string(&node->string, string);
|
||||
|
||||
if (parent) {
|
||||
struct dom_node_list **list = get_dom_node_list(parent, node);
|
||||
@ -343,6 +342,22 @@ init_dom_node_(unsigned char *file, int line,
|
||||
done_dom_node(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make it possible to add a node to a parent without
|
||||
* allocating the strings. */
|
||||
node->allocated = allocated < 0 ? parent->allocated : !!allocated;
|
||||
|
||||
} else if (allocated >= 0) {
|
||||
node->allocated = !!allocated;
|
||||
}
|
||||
|
||||
if (node->allocated) {
|
||||
if (!init_dom_string(&node->string, string->string, string->length)) {
|
||||
done_dom_node(node);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
copy_dom_string(&node->string, string);
|
||||
}
|
||||
|
||||
return node;
|
||||
@ -359,10 +374,8 @@ done_dom_node_data(struct dom_node *node)
|
||||
|
||||
switch (node->type) {
|
||||
case DOM_NODE_ATTRIBUTE:
|
||||
if (node->allocated) {
|
||||
done_dom_string(&node->string);
|
||||
if (node->allocated)
|
||||
done_dom_string(&data->attribute.value);
|
||||
}
|
||||
break;
|
||||
|
||||
case DOM_NODE_DOCUMENT:
|
||||
@ -382,31 +395,21 @@ done_dom_node_data(struct dom_node *node)
|
||||
|
||||
if (data->element.map)
|
||||
done_dom_node_list(data->element.map);
|
||||
|
||||
if (node->allocated)
|
||||
done_dom_string(&node->string);
|
||||
break;
|
||||
|
||||
case DOM_NODE_TEXT:
|
||||
case DOM_NODE_CDATA_SECTION:
|
||||
case DOM_NODE_ENTITY_REFERENCE:
|
||||
if (node->allocated)
|
||||
done_dom_string(&node->string);
|
||||
break;
|
||||
|
||||
case DOM_NODE_PROCESSING_INSTRUCTION:
|
||||
if (data->proc_instruction.map)
|
||||
done_dom_node_list(data->proc_instruction.map);
|
||||
if (node->allocated) {
|
||||
done_dom_string(&node->string);
|
||||
if (node->allocated)
|
||||
done_dom_string(&data->proc_instruction.instruction);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (node->allocated)
|
||||
done_dom_string(&node->string);
|
||||
mem_free(node);
|
||||
}
|
||||
|
||||
|
@ -256,12 +256,21 @@ get_dom_node_map_entry(struct dom_node_list *node_map,
|
||||
enum dom_node_type type, uint16_t subtype,
|
||||
struct dom_string *name);
|
||||
|
||||
/* Removes the node and all its children and free()s itself */
|
||||
void done_dom_node(struct dom_node *node);
|
||||
|
||||
/* The allocated argument is used as the value of node->allocated if >= 0.
|
||||
* Use -1 to default node->allocated to the value of parent->allocated. */
|
||||
struct dom_node *
|
||||
init_dom_node_(unsigned char *file, int line,
|
||||
struct dom_node *parent, enum dom_node_type type,
|
||||
struct dom_string *string);
|
||||
#define init_dom_node(type, string) init_dom_node_(__FILE__, __LINE__, NULL, type, string)
|
||||
#define add_dom_node(parent, type, string) init_dom_node_(__FILE__, __LINE__, parent, type, string)
|
||||
struct dom_string *string, int allocated);
|
||||
|
||||
#define init_dom_node(type, string, allocated) \
|
||||
init_dom_node_(__FILE__, __LINE__, NULL, type, string, allocated)
|
||||
|
||||
#define add_dom_node(parent, type, string) \
|
||||
init_dom_node_(__FILE__, __LINE__, parent, type, string, -1)
|
||||
|
||||
#define add_dom_element(parent, string) \
|
||||
add_dom_node(parent, DOM_NODE_ELEMENT, string)
|
||||
@ -273,7 +282,16 @@ add_dom_attribute(struct dom_node *parent, struct dom_string *name,
|
||||
struct dom_node *node = add_dom_node(parent, DOM_NODE_ATTRIBUTE, name);
|
||||
|
||||
if (node && value) {
|
||||
copy_dom_string(&node->data.attribute.value, value);
|
||||
struct dom_string *str = &node->data.attribute.value;
|
||||
|
||||
if (node->allocated) {
|
||||
if (!init_dom_string(str, value->string, value->length)) {
|
||||
done_dom_node(node);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
copy_dom_string(str, value);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
@ -286,15 +304,21 @@ add_dom_proc_instruction(struct dom_node *parent, struct dom_string *string,
|
||||
struct dom_node *node = add_dom_node(parent, DOM_NODE_PROCESSING_INSTRUCTION, string);
|
||||
|
||||
if (node && instruction) {
|
||||
copy_dom_string(&node->data.proc_instruction.instruction, instruction);
|
||||
struct dom_string *str = &node->data.proc_instruction.instruction;
|
||||
|
||||
if (node->allocated) {
|
||||
if (!init_dom_string(str, instruction->string, instruction->length)) {
|
||||
done_dom_node(node);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
copy_dom_string(str, instruction);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Removes the node and all its children and free()s itself */
|
||||
void done_dom_node(struct dom_node *node);
|
||||
|
||||
/* Compare two nodes returning non-zero if they differ. */
|
||||
int dom_node_casecmp(struct dom_node *node1, struct dom_node *node2);
|
||||
|
||||
|
@ -35,11 +35,13 @@
|
||||
* information like node subtypes and SGML parser state information. */
|
||||
|
||||
static inline struct dom_node *
|
||||
add_sgml_document(struct dom_stack *stack, struct dom_string *string)
|
||||
add_sgml_document(struct sgml_parser *parser)
|
||||
{
|
||||
struct dom_node *node = init_dom_node(DOM_NODE_DOCUMENT, string);
|
||||
int allocated = parser->flags & SGML_PARSER_INCREMENTAL;
|
||||
struct dom_node *node;
|
||||
|
||||
if (node && push_dom_node(stack, node) == DOM_STACK_CODE_OK)
|
||||
node = init_dom_node(DOM_NODE_DOCUMENT, &parser->uri, allocated);
|
||||
if (node && push_dom_node(&parser->stack, node) == DOM_STACK_CODE_OK)
|
||||
return node;
|
||||
|
||||
return NULL;
|
||||
@ -432,13 +434,13 @@ parse_sgml(struct sgml_parser *parser, unsigned char *buf, size_t bufsize,
|
||||
parser->flags |= SGML_PARSER_COMPLETE;
|
||||
|
||||
if (!parser->root) {
|
||||
parser->root = add_sgml_document(&parser->stack, &parser->uri);
|
||||
parser->root = add_sgml_document(parser);
|
||||
if (!parser->root)
|
||||
return SGML_PARSER_CODE_MEM_ALLOC;
|
||||
get_dom_stack_top(&parser->stack)->immutable = 1;
|
||||
}
|
||||
|
||||
node = init_dom_node(DOM_NODE_TEXT, &source);
|
||||
node = init_dom_node(DOM_NODE_TEXT, &source, 0);
|
||||
if (!node || push_dom_node(&parser->parsing, node) != DOM_STACK_CODE_OK)
|
||||
return SGML_PARSER_CODE_MEM_ALLOC;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user