From e66f4bb62e4dfb836b5171c70dc517273eee6e85 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Sun, 9 Mar 2008 00:54:49 +0000 Subject: [PATCH] According to the XPS specification, section 10.1.2, an XML file in the archive can be splitted in small sub-pieces placed with sequential names in a directory called like the XML file. Handle this case for the relation parts, the references and the documents contents. svn path=/trunk/KDE/kdegraphics/okular/; revision=783647 --- generators/xps/generator_xps.cpp | 57 ++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/generators/xps/generator_xps.cpp b/generators/xps/generator_xps.cpp index 516565981..528825d0a 100644 --- a/generators/xps/generator_xps.cpp +++ b/generators/xps/generator_xps.cpp @@ -443,6 +443,44 @@ static QString absolutePath( const QString &path, const QString &location ) return url.toLocalFile(); } +/** + Read the content of an archive entry in both the cases: + a) single file + + foobar + b) directory + + foobar/ + + [0].piece + + [1].piece + + ... + + [x].last.piece + + \see XPS specification 10.1.2 +*/ +static QByteArray readFileOrDirectoryParts( const KArchiveEntry *entry, QString *pathOfFile = 0 ) +{ + QByteArray data; + if ( entry->isDirectory() ) { + const KArchiveDirectory* relDir = static_cast( entry ); + QStringList entries = relDir->entries(); + qSort( entries ); + Q_FOREACH ( const QString &entry, entries ) { + const KArchiveEntry* relSubEntry = relDir->entry( entry ); + if ( !relSubEntry->isFile() ) + continue; + + const KZipFileEntry* relSubFile = static_cast( relSubEntry ); + data.append( relSubFile->data() ); + } + } else { + const KZipFileEntry* relFile = static_cast( entry ); + data.append( relFile->data() ); + if ( pathOfFile ) { + *pathOfFile = entryPath( relFile ); + } + } + return data; +} + XpsHandler::XpsHandler(XpsPage *page): m_page(page) { m_painter = NULL; @@ -1080,11 +1118,11 @@ XpsDocument::XpsDocument(XpsFile *file, const QString &fileName): m_file(file), { kDebug(XpsDebug) << "document file name: " << fileName; - const KZipFileEntry* documentFile = static_cast(file->xpsArchive()->directory()->entry( fileName )); - const QString documentFilePath = entryPath( documentFile ); + const KArchiveEntry* documentEntry = file->xpsArchive()->directory()->entry( fileName ); + QString documentFilePath = fileName; QXmlStreamReader docXml; - docXml.addData( documentFile->data() ); + docXml.addData( readFileOrDirectoryParts( documentEntry, &documentFilePath ) ); while( !docXml.atEnd() ) { docXml.readNext(); if ( docXml.isStartElement() ) { @@ -1216,15 +1254,14 @@ bool XpsFile::loadDocument(const QString &filename) } // The only fixed entry in XPS is /_rels/.rels - const KZipFileEntry* relFile = static_cast(m_xpsArchive->directory()->entry("_rels/.rels")); - - if ( !relFile ) { + const KArchiveEntry* relEntry = m_xpsArchive->directory()->entry("_rels/.rels"); + if ( !relEntry ) { // this might occur if we can't read the zip directory, or it doesn't have the relationships entry return false; } QXmlStreamReader relXml; - relXml.addData( relFile->data() ); + relXml.addData( readFileOrDirectoryParts( relEntry ) ); QString fixedRepresentationFileName; // We work through the relationships document and pull out each element. @@ -1264,11 +1301,11 @@ bool XpsFile::loadDocument(const QString &filename) return false; } - const KZipFileEntry* fixedRepFile = static_cast(m_xpsArchive->directory()->entry( fixedRepresentationFileName )); - const QString fixedRepresentationFilePath = entryPath( fixedRepFile ); + const KArchiveEntry* fixedRepEntry = m_xpsArchive->directory()->entry( fixedRepresentationFileName ); + QString fixedRepresentationFilePath = fixedRepresentationFileName; QXmlStreamReader fixedRepXml; - fixedRepXml.addData( fixedRepFile->data() ); + fixedRepXml.addData( readFileOrDirectoryParts( fixedRepEntry, &fixedRepresentationFileName ) ); while ( !fixedRepXml.atEnd() ) {