corinthia-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pmke...@apache.org
Subject incubator-corinthia git commit: ODFPackage: Use DFStorage, not a filesystem path
Date Fri, 27 Feb 2015 20:26:35 GMT
Repository: incubator-corinthia
Updated Branches:
  refs/heads/master 3dfd8c86b -> 9fae5b277


ODFPackage: Use DFStorage, not a filesystem path

An ODFPackage object is our in-memory representation of a .odt, .odp, or
.ods file. Previously, to use this class, you had to first extract the
contents of the .od* file (actually a zip file) in a temporary
directory, so that the ODFPackage load and save routines could then
access the XML files directly from the filesystem.

Now we use DFStorage, which provides a level of abstraction that no
longer requires us to necessarily have the package contents stored in a
temporary directory. A DFStorage object can represent a zip file, a
filesystem directory, or a purely in-memory map of filenames to byte
arrays. The Word filter already works entirely in terms of DFStorage
objects for all its I/O; this commit makes the ODF filter do so too.

ODFPackageCreateNew() is for when you want to create a new ODF package
without any existing data. Although it does not read anything, but just
creates a series of DFDocument objects, it still requires a DFStorage
object to be supplied, as this is retained and used to represent the
location to which the package will eventually be saved. So for example
if you wanted to create a new .odt *file*, you would first call
DFStorageCreateZip(), and then pass the resulting object to
ODFPackageCreateNew().

ODFPackageOpenFrom() is for when you have an existing ODF package
represented by some DFStorage object. It expects to find content.xml,
meta.xml, settings.xml, styles.xml, and META-INF/manifest.xml, parsing
each of these into DFDocument objects. If you want to open an existing
.odt file, you would call DFStorageOpenZip(), and then pass the
resulting object to ODFPackageCreateNew().

ODFPackageSave() serialises the various DFDocument objects to XML and
writes them to the storage object. It then calls DFStorageSave(), to
write them to the actual physical location represented by the storage
object. In the case of DFStorage objects that correspond to zip files,
this causes all the in-memory byte arrays corresponding to the files in
the package to be written to a zip file.


Project: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/commit/9fae5b27
Tree: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/tree/9fae5b27
Diff: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/diff/9fae5b27

Branch: refs/heads/master
Commit: 9fae5b277e3b2b922d422e783bdb2a28920a1be2
Parents: 3dfd8c8
Author: Peter Kelly <peter@uxproductivity.com>
Authored: Sat Feb 28 03:14:54 2015 +0700
Committer: Peter Kelly <peter@uxproductivity.com>
Committed: Sat Feb 28 03:14:54 2015 +0700

----------------------------------------------------------------------
 DocFormats/filters/odf/src/ODFPackage.c | 103 ++++++++++++++++++---------
 DocFormats/filters/odf/src/ODFPackage.h |   6 +-
 2 files changed, 72 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9fae5b27/DocFormats/filters/odf/src/ODFPackage.c
----------------------------------------------------------------------
diff --git a/DocFormats/filters/odf/src/ODFPackage.c b/DocFormats/filters/odf/src/ODFPackage.c
index b8d1d4b..b937c1d 100644
--- a/DocFormats/filters/odf/src/ODFPackage.c
+++ b/DocFormats/filters/odf/src/ODFPackage.c
@@ -25,33 +25,37 @@
 #include <stdlib.h>
 #include <string.h>
 
-static DFDocument *readOrCreateDocument(ODFPackage *package, const char *filename, Tag rootTag,
Tag childTag)
+static DFDocument *createDocument(Tag rootTag, Tag childTag)
 {
-    char *fullPath = DFFormatString("%s/%s",package->tempPath,filename);
-    DFDocument *doc = DFParseXMLFile(fullPath,NULL);
-    free(fullPath);
-    if (doc != NULL)
-        return doc;
-
-    doc = DFDocumentNewWithRoot(rootTag);
+    DFDocument *doc = DFDocumentNewWithRoot(rootTag);
     DFCreateChildElement(doc->root,childTag);
     return doc;
 }
 
-static ODFManifest *readOrCreateManifest(ODFPackage *package)
+static DFDocument *readDocument(ODFPackage *package, const char *filename, DFError **error)
 {
-    char *fullPath = DFFormatString("%s/%s",package->tempPath,"META-INF/manifest.xml");
-    DFDocument *manifestDoc = DFParseXMLFile(fullPath,NULL);
-    free(fullPath);
-    return (manifestDoc != NULL) ? ODFManifestNewWithDoc(manifestDoc) : ODFManifestNew();
+    DFDocument *doc = DFParseXMLStorage(package->storage,filename,error);
+    if (doc == NULL) {
+        DFErrorFormat(error,"%s: %s",filename,DFErrorMessage(error));
+        return NULL;
+    }
+    return doc;
 }
 
-static int writeDocument(ODFPackage *package, DFDocument *doc, NamespaceID defaultNS, const
char *filename, DFError **error)
+static ODFManifest *readManifest(ODFPackage *package, DFError **error)
 {
-    char *fullPath = DFFormatString("%s/%s",package->tempPath,filename);
-    int ok = DFSerializeXMLFile(doc,defaultNS,0,fullPath,error);
-    free(fullPath);
+    DFDocument *manifestDoc = DFParseXMLStorage(package->storage,"META-INF/manifest.xml",error);
+    if (manifestDoc == NULL) {
+        DFErrorFormat(error,"META-INF/manifest.xml: %s",DFErrorMessage(error));
+        return NULL;
+    }
+    return ODFManifestNewWithDoc(manifestDoc);
+}
 
+static int writeDocument(ODFPackage *package, DFDocument *doc, NamespaceID defaultNS,
+                         const char *filename, DFError **error)
+{
+    int ok = DFSerializeXMLStorage(doc,defaultNS,0,package->storage,filename,error);
     if (!ok)
         DFErrorFormat(error,"%s: %s",filename,DFErrorMessage(error));
     return ok;
@@ -59,36 +63,70 @@ static int writeDocument(ODFPackage *package, DFDocument *doc, NamespaceID
defau
 
 static int writeString(ODFPackage *package, const char *str, const char *filename, DFError
**error)
 {
-    char *fullPath = DFFormatString("%s/%s",package->tempPath,filename);
-    int ok = DFStringWriteToFile(str,fullPath,error);
-    free(fullPath);
+    DFBuffer *buf = DFBufferNew();
+    DFBufferAppendString(buf,str);
+    int ok = DFBufferWriteToStorage(buf,package->storage,filename,error);
+    DFBufferRelease(buf);
 
     if (!ok)
         DFErrorFormat(error,"%s: %s",filename,DFErrorMessage(error));
     return ok;
 }
 
-ODFPackage *ODFPackageNew(const char *tempPath, DFError **error)
+ODFPackage *ODFPackageOpenNew(DFStorage *storage, DFError **error)
 {
     ODFPackage *package = (ODFPackage *)calloc(1,sizeof(ODFPackage));
     package->retainCount = 1;
-    package->tempPath = strdup(tempPath);
+    package->storage = DFStorageRetain(storage);
 
-    package->contentDoc = readOrCreateDocument(package,"content.xml",OFFICE_DOCUMENT_CONTENT,OFFICE_BODY);
-    package->metaDoc = readOrCreateDocument(package,"meta.xml",OFFICE_DOCUMENT_META,OFFICE_META);
-    package->settingsDoc = readOrCreateDocument(package,"settings.xml",OFFICE_DOCUMENT_SETTINGS,OFFICE_SETTINGS);
-    package->stylesDoc = readOrCreateDocument(package,"styles.xml",OFFICE_DOCUMENT_STYLES,OFFICE_STYLES);
+    // Create XML documents
+    package->contentDoc = createDocument(OFFICE_DOCUMENT_CONTENT,OFFICE_BODY);
+    package->metaDoc = createDocument(OFFICE_DOCUMENT_META,OFFICE_META);
+    package->settingsDoc = createDocument(OFFICE_DOCUMENT_SETTINGS,OFFICE_SETTINGS);
+    package->stylesDoc = createDocument(OFFICE_DOCUMENT_STYLES,OFFICE_STYLES);
 
-    package->manifest = readOrCreateManifest(package);
+    // Create manifst
+    package->manifest = ODFManifestNew();
     ODFManifestAddEntry(package->manifest,"/","application/vnd.oasis.opendocument.text","1.2");
     ODFManifestAddEntry(package->manifest,"content.xml","text/xml",NULL);
     ODFManifestAddEntry(package->manifest,"meta.xml","text/xml",NULL);
     ODFManifestAddEntry(package->manifest,"settings.xml","text/xml",NULL);
     ODFManifestAddEntry(package->manifest,"styles.xml","text/xml",NULL);
 
+    // Setup ODF objects
+    package->sheet = ODFSheetNew(package->stylesDoc,package->contentDoc);
+
+    return package;
+}
+
+ODFPackage *ODFPackageOpenFrom(DFStorage *storage, DFError **error)
+{
+    ODFPackage *package = (ODFPackage *)calloc(1,sizeof(ODFPackage));
+    package->retainCount = 1;
+    package->storage = DFStorageRetain(storage);
+
+    // Read XML documents
+    if ((package->contentDoc = readDocument(package,"content.xml",error)) == NULL)
+        goto end;
+    if ((package->metaDoc = readDocument(package,"meta.xml",error)) == NULL)
+        goto end;
+    if ((package->settingsDoc = readDocument(package,"settings.xml",error)) == NULL)
+        goto end;
+    if ((package->stylesDoc = readDocument(package,"styles.xml",error)) == NULL)
+        goto end;
+
+    // Read manifest
+    if ((package->manifest = readManifest(package,error)) == NULL)
+        goto end;
+
+    // Setup ODF objects
     package->sheet = ODFSheetNew(package->stylesDoc,package->contentDoc);
 
     return package;
+
+end:
+    ODFPackageRelease(package);
+    return NULL;
 }
 
 ODFPackage *ODFPackageRetain(ODFPackage *package)
@@ -103,7 +141,7 @@ void ODFPackageRelease(ODFPackage *package)
     if ((package == NULL) || (--package->retainCount > 0))
         return;
 
-    free(package->tempPath);
+    DFStorageRelease(package->storage);
     ODFManifestRelease(package->manifest);
     ODFSheetRelease(package->sheet);
     DFDocumentRelease(package->contentDoc);
@@ -115,13 +153,6 @@ void ODFPackageRelease(ODFPackage *package)
 
 int ODFPackageSave(ODFPackage *package, DFError **error)
 {
-    char *metaInfPath = DFFormatString("%s/META-INF",package->tempPath);
-    if (!DFFileExists(metaInfPath) && !DFCreateDirectory(metaInfPath,1,error)) {
-        free(metaInfPath);
-        return 0;
-    }
-    free(metaInfPath);
-
     if (!writeDocument(package,package->contentDoc,NAMESPACE_NULL,"content.xml",error))
         return 0;
     if (!writeDocument(package,package->metaDoc,NAMESPACE_NULL,"meta.xml",error))
@@ -134,6 +165,8 @@ int ODFPackageSave(ODFPackage *package, DFError **error)
         return 0;
     if (!writeString(package,"application/vnd.oasis.opendocument.text","mimetype",error))
         return 0;
+    if (!DFStorageSave(package->storage,error))
+        return 0;
 
     return 1;
 }

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/9fae5b27/DocFormats/filters/odf/src/ODFPackage.h
----------------------------------------------------------------------
diff --git a/DocFormats/filters/odf/src/ODFPackage.h b/DocFormats/filters/odf/src/ODFPackage.h
index 1dfe649..e56ebc2 100644
--- a/DocFormats/filters/odf/src/ODFPackage.h
+++ b/DocFormats/filters/odf/src/ODFPackage.h
@@ -20,6 +20,7 @@
 
 #include <DocFormats/DFXMLForward.h>
 #include <DocFormats/DFError.h>
+#include <DocFormats/DFStorage.h>
 #include "ODFManifest.h"
 #include "ODFSheet.h"
 
@@ -27,7 +28,7 @@ typedef struct ODFPackage ODFPackage;
 
 struct ODFPackage {
     size_t retainCount;
-    char *tempPath;
+    DFStorage *storage;
     DFDocument *contentDoc;
     DFDocument *metaDoc;
     DFDocument *settingsDoc;
@@ -36,7 +37,8 @@ struct ODFPackage {
     ODFSheet *sheet;
 };
 
-ODFPackage *ODFPackageNew(const char *tempPath, DFError **error);
+ODFPackage *ODFPackageOpenNew(DFStorage *storage, DFError **error);
+ODFPackage *ODFPackageOpenFrom(DFStorage *storage, DFError **error);
 ODFPackage *ODFPackageRetain(ODFPackage *package);
 void ODFPackageRelease(ODFPackage *package);
 int ODFPackageSave(ODFPackage *package, DFError **error);


Mime
View raw message