static bool save_complete_handle_attrs(save_complete_ctx *ctx, dom_string *node_name, dom_namednodemap *attrs) { uint32_t length, i; dom_exception error; error = dom_namednodemap_get_length(attrs, &length); if (error != DOM_NO_ERR) return false; for (i = 0; i < length; i++) { dom_attr *attr; error = dom_namednodemap_item(attrs, i, (void *) &attr); if (error != DOM_NO_ERR) return false; if (attr == NULL) continue; if (save_complete_handle_attr(ctx, node_name, attr) == false) { dom_node_unref(attr); return false; } dom_node_unref(attr); } return true; }
/** * Load the file as it is a XML file * * \param file The file path * \param willBeModified Whether this file will be modified, not used */ dom_document *load_xml(const char *file, bool willBeModified) { dom_xml_parser *parser = NULL; int handle; int readed; dom_xml_error error; dom_document *ret; uint8_t buffer[1024]; UNUSED(willBeModified); parser = dom_xml_parser_create(NULL, NULL, mymsg, NULL, &ret); if (parser == NULL) { fprintf(stderr, "Can't create XMLParser\n"); return NULL; } handle = open(file, O_RDONLY); if (handle == -1) { dom_node_unref(ret); dom_xml_parser_destroy(parser); fprintf(stderr, "Can't open test input file: %s\n", file); return NULL; } readed = read(handle, buffer, 1024); error = dom_xml_parser_parse_chunk(parser, buffer, readed); if (error != DOM_XML_OK) { dom_node_unref(ret); dom_xml_parser_destroy(parser); fprintf(stderr, "Parsing errors occur\n"); return NULL; } while(readed == 1024) { readed = read(handle, buffer, 1024); error = dom_xml_parser_parse_chunk(parser, buffer, readed); if (error != DOM_XML_OK) { dom_node_unref(ret); dom_xml_parser_destroy(parser); fprintf(stderr, "Parsing errors occur\n"); return NULL; } } error = dom_xml_parser_completed(parser); if (error != DOM_XML_OK) { dom_node_unref(ret); dom_xml_parser_destroy(parser); fprintf(stderr, "Parsing error when construct DOM\n"); return NULL; } dom_xml_parser_destroy(parser); return ret; }
/** * Callback to find a named sibling node. * * \param pw HTML document * \param node DOM node * \param qname Node name to search for * \param sibling Pointer to location to receive sibling * \return CSS_OK. * * \post \a sibling will contain the result, or NULL if there is no match */ css_error named_sibling_node(void *pw, void *node, const css_qname *qname, void **sibling) { dom_node *n = node; dom_node *prev; dom_exception err; *sibling = NULL; /* Find sibling element */ err = dom_node_get_previous_sibling(n, &n); if (err != DOM_NO_ERR) return CSS_OK; while (n != NULL) { dom_node_type type; err = dom_node_get_node_type(n, &type); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_OK; } if (type == DOM_ELEMENT_NODE) break; err = dom_node_get_previous_sibling(n, &prev); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_OK; } dom_node_unref(n); n = prev; } if (n != NULL) { dom_string *name; err = dom_node_get_node_name(n, &name); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_OK; } dom_node_unref(n); if (dom_string_caseless_lwc_isequal(name, qname->name)) { *sibling = n; } dom_string_unref(name); } return CSS_OK; }
/** * Finalise a dom_html_collection object * * \param col The dom_html_collection object */ void _dom_html_collection_finalise(struct dom_html_collection *col) { dom_node_unref(col->doc); col->doc = NULL; dom_node_unref(col->root); col->root = NULL; col->ic = NULL; }
/** * Callback to count a node's siblings. * * \param pw HTML document * \param n DOM node * \param same_name Only count siblings with the same name, or all * \param after Count anteceding instead of preceding siblings * \param count Pointer to location to receive result * \return CSS_OK. * * \post \a count will contain the number of siblings */ css_error node_count_siblings(void *pw, void *n, bool same_name, bool after, int32_t *count) { int32_t cnt = 0; dom_exception exc; dom_string *node_name = NULL; if (same_name) { dom_node *node = n; exc = dom_node_get_node_name(node, &node_name); if ((exc != DOM_NO_ERR) || (node_name == NULL)) { return CSS_NOMEM; } } if (after) { dom_node *node = dom_node_ref(n); dom_node *next; do { exc = dom_node_get_next_sibling(node, &next); if ((exc != DOM_NO_ERR)) break; dom_node_unref(node); node = next; cnt += node_count_siblings_check(node, same_name, node_name); } while (node != NULL); } else { dom_node *node = dom_node_ref(n); dom_node *next; do { exc = dom_node_get_previous_sibling(node, &next); if ((exc != DOM_NO_ERR)) break; dom_node_unref(node); node = next; cnt += node_count_siblings_check(node, same_name, node_name); } while (node != NULL); } if (node_name != NULL) { dom_string_unref(node_name); } *count = cnt; return CSS_OK; }
/** * Callback to determine if a node is the root node of the document. * * \param pw HTML document * \param node DOM node * \param match Pointer to location to receive result * \return CSS_OK. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_is_root(void *pw, void *node, bool *match) { dom_node *n = node; dom_node *parent; dom_node_type type; dom_exception err; err = dom_node_get_parent_node(n, &parent); if (err != DOM_NO_ERR) { return CSS_NOMEM; } if (parent != NULL) { err = dom_node_get_node_type(parent, &type); dom_node_unref(parent); if (err != DOM_NO_ERR) return CSS_NOMEM; if (type != DOM_DOCUMENT_NODE) { *match = false; return CSS_OK; } } *match = true; return CSS_OK; }
dom_exception dom_element_get_elements_by_tag_name(dom_element *element, dom_string *string, dom_nodelist **outNodeList) { dom_nodelist *result = NULL; dom_element **nodeList = NULL; int nodeCount = 0; for (ezxml_t candidate = ezxml_child(element->node, string->s); candidate; candidate = candidate->next) { if (NULL == nodeList) { nodeList = (dom_element **)malloc(nodeCount * sizeof(dom_element *)); } else { dom_element **t = realloc(nodeList, (1+nodeCount) * sizeof(dom_element *)); if (t) { nodeList = t; } else { for (int i = 0; i < nodeCount; ++i) { dom_node_unref(nodeList[i]); } free(nodeList); *outNodeList = result; return DOM_MEM_ERR; } } dom_element *elem = (dom_element *)calloc(sizeof(dom_element), 1); elem->node = candidate; elem->ref = 1; nodeList[nodeCount++] = elem; } if (nodeCount) { result = calloc(sizeof(dom_nodelist), 1); result->nodes = nodeList; result->count = nodeCount; result->ref = 1; } *outNodeList = result; return DOM_NO_ERR; }
/** * Callback to retrieve the preceding sibling of a node. * * \param pw HTML document * \param node DOM node * \param sibling Pointer to location to receive sibling * \return CSS_OK. * * \post \a sibling will contain the result, or NULL if there is no match */ css_error sibling_node(void *pw, void *node, void **sibling) { dom_node *n = node; dom_node *prev; dom_exception err; *sibling = NULL; /* Find sibling element */ err = dom_node_get_previous_sibling(n, &n); if (err != DOM_NO_ERR) return CSS_OK; while (n != NULL) { dom_node_type type; err = dom_node_get_node_type(n, &type); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_OK; } if (type == DOM_ELEMENT_NODE) break; err = dom_node_get_previous_sibling(n, &prev); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_OK; } dom_node_unref(n); n = prev; } if (n != NULL) { /** \todo Sort out reference counting */ dom_node_unref(n); *sibling = n; } return CSS_OK; }
static hubbub_error reparent_children(void *parser, void *node, void *new_parent) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; struct dom_node *child, *result; while(true) { err = dom_node_get_first_child((struct dom_node *) node, &child); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_note_get_first_child"); return HUBBUB_UNKNOWN; } if (child == NULL) break; err = dom_node_remove_child(node, (struct dom_node *) child, &result); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_remove_child"); goto fail; } dom_node_unref(result); err = dom_node_append_child((struct dom_node *) new_parent, (struct dom_node *) child, &result); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_append_child"); goto fail; } dom_node_unref(result); dom_node_unref(child); } return HUBBUB_OK; fail: dom_node_unref(child); return HUBBUB_UNKNOWN; }
static hubbub_error unref_node(void *parser, void *node) { struct dom_node *dnode = (struct dom_node *) node; UNUSED(parser); dom_node_unref(dnode); return HUBBUB_OK; }
/** * Extract an imagemap from html source * * \param node XML node containing map * \param c Content containing document * \param entry List of map entries * \param tname The sub-tags to consider on this pass * \return false on memory exhaustion, true otherwise */ static bool imagemap_extract_map_entries(dom_node *node, html_content *c, struct mapentry **entry, dom_string *tname) { dom_nodelist *nlist; dom_exception exc; unsigned long ent; uint32_t tag_count; exc = dom_element_get_elements_by_tag_name(node, tname, &nlist); if (exc != DOM_NO_ERR) { return false; } exc = dom_nodelist_get_length(nlist, &tag_count); if (exc != DOM_NO_ERR) { dom_nodelist_unref(nlist); return false; } for (ent = 0; ent < tag_count; ++ent) { dom_node *subnode; exc = dom_nodelist_item(nlist, ent, &subnode); if (exc != DOM_NO_ERR) { dom_nodelist_unref(nlist); return false; } if (imagemap_addtolist(c, subnode, c->base_url, entry, tname) == false) { dom_node_unref(subnode); dom_nodelist_unref(nlist); return false; } dom_node_unref(subnode); } dom_nodelist_unref(nlist); return true; }
/** * Destroy a Hubbub parser instance * * \param parser The Hubbub parser object */ void dom_hubbub_parser_destroy(dom_hubbub_parser *parser) { hubbub_parser_destroy(parser->parser); parser->parser = NULL; if (parser->doc != NULL) { dom_node_unref((struct dom_node *) parser->doc); parser->doc = NULL; } free(parser); }
static hubbub_error get_parent(void *parser, void *node, bool element_only, void **result) { dom_hubbub_parser *dom_parser = (dom_hubbub_parser *) parser; dom_exception err; struct dom_node *parent; dom_node_type type = DOM_NODE_TYPE_COUNT; err = dom_node_get_parent_node((struct dom_node *) node, &parent); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_get_parent"); return HUBBUB_UNKNOWN; } if (element_only == false) { *result = parent; return HUBBUB_OK; } err = dom_node_get_node_type(parent, &type); if (err != DOM_NO_ERR) { dom_parser->msg(DOM_MSG_CRITICAL, dom_parser->mctx, "Error in dom_node_get_type"); goto fail; } if (type == DOM_ELEMENT_NODE) { *result = parent; return HUBBUB_OK; } else { *result = NULL; dom_node_unref(parent); return HUBBUB_OK; } return HUBBUB_OK; fail: dom_node_unref(parent); return HUBBUB_UNKNOWN; }
/** * Callback to determine if a node is empty. * * \param pw HTML document * \param node DOM node * \param match Pointer to location to receive result * \return CSS_OK. * * \post \a match will contain true if the node is empty and false otherwise. */ css_error node_is_empty(void *pw, void *node, bool *match) { dom_node *n = node, *next; dom_exception err; *match = true; err = dom_node_get_first_child(n, &n); if (err != DOM_NO_ERR) { return CSS_BADPARM; } while (n != NULL) { dom_node_type ntype; err = dom_node_get_node_type(n, &ntype); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_BADPARM; } if (ntype == DOM_ELEMENT_NODE || ntype == DOM_TEXT_NODE) { *match = false; dom_node_unref(n); break; } err = dom_node_get_next_sibling(n, &next); if (err != DOM_NO_ERR) { dom_node_unref(n); return CSS_BADPARM; } dom_node_unref(n); n = next; } return CSS_OK; }
void dom_nodelist_unref(dom_nodelist *nodeList) { assert(nodeList); nodeList->ref--; if (0 == nodeList->ref) { int count = nodeList->count; for (int i = 0; i < count; ++i) { dom_node_unref(nodeList->nodes[i]); } if (0 < count) { free(nodeList->nodes); } free(nodeList); } }
void list_destroy(struct list* list) { struct list_elt* elt = list->head; while (elt != NULL) { if (list->type == DOM_STRING) dom_string_unref((dom_string *) elt->data); if (list->type == NODE) dom_node_unref(elt->data); struct list_elt* nextElt = elt->next; free(elt); elt = nextElt; } free(list); }
static struct form_control * parse_select_element(struct form *forms, dom_html_select_element *select) { struct form_control *control = NULL; dom_html_form_element *form = NULL; dom_string *ds_name = NULL; char *name = NULL; if (dom_html_select_element_get_form(select, &form) != DOM_NO_ERR) goto out; if (dom_html_select_element_get_name(select, &ds_name) != DOM_NO_ERR) goto out; if (ds_name != NULL) name = strndup(dom_string_data(ds_name), dom_string_byte_length(ds_name)); control = form_new_control(select, GADGET_SELECT); if (control == NULL) goto out; if (name != NULL) { /* Hand the name string over */ control->name = name; name = NULL; } dom_html_select_element_get_multiple(select, &(control->data.select.multiple)); if (form != NULL && control != NULL) form_add_control(find_form(forms, form), control); out: if (form != NULL) dom_node_unref(form); if (ds_name != NULL) dom_string_unref(ds_name); if (name != NULL) free(name); return control; }
/* documented in html_internal.h */ struct form *html_forms_get_forms(const char *docenc, dom_html_document *doc) { dom_html_collection *forms; struct form *ret = NULL, *newf; dom_node *node; unsigned long n; uint32_t nforms; if (doc == NULL) return NULL; /* Attempt to build a set of all the forms */ if (dom_html_document_get_forms(doc, &forms) != DOM_NO_ERR) return NULL; /* Count the number of forms so we can iterate */ if (dom_html_collection_get_length(forms, &nforms) != DOM_NO_ERR) goto out; /* Iterate the forms collection, making form structs for returning */ for (n = 0; n < nforms; ++n) { if (dom_html_collection_item(forms, n, &node) != DOM_NO_ERR) { goto out; } newf = parse_form_element(docenc, node); dom_node_unref(node); if (newf == NULL) { goto err; } newf->prev = ret; ret = newf; } /* All went well */ goto out; err: while (ret != NULL) { struct form *prev = ret->prev; /* Destroy ret */ free(ret); ret = prev; } out: /* Finished with the collection, return it */ dom_html_collection_unref(forms); return ret; }
svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, const char *buffer, size_t size, const char *url, int viewport_width, int viewport_height) { svgtiny_code code; dom_document *document; code = svgtiny_parse_dom(buffer, size, url, &document); if (code != svgtiny_OK) { return code; } code = svgtiny_parse_svg_from_dom(diagram, document, viewport_width, viewport_height); dom_node_unref(document); return code; }
static struct form_control * parse_textarea_element(struct form *forms, dom_html_text_area_element *ta) { struct form_control *control = NULL; dom_html_form_element *form = NULL; dom_string *ds_name = NULL; char *name = NULL; if (dom_html_text_area_element_get_form(ta, &form) != DOM_NO_ERR) goto out; if (dom_html_text_area_element_get_name(ta, &ds_name) != DOM_NO_ERR) goto out; if (ds_name != NULL) name = strndup(dom_string_data(ds_name), dom_string_byte_length(ds_name)); control = form_new_control(ta, GADGET_TEXTAREA); if (control == NULL) goto out; if (name != NULL) { /* Hand the name string over */ control->name = name; name = NULL; } if (form != NULL && control != NULL) form_add_control(find_form(forms, form), control); out: if (form != NULL) dom_node_unref(form); if (ds_name != NULL) dom_string_unref(ds_name); if (name != NULL) free(name); return control; }
/* exported interface documented in render/html_internal.h */ nserror html_css_free_stylesheets(html_content *html) { unsigned int i; guit->misc->schedule(-1, html_css_process_modified_styles, html); for (i = 0; i != html->stylesheet_count; i++) { if (html->stylesheets[i].sheet != NULL) { hlcache_handle_release(html->stylesheets[i].sheet); } if (html->stylesheets[i].node != NULL) { dom_node_unref(html->stylesheets[i].node); } } free(html->stylesheets); return NSERROR_OK; }
static struct form_control * parse_button_element(struct form *forms, dom_html_button_element *button) { struct form_control *control = NULL; dom_exception err; dom_html_form_element *form = NULL; dom_string *ds_type = NULL; dom_string *ds_value = NULL; dom_string *ds_name = NULL; err = dom_html_button_element_get_form(button, &form); if (err != DOM_NO_ERR) goto out; err = dom_html_button_element_get_type(button, &ds_type); if (err != DOM_NO_ERR) goto out; if (ds_type == NULL) { control = form_new_control(button, GADGET_SUBMIT); } else { if (dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_submit)) { control = form_new_control(button, GADGET_SUBMIT); } else if (dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_reset)) { control = form_new_control(button, GADGET_RESET); } else { control = form_new_control(button, GADGET_BUTTON); } } if (control == NULL) goto out; err = dom_html_button_element_get_value(button, &ds_value); if (err != DOM_NO_ERR) goto out; err = dom_html_button_element_get_name(button, &ds_name); if (err != DOM_NO_ERR) goto out; if (ds_value != NULL) { control->value = strndup( dom_string_data(ds_value), dom_string_byte_length(ds_value)); if (control->value == NULL) { form_free_control(control); control = NULL; goto out; } } if (ds_name != NULL) { control->name = strndup( dom_string_data(ds_name), dom_string_byte_length(ds_name)); if (control->name == NULL) { form_free_control(control); control = NULL; goto out; } } if (form != NULL && control != NULL) form_add_control(find_form(forms, form), control); out: if (form != NULL) dom_node_unref(form); if (ds_type != NULL) dom_string_unref(ds_type); if (ds_value != NULL) dom_string_unref(ds_value); if (ds_name != NULL) dom_string_unref(ds_name); return control; }
static bool save_complete_libdom_treewalk(dom_node *root, bool (*callback)(dom_node *node, save_complete_event_type event_type, void *ctx), void *ctx) { dom_node *node; node = dom_node_ref(root); /* tree root */ while (node != NULL) { dom_node *next = NULL; dom_exception exc; exc = dom_node_get_first_child(node, &next); if (exc != DOM_NO_ERR) { dom_node_unref(node); break; } if (next != NULL) { /* 1. children */ dom_node_unref(node); node = next; } else { exc = dom_node_get_next_sibling(node, &next); if (exc != DOM_NO_ERR) { dom_node_unref(node); break; } if (next != NULL) { /* 2. siblings */ if (callback(node, EVENT_LEAVE, ctx) == false) { return false; } dom_node_unref(node); node = next; } else { /* 3. ancestor siblings */ while (node != NULL) { exc = dom_node_get_next_sibling(node, &next); if (exc != DOM_NO_ERR) { dom_node_unref(node); node = NULL; break; } if (next != NULL) { dom_node_unref(next); break; } exc = dom_node_get_parent_node(node, &next); if (exc != DOM_NO_ERR) { dom_node_unref(node); node = NULL; break; } if (callback(node, EVENT_LEAVE, ctx) == false) { return false; } dom_node_unref(node); node = next; } if (node == NULL) break; exc = dom_node_get_next_sibling(node, &next); if (exc != DOM_NO_ERR) { dom_node_unref(node); break; } if (callback(node, EVENT_LEAVE, ctx) == false) { return false; } dom_node_unref(node); node = next; } } assert(node != NULL); if (callback(node, EVENT_ENTER, ctx) == false) { return false; /* callback caused early termination */ } } return true; }
svgtiny_code svgtiny_parse_svg(dom_element *svg, struct svgtiny_parse_state state) { float x, y, width, height; dom_string *view_box; dom_element *child; dom_exception exc; svgtiny_setup_state_local(&state); svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); svgtiny_parse_paint_attributes(svg, &state); svgtiny_parse_font_attributes(svg, &state); exc = dom_element_get_attribute(svg, state.interned_viewBox, &view_box); if (exc != DOM_NO_ERR) { svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } if (view_box) { char *s = strndup(dom_string_data(view_box), dom_string_byte_length(view_box)); float min_x, min_y, vwidth, vheight; if (sscanf(s, "%f,%f,%f,%f", &min_x, &min_y, &vwidth, &vheight) == 4 || sscanf(s, "%f %f %f %f", &min_x, &min_y, &vwidth, &vheight) == 4) { state.ctm.a = (float) state.viewport_width / vwidth; state.ctm.d = (float) state.viewport_height / vheight; state.ctm.e += -min_x * state.ctm.a; state.ctm.f += -min_y * state.ctm.d; } free(s); dom_string_unref(view_box); } svgtiny_parse_transform_attributes(svg, &state); exc = dom_node_get_first_child(svg, (dom_node **) (void *) &child); if (exc != DOM_NO_ERR) { svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } while (child != NULL) { dom_element *next; dom_node_type nodetype; svgtiny_code code = svgtiny_OK; exc = dom_node_get_node_type(child, &nodetype); if (exc != DOM_NO_ERR) { dom_node_unref(child); return svgtiny_LIBDOM_ERROR; } if (nodetype == DOM_ELEMENT_NODE) { dom_string *nodename; exc = dom_node_get_node_name(child, &nodename); if (exc != DOM_NO_ERR) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } if (dom_string_caseless_isequal(state.interned_svg, nodename)) code = svgtiny_parse_svg(child, state); else if (dom_string_caseless_isequal(state.interned_g, nodename)) code = svgtiny_parse_svg(child, state); else if (dom_string_caseless_isequal(state.interned_a, nodename)) code = svgtiny_parse_svg(child, state); else if (dom_string_caseless_isequal(state.interned_path, nodename)) code = svgtiny_parse_path(child, state); else if (dom_string_caseless_isequal(state.interned_rect, nodename)) code = svgtiny_parse_rect(child, state); else if (dom_string_caseless_isequal(state.interned_circle, nodename)) code = svgtiny_parse_circle(child, state); else if (dom_string_caseless_isequal(state.interned_ellipse, nodename)) code = svgtiny_parse_ellipse(child, state); else if (dom_string_caseless_isequal(state.interned_line, nodename)) code = svgtiny_parse_line(child, state); else if (dom_string_caseless_isequal(state.interned_polyline, nodename)) code = svgtiny_parse_poly(child, state, false); else if (dom_string_caseless_isequal(state.interned_polygon, nodename)) code = svgtiny_parse_poly(child, state, true); else if (dom_string_caseless_isequal(state.interned_text, nodename)) code = svgtiny_parse_text(child, state); dom_string_unref(nodename); } if (code != svgtiny_OK) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return code; } exc = dom_node_get_next_sibling(child, (dom_node **) (void *) &next); dom_node_unref(child); if (exc != DOM_NO_ERR) { svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } child = next; } svgtiny_cleanup_state_local(&state); return svgtiny_OK; }
void svgtiny_free_dom(dom_document *dom) { dom_node_unref(dom); }
svgtiny_code svgtiny_parse_svg_from_dom(struct svgtiny_diagram *diagram, dom_document *document, int viewport_width, int viewport_height) { dom_element *svg; dom_exception exc; svgtiny_code code; exc = dom_document_get_document_element(document, &svg); if (exc != DOM_NO_ERR) { dom_node_unref(document); return svgtiny_LIBDOM_ERROR; } struct svgtiny_parse_state state; float x, y, width, height; assert(diagram); state.gradient_x1 = NULL; state.gradient_y1 = NULL; state.gradient_x2 = NULL; state.gradient_y2 = NULL; /* get graphic dimensions */ memset(&state, 0, sizeof(state)); state.diagram = diagram; state.document = document; state.viewport_width = viewport_width; state.viewport_height = viewport_height; #define SVGTINY_STRING_ACTION2(s,n) \ if (dom_string_create_interned((const uint8_t *) #n, \ strlen(#n), &state.interned_##s) \ != DOM_NO_ERR) { \ code = svgtiny_LIBDOM_ERROR; \ goto cleanup; \ } #include "svgtiny_strings.h" #undef SVGTINY_STRING_ACTION2 svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); diagram->width = width; diagram->height = height; /* set up parsing state */ state.viewport_width = width; state.viewport_height = height; state.ctm.a = 1; /*(float) viewport_width / (float) width;*/ state.ctm.b = 0; state.ctm.c = 0; state.ctm.d = 1; /*(float) viewport_height / (float) height;*/ state.ctm.e = 0; /*x;*/ state.ctm.f = 0; /*y;*/ /*state.style = css_base_style; state.style.font_size.value.length.value = option_font_size * 0.1;*/ state.fill = 0x000000; state.stroke = svgtiny_TRANSPARENT; state.stroke_width = 1; state.linear_gradient_stop_count = 0; /* parse tree */ code = svgtiny_parse_svg(svg, state); dom_node_unref(svg); cleanup: svgtiny_cleanup_state_local(&state); #define SVGTINY_STRING_ACTION2(s,n) \ if (state.interned_##s != NULL) \ dom_string_unref(state.interned_##s); #include "svgtiny_strings.h" #undef SVGTINY_STRING_ACTION2 return code; }
svgtiny_code svgtiny_parse_dom(const char *buffer, size_t size, const char *url, dom_document **output_dom) { dom_document *document; dom_exception exc; dom_xml_parser *parser; dom_xml_error err; dom_element *svg; dom_string *svg_name; lwc_string *svg_name_lwc; assert(buffer); assert(url); UNUSED(url); parser = dom_xml_parser_create(NULL, NULL, ignore_msg, NULL, &document); if (parser == NULL) return svgtiny_LIBDOM_ERROR; err = dom_xml_parser_parse_chunk(parser, (uint8_t *)buffer, size); if (err != DOM_XML_OK) { dom_node_unref(document); dom_xml_parser_destroy(parser); return svgtiny_LIBDOM_ERROR; } err = dom_xml_parser_completed(parser); if (err != DOM_XML_OK) { dom_node_unref(document); dom_xml_parser_destroy(parser); return svgtiny_LIBDOM_ERROR; } /* We're done parsing, drop the parser. * We now own the document entirely. */ dom_xml_parser_destroy(parser); /* find root <svg> element */ exc = dom_document_get_document_element(document, &svg); if (exc != DOM_NO_ERR) { dom_node_unref(document); return svgtiny_LIBDOM_ERROR; } exc = dom_node_get_node_name(svg, &svg_name); if (exc != DOM_NO_ERR) { dom_node_unref(svg); dom_node_unref(document); return svgtiny_LIBDOM_ERROR; } if (lwc_intern_string("svg", 3 /* SLEN("svg") */, &svg_name_lwc) != lwc_error_ok) { dom_string_unref(svg_name); dom_node_unref(svg); dom_node_unref(document); return svgtiny_LIBDOM_ERROR; } if (!dom_string_caseless_lwc_isequal(svg_name, svg_name_lwc)) { lwc_string_unref(svg_name_lwc); dom_string_unref(svg_name); dom_node_unref(svg); dom_node_unref(document); return svgtiny_NOT_SVG; } dom_node_unref(svg); lwc_string_unref(svg_name_lwc); dom_string_unref(svg_name); *output_dom = document; return svgtiny_OK; }
svgtiny_code svgtiny_parse_text(dom_element *text, struct svgtiny_parse_state state) { float x, y, width, height; float px, py; dom_node *child; dom_exception exc; svgtiny_setup_state_local(&state); svgtiny_parse_position_attributes(text, state, &x, &y, &width, &height); svgtiny_parse_font_attributes(text, &state); svgtiny_parse_transform_attributes(text, &state); px = state.ctm.a * x + state.ctm.c * y + state.ctm.e; py = state.ctm.b * x + state.ctm.d * y + state.ctm.f; /* state.ctm.e = px - state.origin_x; */ /* state.ctm.f = py - state.origin_y; */ /*struct css_style style = state.style; style.font_size.value.length.value *= state.ctm.a;*/ exc = dom_node_get_first_child(text, &child); if (exc != DOM_NO_ERR) { return svgtiny_LIBDOM_ERROR; svgtiny_cleanup_state_local(&state); } while (child != NULL) { dom_node *next; dom_node_type nodetype; svgtiny_code code = svgtiny_OK; exc = dom_node_get_node_type(child, &nodetype); if (exc != DOM_NO_ERR) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } if (nodetype == DOM_ELEMENT_NODE) { dom_string *nodename; exc = dom_node_get_node_name(child, &nodename); if (exc != DOM_NO_ERR) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } if (dom_string_caseless_isequal(nodename, state.interned_tspan)) code = svgtiny_parse_text((dom_element *)child, state); dom_string_unref(nodename); } else if (nodetype == DOM_TEXT_NODE) { struct svgtiny_shape *shape = svgtiny_add_shape(&state); dom_string *content; if (shape == NULL) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return svgtiny_OUT_OF_MEMORY; } exc = dom_text_get_whole_text(child, &content); if (exc != DOM_NO_ERR) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } if (content != NULL) { shape->text = strndup(dom_string_data(content), dom_string_byte_length(content)); dom_string_unref(content); } else { shape->text = strdup(""); } shape->text_x = px; shape->text_y = py; state.diagram->shape_count++; } if (code != svgtiny_OK) { dom_node_unref(child); svgtiny_cleanup_state_local(&state); return code; } exc = dom_node_get_next_sibling(child, &next); dom_node_unref(child); if (exc != DOM_NO_ERR) { svgtiny_cleanup_state_local(&state); return svgtiny_LIBDOM_ERROR; } child = next; } svgtiny_cleanup_state_local(&state); return svgtiny_OK; }
static struct form_control * parse_input_element(struct form *forms, dom_html_input_element *input) { struct form_control *control = NULL; dom_html_form_element *form = NULL; dom_string *ds_type = NULL; dom_string *ds_name = NULL; dom_string *ds_value = NULL; char *name = NULL; if (dom_html_input_element_get_form(input, &form) != DOM_NO_ERR) goto out; if (dom_html_input_element_get_type(input, &ds_type) != DOM_NO_ERR) goto out; if (dom_html_input_element_get_name(input, &ds_name) != DOM_NO_ERR) goto out; if (ds_name != NULL) name = strndup(dom_string_data(ds_name), dom_string_byte_length(ds_name)); if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_password)) { control = form_new_control(input, GADGET_PASSWORD); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_file)) { control = form_new_control(input, GADGET_FILE); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_hidden)) { control = form_new_control(input, GADGET_HIDDEN); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_checkbox)) { control = form_new_control(input, GADGET_CHECKBOX); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_radio)) { control = form_new_control(input, GADGET_RADIO); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_submit)) { control = form_new_control(input, GADGET_SUBMIT); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_reset)) { control = form_new_control(input, GADGET_RESET); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_button)) { control = form_new_control(input, GADGET_BUTTON); } else if (ds_type != NULL && dom_string_caseless_lwc_isequal(ds_type, corestring_lwc_image)) { control = form_new_control(input, GADGET_IMAGE); } else { control = form_new_control(input, GADGET_TEXTBOX); } if (control == NULL) goto out; if (name != NULL) { /* Hand the name string over */ control->name = name; name = NULL; } if (control->type == GADGET_CHECKBOX || control->type == GADGET_RADIO) { bool selected; if (dom_html_input_element_get_checked( input, &selected) == DOM_NO_ERR) { control->selected = selected; } } if (control->type == GADGET_PASSWORD || control->type == GADGET_TEXTBOX) { int32_t maxlength; if (dom_html_input_element_get_max_length( input, &maxlength) != DOM_NO_ERR) { maxlength = -1; } if (maxlength >= 0) { /* Got valid maxlength */ control->maxlength = maxlength; } else { /* Input has no maxlength attr, or * dom_html_input_element_get_max_length failed. * * Set it to something insane. */ control->maxlength = UINT_MAX; } } if (control->type != GADGET_FILE && control->type != GADGET_IMAGE) { if (dom_html_input_element_get_value( input, &ds_value) == DOM_NO_ERR) { if (ds_value != NULL) { control->value = strndup( dom_string_data(ds_value), dom_string_byte_length(ds_value)); if (control->value == NULL) { form_free_control(control); control = NULL; goto out; } control->length = strlen(control->value); } } if (control->type == GADGET_TEXTBOX || control->type == GADGET_PASSWORD) { if (control->value == NULL) { control->value = strdup(""); if (control->value == NULL) { form_free_control(control); control = NULL; goto out; } control->length = 0; } control->initial_value = strdup(control->value); if (control->initial_value == NULL) { form_free_control(control); control = NULL; goto out; } } } if (form != NULL && control != NULL) form_add_control(find_form(forms, form), control); out: if (form != NULL) dom_node_unref(form); if (ds_type != NULL) dom_string_unref(ds_type); if (ds_name != NULL) dom_string_unref(ds_name); if (ds_value != NULL) dom_string_unref(ds_value); if (name != NULL) free(name); return control; }
void binding_destroy_document(dom_document *doc) { dom_node_unref(doc); }