diff --git a/lib/libebook/ebook_epub.cpp b/lib/libebook/ebook_epub.cpp index 51755a3..1eea519 100644 --- a/lib/libebook/ebook_epub.cpp +++ b/lib/libebook/ebook_epub.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -226,26 +227,22 @@ bool EBook_EPUB::parseBookinfo() return false; // Parse the content.opf - HelperXmlHandler_EpubContent content_parser; + // TOC is relative to the container_parser.contentPath + QString parentPath = getParentPath( container_parser.contentPath ); + HelperXmlHandler_EpubContent content_parser( parentPath ); if ( !parseXML( container_parser.contentPath, &content_parser ) ) return false; // At least the TOC must be present - if ( content_parser.tocname.isEmpty() ) + if ( content_parser.tocPath.isEmpty() ) return false; - // All the files, including TOC, are relative to the container_parser.contentPath - m_documentRoot.clear(); - int sep = container_parser.contentPath.lastIndexOf( '/' ); - - if ( sep != -1 ) - m_documentRoot = container_parser.contentPath.left( sep + 1 ); // Keep the trailing slash - // Parse the TOC - HelperXmlHandler_EpubTOC toc_parser( this ); + parentPath = getParentPath( content_parser.tocPath ); + HelperXmlHandler_EpubTOC toc_parser( this, parentPath ); - if ( !parseXML( content_parser.tocname, &toc_parser ) ) + if ( !parseXML( content_parser.tocPath, &toc_parser ) ) return false; // Get the data @@ -372,12 +369,11 @@ bool EBook_EPUB::getFileAsBinary( QByteArray& data, const QString& path ) const { // Retrieve the file size struct zip_stat fileinfo; - QString completeUrl; + + QString completeUrl = path; if ( !path.isEmpty() && path[0] == '/' ) - completeUrl = m_documentRoot + path.mid( 1 ); - else - completeUrl = m_documentRoot + path; + completeUrl = path.mid( 1 ); //qDebug("URL requested: %s (%s)", qPrintable(path), qPrintable(completeUrl)); @@ -413,3 +409,19 @@ bool EBook_EPUB::getFileAsBinary( QByteArray& data, const QString& path ) const zip_fclose( file ); return true; } + +QString EBook_EPUB::combinePath( const QString& baseDirPath, const QString& path ) +{ + QString combined = QDir( baseDirPath ).filePath( path ); + return QDir::cleanPath( combined ); +} + +QString EBook_EPUB::getParentPath( const QString& path ) +{ + int sep = path.lastIndexOf( '/' ); + + if ( sep != -1 ) + return path.left( sep + 1 ); // Keep the trailing slash + + return ""; +} diff --git a/lib/libebook/ebook_epub.h b/lib/libebook/ebook_epub.h index 7f2e370..3ba928c 100644 --- a/lib/libebook/ebook_epub.h +++ b/lib/libebook/ebook_epub.h @@ -179,6 +179,10 @@ class EBook_EPUB : public EBook protected: void loadNavigation( Navigator& nav ) override; + public: + // Combine path and resolve relative path + static QString combinePath( const QString& baseDirPath, const QString& path ); + private: // Parses the XML file using a specified parser bool parseXML( const QString& uri, QXmlDefaultHandler* reader ); @@ -190,13 +194,15 @@ class EBook_EPUB : public EBook bool getFileAsString( QString& str, const QString& path ) const; bool getFileAsBinary( QByteArray& data, const QString& path ) const; + // Get parent path + static QString getParentPath( const QString& path ); + // ZIP archive fd and structs QFile m_epubFile; struct zip* m_zipFile; // Ebook info QString m_title; - QString m_documentRoot; // List of files in the ebook QList m_ebookManifest; diff --git a/lib/libebook/helperxmlhandler_epubcontent.cpp b/lib/libebook/helperxmlhandler_epubcontent.cpp index 8e9b8e8..451b6b9 100644 --- a/lib/libebook/helperxmlhandler_epubcontent.cpp +++ b/lib/libebook/helperxmlhandler_epubcontent.cpp @@ -19,12 +19,14 @@ #include #include +#include "ebook_epub.h" #include "helperxmlhandler_epubcontent.h" -HelperXmlHandler_EpubContent::HelperXmlHandler_EpubContent() +HelperXmlHandler_EpubContent::HelperXmlHandler_EpubContent( const QString& basePath ) + : m_state( STATE_NONE ), + m_basePath( basePath ) { - m_state = STATE_NONE; } bool HelperXmlHandler_EpubContent::startElement( const QString&, const QString& localName, const QString&, const QXmlAttributes& atts ) @@ -48,10 +50,10 @@ bool HelperXmlHandler_EpubContent::startElement( const QString&, const QString& if ( idx_id == -1 || idx_href == -1 || idx_mtype == -1 ) return false; - manifest[ atts.value( idx_id ) ] = atts.value( idx_href ); + manifest[ atts.value( idx_id ) ] = EBook_EPUB::combinePath( m_basePath, atts.value( idx_href ) ); if ( atts.value( idx_mtype ) == "application/x-dtbncx+xml" ) - tocname = atts.value( idx_href ); + tocPath = EBook_EPUB::combinePath( m_basePath, atts.value( idx_href ) ); //qDebug() << "MANIFEST: " << atts.value( idx_id ) << "->" << atts.value( idx_href ); } diff --git a/lib/libebook/helperxmlhandler_epubcontent.h b/lib/libebook/helperxmlhandler_epubcontent.h index 0e27b4e..2354bc2 100644 --- a/lib/libebook/helperxmlhandler_epubcontent.h +++ b/lib/libebook/helperxmlhandler_epubcontent.h @@ -30,7 +30,7 @@ class QXmlAttributes; class HelperXmlHandler_EpubContent : public QXmlDefaultHandler { public: - HelperXmlHandler_EpubContent(); + HelperXmlHandler_EpubContent( const QString& basePath ); // Keep the tag-associated metadata QMap< QString, QString > metadata; @@ -41,8 +41,8 @@ class HelperXmlHandler_EpubContent : public QXmlDefaultHandler // Spine storage QList< QString > spine; - // TOC (NCX) filename - QString tocname; + // TOC (NCX) file path + QString tocPath; private: enum State @@ -60,6 +60,7 @@ class HelperXmlHandler_EpubContent : public QXmlDefaultHandler // Tracking State m_state; QString m_tagname; + QString m_basePath; }; #endif // HELPERXMLHANDLER_EPUBCONTENT_H diff --git a/lib/libebook/helperxmlhandler_epubtoc.cpp b/lib/libebook/helperxmlhandler_epubtoc.cpp index 863fd62..4fd67a4 100644 --- a/lib/libebook/helperxmlhandler_epubtoc.cpp +++ b/lib/libebook/helperxmlhandler_epubtoc.cpp @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -24,12 +25,13 @@ #include "helperxmlhandler_epubtoc.h" -HelperXmlHandler_EpubTOC::HelperXmlHandler_EpubTOC( EBook_EPUB* epub ) +HelperXmlHandler_EpubTOC::HelperXmlHandler_EpubTOC( EBook_EPUB* epub, const QString& basePath ) + : m_inNavMap( false ), + m_inText( false ), + m_indent( 0 ), + m_epub( epub ), + m_basePath( basePath ) { - m_epub = epub; - m_inNavMap = false; - m_inText = false; - m_indent = 0; } bool HelperXmlHandler_EpubTOC::startElement( const QString&, const QString& localName, const QString&, const QXmlAttributes& atts ) @@ -103,7 +105,8 @@ void HelperXmlHandler_EpubTOC::checkNewTocEntry() { EBookTocEntry entry; entry.name = m_lastTitle; - entry.url = m_epub->pathToUrl( m_lastId ); + QString combined = EBook_EPUB::combinePath( m_basePath, m_lastId ); + entry.url = m_epub->pathToUrl( combined ); entry.iconid = EBookTocEntry::IMAGE_AUTO; entry.indent = m_indent - 1; diff --git a/lib/libebook/helperxmlhandler_epubtoc.h b/lib/libebook/helperxmlhandler_epubtoc.h index 90cd083..41312be 100644 --- a/lib/libebook/helperxmlhandler_epubtoc.h +++ b/lib/libebook/helperxmlhandler_epubtoc.h @@ -33,7 +33,7 @@ class EBook_EPUB; class HelperXmlHandler_EpubTOC : public QXmlDefaultHandler { public: - HelperXmlHandler_EpubTOC( EBook_EPUB* epub ); + HelperXmlHandler_EpubTOC( EBook_EPUB* epub, const QString& basePath ); QList< EBookTocEntry > entries; @@ -50,6 +50,7 @@ class HelperXmlHandler_EpubTOC : public QXmlDefaultHandler QString m_lastId; QString m_lastTitle; EBook_EPUB* m_epub; + QString m_basePath; }; #endif // HELPERXMLHANDLER_EPUBTOC_H