diff options
Diffstat (limited to 'filters/kword/wordperfect/import/wpimport.cpp')
-rw-r--r-- | filters/kword/wordperfect/import/wpimport.cpp | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/filters/kword/wordperfect/import/wpimport.cpp b/filters/kword/wordperfect/import/wpimport.cpp new file mode 100644 index 000000000..12f5446e3 --- /dev/null +++ b/filters/kword/wordperfect/import/wpimport.cpp @@ -0,0 +1,391 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2005 Ariya Hidayat <ariya@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <config.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <kdebug.h> +#include <KoFilterChain.h> +#include <kgenericfactory.h> + +#include <wpimport.h> + +#include <stdio.h> // debug + +typedef KGenericFactory<WPImport, KoFilter> WPImportFactory; +K_EXPORT_COMPONENT_FACTORY( libwpimport, WPImportFactory( "kofficefilters" ) ) + +#include <libwpd/libwpd.h> +#include "DocumentHandler.h" +#include "WordPerfectCollector.h" + +class _SH_MemoryInputStream : public _SH_InputStream +{ +public: + _SH_MemoryInputStream(unsigned char *data, unsigned long size); + virtual ~_SH_MemoryInputStream(); + + virtual bool isOLEStream() { return false; } +#if defined(HAVE_LIBWPD_0100) || defined(HAVE_LIBWPD_090) + virtual _SH_InputStream * getDocumentOLEStream(const char *name = NULL) { return NULL; } + const virtual unsigned char *read(unsigned long numBytes, unsigned long &numBytesRead); +#else + virtual _SH_InputStream * getDocumentOLEStream() { return NULL; } + const virtual uint8_t *read(size_t numBytes, size_t &numBytesRead); +#endif + + virtual int seek(long offset, _SH_SEEK_TYPE seekType); + virtual long tell(); + virtual bool atEOS(); + +#ifdef HAVE_LIBWPD_0100 + virtual bool isStructured() { return false; } + virtual unsigned subStreamCount() { return 0U; } + virtual const char *subStreamName(unsigned id) { return NULL; } + virtual bool existsSubStream(const char *name) { return false; } + virtual RVNGInputStream *getSubStreamByName(const char *name) { return NULL; } + virtual RVNGInputStream *getSubStreamById(unsigned id) { return NULL; } + virtual bool isEnd() { return false; } +#endif + +private: + long m_offset; + size_t m_size; + unsigned char *m_data; +}; + +_SH_MemoryInputStream::_SH_MemoryInputStream(unsigned char *data, unsigned long size) : +#if defined(HAVE_LIBWPD_090) || defined(HAVE_LIBWPD_0100) + _SH_InputStream(), +#else + _SH_InputStream(false), +#endif + m_offset(0), + m_size(size), + m_data(data) +{ +} + +_SH_MemoryInputStream::~_SH_MemoryInputStream() +{ + if (m_data) + delete [] m_data; +} + +#if defined(HAVE_LIBWPD_090) || defined(HAVE_LIBWPD_0100) +const unsigned char * _SH_MemoryInputStream::read(unsigned long numBytes, unsigned long &numBytesRead) +#else +const uint8_t * _SH_MemoryInputStream::read(size_t numBytes, size_t &numBytesRead) +#endif +{ + numBytesRead = 0; + + if (numBytes == 0) + return 0; + + int numBytesToRead; + + if ((m_offset+numBytes) < m_size) + numBytesToRead = numBytes; + else + numBytesToRead = m_size - m_offset; + + numBytesRead = numBytesToRead; // about as paranoid as we can be.. + + if (numBytesToRead == 0) + return 0; + + long oldOffset = m_offset; + m_offset += numBytesToRead; + + return &m_data[oldOffset]; +} + +int _SH_MemoryInputStream::seek(long offset, _SH_SEEK_TYPE seekType) +{ + if (seekType == _SH_SEEK_CUR) + m_offset += offset; + else if (seekType == _SH_SEEK_SET) + m_offset = offset; + + if (m_offset < 0) + { + m_offset = 0; + return 1; + } + if ((long)m_offset > (long)m_size) + { + m_offset = m_size; + return 1; + } + + return 0; +} + +long _SH_MemoryInputStream::tell() +{ + return m_offset; +} + +bool _SH_MemoryInputStream::atEOS() +{ + if ((long)m_offset == (long)m_size) + return true; + + return false; +} + +class KWordHandler : public DocumentHandler +{ +public: + KWordHandler(); + virtual ~KWordHandler() {}; + void startDocument(); + void endDocument(); + void startElement(const char *psName, const _SH_PropertyList &xPropList); + void endElement(const char *psName); + void characters(const _SH_String &sCharacters); + _SH_String documentstring; +private: + bool isTagOpened; + _SH_String openedTagName; +}; + +KWordHandler::KWordHandler() : + isTagOpened(false) +{ +} + +void KWordHandler::startDocument() +{ + documentstring.clear(); +} + +void KWordHandler::startElement(const char *psName, const _SH_PropertyList &xPropList) +{ + if (isTagOpened) + { + documentstring.append( ">" ); + isTagOpened = false; + } + _SH_String tempString; + tempString.sprintf("<%s", psName); + documentstring.append( tempString ); + _SH_PropertyList::Iter i(xPropList); + for (i.rewind(); i.next(); ) + { + // filter out libwpd elements + if (strlen(i.key()) > 6 && strncmp(i.key(), "libwpd", 6) != 0) + { + tempString.sprintf(" %s=\"%s\"", i.key(), i()->getStr().cstr()); + documentstring.append( tempString ); + } + } + isTagOpened = true; + openedTagName.sprintf("%s", psName); +} + +void KWordHandler::endElement(const char *psName) +{ + if ((isTagOpened) && (openedTagName == psName)) + documentstring.append( " />" ); + else + { + _SH_String tempString; + tempString.sprintf("</%s>", psName); + documentstring.append( tempString ); + } + isTagOpened = false; +} + +void KWordHandler::characters(const _SH_String &sCharacters) +{ + if (isTagOpened) + { + documentstring.append( ">" ); + isTagOpened = false; + } +#ifdef HAVE_LIBWPD_0100 + documentstring.append( _SH_String::escapeXML(sCharacters) ); +#else + documentstring.append( _SH_String(sCharacters, true) ); +#endif +} + + +void KWordHandler::endDocument() +{ + if (isTagOpened) + { + documentstring.append( ">" ); + isTagOpened = false; + } +} + + + +WPImport::WPImport( KoFilter *, const char *, const TQStringList& ): KoFilter() +{ +} + +KoFilter::ConversionStatus WPImport::convert( const TQCString& from, const TQCString& to ) +{ + // check for proper conversion + if(to!= "application/vnd.sun.xml.writer" || from != "application/wordperfect" ) + return KoFilter::NotImplemented; + + // open input file + const char* infile = m_chain->inputFile().latin1(); + FILE *f = fopen( infile, "rb" ); + if( !f ) + return KoFilter::StupidError; + + fseek( f, 0, SEEK_END ); + long fsize = ftell( f ); + fseek( f, 0, SEEK_SET ); + + unsigned char* buf = new unsigned char[fsize]; + fread( buf, 1, fsize, f ); + fclose( f ); + + // instream now owns buf, no need to delete buf later + _SH_MemoryInputStream instream = _SH_MemoryInputStream( buf, fsize ); + +#if defined(HAVE_LIBWPD_0100) + libwpd::WPDConfidence confidence = libwpd::WPDocument::isFileFormatSupported(&instream); +#elif defined(HAVE_LIBWPD_090) + WPDConfidence confidence = WPDocument::isFileFormatSupported(&instream); +#else + WPDConfidence confidence = WPDocument::isFileFormatSupported(&instream, false); +#endif +#if defined(HAVE_LIBWPD_0100) + if( confidence == libwpd::WPD_CONFIDENCE_NONE ) +#else + if( confidence == WPD_CONFIDENCE_NONE ) +#endif + { + fprintf(stderr, "ERROR: We have no confidence that you are giving us a valid WordPerfect document.\n"); + return KoFilter::StupidError; + } + instream.seek(0, _SH_SEEK_SET); + + // open and parse the file + KWordHandler handler; + + WordPerfectCollector collector(&instream, &handler); + + if ( !collector.filter() ) return KoFilter::StupidError; + + // prepare storage + KoStoreDevice* manifest = m_chain->storageFile( "META-INF/manifest.xml", KoStore::Write ); + if ( manifest ) + { + TQCString manifeststring = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ +<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">\n\ +<manifest:manifest xmlns:manifest=\"http://openoffice.org/2001/manifest\">\n\ +<manifest:file-entry manifest:media-type=\"application/vnd.sun.xml.writer\" manifest:full-path=\"/\"/>\n\ +<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/>\n\ +<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"styles.xml\"/>\n\ +</manifest:manifest>\n"; + manifest->writeBlock( (const char*) manifeststring, manifeststring.length() ); + } + + KoStoreDevice* styles = m_chain->storageFile( "styles.xml", KoStore::Write ); + if ( styles ) + { + TQCString stylesstring = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ +<!DOCTYPE office:document-styles PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"office.dtd\">\ +<office:document-styles xmlns:office=\"http://openoffice.org/2000/office\" xmlns:style=\"http://openoffice.org/2000/style\"\ + xmlns:text=\"http://openoffice.org/2000/text\" xmlns:table=\"http://openoffice.org/2000/table\"\ + xmlns:draw=\"http://openoffice.org/2000/drawing\" xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"\ + xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:number=\"http://openoffice.org/2000/datastyle\"\ + xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:chart=\"http://openoffice.org/2000/chart\" xmlns:dr3d=\"http://openoffice.org/2000/dr3d\"\ + xmlns:math=\"http://www.w3.org/1998/Math/MathML\" xmlns:form=\"http://openoffice.org/2000/form\"\ + xmlns:script=\"http://openoffice.org/2000/script\" office:version=\"1.0\">\ +<office:styles>\ +<style:default-style style:family=\"paragraph\">\ +<style:properties style:use-window-font-color=\"true\" style:text-autospace=\"ideograph-alpha\"\ + style:punctuation-wrap=\"hanging\" style:line-break=\"strict\" style:writing-mode=\"page\"/>\ +</style:default-style>\ +<style:default-style style:family=\"table\"/>\ +<style:default-style style:family=\"table-row\"/>\ +<style:default-style style:family=\"table-column\"/>\ +<style:style style:name=\"Standard\" style:family=\"paragraph\" style:class=\"text\"/>\ +<style:style style:name=\"Text body\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"text\"/>\ +<style:style style:name=\"List\" style:family=\"paragraph\" style:parent-style-name=\"Text body\" style:class=\"list\"/>\ +<style:style style:name=\"Header\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"extra\"/>\ +<style:style style:name=\"Footer\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"extra\"/>\ +<style:style style:name=\"Caption\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"extra\"/>\ +<style:style style:name=\"Footnote\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"extra\"/>\ +<style:style style:name=\"Endnote\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"extra\"/>\ +<style:style style:name=\"Index\" style:family=\"paragraph\" style:parent-style-name=\"Standard\" style:class=\"index\"/>\ +<style:style style:name=\"Footnote Symbol\" style:family=\"text\">\ +<style:properties style:text-position=\"super 58%\"/>\ +</style:style>\ +<style:style style:name=\"Endnote Symbol\" style:family=\"text\">\ +<style:properties style:text-position=\"super 58%\"/>\ +</style:style>\ +<style:style style:name=\"Footnote anchor\" style:family=\"text\">\ +<style:properties style:text-position=\"super 58%\"/>\ +</style:style>\ +<style:style style:name=\"Endnote anchor\" style:family=\"text\">\ +<style:properties style:text-position=\"super 58%\"/>\ +</style:style>\ +<text:footnotes-configuration text:citation-style-name=\"Footnote Symbol\" text:citation-body-style-name=\"Footnote anchor\"\ + style:num-format=\"1\" text:start-value=\"0\" text:footnotes-position=\"page\" text:start-numbering-at=\"document\"/>\ +<text:endnotes-configuration text:citation-style-name=\"Endnote Symbol\" text:citation-body-style-name=\"Endnote anchor\"\ + text:master-page-name=\"Endnote\" style:num-format=\"i\" text:start-value=\"0\"/>\ +<text:linenumbering-configuration text:number-lines=\"false\" text:offset=\"0.1965inch\" style:num-format=\"1\"\ + text:number-position=\"left\" text:increment=\"5\"/>\ +</office:styles>\ +<office:automatic-styles>\ +<style:page-master style:name=\"PM0\">\ +<style:properties fo:margin-bottom=\"1.0000inch\" fo:margin-left=\"1.0000inch\" fo:margin-right=\"1.0000inch\" fo:margin-top=\"1.0000inch\"\ + fo:page-height=\"11.0000inch\" fo:page-width=\"8.5000inch\" style:print-orientation=\"portrait\">\ +<style:footnote-sep style:adjustment=\"left\" style:color=\"#000000\" style:distance-after-sep=\"0.0398inch\"\ + style:distance-before-sep=\"0.0398inch\" style:rel-width=\"25%\" style:width=\"0.0071inch\"/>\ +</style:properties>\ +</style:page-master>\ +<style:page-master style:name=\"PM1\">\ +<style:properties fo:margin-bottom=\"1.0000inch\" fo:margin-left=\"1.0000inch\" fo:margin-right=\"1.0000inch\" fo:margin-top=\"1.0000inch\"\ + fo:page-height=\"11.0000inch\" fo:page-width=\"8.5000inch\" style:print-orientation=\"portrait\">\ +<style:footnote-sep style:adjustment=\"left\" style:color=\"#000000\" style:rel-width=\"25%\"/>\ +</style:properties>\ +</style:page-master>\ +</office:automatic-styles>\ +<office:master-styles>\ +<style:master-page style:name=\"Standard\" style:page-master-name=\"PM0\"/>\ +<style:master-page style:name=\"Endnote\" style:page-master-name=\"PM1\"/>\ +</office:master-styles>\ +</office:document-styles>"; + styles->writeBlock( (const char*) stylesstring, stylesstring.length() ); + } + + KoStoreDevice* out = m_chain->storageFile( "content.xml", KoStore::Write ); + + if( out ) + out->writeBlock( (const char*) handler.documentstring.cstr(), strlen(handler.documentstring.cstr()) ); + + return KoFilter::OK; +} + +#include "wpimport.moc" |