summaryrefslogtreecommitdiff
path: root/backend/epub/epub-document.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/epub/epub-document.c')
-rw-r--r--backend/epub/epub-document.c228
1 files changed, 215 insertions, 13 deletions
diff --git a/backend/epub/epub-document.c b/backend/epub/epub-document.c
index c6bbf684..165bbc85 100644
--- a/backend/epub/epub-document.c
+++ b/backend/epub/epub-document.c
@@ -1,13 +1,27 @@
+#include "ev-file-helpers.h"
#include "epub-document.h"
+#include "unzip.h"
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+#include <config.h>
+/* A variable to hold the path where we extact our ePub */
+static gchar* tmp_dir ;
+/* A variable to hold our epubDocument , for unzip purposes */
+static unzFile epubDocument ;
+
+/*Global variables for XML parsing*/
static xmlDocPtr xmldocument ;
static xmlNodePtr xmlroot ;
static xmlChar* xmlkey ;
static xmlChar* retval ;
-/*Open a XML document for reading */
+/*
+**Functions to parse the xml files.
+**Open a XML document for reading
+*/
gboolean
-openXmlDocument ( const gchar* filename )
+open_xml_document ( const gchar* filename )
{
xmldocument = xmlParseFile(filename);
@@ -26,7 +40,7 @@ openXmlDocument ( const gchar* filename )
*if supplied rootvalue = NULL ,just set root to rootnode .
**/
gboolean
-checkRoot(xmlChar* rootname)
+check_xml_root_node(xmlChar* rootname)
{
xmlroot = xmlDocGetRootElement(xmldocument);
@@ -52,9 +66,9 @@ checkRoot(xmlChar* rootname)
}
xmlChar*
-parseXMLchildren( xmlChar* parserfor,
- XMLparsereturntype rettype,
- xmlChar* attributename )
+parse_xml_children(xmlChar* parserfor,
+ XMLparsereturntype rettype,
+ xmlChar* attributename )
{
xmlNodePtr topchild,children ;
@@ -76,7 +90,7 @@ parseXMLchildren( xmlChar* parserfor,
return retval ;
}
}
- parseChildren( topchild , parserfor,rettype,attributename) ;
+ parse_children( topchild , parserfor,rettype,attributename) ;
topchild = topchild->next ;
}
@@ -84,10 +98,11 @@ parseXMLchildren( xmlChar* parserfor,
return retval ;
}
-void parseChildren(xmlNodePtr parent,
- xmlChar* parserfor,
- XMLparsereturntype rettype,
- xmlChar* attributename )
+static void
+parse_children(xmlNodePtr parent,
+ xmlChar* parserfor,
+ XMLparsereturntype rettype,
+ xmlChar* attributename )
{
xmlNodePtr child = parent->xmlChildrenNode ;
@@ -112,14 +127,201 @@ void parseChildren(xmlNodePtr parent,
return ;
}
- parseChildren(child,parserfor,rettype,attributename) ;
+ parse_children(child,parserfor,rettype,attributename) ;
child = child->next ;
}
}
-void xmlFreeAll()
+static void
+xml_free_all()
{
xmlFreeDoc(xmldocument);
xmlFree(retval);
xmlFree(xmlkey);
+}
+
+static gboolean
+check_mime_type(const gchar* uri,GError** error)
+{
+ GError * err = NULL ;
+ gchar* mimeFromFile = ev_file_get_mime_type(uri,FALSE,&err);
+
+ if ( !mimeFromFile )
+ {
+ if (err) {
+ g_propagate_error (error, err);
+ }
+ else {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("Unknown MIME Type"));
+ }
+ return FALSE;
+ }
+ else if ( g_strcmp0(mimeFromFile, "application/epub+zip") == 0 )
+ {
+ return TRUE ;
+ }
+ else
+ {
+ if (err) {
+ g_propagate_error (error, err);
+ }
+ else {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("Not an ePub document"));
+ }
+ return FALSE;
+ }
+}
+
+static gboolean
+extract_epub_from_container (const gchar* uri, GError ** error)
+{
+ GError* err = NULL ;
+ GString * temporary_sub_directory ;
+ gchar* archivename = g_filename_from_uri(uri,NULL,error);
+
+ if ( !archivename )
+ {
+ if (err) {
+ g_propagate_error (error, err);
+ }
+ else {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("could not retrieve filename"));
+ }
+ return FALSE ;
+ }
+
+ tmp_dir = g_strrstr(archivename,"/");
+ if ( *tmp_dir == '/' )
+ tmp_dir++ ;
+
+ temporary_sub_directory = g_string_new( tmp_dir );
+ g_string_append(temporary_sub_directory,"XXXXXX") ;
+
+ tmp_dir = ev_mkdtemp(temporary_sub_directory->str,error) ;
+
+ if (!tmp_dir) {
+ return FALSE ;
+ }
+
+ g_string_free(temporary_sub_directory,TRUE);
+
+ epubDocument = unzOpen64(archivename);
+
+ if ( epubDocument == NULL )
+ {
+ if (err) {
+ g_propagate_error (error, err);
+ }
+ else {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("could not open archive"));
+ }
+ return FALSE ;
+ }
+ if ( unzGoToFirstFile(epubDocument) != UNZ_OK )
+ {
+ if (err) {
+ g_propagate_error (error, err);
+ }
+ else {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("could not extract archive"));
+ }
+ return FALSE ;
+ }
+ while ( TRUE )
+ {
+ if ( extract_one_file(&err) == FALSE )
+ {
+ if (err) {
+ g_propagate_error (error, err);
+ }
+ else {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("could not extract archive"));
+ }
+ }
+
+ if ( unzGoToNextFile(epubDocument) == UNZ_END_OF_LIST_OF_FILE )
+ break ;
+ }
+
+ unzClose(epubDocument);
+
+ if ( err != NULL )
+ g_error_free(err);
+
+ g_free(archivename);
+
+ return TRUE ;
+}
+
+gboolean
+extract_one_file(GError ** error)
+{
+ GFile * outfile ;
+ gsize writesize = 0;
+ GString * gfilepath ;
+ unz_file_info64 info ;
+ gchar* directory;
+ GFileOutputStream * outstream ;
+ gpointer currentfilename = g_malloc0(512);
+ gpointer buffer = g_malloc0(512);
+
+ if ( unzOpenCurrentFile(epubDocument) != UNZ_OK )
+ {
+ return FALSE ;
+ }
+
+ unzGetCurrentFileInfo64(epubDocument,&info,currentfilename,512,NULL,0,NULL,0) ;
+ directory = g_strrstr(currentfilename,"/") ;
+
+ if ( directory != NULL )
+ directory++;
+
+ gfilepath = g_string_new(tmp_dir) ;
+ g_string_append(gfilepath,"/");
+ g_string_append(gfilepath,currentfilename);
+
+ /*if we encounter a directory, make a directory inside our temporary folder.*/
+ if (directory != NULL && *directory == '\0')
+ {
+ g_mkdir(gfilepath->str,0777);
+ }
+ else
+ {
+ outfile = g_file_new_for_path(gfilepath->str);
+ outstream = g_file_create(outfile,G_FILE_CREATE_PRIVATE,NULL,error);
+ while ( (writesize = unzReadCurrentFile(epubDocument,buffer,512) ) != 0 )
+ {
+ if ( g_output_stream_write((GOutputStream*)outstream,buffer,writesize,NULL,error) == -1 )
+ {
+ return FALSE ;
+ }
+ }
+ g_output_stream_close((GOutputStream*)outstream,NULL,error);
+ g_object_unref(outfile) ;
+ g_object_unref(outstream) ;
+ }
+
+ unzCloseCurrentFile (epubDocument) ;
+ g_string_free(gfilepath);
+ g_free(currentfilename);
+ g_free(buffer);
+
} \ No newline at end of file