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 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; }
static int xps_find_doc_props_path(xps_context *ctx, char path[1024]) { xml_element *root; int code = xps_open_and_parse(ctx, "/_rels/.rels", &root); if (code != fz_okay) return code; *path = '\0'; if (!strcmp(xml_tag(root), "Relationships")) { xml_element *item; for (item = xml_down(root); item; item = xml_next(item)) { if (!strcmp(xml_tag(item), "Relationship") && xml_att(item, "Type") && !strcmp(xml_att(item, "Type"), REL_CORE_PROPERTIES) && xml_att(item, "Target")) { xps_absolute_path(path, "", xml_att(item, "Target"), 1024); } } } else code = fz_error_make(ctx->ctx, "couldn't parse part '/_rels/.rels'"); xml_free_element(ctx->ctx, root); return code; }
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_find_doc_props_path(xps_context *ctx, char path[1024]) { xml_element *root; int code = xps_open_and_parse(ctx, "/[Content_Types].xml", &root); if (code != fz_okay) return code; *path = '\0'; if (root && !strcmp(xml_tag(root), "Types")) { xml_element *item; for (item = xml_down(root); item; item = xml_next(item)) { if (!strcmp(xml_tag(item), "Override") && xml_att(item, "ContentType") && !strcmp(xml_att(item, "ContentType"), CONTENT_TYPE_CORE_PROPS) && xml_att(item, "PartName")) { fz_strlcpy(path, xml_att(item, "PartName"), 1024); } } } else code = fz_throw("couldn't parse part '[Content_Types].xml'"); xml_free_element(root); return code; }
void xps_free_page(xps_context *ctx, xps_page *page) { /* only free the XML contents */ if (page->root) xml_free_element(page->root); page->root = NULL; }
void xml_free_element(fz_context *ctx, struct element *item) { while (item) { struct element *next = item->next; if (item->atts) xml_free_attribute(ctx, item->atts); if (item->down) xml_free_element(ctx, item->down); fz_free(ctx, item); item = next; } }
void xps_free_resource_dictionary(xps_document *doc, xps_resource *dict) { xps_resource *next; while (dict) { next = dict->next; if (dict->base_xml) xml_free_element(doc->ctx, dict->base_xml); if (dict->base_uri) fz_free(doc->ctx, dict->base_uri); fz_free(doc->ctx, dict); dict = next; } }
static int xps_read_and_process_dest_names(xps_named_dest **destsp, xps_context *ctx, xps_document *doc) { char base_uri[1024]; xml_element *root; int code = xps_open_and_parse(ctx, doc->name, &root); if (code != fz_okay) return code; fz_strlcpy(base_uri, doc->name, sizeof(base_uri)); *(xps_get_part_base_name(base_uri) - 1) = '\0'; xps_parse_names_imp(destsp, ctx, doc, root, base_uri, 0); xml_free_element(root); return fz_okay; }
static int xps_parse_outline_structure(xps_outline **outlinep, xps_context *ctx, char *name) { char base_uri[1024]; xml_element *root; int code = xps_open_and_parse(ctx, name, &root); if (code != fz_okay) return code; fz_strlcpy(base_uri, name, sizeof(base_uri)); *(xps_get_part_base_name(base_uri) - 1) = '\0'; xps_parse_outline_imp(outlinep, root, base_uri); xml_free_element(root); return fz_okay; }
static int xps_read_and_process_document_outline(xps_outline **outlinep, xps_context *ctx, xps_document *doc) { char base_uri[1024]; xml_element *root; xml_element *item; int code = fz_okay; xps_rels_for_part(base_uri, doc->name, sizeof(base_uri)); code = xps_open_and_parse(ctx, base_uri, &root); if (code != fz_okay) return code; *strstr(base_uri, "/_rels/") = '\0'; for (item = root; item; item = xml_next(item)) { xml_element *relItem; if (strcmp(xml_tag(item), "Relationships") != 0) continue; for (relItem = xml_down(item); relItem; relItem = xml_next(relItem)) { char *target, *type; if (!strcmp(xml_tag(relItem), "Relationship") && (target = xml_att(relItem, "Target")) && (type = xml_att(relItem, "Type")) && !strcmp(type, REL_DOC_STRUCTURE)) { char tgtbuf[1024]; xps_absolute_path(tgtbuf, base_uri, target, sizeof(tgtbuf)); code = xps_parse_outline_structure(outlinep, ctx, tgtbuf); } } } xml_free_element(root); return code; }
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; }