/** * gsf_structured_blob_write: * @blob: #GsfStructuredBlob * @container: #GsfOutfile * * Dumps structured blob @blob onto the @container. Will fail if the output is * not an Outfile and blob has multiple streams. * * Returns: %TRUE on success. **/ gboolean gsf_structured_blob_write (GsfStructuredBlob *blob, GsfOutfile *container) { GsfOutput *output; gboolean has_kids; g_return_val_if_fail (GSF_IS_STRUCTURED_BLOB (blob), FALSE); g_return_val_if_fail (GSF_IS_OUTFILE (container), FALSE); has_kids = (blob->children != NULL && blob->children->len > 0); output = gsf_outfile_new_child (GSF_OUTFILE (container), gsf_input_name (GSF_INPUT (blob)), has_kids); if (has_kids) { GsfStructuredBlob *child_blob; unsigned i; for (i = 0 ; i < blob->children->len ; i++) { child_blob = g_ptr_array_index (blob->children, i); if (!gsf_structured_blob_write (child_blob, GSF_OUTFILE (output))) return FALSE; } } if (blob->data != NULL) gsf_output_write (output, blob->data->size, blob->data->buf); gsf_output_close (output); g_object_unref (output); return TRUE; }
static void clone (GsfInput *input, GsfOutput *output) { if (gsf_input_size (input) > 0) { guint8 const *data; size_t len; while ((len = gsf_input_remaining (input)) > 0) { /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); return; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); return; } } } else if (GSF_IS_INFILE(input)) clone_dir (GSF_INFILE(input), GSF_OUTFILE(output)); gsf_output_close (output); g_object_unref (G_OBJECT (output)); g_object_unref (G_OBJECT (input)); }
uint32_t FileWriterI::mkdir(string inpath) { // check if writer is ready if (baseOutfile == NULL) { ERROR << "ops::msole::FileWriterI::writeAllImpl() : file not opened"; return RET_ERR; } // split inpath vector<string> pathElements = ops::tools::split(inpath, '/'); // go into subdirs size_t currentPathIndex = 0; string partialInpath = "/"; GsfOutput * output = GSF_OUTPUT(baseOutfile); for (; currentPathIndex < pathElements.size() ; currentPathIndex++) { partialInpath += pathElements[currentPathIndex] + "/"; if (openDirList.find(partialInpath) != openDirList.end()) { output = openDirList[partialInpath]; } else { // create new child ans store it output = gsf_outfile_new_child(GSF_OUTFILE(output), pathElements[currentPathIndex].c_str(), true); openDirList[partialInpath] = output; } } DEBUG << "ops::msole::FileWriterI::writeAllImpl() : " + inpath + " created"; return RET_OK; }
static GsfOutput * gsf_outfile_open_pkg_new_child (GsfOutfile *parent, char const *name, gboolean is_dir, char const *first_property_name, va_list args) { GsfOutfileOpenPkg *child, *open_pkg = GSF_OUTFILE_OPEN_PKG (parent); GsfOutput *sink; if (!open_pkg->is_dir) return NULL; child = (GsfOutfileOpenPkg *)g_object_new_valist ( GSF_OUTFILE_OPEN_PKG_TYPE, first_property_name, args); gsf_output_set_name (GSF_OUTPUT (child), name); gsf_output_set_container (GSF_OUTPUT (child), parent); child->is_dir = is_dir; sink = gsf_outfile_new_child (GSF_OUTFILE (open_pkg->sink), name, is_dir); gsf_outfile_open_pkg_set_sink (child, sink); g_object_unref (sink); /* * Holding a ref here is not ideal. It means we won't release any of the * children until the package is closed. */ open_pkg->children = g_slist_prepend (open_pkg->children, g_object_ref (child)); return GSF_OUTPUT (child); }
static GsfOutput * gsf_outfile_open_pkg_new_child (GsfOutfile *parent, char const *name, gboolean is_dir, char const *first_property_name, va_list args) { GsfOutfileOpenPkg *child, *open_pkg = GSF_OUTFILE_OPEN_PKG (parent); GsfOutput *sink; if (!open_pkg->is_dir) return NULL; child = (GsfOutfileOpenPkg *)g_object_new_valist ( GSF_OUTFILE_OPEN_PKG_TYPE, first_property_name, args); gsf_output_set_name (GSF_OUTPUT (child), name); gsf_output_set_container (GSF_OUTPUT (child), parent); child->is_dir = is_dir; sink = gsf_outfile_new_child (GSF_OUTFILE (open_pkg->sink), name, is_dir); gsf_outfile_open_pkg_set_sink (child, sink); g_object_unref (sink); open_pkg->children = g_slist_prepend (open_pkg->children, child); g_object_ref (child); return GSF_OUTPUT (child); }
/* Add all the files in the folder under the working_dir to the gst_outfile. */ static void add_folder_to_gst_outfile (GsfOutfile *gst_outfile, gchar *working_dir, gchar *folder) { GsfOutfile *gst_dir = GSF_OUTFILE (gsf_outfile_new_child (gst_outfile, folder, TRUE)); gchar *path = g_build_filename (working_dir, folder, NULL); GDir *dir = g_dir_open (path, 0, NULL); if (dir) { const gchar *file = (const gchar *) NULL; while ( (file = g_dir_read_name (dir))) { add_file_to_gst_outfile (gst_dir, path, file); } g_dir_close (dir); } gsf_output_close ((GsfOutput *) gst_dir); g_object_unref (gst_dir); g_free (path); }
int32_t FileWriterI::fileOpen(std::string inpath) { int32_t handler = -1; // check if writer is ready if (baseOutfile == NULL) { ERROR << "ops::msole::FileWriterI::fileOpen() : file not opened"; return RET_ERR; } // split inpath vector<string> pathElements = ops::tools::split(inpath, '/'); // go into subdirs size_t currentPathIndex = 0; string partialInpath = "/"; GsfOutput * output = GSF_OUTPUT(baseOutfile); for (; currentPathIndex < pathElements.size() ; currentPathIndex++) { if (currentPathIndex < pathElements.size() - 1) { partialInpath += pathElements[currentPathIndex] + "/"; if (openDirList.find(partialInpath) != openDirList.end()) { output = openDirList[partialInpath]; } else { // create new child ans store it output = gsf_outfile_new_child(GSF_OUTFILE(output), pathElements[currentPathIndex].c_str(), true); openDirList[partialInpath] = output; } } else { // last path, so it's a plain file output = gsf_outfile_new_child(GSF_OUTFILE(output), pathElements[currentPathIndex].c_str(), false); // store file and return handler handler = openFileHandler.size(); openFileHandler.push_back(output); } } DEBUG << "ops::msole::FileWriterI::fileOpen() : " + inpath + " opened"; return handler; }
static void clone (GsfInput *input, GsfOutput *output) { guint8 const *data; size_t len; int i; if (gsf_input_size (input) > 0) { while ((len = gsf_input_remaining (input)) > 0) { /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); return; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); return; } } } /* See test-cp-msole.c for explanation how to distinct directories * from regular files. */ if (GSF_IS_INFILE (input) && gsf_infile_num_children (GSF_INFILE (input)) > 0) { GsfInfile *in = GSF_INFILE (input); GsfOutfile *out = GSF_OUTFILE (output); GsfInput *src; GsfOutput *dst; gboolean is_dir; for (i = 0 ; i < gsf_infile_num_children (in) ; i++) { src = gsf_infile_child_by_index (in, i); is_dir = GSF_IS_INFILE (src) && gsf_infile_num_children (GSF_INFILE (src)) >= 0; dst = gsf_outfile_new_child (out, gsf_infile_name_by_index (in, i), is_dir); clone (src, dst); } } gsf_output_close (output); g_object_unref (G_OBJECT (output)); g_object_unref (G_OBJECT (input)); }
/** * gsf_outfile_open_pkg_relate: * @child: #GsfOutfileOpenPkg * @parent: #GsfOutfileOpenPkg * @type: target type * * Create a relationship between @child and @parent of @type. * * Returns: (transfer none): the relID which the caller does not own * but will live as long as @parent. **/ char const * gsf_outfile_open_pkg_relate (GsfOutfileOpenPkg *child, GsfOutfileOpenPkg *parent, char const *type) { GString *path; int up = -1; GsfOutfile *child_dir, *parent_dir; /* Calculate the path from @child to @parent */ parent_dir = parent->is_dir ? GSF_OUTFILE (parent) : gsf_output_container (GSF_OUTPUT (parent)); do { up++; child_dir = GSF_OUTFILE (child); while (NULL != (child_dir = gsf_output_container (GSF_OUTPUT (child_dir)))) if (child_dir == parent_dir) goto found; /* break out of both loops */ } while (NULL != (parent_dir = gsf_output_container (GSF_OUTPUT (parent_dir)))); found: /* yes prepend is slow, this will never be preformance critical */ path = g_string_new (gsf_output_name (GSF_OUTPUT (child))); child_dir = GSF_OUTFILE (child); while (NULL != (child_dir = gsf_output_container (GSF_OUTPUT (child_dir))) && NULL != gsf_output_name (GSF_OUTPUT (child_dir)) && child_dir != parent_dir) { g_string_prepend_c (path, '/'); g_string_prepend (path, gsf_output_name (GSF_OUTPUT (child_dir))); } while (up--) g_string_prepend (path, "../"); return gsf_outfile_open_pkg_create_rel (parent, g_string_free (path, FALSE), type, FALSE); }
/** * Convert the RDF contained in pDoc->getDocumenrRDF() to RDF/XML and * store that in manifest.rdf updating the pDoc so that a manifest * entry is created in META_INF by the manifest writing code. */ bool ODe_RDFWriter::writeRDF( PD_Document* pDoc, GsfOutfile* pODT, PD_RDFModelHandle additionalRDF ) { #ifndef WITH_REDLAND UT_UNUSED(pDoc); UT_UNUSED(pODT); UT_UNUSED(additionalRDF); return true; #else UT_DEBUGMSG(("writeRDF() \n")); GsfOutput* oss = gsf_outfile_new_child(GSF_OUTFILE(pODT), "manifest.rdf", FALSE); // // Convert the native RDF model into a redland one // PD_DocumentRDFHandle rdf = pDoc->getDocumentRDF(); std::list< PD_RDFModelHandle > ml; ml.push_back( rdf ); ml.push_back( additionalRDF ); std::string rdfxml = toRDFXML( ml ); ODe_gsf_output_write (oss, rdfxml.size(), (const guint8*)rdfxml.data() ); ODe_gsf_output_close(oss); // // add an entry that the manifest writing code will pick up // { UT_ByteBufPtr pByteBuf(new UT_ByteBuf); std::string mime_type = "application/rdf+xml"; PD_DataItemHandle* ppHandle = NULL; if(!pDoc->createDataItem("manifest.rdf", 0, pByteBuf, mime_type, ppHandle)) { UT_DEBUGMSG(("writeRDF() setting up manifest entry failed!\n")); } // This is to test to new dnode manifest code. // pDoc->createDataItem( "some/many/directories/foo.xml", 0, &pByteBuf, // mime_type, ppHandle ); } UT_DEBUGMSG(("writeRDF() complete\n")); return true; #endif }
/** * Writes all pictures inside the Pictures subdirectory. */ bool ODe_PicturesWriter::writePictures(PD_Document* pDoc, GsfOutfile* pODT) { const char * szName; std::string mimeType; std::string extension; std::string fullName; const UT_ByteBuf * pByteBuf; GsfOutput* pImg; GsfOutput* pPicsDir = NULL; for (UT_uint32 k=0; (pDoc->enumDataItems(k, NULL, &szName, &pByteBuf, &mimeType)); k++) { // We must avoid saving RDF data as image if (!mimeType.empty() && (mimeType != "application/rdf+xml")) { if (pPicsDir == NULL) { // create Pictures directory pPicsDir = gsf_outfile_new_child(pODT, "Pictures", TRUE); } pDoc->getDataItemFileExtension(szName, extension, true); fullName = szName + extension; pImg = gsf_outfile_new_child(GSF_OUTFILE(pPicsDir), fullName.c_str(), FALSE); ODe_gsf_output_write(pImg, pByteBuf->getLength(), pByteBuf->getPointer(0)); ODe_gsf_output_close(pImg); } } if (pPicsDir != NULL) { ODe_gsf_output_close(pPicsDir); } return true; }
HRESULT STDMETHODCALLTYPE OMGSFIStorage::StgCreateStorageEx( const TCHAR FAR* in_filename, OMFile::OMAccessMode in_accessMode, void **out_storage, ULONG in_sectorSize) { TRACE("OMGSFIStorage::StgCreateStorageEx"); PRECONDITION("Valid access mode", in_accessMode == OMFile::writeOnlyMode); GsfStorage *storage = 0; *out_storage = 0; char storageName[FILENAME_MAX]; #ifndef OM_UNICODE_APIS strncpy (storageName, in_filename, sizeof(storageName) -1); storageName[sizeof(storageName) -1] = '\0'; #else convertWideStringToString (storageName, in_filename, FILENAME_MAX); #endif int status = GSTG_OK; GError *err; GsfOutput *output = GSF_OUTPUT (gsf_output_stdio_new (storageName, &err)); if (output != NULL) { storage = GSF_OUTFILE (gsf_outfile_msole_new_full ( output, in_sectorSize, // sector size - 512 or 4096 bytes 64)); // mini-sector size always 64 bytes g_object_unref (G_OBJECT (output)); } else status = GSTG_ERROR; if (status == GSTG_OK) { OMGSFIStorage *newStorage = new OMGSFIStorage (storage, GSF_WRITE, storageName); *out_storage = newStorage; } return makeStatus(status); }
UT_Error IE_Exp_EPUB::compress() { GsfInfile* oebpsDir = gsf_infile_stdio_new( UT_go_filename_from_uri(m_oebpsDir.c_str()), NULL); if (oebpsDir == NULL) { UT_DEBUGMSG(("RUDYJ: Can`t open temporary OEBPS directory\n")); return UT_ERROR; } std::vector<std::string> listing = getFileList( UT_go_filename_from_uri(m_oebpsDir.c_str())); for (std::vector<std::string>::iterator i = listing.begin(); i != listing.end(); i++) { GsfOutput* item = gsf_outfile_new_child(GSF_OUTFILE(m_oebps), (*i).c_str(), FALSE); std::string fullPath = m_oebpsDir + G_DIR_SEPARATOR_S + *i; GsfInput* file = UT_go_file_open(fullPath.c_str(), NULL); if (file == NULL) { UT_DEBUGMSG(("RUDYJ: Can`t open file\n")); return UT_ERROR; } gsf_output_seek(item, 0, G_SEEK_SET); gsf_input_seek(file, 0, G_SEEK_SET); gsf_input_copy(file, item); gsf_output_close(item); // Time to delete temporary file UT_go_file_remove(fullPath.c_str(), NULL); } UT_go_file_remove((m_oebpsDir + G_DIR_SEPARATOR_S + "index.xhtml_files").c_str(), NULL); UT_go_file_remove(m_oebpsDir.c_str(), NULL); return UT_OK; }
UT_Error IE_Exp_EPUB::writeContainer() { GsfOutput* metaInf = gsf_outfile_new_child(m_root, "META-INF", TRUE); if (metaInf == NULL) { UT_DEBUGMSG(("Can`t create META-INF dir\n")); return UT_ERROR; } GsfOutput* container = gsf_outfile_new_child(GSF_OUTFILE(metaInf), "container.xml", FALSE); if (container == NULL) { UT_DEBUGMSG(("Can`t create container.xml\n")); gsf_output_close(metaInf); return UT_ERROR; } GsfXMLOut * containerXml = gsf_xml_out_new(container); // <container> gsf_xml_out_start_element(containerXml, "container"); gsf_xml_out_add_cstr(containerXml, "version", "1.0"); gsf_xml_out_add_cstr(containerXml, "xmlns", OCF201_NAMESPACE); // <rootfiles> gsf_xml_out_start_element(containerXml, "rootfiles"); // <rootfile> gsf_xml_out_start_element(containerXml, "rootfile"); gsf_xml_out_add_cstr(containerXml, "full-path", "OEBPS/book.opf"); gsf_xml_out_add_cstr(containerXml, "media-type", OPF_MIMETYPE); // </rootfile> gsf_xml_out_end_element(containerXml); // </rootfiles> gsf_xml_out_end_element(containerXml); // </container> gsf_xml_out_end_element(containerXml); gsf_output_close(container); gsf_output_close(metaInf); return UT_OK; }
static gboolean gsf_outfile_open_pkg_close (GsfOutput *output) { GsfOutfileOpenPkg *open_pkg = GSF_OUTFILE_OPEN_PKG (output); GsfOutput *dir; gboolean res = FALSE; char *rels_name; if (NULL == open_pkg->sink || gsf_output_is_closed (open_pkg->sink)) return TRUE; /* Generate [Content_types].xml when we close the root dir */ if (NULL == gsf_output_name (output)) { GsfOutput *out = gsf_outfile_new_child (GSF_OUTFILE (open_pkg->sink), "[Content_Types].xml", FALSE); GsfXMLOut *xml = gsf_xml_out_new (out); gsf_xml_out_start_element (xml, "Types"); gsf_xml_out_add_cstr_unchecked (xml, "xmlns", "http://schemas.openxmlformats.org/package/2006/content-types"); gsf_open_pkg_write_content_default (xml, "rels", "application/vnd.openxmlformats-package.relationships+xml"); gsf_open_pkg_write_content_default (xml, "xlbin", "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"); gsf_open_pkg_write_content_default (xml, "xml", "application/xml"); gsf_open_pkg_write_content_override (open_pkg, "/", xml); gsf_xml_out_end_element (xml); /* </Types> */ g_object_unref (xml); gsf_output_close (out); g_object_unref (out); dir = open_pkg->sink; rels_name = g_strdup (".rels"); } else { res = gsf_output_close (open_pkg->sink); dir = (GsfOutput *)gsf_output_container (open_pkg->sink); rels_name = g_strconcat (gsf_output_name (output), ".rels", NULL); } if (NULL != open_pkg->relations) { GsfOutput *rels; GsfXMLOut *xml; GsfOpenPkgRel *rel; GSList *ptr; dir = gsf_outfile_new_child (GSF_OUTFILE (dir), "_rels", TRUE); rels = gsf_outfile_new_child (GSF_OUTFILE (dir), rels_name, FALSE); xml = gsf_xml_out_new (rels); gsf_xml_out_start_element (xml, "Relationships"); gsf_xml_out_add_cstr_unchecked (xml, "xmlns", "http://schemas.openxmlformats.org/package/2006/relationships"); for (ptr = open_pkg->relations ; ptr != NULL ; ptr = ptr->next) { rel = ptr->data; gsf_xml_out_start_element (xml, "Relationship"); gsf_xml_out_add_cstr (xml, "Id", rel->id); gsf_xml_out_add_cstr (xml, "Type", rel->type); gsf_xml_out_add_cstr (xml, "Target", rel->target); if (rel->is_extern) gsf_xml_out_add_cstr_unchecked (xml, "TargetMode", "External"); gsf_xml_out_end_element (xml); /* </Relationship> */ g_free (rel->id); g_free (rel->type); g_free (rel->target); g_free (rel); } g_slist_free (open_pkg->relations); gsf_xml_out_end_element (xml); /* </Relationships> */ g_object_unref (xml); gsf_output_close (rels); g_object_unref (rels); g_object_unref (dir); } g_free (rels_name); /* close the container */ if (NULL == gsf_output_name (output)) return gsf_output_close (open_pkg->sink); return res; }
/** * This writes out our AbiWord file as an OpenOffice * compound document */ UT_Error IE_Exp_OpenDocument::_writeDocument(void) { ODe_DocumentData docData(getDoc()); ODe_AuxiliaryData auxData; ODe_AbiDocListener* pAbiDocListener = NULL; ODe_AbiDocListenerImpl* pAbiDocListenerImpl = NULL; UT_return_val_if_fail (getFp(), UT_ERROR); PD_DocumentRDFHandle rdf = getDoc()->getDocumentRDF(); auxData.m_additionalRDF = rdf->createScratchModel(); const std::string & prop = getProperty ("uncompressed"); if (!prop.empty() && UT_parseBool (prop.c_str (), false)) { m_odt = GSF_OUTFILE(g_object_ref(G_OBJECT(getFp()))); } else { GError* error = NULL; m_odt = GSF_OUTFILE (gsf_outfile_zip_new (getFp(), &error)); if (error) { UT_DEBUGMSG(("Error writing odt file: %s\n", error->message)); UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } UT_return_val_if_fail(m_odt, UT_ERROR); // Needed to ensure that all *printf writes numbers correctly, // like "45.56mm" instead of "45,56mm". UT_LocaleTransactor numericLocale (LC_NUMERIC, "C"); { GsfOutput * mimetype = gsf_outfile_new_child_full (m_odt, "mimetype", FALSE, "compression-level", 0, (void*)0); if (!mimetype) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } ODe_gsf_output_write(mimetype, 39 /*39 == strlen("application/vnd.oasis.opendocument.text")*/, (const guint8 *)"application/vnd.oasis.opendocument.text"); ODe_gsf_output_close(mimetype); } if (!ODe_MetaDataWriter::writeMetaData(getDoc(), m_odt)) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } if (!ODe_SettingsWriter::writeSettings(getDoc(), m_odt)) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } if (!ODe_PicturesWriter::writePictures(getDoc(), m_odt)) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } if (!ODe_ManifestWriter::writeManifest(getDoc(), m_odt)) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } // Gather all paragraph style names used by heading paragraphs // (ie. all paragraph styles that are used to build up TOCs). pAbiDocListenerImpl = new ODe_HeadingSearcher_Listener(docData.m_styles, auxData); pAbiDocListener = new ODe_AbiDocListener(getDoc(), pAbiDocListenerImpl, false); if (!getDoc()->tellListener(static_cast<PL_Listener *>(pAbiDocListener))) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } pAbiDocListener->finished(); DELETEP(pAbiDocListener); DELETEP(pAbiDocListenerImpl); // Now that we have all paragraph styles that build up the TOCs in the // document (if any), we can build up the TOC bodies. We do this because // OpenOffice.org requires the TOC bodies to be present and filled // when initially opening the document. Without it, it will show // an empty TOC until the user regenerates it, which is not that pretty. // Annoyingly we have to build up the TOC ourselves during export, as // it doesn't exist within AbiWord's PieceTable. Until that changes, this // is the best we can do. if (auxData.m_pTOCContents) { pAbiDocListenerImpl = new ODe_TOC_Listener(auxData); pAbiDocListener = new ODe_AbiDocListener(getDoc(), pAbiDocListenerImpl, false); if (!getDoc()->tellListener(static_cast<PL_Listener *>(pAbiDocListener))) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } pAbiDocListener->finished(); DELETEP(pAbiDocListener); DELETEP(pAbiDocListenerImpl); } // Gather document content and styles if (!docData.doPreListeningWork()) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } pAbiDocListenerImpl = new ODe_Main_Listener(docData, auxData); pAbiDocListener = new ODe_AbiDocListener(getDoc(), pAbiDocListenerImpl, false); if (!getDoc()->tellListener(static_cast<PL_Listener *>(pAbiDocListener))) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } pAbiDocListener->finished(); DELETEP(pAbiDocListener); DELETEP(pAbiDocListenerImpl); if (!docData.doPostListeningWork()) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } // Write RDF. if (!ODe_RDFWriter::writeRDF(getDoc(), m_odt, auxData.m_additionalRDF )) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } // Write content and styles if (!docData.writeStylesXML(m_odt)) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } if (!docData.writeContentXML(m_odt)) { ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_ERROR; } ODe_gsf_output_close(GSF_OUTPUT(m_odt)); return UT_OK; }
UT_Error IE_Exp_EPUB::EPUB3_writeNavigation() { GsfOutput* nav = gsf_outfile_new_child(GSF_OUTFILE(m_oebps), "toc.xhtml", FALSE); if (nav == NULL) { UT_DEBUGMSG(("Can`t create toc.xhtml file\n")); return UT_ERROR; } GsfXMLOut* navXHTML = gsf_xml_out_new(nav); gsf_xml_out_start_element(navXHTML, "html"); gsf_xml_out_add_cstr(navXHTML, "xmlns", XHTML_NS); gsf_xml_out_add_cstr(navXHTML, "xmlns:epub", OPS201_NAMESPACE); gsf_xml_out_add_cstr(navXHTML, "profile", EPUB3_CONTENT_PROFILE); gsf_xml_out_start_element(navXHTML, "head"); gsf_xml_out_start_element(navXHTML, "title"); gsf_xml_out_add_cstr(navXHTML, NULL, "Table of Contents"); gsf_xml_out_end_element(navXHTML); gsf_xml_out_end_element(navXHTML); gsf_xml_out_start_element(navXHTML, "body"); gsf_xml_out_start_element(navXHTML, "section"); gsf_xml_out_add_cstr(navXHTML, "class", "frontmatter TableOfContents"); gsf_xml_out_start_element(navXHTML, "header"); gsf_xml_out_start_element(navXHTML, "h1"); gsf_xml_out_add_cstr(navXHTML, NULL, "Contents"); gsf_xml_out_end_element(navXHTML); gsf_xml_out_end_element(navXHTML); gsf_xml_out_start_element(navXHTML, "nav"); gsf_xml_out_add_cstr(navXHTML, "epub:type", "toc"); gsf_xml_out_add_cstr(navXHTML, "id", "toc"); if (m_pHmtlExporter->getNavigationHelper()->hasTOC()) { int lastItemLevel; int curItemLevel = 0; std::vector<int> tagLevels; int tocNum = 0; bool newList = true; for (int currentItem = 0; currentItem < m_pHmtlExporter->getNavigationHelper()->getNumTOCEntries(); currentItem++) { lastItemLevel = curItemLevel; UT_UTF8String itemStr = m_pHmtlExporter->getNavigationHelper() ->getNthTOCEntry(currentItem, &curItemLevel); PT_DocPosition itemPos; m_pHmtlExporter->getNavigationHelper()->getNthTOCEntryPos(currentItem, itemPos); std::string itemFilename; if (m_exp_opt.bSplitDocument) { itemFilename = m_pHmtlExporter->getNavigationHelper() ->getFilenameByPosition(itemPos).utf8_str(); if ((itemFilename == "") || itemFilename.length() == 0) { itemFilename = "index.xhtml"; } else { itemFilename += ".xhtml"; } } else { itemFilename = "index.xhtml"; } if (std::find(m_opsId.begin(), m_opsId.end(), escapeForId(itemFilename)) == m_opsId.end()) { m_opsId.push_back(escapeForId(itemFilename)); tocNum = 0; } UT_DEBUGMSG(("Item filename %s at pos %d\n", itemFilename.c_str(),itemPos)); if ((lastItemLevel >= curItemLevel) && (currentItem != 0)) { while ((tagLevels.size() > 0) && (tagLevels.back() >= curItemLevel)) { if (tagLevels.back() == curItemLevel) { gsf_xml_out_end_element(navXHTML); } else { closeNTags(navXHTML, 2); } tagLevels.pop_back(); } } else if ((lastItemLevel < curItemLevel) || newList) { gsf_xml_out_start_element(navXHTML, "ol"); newList = false; } std::string navClass = UT_std_string_sprintf("h%d", curItemLevel); std::string navId = UT_std_string_sprintf("AbiTOC%d", tocNum); std::string navSrc = std::string(itemFilename.c_str()) + "#" + navId; gsf_xml_out_start_element(navXHTML, "li"); gsf_xml_out_add_cstr(navXHTML, "class", navClass.c_str()); gsf_xml_out_add_cstr(navXHTML, "id", navId.c_str()); gsf_xml_out_start_element(navXHTML, "a"); gsf_xml_out_add_cstr(navXHTML, "href", navSrc.c_str()); gsf_xml_out_add_cstr(navXHTML, NULL, itemStr.utf8_str()); gsf_xml_out_end_element(navXHTML); // gsf_xml_out_end_element(navXHTML); tagLevels.push_back(curItemLevel); tocNum++; } closeNTags(navXHTML, tagLevels.size()*2); } else { gsf_xml_out_start_element(navXHTML, "ol"); gsf_xml_out_start_element(navXHTML, "li"); gsf_xml_out_add_cstr(navXHTML, "class", "h1"); gsf_xml_out_add_cstr(navXHTML, "id", "index"); gsf_xml_out_start_element(navXHTML, "a"); gsf_xml_out_add_cstr(navXHTML, "href", "index.xhtml"); gsf_xml_out_add_cstr(navXHTML, NULL, getTitle().c_str()); gsf_xml_out_end_element(navXHTML); gsf_xml_out_end_element(navXHTML); gsf_xml_out_end_element(navXHTML); } gsf_xml_out_end_element(navXHTML); // </section> gsf_xml_out_end_element(navXHTML); gsf_xml_out_end_element(navXHTML); gsf_xml_out_end_element(navXHTML); gsf_output_close(nav); return UT_OK; }
UT_Error IE_Exp_EPUB::EPUB2_writeNavigation() { GsfOutput* ncx = gsf_outfile_new_child(GSF_OUTFILE(m_oebps), "toc.ncx", FALSE); if (ncx == NULL) { UT_DEBUGMSG(("Can`t create toc.ncx file\n")); return UT_ERROR; } GsfXMLOut* ncxXml = gsf_xml_out_new(ncx); // <ncx> gsf_xml_out_start_element(ncxXml, "ncx"); gsf_xml_out_add_cstr(ncxXml, "xmlns", NCX_NAMESPACE); gsf_xml_out_add_cstr(ncxXml, "version", "2005-1"); gsf_xml_out_add_cstr(ncxXml, "xml:lang", NULL); // <head> gsf_xml_out_start_element(ncxXml, "head"); // <meta name="dtb:uid" content=... > gsf_xml_out_start_element(ncxXml, "meta"); gsf_xml_out_add_cstr(ncxXml, "name", "dtb:uid"); gsf_xml_out_add_cstr(ncxXml, "content", getDoc()->getDocUUIDString()); // </meta> gsf_xml_out_end_element(ncxXml); // <meta name="epub-creator" content=... > gsf_xml_out_start_element(ncxXml, "meta"); gsf_xml_out_add_cstr(ncxXml, "name", "epub-creator"); gsf_xml_out_add_cstr(ncxXml, "content", "AbiWord (http://www.abisource.com/)"); // </meta> gsf_xml_out_end_element(ncxXml); // <meta name="dtb:depth" content=... > gsf_xml_out_start_element(ncxXml, "meta"); gsf_xml_out_add_cstr(ncxXml, "name", "dtb:depth"); gsf_xml_out_add_cstr(ncxXml, "content", "1"); // </meta> gsf_xml_out_end_element(ncxXml); // <meta name="dtb:totalPageCount" content=... > gsf_xml_out_start_element(ncxXml, "meta"); gsf_xml_out_add_cstr(ncxXml, "name", "dtb:totalPageCount"); gsf_xml_out_add_cstr(ncxXml, "content", "0"); // </meta> gsf_xml_out_end_element(ncxXml); // <meta name="dtb:totalPageCount" content=... > gsf_xml_out_start_element(ncxXml, "meta"); gsf_xml_out_add_cstr(ncxXml, "name", "dtb:maxPageCount"); gsf_xml_out_add_cstr(ncxXml, "content", "0"); // </meta> gsf_xml_out_end_element(ncxXml); // </head> gsf_xml_out_end_element(ncxXml); // <docTitle> gsf_xml_out_start_element(ncxXml, "docTitle"); gsf_xml_out_start_element(ncxXml, "text"); gsf_xml_out_add_cstr(ncxXml, NULL, getTitle().c_str()); gsf_xml_out_end_element(ncxXml); // </docTitle> gsf_xml_out_end_element(ncxXml); // <docAuthor> gsf_xml_out_start_element(ncxXml, "docAuthor"); gsf_xml_out_start_element(ncxXml, "text"); gsf_xml_out_add_cstr(ncxXml, NULL, getAuthor().c_str()); gsf_xml_out_end_element(ncxXml); // </docAuthor> gsf_xml_out_end_element(ncxXml); // <navMap> gsf_xml_out_start_element(ncxXml, "navMap"); if (m_pHmtlExporter->getNavigationHelper()->hasTOC()) { int lastItemLevel; int curItemLevel = 0; std::vector<int> tagLevels; int tocNum = 0; for (int currentItem = 0; currentItem < m_pHmtlExporter->getNavigationHelper()->getNumTOCEntries(); currentItem++) { lastItemLevel = curItemLevel; std::string itemStr = m_pHmtlExporter->getNavigationHelper() ->getNthTOCEntry(currentItem, &curItemLevel).utf8_str(); PT_DocPosition itemPos; m_pHmtlExporter->getNavigationHelper()->getNthTOCEntryPos(currentItem, itemPos); std::string itemFilename; if (m_exp_opt.bSplitDocument) { itemFilename = m_pHmtlExporter->getNavigationHelper() ->getFilenameByPosition(itemPos).utf8_str(); if (itemFilename.length() == 0 || (itemFilename[0] == '.')) { itemFilename = "index.xhtml"; } else { itemFilename += + ".xhtml"; } } else { itemFilename = "index.xhtml"; } if (std::find(m_opsId.begin(), m_opsId.end(), escapeForId(itemFilename)) == m_opsId.end()) { m_opsId.push_back(escapeForId(itemFilename)); tocNum = 0; } UT_DEBUGMSG(("Item filename %s at pos %d\n", itemFilename.c_str(),itemPos)); if ((lastItemLevel >= curItemLevel) && (currentItem != 0)) { while ((tagLevels.size() > 0) && (tagLevels.back() >= curItemLevel)) { gsf_xml_out_end_element(ncxXml); tagLevels.pop_back(); } } std::string navClass = UT_std_string_sprintf("h%d", curItemLevel); std::string navId = UT_std_string_sprintf("AbiTOC%d", tocNum); std::string navSrc = std::string(itemFilename.c_str()) + "#" + navId; gsf_xml_out_start_element(ncxXml, "navPoint"); gsf_xml_out_add_cstr(ncxXml, "playOrder", UT_std_string_sprintf("%d", currentItem + 1).c_str()); gsf_xml_out_add_cstr(ncxXml, "class", navClass.c_str()); gsf_xml_out_add_cstr(ncxXml, "id", navId.c_str()); gsf_xml_out_start_element(ncxXml, "navLabel"); gsf_xml_out_start_element(ncxXml, "text"); gsf_xml_out_add_cstr(ncxXml, NULL, itemStr.c_str()); gsf_xml_out_end_element(ncxXml); gsf_xml_out_end_element(ncxXml); gsf_xml_out_start_element(ncxXml, "content"); gsf_xml_out_add_cstr(ncxXml, "src", navSrc.c_str()); gsf_xml_out_end_element(ncxXml); tagLevels.push_back(curItemLevel); tocNum++; } closeNTags(ncxXml, tagLevels.size()); } else { m_opsId.push_back(escapeForId("index.xhtml")); gsf_xml_out_start_element(ncxXml, "navPoint"); gsf_xml_out_add_cstr(ncxXml, "playOrder", "1"); gsf_xml_out_add_cstr(ncxXml, "class", "h1"); gsf_xml_out_add_cstr(ncxXml, "id", "index"); gsf_xml_out_start_element(ncxXml, "navLabel"); gsf_xml_out_start_element(ncxXml, "text"); gsf_xml_out_add_cstr(ncxXml, NULL, getTitle().c_str()); gsf_xml_out_end_element(ncxXml); gsf_xml_out_end_element(ncxXml); gsf_xml_out_start_element(ncxXml, "content"); gsf_xml_out_add_cstr(ncxXml, "src", "index.xhtml"); gsf_xml_out_end_element(ncxXml); gsf_xml_out_end_element(ncxXml); } // </navMap> gsf_xml_out_end_element(ncxXml); // </ncx> gsf_xml_out_end_element(ncxXml); gsf_output_close(ncx); return UT_OK; }
static void clone_ (GsfInfile *in, GsfOutfile *out) { GsfInput *input = GSF_INPUT (in); GsfOutput *output = GSF_OUTPUT (out); if (gsf_input_size (input) > 0) { size_t len; while ((len = gsf_input_remaining (input)) > 0) { guint8 const *data; /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); break; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); break; } } } else { int i, n = gsf_infile_num_children (in); for (i = 0 ; i < n; i++) { int level; gboolean is_dir; char const *name = gsf_infile_name_by_index (in, i); char *display_name = name ? g_filename_display_name (name) : NULL; input = gsf_infile_child_by_index (in, i); if (NULL == input) { g_print ("Error opening '%s, index = %d\n", display_name ? display_name : "?", i); g_free (display_name); continue; } is_dir = gsf_infile_num_children (GSF_INFILE (input)) >= 0; g_object_get (G_OBJECT (input), "compression-level", &level, NULL); g_print ("%s: size=%ld, level=%d, %s\n", display_name ? display_name : "?", (long)gsf_input_size (input), level, is_dir ? "directory" : "file"); g_free (display_name); output = gsf_outfile_new_child_full (out, name, is_dir, "compression-level", level, NULL); clone_ (GSF_INFILE (input), GSF_OUTFILE (output)); } } gsf_output_close (GSF_OUTPUT (out)); g_object_unref (G_OBJECT (out)); g_object_unref (G_OBJECT (in)); }
UT_Error IE_Exp_EPUB::package() { GsfOutput* opf = gsf_outfile_new_child(GSF_OUTFILE(m_oebps), "book.opf", FALSE); if (opf == NULL) { UT_DEBUGMSG(("Can`t create book.opf\n")); return UT_ERROR; } GsfXMLOut* opfXml = gsf_xml_out_new(opf); // <package> gsf_xml_out_start_element(opfXml, "package"); if (m_exp_opt.bEpub2) { gsf_xml_out_add_cstr(opfXml, "version", "2.0"); } else { gsf_xml_out_add_cstr(opfXml, "version", "3.0"); } gsf_xml_out_add_cstr(opfXml, "xmlns", OPF201_NAMESPACE); gsf_xml_out_add_cstr(opfXml, "unique-identifier", "BookId"); if (!m_exp_opt.bEpub2) { gsf_xml_out_add_cstr(opfXml, "profile", EPUB3_PACKAGE_PROFILE); gsf_xml_out_add_cstr(opfXml, "xml:lang", getLanguage().c_str()); } // <metadata> gsf_xml_out_start_element(opfXml, "metadata"); gsf_xml_out_add_cstr(opfXml, "xmlns:dc", DC_NAMESPACE); gsf_xml_out_add_cstr(opfXml, "xmlns:opf", OPF201_NAMESPACE); // Generation of required Dublin Core metadata gsf_xml_out_start_element(opfXml, "dc:title"); gsf_xml_out_add_cstr(opfXml, NULL, getTitle().c_str()); gsf_xml_out_end_element(opfXml); gsf_xml_out_start_element(opfXml, "dc:identifier"); gsf_xml_out_add_cstr(opfXml, "id", "BookId"); gsf_xml_out_add_cstr(opfXml, NULL, getDoc()->getDocUUIDString()); gsf_xml_out_end_element(opfXml); gsf_xml_out_start_element(opfXml, "dc:language"); gsf_xml_out_add_cstr(opfXml, NULL, getLanguage().c_str()); gsf_xml_out_end_element(opfXml); gsf_xml_out_start_element(opfXml, "dc:creator"); gsf_xml_out_add_cstr(opfXml, "opf:role", "aut"); gsf_xml_out_add_cstr(opfXml, NULL, getAuthor().c_str()); gsf_xml_out_end_element(opfXml); // </metadata> gsf_xml_out_end_element(opfXml); // <manifest> gsf_xml_out_start_element(opfXml, "manifest"); gchar *basedir = g_filename_from_uri(m_oebpsDir.c_str(),NULL,NULL); UT_ASSERT(basedir); std::string _baseDir = basedir; std::vector<std::string> listing = getFileList(_baseDir); FREEP(basedir); for (std::vector<std::string>::iterator i = listing.begin(); i != listing.end(); i++) { std::string idStr = escapeForId(*i); std::string fullItemPath = m_oebpsDir + G_DIR_SEPARATOR_S + *i; gsf_xml_out_start_element(opfXml, "item"); if (m_pHmtlExporter->hasMathML((*i))) { gsf_xml_out_add_cstr(opfXml, "mathml", "true"); } gsf_xml_out_add_cstr(opfXml, "id", idStr.c_str()); gsf_xml_out_add_cstr(opfXml, "href", (*i).c_str()); gsf_xml_out_add_cstr(opfXml, "media-type", getMimeType(fullItemPath).c_str()); gsf_xml_out_end_element(opfXml); } // We`ll add navigation files manually gsf_xml_out_start_element(opfXml, "item"); gsf_xml_out_add_cstr(opfXml, "id", "ncx"); gsf_xml_out_add_cstr(opfXml, "href", "toc.ncx"); gsf_xml_out_add_cstr(opfXml, "media-type", "application/x-dtbncx+xml"); gsf_xml_out_end_element(opfXml); if (!m_exp_opt.bEpub2) { gsf_xml_out_start_element(opfXml, "item"); gsf_xml_out_add_cstr(opfXml, "id", "toc"); gsf_xml_out_add_cstr(opfXml, "href", "toc.xhtml"); gsf_xml_out_add_cstr(opfXml, "media-type", "application/xhtml+xml"); gsf_xml_out_end_element(opfXml); } // </manifest> gsf_xml_out_end_element(opfXml); // <spine> gsf_xml_out_start_element(opfXml, "spine"); gsf_xml_out_add_cstr(opfXml, "toc", "ncx"); if (!m_exp_opt.bEpub2) { gsf_xml_out_start_element(opfXml, "itemref"); gsf_xml_out_add_cstr(opfXml, "idref","toc"); gsf_xml_out_end_element(opfXml); } for(std::vector<std::string>::iterator i = m_opsId.begin(); i != m_opsId.end(); i++) { gsf_xml_out_start_element(opfXml, "itemref"); gsf_xml_out_add_cstr(opfXml, "idref", (*i).c_str()); gsf_xml_out_end_element(opfXml); } // </spine> gsf_xml_out_end_element(opfXml); // </package> gsf_xml_out_end_element(opfXml); gsf_output_close(opf); return compress(); }
bool ODe_ManifestWriter::writeManifest(PD_Document* pDoc, GsfOutfile* pODT) { // Create META-INF directory GsfOutput* meta_inf = gsf_outfile_new_child(pODT, "META-INF", TRUE); GsfOutput* manifest = gsf_outfile_new_child( GSF_OUTFILE(meta_inf), "manifest.xml", FALSE); std::string name; static const char * const preamble [] = { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">\n", "<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\">\n", " <manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.text\" manifest:full-path=\"/\"/>\n", " <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/>\n", " <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"styles.xml\"/>\n", " <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"meta.xml\"/>\n", " <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"settings.xml\"/>\n" }; static const char * const postamble [] = { "</manifest:manifest>\n" }; typedef std::set< std::string > absolutePathMimeTypes_t; static absolutePathMimeTypes_t absolutePathMimeTypes; if( absolutePathMimeTypes.empty() ) { absolutePathMimeTypes.insert("application/rdf+xml"); } ODe_writeToStream (manifest, preamble, G_N_ELEMENTS(preamble)); const char* szName; std::string mimeType; const UT_ByteBuf* pByteBuf; std::set< std::string > pathsAlreadyWritten; for (UT_uint32 k = 0; (pDoc->enumDataItems(k, NULL, &szName, &pByteBuf, &mimeType)); k++) { if (!mimeType.empty()) { ensureDirectoryManifest( pDoc, manifest, szName, pathsAlreadyWritten ); std::string automaticPathPrefix = "Pictures/"; if( absolutePathMimeTypes.count(mimeType) ) automaticPathPrefix = ""; name = UT_std_string_sprintf( " <manifest:file-entry manifest:media-type=\"%s\" manifest:full-path=\"%s%s\"/>\n", mimeType.c_str(), automaticPathPrefix.c_str(), szName); ODe_gsf_output_write (manifest, name.size(), reinterpret_cast<const guint8 *>(name.c_str())); } } ODe_writeToStream (manifest, postamble, G_N_ELEMENTS(postamble)); ODe_gsf_output_close(manifest); ODe_gsf_output_close(meta_inf); return true; }