Пример #1
0
/**
 * 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;
}
Пример #2
0
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));
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
/* 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);
}
Пример #7
0
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;
}
Пример #8
0
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));
}
Пример #9
0
/**
 * 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);
}
Пример #10
0
/**
 * 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
}
Пример #11
0
/**
 * 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;
}
Пример #12
0
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);
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
/**
 * 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;
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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));
}
Пример #20
0
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;
}