summaryrefslogtreecommitdiffstats
path: root/filters/olefilters/lib
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /filters/olefilters/lib
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'filters/olefilters/lib')
-rw-r--r--filters/olefilters/lib/Makefile.am16
-rw-r--r--filters/olefilters/lib/filterbase.cc91
-rw-r--r--filters/olefilters/lib/filterbase.h109
-rw-r--r--filters/olefilters/lib/klaola.cc579
-rw-r--r--filters/olefilters/lib/klaola.h193
-rw-r--r--filters/olefilters/lib/myfile.h49
6 files changed, 1037 insertions, 0 deletions
diff --git a/filters/olefilters/lib/Makefile.am b/filters/olefilters/lib/Makefile.am
new file mode 100644
index 00000000..9e902fd2
--- /dev/null
+++ b/filters/olefilters/lib/Makefile.am
@@ -0,0 +1,16 @@
+####### General stuff
+
+INCLUDES = -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes)
+
+####### Files
+
+noinst_LTLIBRARIES = libfilterbase.la libklaola.la
+
+libfilterbase_la_SOURCES = filterbase.cc
+libfilterbase_la_METASOURCES = filterbase.moc
+libfilterbase_la_LDFLAGS = $(all_libraries)
+
+libklaola_la_SOURCES = klaola.cc
+libklaola_la_LDFLAGS = $(all_libraries)
+
+noinst_HEADERS = filterbase.h klaola.h
diff --git a/filters/olefilters/lib/filterbase.cc b/filters/olefilters/lib/filterbase.cc
new file mode 100644
index 00000000..b1ec9c32
--- /dev/null
+++ b/filters/olefilters/lib/filterbase.cc
@@ -0,0 +1,91 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 Werner Trobin <[email protected]>
+
+ 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 <filterbase.h>
+
+FilterBase::FilterBase() : QObject() {
+ m_success=true;
+ m_ready=false;
+}
+
+FilterBase::FilterBase(QStringList &oleStreams) : QObject() {
+ FilterBase();
+ m_oleStreams = oleStreams;
+}
+
+bool FilterBase::filter() {
+ QString newstr;
+
+ // Page sizes, margins etc. all in points.
+
+ const unsigned height = 841; // Height.
+ const unsigned width = 595; // Width.
+ const unsigned hMargin = 28; // Horizontal margin.
+ const unsigned vMargin = 42; // Vertical margin.
+
+ newstr = QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE DOC >\n"
+ "<DOC author=\"Reginald Stadlbauer and Torben Weis\" email=\"[email protected] and [email protected]\" editor=\"KWord\" mime=\"application/x-kword\">\n"
+ " <PAPER format=\"1\" ptWidth=\"595\" ptHeight=\"841\" mmWidth =\"210\" mmHeight=\"297\" inchWidth =\"8.26772\" inchHeight=\"11.6929\" orientation=\"0\" columns=\"1\" ptColumnspc=\"2\" mmColumnspc=\"1\" inchColumnspc=\"0.0393701\" hType=\"0\" fType=\"0\" ptHeadBody=\"9\" ptFootBody=\"9\" mmHeadBody=\"3.5\" mmFootBody=\"3.5\" inchHeadBody=\"0.137795\" inchFootBody=\"0.137795\">\n"
+ " <PAPERBORDERS mmLeft=\"10\" mmTop=\"15\" mmRight=\"10\" mmBottom=\"15\" ptLeft=\"");
+ newstr.append(QString::number(hMargin));
+ newstr.append("\" ptTop=\"");
+ newstr.append(QString::number(vMargin));
+ newstr.append("\" ptRight=\"");
+ newstr.append(QString::number(hMargin));
+ newstr.append("\" ptBottom=\"");
+ newstr.append(QString::number(vMargin));
+ newstr.append("\" inchLeft=\"0.393701\" inchTop=\"0.590551\" inchRight=\"0.393701\" inchBottom=\"0.590551\"/>\n"
+ " </PAPER>\n"
+ " <ATTRIBUTES processing=\"0\" standardpage=\"1\" hasHeader=\"0\" hasFooter=\"0\" unit=\"mm\"/>\n"
+ " <FOOTNOTEMGR>\n"
+ " <START value=\"1\"/>\n"
+ " <FORMAT superscript=\"1\" type=\"1\"/>\n"
+ " <FIRSTPARAG ref=\"(null)\"/>\n"
+ " </FOOTNOTEMGR>\n"
+ " <FRAMESETS>\n");
+ newstr.append(
+ " <FRAMESET frameType=\"1\" frameInfo=\"0\" removeable=\"0\" visible=\"1\">\n"
+ " <FRAME left=\"");
+ newstr.append(QString::number(hMargin));
+ newstr.append("\" top=\"");
+ newstr.append(QString::number(vMargin));
+ newstr.append("\" right=\"");
+ newstr.append(QString::number(width - hMargin));
+ newstr.append("\" bottom=\"");
+ newstr.append(QString::number(height - vMargin));
+ newstr.append("\" runaround=\"1\" runaGapPT=\"2\" runaGapMM=\"1\" runaGapINCH=\"0.0393701\" lWidth=\"1\" lRed=\"255\" lGreen=\"255\" lBlue=\"255\" lStyle=\"0\" rWidth=\"1\" rRed=\"255\" rGreen=\"255\" rBlue=\"255\" rStyle=\"0\" tWidth=\"1\" tRed=\"255\" tGreen=\"255\" tBlue=\"255\" tStyle=\"0\" bWidth=\"1\" bRed=\"255\" bGreen=\"255\" bBlue=\"255\" bStyle=\"0\" bkRed=\"255\" bkGreen=\"255\" bkBlue=\"255\" bleftpt=\"0\" bleftmm=\"0\" bleftinch=\"0\" brightpt=\"0\" brightmm=\"0\" brightinch=\"0\" btoppt=\"0\" btopmm=\"0\" btopinch=\"0\" bbottompt=\"0\" bbottommm=\"0\" bbottominch=\"0");
+ newstr.append("\" autoCreateNewFrame=\"1\" newFrameBehaviour=\"0\"/>\n"
+ " <PARAGRAPH>\n"
+ " <TEXT>");
+ newstr.append("Cannot import OLE streams of type: ");
+ newstr.append(m_oleStreams.join(","));
+ newstr.append("</TEXT>\n"
+ " </PARAGRAPH>\n"
+ " </FRAMESET>\n");
+ newstr.append(
+ " </FRAMESETS>\n"
+ "</DOC>\n");
+ m_part=QDomDocument("doc");
+ m_part.setContent(newstr);
+ m_success=true;
+ m_ready=true;
+ return m_success;
+}
+
+#include <filterbase.moc>
diff --git a/filters/olefilters/lib/filterbase.h b/filters/olefilters/lib/filterbase.h
new file mode 100644
index 00000000..942c3836
--- /dev/null
+++ b/filters/olefilters/lib/filterbase.h
@@ -0,0 +1,109 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 Werner Trobin <[email protected]>
+
+ 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.
+*/
+
+// This class is the base class for all the filters (excel97, powerpoint97,
+// winword97)
+// If you want to write a filter you'll have to derive your class from
+// this one.
+
+#ifndef FILTERBASE_H
+#define FILTERBASE_H
+
+#include <qobject.h>
+#include <qdom.h>
+#include <qstringlist.h>
+
+class myFile;
+class QCString;
+
+// Attention: The nameOUT Strings are allocated with new[] in the
+// slots. Therefore you have to delete [] them!
+// If you call slotGetStream you have to delete [] the
+// stream.data prt after use!
+class FilterBase : public QObject {
+
+ Q_OBJECT
+
+public:
+
+ // Default constructor used by subclasses.
+ FilterBase();
+ // This filter only ever gets used in error cases, when we could not find a
+ // real filter. So, pass in the names of the OLE streams making up the item
+ // item that could not be converted.
+ FilterBase(QStringList &oleStreams);
+ virtual ~FilterBase() {}
+
+ // Manages the filtering process
+ virtual bool filter();
+
+ // override this to return true if you want to return a plain QCString
+ virtual bool plainString() const { return false; }
+ // okay -- let's get the QDomDocument
+ virtual const QDomDocument *const part() { return &m_part; }
+ // or get the plain QCString ;)
+ virtual QCString CString() const { return QCString(); }
+
+signals:
+ // See olefilter.h for information
+ void signalSaveDocumentInformation(
+ const QString &fullName,
+ const QString &title,
+ const QString &company,
+ const QString &email,
+ const QString &telephone,
+ const QString &fax,
+ const QString &postalCode,
+ const QString &country,
+ const QString &city,
+ const QString &street,
+ const QString &docTitle,
+ const QString &docAbstract);
+ void signalSavePic(
+ const QString &nameIN,
+ QString &storageId,
+ const QString &extension,
+ unsigned int length,
+ const char *data);
+ void signalSavePart(
+ const QString &nameIN,
+ QString &storageId,
+ QString &mimeType,
+ const QString &extension,
+ unsigned int length,
+ const char *data);
+ void signalPart(const QString& nameIN, QString &storageId, QString &mimeType);
+ void signalGetStream(const int &handle, myFile &stream);
+ // Note: might return wrong stream as names are NOT unique!!!
+ // (searching only in current dir)
+ void signalGetStream(const QString &name, myFile &stream);
+ void sigProgress(int value);
+
+protected:
+ bool m_success; // ok, the filtering process was successful
+ bool m_ready; // filtering took place, you may fetch the file now
+ QDomDocument m_part; // this represents the part (document)
+
+private:
+ // Don't copy or assign me...
+ FilterBase(const FilterBase &);
+ const FilterBase &operator=(const FilterBase &);
+ QStringList m_oleStreams;
+};
+#endif // FILTERBASE_H
diff --git a/filters/olefilters/lib/klaola.cc b/filters/olefilters/lib/klaola.cc
new file mode 100644
index 00000000..69d5284e
--- /dev/null
+++ b/filters/olefilters/lib/klaola.cc
@@ -0,0 +1,579 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 Werner Trobin <[email protected]>
+
+ 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 <klaola.h>
+#include <kdebug.h>
+
+const int KLaola::s_area = 30510;
+
+KLaola::KLaola(const myFile &file) {
+
+ smallBlockDepot=0L;
+ bigBlockDepot=0L;
+ smallBlockFile=0L;
+ bbd_list=0L;
+ ok=true;
+ m_nodeList.setAutoDelete(true);
+ //m_currentPath.setAutoDelete(true);
+
+ if( (file.length % 0x200) != 0 ) {
+ kdError(s_area) << "KLaola::KLaola(): Invalid file size!" << endl;
+ ok=false;
+ }
+ if(ok) {
+ m_file=file;
+ maxblock = file.length / 0x200 - 2;
+ maxSblock=0; // will be set in readSmallBlockDepot
+
+ if(!parseHeader())
+ ok=false;
+ if(ok) {
+ readBigBlockDepot();
+ readSmallBlockDepot();
+ readSmallBlockFile();
+ readRootList();
+ }
+ }
+ m_currentPath.clear();
+ testIt();
+
+ // current path=root dirHandle
+ m_currentPath.clear();
+ if ( !m_nodeTree.isEmpty() )
+ m_currentPath.append(m_nodeTree.getFirst()->getFirst()->node);
+}
+
+KLaola::~KLaola() {
+
+ delete [] bigBlockDepot;
+ bigBlockDepot=0L;
+ delete [] smallBlockDepot;
+ smallBlockDepot=0L;
+ delete [] smallBlockFile;
+ smallBlockFile=0L;
+ delete [] bbd_list;
+ bbd_list=0L;
+}
+
+// Comvert the given list of nodes into a tree.
+void KLaola::createTree(const int handle, const short index) {
+
+ Node *node = dynamic_cast<Node *>(m_nodeList.at(handle));
+ SubTree *subtree;
+
+ TreeNode *tree=new TreeNode;
+ tree->node=node;
+ tree->subtree=-1;
+
+ //QString nix="### entering create tree: handle=";
+ //nix+=QString::number(handle);
+ //nix+=" index=";
+ //nix+=QString::number(index);
+ //kdDebug(s_area) << nix << endl;
+
+ if(node->prevHandle!=-1) {
+ //kdDebug(s_area) << "create tree: prevHandle" << endl;
+ createTree(node->prevHandle, index);
+ }
+ if(node->dirHandle!=-1) {
+ subtree=new SubTree;
+ subtree->setAutoDelete(true);
+ m_nodeTree.append(subtree);
+ tree->subtree=m_nodeTree.at();
+ //kdDebug(s_area) << "create tree: dirHandle" << endl;
+ createTree(node->dirHandle, tree->subtree);
+ }
+ subtree=m_nodeTree.at(index);
+ //kdDebug(s_area) << "create tree: APPEND " << handle << " tree node " << tree << endl;
+ subtree->append(tree);
+ if(node->nextHandle!=-1) {
+ //kdDebug(s_area) << "create tree: nextHandle" << endl;
+ createTree(node->nextHandle, index);
+ }
+}
+
+const KLaola::NodeList KLaola::currentPath() const {
+ return m_currentPath;
+}
+
+bool KLaola::enterDir(const OLENode *dirHandle) {
+
+ NodeList nodes;
+ Node *node;
+
+ if(ok) {
+ nodes = parseCurrentDir();
+ for (node = dynamic_cast<Node *>(nodes.first()); node; node = dynamic_cast<Node *>(nodes.next()))
+ {
+ if(node->m_handle==dirHandle->handle() && node->isDirectory() && !node->deadDir) {
+ m_currentPath.append(node);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+const KLaola::NodeList KLaola::find(const QString &name, bool onlyCurrentDir) {
+
+ OLENode *node;
+ NodeList ret;
+ int i=0;
+
+ if(ok) {
+ if(!onlyCurrentDir) {
+ for(node=m_nodeList.first(); node; node=m_nodeList.next()) {
+ if(node->name()==name) {
+ ret.append(node);
+ ++i;
+ }
+ }
+ }
+ else {
+ NodeList list=parseCurrentDir();
+
+ for(node=list.first(); node; node=list.next()) {
+ if(node->name()==name) {
+ ret.append(node);
+ ++i;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+bool KLaola::leaveDir() {
+
+ if (ok) {
+ return m_currentPath.removeLast();
+ }
+ return false;
+}
+
+int KLaola::nextBigBlock(int pos) const
+{
+
+ int x=pos*4;
+ return ( (bigBlockDepot[x+3] << 24) + (bigBlockDepot[x+2] << 16) +
+ (bigBlockDepot[x+1] << 8) + bigBlockDepot[x] );
+}
+
+int KLaola::nextSmallBlock(int pos) const
+{
+
+ if(smallBlockDepot) {
+ int x=pos*4;
+ return ( (smallBlockDepot[x+3] << 24) + (smallBlockDepot[x+2] << 16) +
+ (smallBlockDepot[x+1] << 8) + smallBlockDepot[x] );
+ }
+ else
+ return -2; // Emergency Break :)
+}
+
+bool KLaola::parseHeader() {
+
+ if(qstrncmp((const char*)m_file.data,"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1",8 )!=0) {
+ kdError(s_area) << "KLaola::parseHeader(): Invalid file format (unexpected id in header)!" << endl;
+ return false;
+ }
+
+ num_of_bbd_blocks=read32(0x2c);
+ root_startblock=read32(0x30);
+ sbd_startblock=read32(0x3c);
+
+ if (num_of_bbd_blocks >= 0x800000) {
+ kdError(s_area) << "KLaola::parseHeader(): Too many bbd blocks found in header!" << endl;
+ return false;
+ }
+ bbd_list=new unsigned int[num_of_bbd_blocks];
+
+ unsigned int i, j;
+ for(i=0, j=0; i<num_of_bbd_blocks; ++i, j=j+4) {
+ bbd_list[i]=read32(0x4c+j);
+ if (bbd_list[i] >= (0x800000 - 1)) {
+ kdError(s_area) << "KLaola::parseHeader(): bbd " << i << " offset (" << bbd_list[i] << ") too large" << endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+KLaola::NodeList KLaola::parseCurrentDir() {
+
+ Node *node;
+ SubTree *subtree;
+ NodeList nodeList;
+ TreeNode *treeNode;
+ unsigned int i;
+ bool found;
+
+ if(ok) {
+ for(i=0, subtree=m_nodeTree.first(); i<m_currentPath.count(); ++i) {
+ treeNode=subtree->first();
+ found=false;
+ do {
+ if(treeNode==0) {
+ kdError(s_area) << "KLaola::parseCurrentDir(): path seems to be corrupted!" << endl;
+ ok=false;
+ }
+ else if(treeNode->node->handle()==m_currentPath.at(i)->handle() && treeNode->subtree!=-1) {
+ found=true;
+ }
+ else
+ treeNode=subtree->next();
+ } while(!found && ok);
+ subtree=m_nodeTree.at(treeNode->subtree);
+ }
+ }
+ if(ok) {
+ for(treeNode=subtree->first(); treeNode!=0; treeNode=subtree->next()) {
+ node=new Node(*treeNode->node);
+ node->deadDir = (node->dirHandle==-1 && node->isDirectory());
+ // this is a strange situation :)
+ if (node->deadDir)
+ kdDebug(s_area) << "ignoring: " << node->describe() << " is empty" << endl;
+ else
+ nodeList.append(node);
+ }
+ }
+ return nodeList;
+}
+
+KLaola::NodeList KLaola::parseRootDir() {
+
+ NodeList tmpNodeList;
+ NodeList tmp;
+
+ if(ok) {
+ tmp=m_currentPath;
+ m_currentPath.clear(); // current path=root dirHandle
+ m_currentPath.append(m_nodeTree.getFirst()->getFirst()->node);
+ tmpNodeList=parseCurrentDir();
+ m_currentPath=tmp;
+ }
+ return tmpNodeList;
+}
+
+unsigned char KLaola::read8(int i) const
+{
+ return m_file.data[i];
+}
+
+unsigned short KLaola::read16(int i) const
+{
+ return ( (m_file.data[i+1] << 8) + m_file.data[i] );
+}
+
+unsigned int KLaola::read32(int i) const
+{
+ return ( (read16(i+2) << 16) + read16(i) );
+}
+
+const unsigned char *KLaola::readBBStream(int start, bool setmaxSblock)
+{
+
+ int i=0, tmp;
+ unsigned char *p=0;
+
+ tmp=start;
+ /* 0x10000 chosen as arbitrary "too many blocks" limit to not loop forver */
+ while(tmp!=-2 && tmp>=0 && i<0x10000 && tmp<=static_cast<int>(maxblock)) {
+ ++i;
+ tmp=nextBigBlock(tmp);
+ }
+ if(i!=0) {
+ p=new unsigned char[i*0x200];
+ if(setmaxSblock)
+ maxSblock=i*8-1;
+ i=0;
+ tmp=start;
+ while(tmp!=-2 && tmp>=0 && i<0x10000 && tmp<=static_cast<int>(maxblock)) {
+ memcpy(&p[i*0x200], &m_file.data[(tmp+1)*0x200], 0x200);
+ tmp=nextBigBlock(tmp);
+ ++i;
+ }
+ }
+ return p;
+}
+
+const unsigned char *KLaola::readSBStream(int start) const {
+
+ int i=0, tmp;
+ unsigned char *p=0;
+
+ tmp=start;
+ /* 0x10000 chosen as arbitrary "too many blocks" limit to not loop forver */
+ while(tmp!=-2 && tmp>=0 && i<0x10000 && tmp<=static_cast<int>(maxSblock)) {
+ ++i;
+ tmp=nextSmallBlock(tmp);
+ }
+ if(i!=0) {
+ p=new unsigned char[i*0x40];
+ i=0;
+ tmp=start;
+ while(tmp!=-2 && tmp>=0 && i<0x10000 && tmp<=static_cast<int>(maxSblock)) {
+ memcpy(&p[i*0x40], &smallBlockFile[tmp*0x40], 0x40);
+ tmp=nextSmallBlock(tmp);
+ ++i;
+ }
+ }
+ return p;
+}
+
+void KLaola::readBigBlockDepot() {
+ if (num_of_bbd_blocks >= 0x800000)
+ return;
+
+ bigBlockDepot=new unsigned char[0x200*num_of_bbd_blocks];
+ for(unsigned int i=0; i<num_of_bbd_blocks; ++i) {
+ unsigned int offset = (bbd_list[i]+1)*0x200;
+ if (offset > m_file.length - 0x200) {
+ /* attempting to read past end of file */
+ memset(&bigBlockDepot[i*0x200], 0, 0x200);
+ }
+ else {
+ memcpy(&bigBlockDepot[i*0x200], &m_file.data[offset], 0x200);
+ }
+ }
+}
+
+void KLaola::readSmallBlockDepot() {
+ smallBlockDepot=const_cast<unsigned char*>(readBBStream(sbd_startblock));
+}
+
+void KLaola::readSmallBlockFile() {
+ smallBlockFile=const_cast<unsigned char*>(readBBStream( read32( (root_startblock+1)*0x200 + 0x74), true));
+}
+
+void KLaola::readRootList() {
+
+ int pos=root_startblock;
+ int handle=0;
+
+ while(pos!=-2 && pos>=0 && pos<=static_cast<int>(maxblock)) {
+ for(int i=0; i<4; ++i, ++handle)
+ readPPSEntry((pos+1)*0x200+0x80*i, handle);
+ pos=nextBigBlock(pos);
+ }
+ SubTree *subtree=new SubTree;
+ subtree->setAutoDelete(true);
+ m_nodeTree.append(subtree);
+
+ createTree(0, 0); // build the tree with a recursive method :)
+}
+
+// Add the given OLE node to the list of nodes.
+void KLaola::readPPSEntry(int pos, const int handle) {
+
+ int nameSize = read16(pos + 0x40);
+
+ // Does the PPS Entry seem to be valid?
+
+ if (nameSize)
+ {
+ int i;
+ Node *node = new Node(this);
+
+ // The first character of the name can be a prefix.
+ node->m_prefix = static_cast<Prefix>(read16(pos));
+ if (node->m_prefix <= RESERVED_LAST)
+ {
+ i = 1;
+ }
+ else
+ {
+ node->m_prefix = NONE;
+ i = 0;
+ }
+
+ // Get the rest of the name.
+ for (; i < (nameSize / 2) - 1; ++i)
+ {
+ QChar tmp;
+
+ tmp = read16(pos + 2 * i);
+ node->m_name += tmp;
+ }
+ node->m_handle = handle;
+ node->type = static_cast<NodeType>(read8(pos + 0x42));
+ node->prevHandle = static_cast<int>(read32(pos + 0x44));
+ node->nextHandle = static_cast<int>(read32(pos + 0x48));
+ node->dirHandle = static_cast<int>(read32(pos + 0x4C));
+ node->ts1s = static_cast<int>(read32(pos + 0x64));
+ node->ts1d = static_cast<int>(read32(pos + 0x68));
+ node->ts2s = static_cast<int>(read32(pos + 0x6C));
+ node->ts2d = static_cast<int>(read32(pos + 0x70));
+ node->sb = read32(pos + 0x74);
+ node->size = read32(pos + 0x78);
+ node->deadDir = false;
+ m_nodeList.append(node);
+ }
+}
+
+myFile KLaola::stream(const OLENode *node) {
+
+ const Node *realNode = dynamic_cast<const Node *>(node);
+ const unsigned char *temp;
+ myFile ret;
+
+ if(ok) {
+ if(realNode->size>=0x1000)
+ temp = readBBStream(realNode->sb);
+ else
+ temp = readSBStream(realNode->sb);
+ ret.setRawData(temp, realNode->size);
+ }
+ return ret;
+}
+
+myFile KLaola::stream(unsigned handle) {
+
+ OLENode *node;
+
+ node = m_nodeList.at(handle);
+ return stream(node);
+}
+
+void KLaola::testIt(QString prefix)
+{
+
+ NodeList nodes;
+ OLENode *node;
+
+ nodes = parseCurrentDir();
+ for (node = nodes.first(); node; node = nodes.next())
+ {
+ kdDebug(s_area) << prefix + node->describe() << endl;
+ if (node->isDirectory())
+ {
+ enterDir(node);
+ testIt(prefix + " ");
+ }
+ }
+}
+
+// Return a human-readable description of a stream.
+QString KLaola::Node::describe() const
+{
+ QString description;
+ myFile file;
+ unsigned i;
+
+ description = QString::number(m_handle) + " " +
+ m_name + "(" +
+ QString::number(sb) + " " +
+ QString::number(size) + " bytes)";
+ if (isDirectory())
+ description += ", directory";
+ switch (m_prefix)
+ {
+ case OLE_MANAGED_0:
+ description += ", OLE_0";
+ break;
+ case CLSID:
+ description += ", CLSID=";
+ description += readClassStream();
+ file = m_laola->stream(this);
+ description += ", ";
+ for (i = 16; i < file.length; i++)
+ {
+ description += QString::number((file.data[i] >> 4) & 0xf, 16);
+ description += QString::number(file.data[i] & 0xf, 16);
+ }
+ description += ", ";
+ for (i = 16; i < file.length; i++)
+ {
+ QChar tmp = file.data[i];
+
+ if (tmp.isPrint())
+ description += tmp;
+ else
+ description += '.';
+ }
+ break;
+ case OLE_MANAGED_2:
+ description += ", OLE_2";
+ break;
+ case PARENT_MANAGED:
+ description += ", parent managed";
+ break;
+ case STRUCTURED_STORAGE:
+ description += ", reserved 0x" + QString::number(m_prefix, 16);
+ break;
+ case NONE:
+ break;
+ default:
+ description += ", reserved 0x" + QString::number(m_prefix, 16);
+ break;
+ }
+ return description;
+}
+
+QString KLaola::Node::name() const
+{
+ return m_name;
+}
+
+// See "Associating Code with Storage" in Inside OLE.
+QString KLaola::Node::readClassStream() const
+{
+ if (isDirectory())
+ return QString::null;
+ if (m_prefix == CLSID)
+ {
+ myFile file;
+ unsigned i;
+ QString clsid;
+
+ // CLSID format is: 00020900-0000-0000-C000-000000000046
+ file = m_laola->stream(this);
+ for (i = 0; i < 4; i++)
+ {
+ clsid += QString::number((file.data[i] >> 4) & 0xf, 16);
+ clsid += QString::number(file.data[i] & 0xf, 16);
+ }
+ clsid += '-';
+ for (; i < 6; i++)
+ {
+ clsid += QString::number((file.data[i] >> 4) & 0xf, 16);
+ clsid += QString::number(file.data[i] & 0xf, 16);
+ }
+ clsid += '-';
+ for (; i < 8; i++)
+ {
+ clsid += QString::number((file.data[i] >> 4) & 0xf, 16);
+ clsid += QString::number(file.data[i] & 0xf, 16);
+ }
+ clsid += '-';
+ for (; i < 10; i++)
+ {
+ clsid += QString::number((file.data[i] >> 4) & 0xf, 16);
+ clsid += QString::number(file.data[i] & 0xf, 16);
+ }
+ clsid += '-';
+ for (; i < 16; i++)
+ {
+ clsid += QString::number((file.data[i] >> 4) & 0xf, 16);
+ clsid += QString::number(file.data[i] & 0xf, 16);
+ }
+ return clsid;
+ }
+ return QString::null;
+}
diff --git a/filters/olefilters/lib/klaola.h b/filters/olefilters/lib/klaola.h
new file mode 100644
index 00000000..816a7666
--- /dev/null
+++ b/filters/olefilters/lib/klaola.h
@@ -0,0 +1,193 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 Werner Trobin <[email protected]>
+
+ 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.
+
+DESCRIPTION
+
+ This class is used to decode OLE 2 streams. When instantiated, it
+ constructs an internal "filesystem" that corresponds to the OLE storage
+ tree. This tree can be navigated, and the individual OLE streams
+ returned as a linear memory buffer.
+*/
+
+#ifndef KLAOLA_H
+#define KLAOLA_H
+
+#include <myfile.h>
+#include <qstring.h>
+#include <qptrlist.h>
+
+class KLaola {
+
+public:
+ KLaola(const myFile &file); // see myfile.h!
+ ~KLaola();
+
+ bool isOk() {return ok;}
+
+ // A class representing an abstracted node in the OLE filesystem.
+
+ class OLENode {
+ public:
+ virtual ~OLENode() {};
+ virtual unsigned handle() const = 0;
+ virtual QString name() const = 0;
+
+ // Does the node represent a stream datum, or a storage container
+ // of data?
+ virtual bool isDirectory() const = 0;
+
+ // If isDirectory() is true, return the CLSID associated with
+ // any child CompObj node. If the Node is a CompObj, return
+ // its CLSID. Otherwise return QString::null.
+ //
+ // The CLSID is returned in the form:
+ //
+ // 00020900-0000-0000-C000-000000000046
+ //
+ virtual QString readClassStream() const = 0;
+
+ // Return a human-readable description of a stream.
+ virtual QString describe() const = 0;
+ protected:
+ OLENode() {}
+ };
+
+ // Wade through the "file system"
+
+ typedef QPtrList<OLENode> NodeList;
+ NodeList parseRootDir();
+ NodeList parseCurrentDir();
+ const NodeList currentPath() const;
+ const NodeList find(const QString &name, bool onlyCurrentDir=false);
+ bool enterDir(const OLENode *node);
+ bool leaveDir();
+
+ // Return the stream for a given node.
+ //
+ // Note: data - 512 byte blocks, but length is set correctly :)
+ myFile stream(const OLENode *node);
+ myFile stream(unsigned handle);
+
+private:
+ KLaola(const KLaola &);
+ const KLaola &operator=(const KLaola &);
+ static const int s_area;
+
+ unsigned char read8(int i) const;
+ unsigned short read16(int i) const;
+ unsigned int read32(int i) const;
+
+ // Parsing functions.
+ bool parseHeader();
+ void readBigBlockDepot();
+ void readSmallBlockDepot();
+ void readSmallBlockFile();
+ void readRootList();
+ void readPPSEntry(int pos, const int handle);
+ void createTree(const int handle, const short index);
+ const unsigned char *readBBStream(int start, bool setmaxSblock=false);
+ const unsigned char *readSBStream(int start) const;
+ int nextBigBlock(int pos) const;
+ int nextSmallBlock(int pos) const;
+
+ // Dump the parsed structure info (similar to "lls"
+ // of the LAOLA-project).
+ void testIt(QString prefix = "");
+
+public:
+ typedef enum
+ {
+ DIRECTORY = 1,
+ FILE = 2,
+ ROOT_ENTRY = 5
+ } NodeType;
+
+ // If the first part of an on-disk name is less than 32, it is a prefix.
+ typedef enum
+ {
+ OLE_MANAGED_0,
+ CLSID,
+ OLE_MANAGED_2,
+ PARENT_MANAGED, // Marks an element as owned by the code that
+ // manages the parent storage of that element.
+ STRUCTURED_STORAGE, // For the exclusive use of the Structured Storage
+ // implementation.
+ RESERVED_FIRST,
+ RESERVED_LAST = 31,
+ NONE = 32
+ } Prefix;
+
+ class Node: public OLENode {
+ public:
+ Node(KLaola *laola) { m_laola = laola; }
+ ~Node() {}
+ unsigned handle() const { return m_handle; }
+ QString name() const;
+ bool isDirectory() const { return (type == DIRECTORY) || (type == ROOT_ENTRY); }
+ QString readClassStream() const;
+ QString describe() const;
+
+ KLaola *m_laola;
+ unsigned m_handle; // PPS entry number
+ Prefix m_prefix;
+ QString m_name;
+ NodeType type;
+ int prevHandle; // Last pps
+ int nextHandle; // Next pps
+ int dirHandle; // Dir pps
+ int ts1s; // Timestamp 1, seconds
+ int ts1d; // Timestamp 1, days
+ int ts2s; // Timestamp 2, seconds
+ int ts2d; // Timestamp 2, days
+ unsigned sb; // Starting block
+ unsigned size; // Size of property
+ bool deadDir; // true, if the dir is a "dead end"
+ };
+
+private:
+ // Lists of nodes.
+
+ NodeList m_nodeList;
+ NodeList m_currentPath;
+
+ // The OLE storage is represented as a tree. Each node in the tree may
+ // refer to a subtree. Each subtree is stored as a list of nodes.
+
+ struct TreeNode
+ {
+ Node *node;
+ short subtree;
+ };
+ typedef QPtrList<TreeNode> SubTree;
+ QPtrList<SubTree> m_nodeTree;
+
+ bool ok; // is the file OK?
+
+ myFile m_file;
+ unsigned char *bigBlockDepot;
+ unsigned char *smallBlockDepot;
+ unsigned char *smallBlockFile;
+
+ unsigned int maxblock; // maximum number of big-blocks
+ unsigned int maxSblock; // small-blocks
+ unsigned int num_of_bbd_blocks; // number of big block depot blocks
+ unsigned int root_startblock; // Root chain's first big block
+ unsigned int sbd_startblock; // small block depot's first big block
+ unsigned int *bbd_list; //array of num_of_bbd_blocks big block numbers
+};
+#endif // KLAOLA_H
diff --git a/filters/olefilters/lib/myfile.h b/filters/olefilters/lib/myfile.h
new file mode 100644
index 00000000..7be578b3
--- /dev/null
+++ b/filters/olefilters/lib/myfile.h
@@ -0,0 +1,49 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 Werner Trobin <[email protected]>
+
+ 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.
+
+DESCRIPTION
+
+ A data-structure to hold the file data for an OLE stream. Shared storage is
+ used to implement reference counting and storage reclamation.
+*/
+
+#ifndef MYFILE_H
+#define MYFILE_H
+
+#include <qcstring.h>
+
+class myFile: public QByteArray
+{
+public:
+ myFile() { data = 0L; length = 0; }
+
+ // NOTE: this implementation may look completely ugly, but its features are
+ // mostly for backwards compatibility. If you feel like cleaning up, be my
+ // guest!
+
+ const unsigned char *data;
+ unsigned int length;
+
+ void setRawData(const unsigned char *data, unsigned length)
+ {
+ this->data = data;
+ this->length = length;
+ QByteArray::setRawData((const char *)data, length);
+ }
+};
+#endif // MYFILE_H