You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@corinthia.apache.org by pm...@apache.org on 2014/12/17 14:29:09 UTC
[59/92] [abbrv] incubator-corinthia git commit: Add zip-based
DFPackage
Add zip-based DFPackage
This new "subclass" of DFPackage operates with a zip file, allowing code
that loads and stores data from DFPackage objects to work directly with
zip files, rather there having to be an explicit DFUnzip call beforehand
or a DFZip call afterwards. As such, code like the word converter
doesn't need to actually care whether the package contents originally
came from or a destined for a zip file; it just deals with packages in
the abstract sense.
Currently, the implementation actually operates just like a memory
package, unzipping the contents when created, and creating a new zip
file on save. It is envisaged however that eventually this will be
changed to read from an existing zip file on-demand.
Project: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/commit/bf6a061d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/tree/bf6a061d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-corinthia/diff/bf6a061d
Branch: refs/heads/stable
Commit: bf6a061df4072a6987d33056da024405f73ba6c8
Parents: f862f4d
Author: Peter Kelly <pe...@uxproductivity.com>
Authored: Tue Dec 2 16:24:19 2014 +0700
Committer: Peter Kelly <pe...@uxproductivity.com>
Committed: Tue Dec 2 16:24:19 2014 +0700
----------------------------------------------------------------------
DocFormats/api/src/Operations.c | 28 ++++++---
DocFormats/core/src/lib/DFPackage.c | 85 +++++++++++++++++++++++++++
DocFormats/core/src/lib/DFPackage.h | 1 +
DocFormats/filters/ooxml/src/word/Word.c | 11 +++-
consumers/dfutil/src/Commands.c | 8 ++-
consumers/dfutil/src/Plain.c | 17 ++++--
6 files changed, 133 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bf6a061d/DocFormats/api/src/Operations.c
----------------------------------------------------------------------
diff --git a/DocFormats/api/src/Operations.c b/DocFormats/api/src/Operations.c
index d6c51e8..3c65375 100644
--- a/DocFormats/api/src/Operations.c
+++ b/DocFormats/api/src/Operations.c
@@ -26,17 +26,23 @@
static int generateHTML(const char *packageFilename, const char *htmlFilename, DFError **error)
{
int ok = 0;
- DFPackage *rawPackage = DFPackageNewMemory();
+ DFPackage *rawPackage = NULL;
WordPackage *wordPackage = NULL;
char *htmlPath = DFPathDirName(htmlFilename);
DFBuffer *warnings = DFBufferNew();
DFDocument *htmlDoc = NULL;
- if (!DFUnzip(packageFilename,rawPackage,error))
+ rawPackage = DFPackageNewZip(packageFilename,1,error);
+ if (rawPackage == NULL) {
+ DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
goto end;
+ }
+
wordPackage = WordPackageOpenFrom(rawPackage,error);
- if (wordPackage == NULL)
+ if (wordPackage == NULL) {
+ DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
goto end;
+ }
htmlDoc = WordPackageGenerateHTML(wordPackage,htmlPath,"word",error,warnings);
if (htmlDoc == NULL)
@@ -68,7 +74,7 @@ end:
static int updateFrom(const char *packageFilename, const char *htmlFilename, DFError **error)
{
int ok = 0;
- DFPackage *rawPackage = DFPackageNewMemory();
+ DFPackage *rawPackage = NULL;
WordPackage *wordPackage = NULL;
DFDocument *htmlDoc = NULL;
DFBuffer *warnings = DFBufferNew();
@@ -83,6 +89,13 @@ static int updateFrom(const char *packageFilename, const char *htmlFilename, DFE
const char *idPrefix = "word";
if (!DFFileExists(packageFilename)) {
+
+ rawPackage = DFPackageNewZip(packageFilename,0,error);
+ if (rawPackage == NULL) {
+ DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
+ goto end;
+ }
+
wordPackage = WordPackageOpenNew(rawPackage,error);
if (wordPackage == NULL)
goto end;
@@ -94,8 +107,11 @@ static int updateFrom(const char *packageFilename, const char *htmlFilename, DFE
HTMLBreakBDTRefs(htmlDoc->docNode,idPrefix);
}
else {
- if (!DFUnzip(packageFilename,rawPackage,error))
+ rawPackage = DFPackageNewZip(packageFilename,1,error);
+ if (rawPackage == NULL) {
+ DFErrorFormat(error,"%s: %s",packageFilename,DFErrorMessage(error));
goto end;
+ }
wordPackage = WordPackageOpenFrom(rawPackage,error);
if (wordPackage == NULL)
goto end;
@@ -111,8 +127,6 @@ static int updateFrom(const char *packageFilename, const char *htmlFilename, DFE
if (!WordPackageSave(wordPackage,error))
goto end;
- if (!DFZip(packageFilename,rawPackage,error))
- goto end;
ok = 1;
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bf6a061d/DocFormats/core/src/lib/DFPackage.c
----------------------------------------------------------------------
diff --git a/DocFormats/core/src/lib/DFPackage.c b/DocFormats/core/src/lib/DFPackage.c
index 688f5cd..a9a291e 100644
--- a/DocFormats/core/src/lib/DFPackage.c
+++ b/DocFormats/core/src/lib/DFPackage.c
@@ -17,6 +17,7 @@
#include "DFString.h"
#include "DFFilesystem.h"
#include "DFBuffer.h"
+#include "DFZipFile.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -36,6 +37,7 @@ struct DFPackageOps {
struct DFPackage {
size_t retainCount;
char *rootPath;
+ char *zipFilename;
DFHashTable *files;
const DFPackageOps *ops;
};
@@ -225,6 +227,74 @@ static DFPackageOps memOps = {
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
+// DFPackage (Zip) //
+// //
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Currently, zip packages operate just like memory packages, in that they store their contents in
+// a hash table. The only difference is that they extract all the entries from a zip file on
+// creation, and overwrite the zip file on save.
+//
+// Eventually, we should make it so the entries are read on-demand, and also that a new, temporary
+// zip file is written if the package is modified, and that new version replaces the existing one on
+// save.
+
+static int zipSave(DFPackage *package, DFError **error)
+{
+ return DFZip(package->zipFilename,package,error);
+}
+
+static int zipRead(DFPackage *package, const char *path, void **buf, size_t *nbytes, DFError **error)
+{
+ DFBuffer *buffer = DFHashTableLookup(package->files,path);
+ if (buffer == NULL) {
+ DFErrorSetPosix(error,ENOENT);
+ return 0;
+ }
+
+ *buf = malloc(buffer->len);
+ memcpy(*buf,buffer->data,buffer->len);
+ *nbytes = buffer->len;
+
+ return 1;
+}
+
+static int zipWrite(DFPackage *package, const char *path, void *buf, size_t nbytes, DFError **error)
+{
+ DFBuffer *buffer = DFBufferNew();
+ DFBufferAppendData(buffer,buf,nbytes);
+ DFHashTableAdd(package->files,path,buffer);
+ DFBufferRelease(buffer);
+ return 1;
+}
+
+static int zipExists(DFPackage *package, const char *path)
+{
+ return (DFHashTableLookup(package->files,path) != NULL);
+}
+
+static int zipDelete(DFPackage *package, const char *path, DFError **error)
+{
+ DFHashTableRemove(package->files,path);
+ return 1;
+}
+
+static const char **zipList(DFPackage *package, DFError **error)
+{
+ return DFHashTableCopyKeys(package->files);
+}
+
+static DFPackageOps zipOps = {
+ .save = zipSave,
+ .read = zipRead,
+ .write = zipWrite,
+ .exists = zipExists,
+ .delete = zipDelete,
+ .list = zipList,
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// //
// DFPackage //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -264,6 +334,20 @@ DFPackage *DFPackageNewMemory(void)
return package;
}
+DFPackage *DFPackageNewZip(const char *filename, int mustExist, DFError **error)
+{
+ DFPackage *package = (DFPackage *)calloc(1,sizeof(DFPackage));
+ package->retainCount = 1;
+ package->files = DFHashTableNew((DFCopyFunction)DFBufferRetain,(DFFreeFunction)DFBufferRelease);
+ package->ops = &zipOps;
+ package->zipFilename = strdup(filename);
+ if (mustExist && !DFUnzip(filename,package,error)) {
+ DFPackageRelease(package);
+ return NULL;
+ }
+ return package;
+}
+
DFPackage *DFPackageRetain(DFPackage *package)
{
if (package != NULL)
@@ -278,6 +362,7 @@ void DFPackageRelease(DFPackage *package)
DFHashTableRelease(package->files);
free(package->rootPath);
+ free(package->zipFilename);
free(package);
}
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bf6a061d/DocFormats/core/src/lib/DFPackage.h
----------------------------------------------------------------------
diff --git a/DocFormats/core/src/lib/DFPackage.h b/DocFormats/core/src/lib/DFPackage.h
index ac9478c..f15c17e 100644
--- a/DocFormats/core/src/lib/DFPackage.h
+++ b/DocFormats/core/src/lib/DFPackage.h
@@ -22,6 +22,7 @@ typedef struct DFPackage DFPackage;
DFPackage *DFPackageNewFilesystem(const char *rootPath);
DFPackage *DFPackageNewMemory(void);
+DFPackage *DFPackageNewZip(const char *filename, int mustExist, DFError **error);
DFPackage *DFPackageRetain(DFPackage *package);
void DFPackageRelease(DFPackage *package);
int DFPackageSave(DFPackage *package, DFError **error);
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bf6a061d/DocFormats/filters/ooxml/src/word/Word.c
----------------------------------------------------------------------
diff --git a/DocFormats/filters/ooxml/src/word/Word.c b/DocFormats/filters/ooxml/src/word/Word.c
index 2436af8..e00b214 100644
--- a/DocFormats/filters/ooxml/src/word/Word.c
+++ b/DocFormats/filters/ooxml/src/word/Word.c
@@ -29,7 +29,7 @@ int DFHTMLToWord(const char *sourcePath, const char *destPath, DFError **error)
char *htmlPath = DFPathDirName(sourcePath);
DFDocument *htmlDoc = NULL;
DFBuffer *warnings = DFBufferNew();
- DFPackage *rawPackage = DFPackageNewMemory();
+ DFPackage *rawPackage = NULL;
WordPackage *wordPackage = NULL;
htmlDoc = DFParseHTMLFile(sourcePath,0,error);
@@ -40,6 +40,13 @@ int DFHTMLToWord(const char *sourcePath, const char *destPath, DFError **error)
goto end;
}
+ if (DFFileExists(destPath) && !DFDeleteFile(destPath,error))
+ goto end;
+
+ rawPackage = DFPackageNewZip(destPath,0,error);
+ if (rawPackage == NULL)
+ goto end;
+
wordPackage = WordPackageOpenNew(rawPackage,error);
if (wordPackage == NULL)
goto end;
@@ -54,8 +61,6 @@ int DFHTMLToWord(const char *sourcePath, const char *destPath, DFError **error)
if (!WordPackageSave(wordPackage,error))
goto end;
- if (!DFZip(destPath,rawPackage,error))
- goto end;
ok = 1;
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bf6a061d/consumers/dfutil/src/Commands.c
----------------------------------------------------------------------
diff --git a/consumers/dfutil/src/Commands.c b/consumers/dfutil/src/Commands.c
index 59ed80e..eabcdd9 100644
--- a/consumers/dfutil/src/Commands.c
+++ b/consumers/dfutil/src/Commands.c
@@ -111,13 +111,17 @@ static int prettyPrintWordFile(const char *filename, DFError **error)
char *wordTempPath = DFAppendPathComponent(tempPath,"word");
char *plain = NULL;
WordPackage *wordPackage = NULL;
- DFPackage *rawPackage = DFPackageNewMemory();
+ DFPackage *rawPackage = NULL;
if (!DFEmptyDirectory(wordTempPath,error))
goto end;
- if (!DFUnzip(filename,rawPackage,error))
+ rawPackage = DFPackageNewZip(filename,1,error);
+ if (rawPackage == NULL) {
+ DFErrorFormat(error,"%s: %s",filename,DFErrorMessage(error));
goto end;
+ }
+
wordPackage = WordPackageOpenFrom(rawPackage,error);
if (wordPackage == NULL)
goto end;
http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/bf6a061d/consumers/dfutil/src/Plain.c
----------------------------------------------------------------------
diff --git a/consumers/dfutil/src/Plain.c b/consumers/dfutil/src/Plain.c
index 9167920..0b71e2c 100644
--- a/consumers/dfutil/src/Plain.c
+++ b/consumers/dfutil/src/Plain.c
@@ -581,8 +581,8 @@ int Word_fromPlain(const char *plain, const char *plainPath, const char *zipTemp
{
int ok = 0;
char *docxPath = DFAppendPathComponent(zipTempPath,"document.docx");
- DFPackage *firstStore = DFPackageNewMemory();
- DFPackage *secondStore = DFPackageNewMemory();
+ DFPackage *firstStore = NULL;
+ DFPackage *secondStore = NULL;
WordPackage *wp = NULL;
TextPackage *tp = NULL;
@@ -600,21 +600,28 @@ int Word_fromPlain(const char *plain, const char *plainPath, const char *zipTemp
goto end;
}
+ firstStore = DFPackageNewZip(docxPath,0,error);
+ if (firstStore == NULL) {
+ DFErrorFormat(error,"%s: %s",docxPath,DFErrorMessage(error));
+ goto end;
+ }
+
if (!Word_fromPackage(tp,firstStore,error)) {
DFErrorFormat(error,"Word_fromPackageNew: %s",DFErrorMessage(error));
printf("%s\n",DFErrorMessage(error));
goto end;
}
- if (!DFZip(docxPath,firstStore,error)) {
+ if (!DFPackageSave(firstStore,error)) {
DFErrorFormat(error,"zip %s: %s",docxPath,DFErrorMessage(error));
goto end;
}
// Now we have a .docx file; access it using what will be the new way (this API will change so we just say
// "open a word document from here", without having to separately create the package object first.
- if (!DFUnzip(docxPath,secondStore,error)) {
- DFErrorFormat(error,"DFUnzip %s: %s\n",docxPath,DFErrorMessage(error));
+ secondStore = DFPackageNewZip(docxPath,1,error);
+ if (secondStore == NULL) {
+ DFErrorFormat(error,"%s: %s\n",docxPath,DFErrorMessage(error));
goto end;
}
wp = WordPackageOpenFrom(secondStore,error);