static xps_resource * xps_parse_remote_resource_dictionary(xps_document *doc, char *base_uri, char *source_att) { char part_name[1024]; char part_uri[1024]; xps_resource *dict; xps_part *part; xml_element *xml; char *s; /* External resource dictionaries MUST NOT reference other resource dictionaries */ xps_resolve_url(part_name, base_uri, source_att, sizeof part_name); part = xps_read_part(doc, part_name); xml = xml_parse_document(doc->ctx, part->data, part->size); xps_free_part(doc, part); if (strcmp(xml_tag(xml), "ResourceDictionary")) { xml_free_element(doc->ctx, xml); fz_throw(doc->ctx, "expected ResourceDictionary element (found %s)", xml_tag(xml)); } fz_strlcpy(part_uri, part_name, sizeof part_uri); s = strrchr(part_uri, '/'); if (s) s[1] = 0; dict = xps_parse_resource_dictionary(doc, part_uri, xml); if (dict) dict->base_xml = xml; /* pass on ownership */ return dict; }
/** * Tries to parse a document containing multiple tags */ static void test_xml_parse_document_1() { SOURCE(source, "" "<Parent>\n" "\t<Child>\n" "\t\tFirst content\n" "\t</Child>\n" "\t<Child>\n" "\t\tSecond content\n" "\t</Child>\n" "</Parent>\n" ); struct xml_document* document = xml_parse_document(source, strlen(source)); assert_that(document, "Could not parse document"); struct xml_node* root = xml_document_root(document); // assert_that(string_equals(xml_node_name(root), "Parent"), "root node name must be `Parent'"); assert_that(2 == xml_node_children(root), "root must have two children"); struct xml_node* first_child = xml_node_child(root, 0); struct xml_node* second_child = xml_node_child(root, 1); assert_that(first_child && second_child, "Failed retrieving the children of root"); struct xml_node* third_child = xml_node_child(root, 2); assert_that(!third_child, "root has a third child where non should be"); // assert_that(string_equals(xml_node_name(first_child), "Child"), "first_child node name must be `Child'"); // assert_that(string_equals(xml_node_content(first_child), "First content"), "first_child node content must be `First content'"); // assert_that(string_equals(xml_node_name(second_child), "Child"), "second_child node name must be `Child'"); // assert_that(string_equals(xml_node_content(second_child), "Second content"), "second_child node content must be `tSecond content'"); xml_document_free(document, true); }
static fz_outline * xps_load_document_structure(xps_context *ctx, xps_document *fixdoc) { xps_part *part; xml_element *root; fz_outline *outline; part = xps_read_part(ctx, fixdoc->outline); if (!part) return NULL; root = xml_parse_document(ctx->ctx, part->data, part->size); if (!root) { fz_error_handle(ctx->ctx, -1, "cannot parse document structure part '%s'", part->name); xps_free_part(ctx, part); return NULL; } outline = xps_parse_document_structure(ctx, root); xml_free_element(ctx->ctx, root); xps_free_part(ctx, part); return outline; }
static int xps_load_fixed_page(xps_context *ctx, xps_page *page) { xps_part *part; xml_element *root; char *width_att; char *height_att; part = xps_read_part(ctx, page->name); if (!part) return fz_rethrow(-1, "cannot read zip part '%s'", page->name); root = xml_parse_document(part->data, part->size); if (!root) return fz_rethrow(-1, "cannot parse xml part '%s'", page->name); xps_free_part(ctx, part); if (strcmp(xml_tag(root), "FixedPage")) return fz_throw("expected FixedPage element (found %s)", xml_tag(root)); width_att = xml_att(root, "Width"); if (!width_att) return fz_throw("FixedPage missing required attribute: Width"); height_att = xml_att(root, "Height"); if (!height_att) return fz_throw("FixedPage missing required attribute: Height"); page->width = atoi(width_att); page->height = atoi(height_att); page->root = root; return 0; }
static int xps_parse_remote_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, char *source_att) { char part_name[1024]; char part_uri[1024]; xps_resource *dict; xps_part *part; xml_element *xml; char *s; int code; /* External resource dictionaries MUST NOT reference other resource dictionaries */ xps_absolute_path(part_name, base_uri, source_att, sizeof part_name); part = xps_read_part(ctx, part_name); if (!part) { return fz_throw("cannot find remote resource part '%s'", part_name); } xml = xml_parse_document(part->data, part->size); if (!xml) { xps_free_part(ctx, part); return fz_rethrow(-1, "cannot parse xml"); } if (strcmp(xml_tag(xml), "ResourceDictionary")) { xml_free_element(xml); xps_free_part(ctx, part); return fz_throw("expected ResourceDictionary element (found %s)", xml_tag(xml)); } fz_strlcpy(part_uri, part_name, sizeof part_uri); s = strrchr(part_uri, '/'); if (s) s[1] = 0; code = xps_parse_resource_dictionary(ctx, &dict, part_uri, xml); if (code) { xml_free_element(xml); xps_free_part(ctx, part); return fz_rethrow(code, "cannot parse remote resource dictionary: %s", part_uri); } dict->base_xml = xml; /* pass on ownership */ xps_free_part(ctx, part); *dictp = dict; return fz_okay; }
static int xps_open_and_parse(xps_context *ctx, char *path, xml_element **rootp) { xps_part *part = xps_read_part(ctx, path); if (!part) return fz_error_note(ctx->ctx, -1, "cannot read part '%s'", path); *rootp = xml_parse_document(ctx->ctx, part->data, part->size); xps_free_part(ctx, part); if (!*rootp) return fz_error_note(ctx->ctx, -1, "cannot parse part '%s'", path); return fz_okay; }
static int xps_open_and_parse(xps_context *ctx, char *path, xml_element **rootp) { xps_part *part = xps_read_part(ctx, path); if (!part) return fz_rethrow(-1, "cannot read zip part '%s'", path); *rootp = xml_parse_document(part->data, part->size); xps_free_part(ctx, part); if (!*rootp) return fz_rethrow(-1, "cannot parse metadata for part '%s'", path); return fz_okay; }
/** * Tries to parse a simple document containing only one tag */ static void test_xml_parse_document_0() { SOURCE(source, "<Hello>World</Hello>"); // uint8_t* source = malloc((1 + strlen("<Hello>World</Hello>")) * sizeof(uint8_t)); // { char const* content_string = "<Hello>World</Hello>"; // memcpy(source, content_string, strlen("<Hello>World</Hello>") + 1); // } struct xml_document* document = xml_parse_document(source, strlen(source)); assert_that(document, "Could not parse document"); struct xml_node* root = xml_document_root(document); // assert_that(string_equals(xml_node_name(root), "Hello"), "root node name must be `Hello'"); // assert_that(string_equals(xml_node_content(root), "World"), "root node content must be `World'"); xml_document_free(document, true); }
/** * Tests the eas functionality */ static void test_xml_parse_document_2() { SOURCE(source, "" "<Parent>\n" "\t<Child>\n" "\t\tFirst content\n" "\t</Child>\n" "\t<This><Is>\n" "<A><Test>Content A</Test></A>\n" "<B><Test>Content B</Test></B>\n" "\t</Is></This>\n" "\t<Child>\n" "\t\tSecond content\n" "\t</Child>\n" "</Parent>\n" ); struct xml_document* document = xml_parse_document(source, strlen(source)); assert_that(document, "Could not parse document"); struct xml_node* root = xml_document_root(document); // assert_that(string_equals(xml_node_name(root), "Parent"), "root node name must be `Parent'"); assert_that(3 == xml_node_children(root), "root must have two children"); struct xml_node* test_a = xml_easy_child(root, "This", "Is", "A", "Test", 0); assert_that(test_a, "Cannot find Parent/This/Is/A/Test"); // assert_that(string_equals(xml_node_content(test_a), "Content A"), "Content of Parent/This/Is/A/Test must be `Content A'"); struct xml_node* test_b = xml_easy_child(root, "This", "Is", "B", "Test", 0); assert_that(test_b, "Cannot find Parent/This/Is/B/Test"); // assert_that(string_equals(xml_node_content(test_b), "Content B"), "Content of Parent/This/Is/B/Test must be `Content B'"); struct xml_node* test_c = xml_easy_child(root, "This", "Is", "C", "Test", 0); assert_that(!test_c, "Must not find Parent/This/Is/C/Test because no such path exists"); struct xml_node* must_be_null = xml_easy_child(root, "Child"); assert_that(!must_be_null, "Parent/Child cannot be a valid expression, because there are two children named `Child' in `Parent'"); // uint8_t* name_is = xml_easy_name(xml_easy_child(root, "This", "Is", 0)); // assert_that(!strcmp(name_is, "Is"), "Name of Parent/This/Is must be `Is'"); // free(name_is); // uint8_t* content_a = xml_easy_content(test_a); // assert_that(!strcmp(content_a, "Content A"), "Content of Parent/This/Is/A/Test must be `Content A'"); // free(content_a); xml_document_free(document, true); }
static int xps_parse_metadata(xps_context *ctx, xps_part *part) { xml_element *root; char buf[1024]; char *s; /* Save directory name part */ fz_strlcpy(buf, part->name, sizeof buf); s = strrchr(buf, '/'); if (s) s[0] = 0; /* _rels parts are voodoo: their URI references are from * the part they are associated with, not the actual _rels * part being parsed. */ s = strstr(buf, "/_rels"); if (s) *s = 0; ctx->base_uri = buf; ctx->part_uri = part->name; root = xml_parse_document(part->data, part->size); if (!root) return fz_rethrow(-1, "cannot parse metadata part '%s'", part->name); xps_parse_metadata_imp(ctx, root); xml_free_element(root); ctx->base_uri = NULL; ctx->part_uri = NULL; return fz_okay; }