Commit c394549b authored by Piotr Szymanski's avatar Piotr Szymanski
Browse files

- reusing code from KCHHViewer, contains a small wrapper around chmlib and a...

- reusing code from KCHHViewer, contains a small wrapper around chmlib and a better version of kio-msits then the one from kdevelop, added minor modifications by myself so that they can be used in oKular, also stripped the library of unneeded stuff

svn path=/trunk/playground/graphics/oKular/kpdf/; revision=450783
parent e73e14bb
METASOURCES = AUTO
INCLUDES = $(QT_INCLUDES) -I$(CHM_INCLUDES) $(KDE_INCLUDES)
kde_module_LTLIBRARIES = kio_msits.la
kio_msits_la_SOURCES = msits.cpp
kio_msits_la_LIBADD = -lkio -lchm
kio_msits_la_LDFLAGS = -module -avoid-version $(QT_LIBS) $(KDE_LDFLAGS) $(KDE_LIBS) $(KDE_PLUGIN)
protocol_DATA = msits.protocol
protocoldir = $(kde_servicesdir)
/* 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., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kinstance.h>
#include <kurl.h>
#include <kmimemagic.h>
#include <qfile.h>
#include <qbitarray.h>
#include <qvaluevector.h>
#include "msits.h"
using namespace KIO;
extern "C"
{
int kdemain( int argc, char **argv )
{
kdDebug() << "*** kio_msits Init" << endl;
KInstance instance( "kio_msits" );
if ( argc != 4 )
{
kdDebug() << "Usage: kio_msits protocol domain-socket1 domain-socket2" << endl;
exit (-1);
}
ProtocolMSITS slave ( argv[2], argv[3] );
slave.dispatchLoop();
kdDebug() << "*** kio_msits Done" << endl;
return 0;
}
}
ProtocolMSITS::ProtocolMSITS (const QCString &pool_socket, const QCString &app_socket)
: SlaveBase ("kio_msits", pool_socket, app_socket)
{
m_chmFile = 0;
}
ProtocolMSITS::~ProtocolMSITS()
{
if ( !m_chmFile )
return;
chm_close (m_chmFile);
m_chmFile = 0;
}
// A simple stat() wrapper
static bool isDirectory ( const QString & filename )
{
return filename[filename.length() - 1] == '/';
}
void ProtocolMSITS::get( const KURL& url )
{
QString fileName;
chmUnitInfo ui;
kdDebug() << "kio_msits::get() " << url.path() << endl;
if ( !parseLoadAndLookup ( url, fileName ) )
return; // error() has been called by parseLoadAndLookup
kdDebug() << "kio_msits::get: parseLoadAndLookup returned " << fileName << endl;
if ( isDirectory (fileName) )
{
error( KIO::ERR_IS_DIRECTORY, url.prettyURL() );
return;
}
if ( !ResolveObject ( fileName, &ui) )
{
kdDebug() << "kio_msits::get: could not resolve filename " << fileName << endl;
error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
return;
}
QByteArray buf (ui.length);
if ( RetrieveObject (&ui, (unsigned char*) buf.data(), 0, ui.length) == 0 )
{
kdDebug() << "kio_msits::get: could not retrieve filename " << fileName << endl;
error( KIO::ERR_NO_CONTENT, url.prettyURL() );
return;
}
totalSize( ui.length );
KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( buf, fileName );
kdDebug() << "Emitting mimetype " << result->mimeType() << endl;
mimeType( result->mimeType() );
data( buf );
processedSize( ui.length );
finished();
}
bool ProtocolMSITS::parseLoadAndLookup ( const KURL& url, QString& abspath )
{
kdDebug() << "ProtocolMSITS::parseLoadAndLookup (const KURL&) " << url.path() << endl;
int pos = url.path().find ("::");
if ( pos == -1 )
{
error( KIO::ERR_MALFORMED_URL, url.prettyURL() );
return false;
}
QString filename = url.path().left (pos);
abspath = url.path().mid (pos + 2); // skip ::
kdDebug() << "ProtocolMSITS::parseLoadAndLookup: filename " << filename << ", path " << abspath << endl;
if ( filename.isEmpty() )
{
error( KIO::ERR_MALFORMED_URL, url.prettyURL() );
return false;
}
// If the file has been already loaded, nothing to do.
if ( m_chmFile && filename == m_openedFile )
return true;
kdDebug() << "Opening a new CHM file " << filename << endl;
// First try to open a temporary file
chmFile * tmpchm;
if ( (tmpchm = chm_open ( QFile::encodeName (filename))) == 0 )
{
error( KIO::ERR_COULD_NOT_READ, url.prettyURL() );
return false;
}
// Replace an existing file by a new one
if ( m_chmFile )
chm_close (m_chmFile);
m_chmFile = tmpchm;
m_openedFile = filename;
kdDebug() << "A CHM file " << filename << " has beed opened successfully" << endl;
return true;
}
/*
* Shamelessly stolen from a KDE KIO tutorial
*/
static void app_entry(UDSEntry& e, unsigned int uds, const QString& str)
{
UDSAtom a;
a.m_uds = uds;
a.m_str = str;
e.append(a);
}
// appends an int with the UDS-ID uds
static void app_entry(UDSEntry& e, unsigned int uds, long l)
{
UDSAtom a;
a.m_uds = uds;
a.m_long = l;
e.append(a);
}
// internal function
// fills a directory item with its name and size
static void app_dir(UDSEntry& e, const QString & name)
{
e.clear();
app_entry(e, KIO::UDS_NAME, name);
app_entry(e, KIO::UDS_FILE_TYPE, S_IFDIR);
app_entry(e, KIO::UDS_SIZE, 1);
}
// internal function
// fills a file item with its name and size
static void app_file(UDSEntry& e, const QString & name, size_t size)
{
e.clear();
app_entry(e, KIO::UDS_NAME, name);
app_entry(e, KIO::UDS_FILE_TYPE, S_IFREG);
app_entry(e, KIO::UDS_SIZE, size);
}
void ProtocolMSITS::stat (const KURL & url)
{
QString fileName;
chmUnitInfo ui;
kdDebug() << "kio_msits::stat (const KURL& url) " << url.path() << endl;
if ( !parseLoadAndLookup ( url, fileName ) )
return; // error() has been called by parseLoadAndLookup
if ( !ResolveObject ( fileName, &ui ) )
{
error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
return;
}
kdDebug() << "kio_msits::stat: adding an entry for " << fileName << endl;
UDSEntry entry;
if ( isDirectory ( fileName ) )
app_dir(entry, fileName);
else
app_file(entry, fileName, ui.length);
statEntry (entry);
finished();
}
// A local CHMLIB enumerator
static int chmlib_enumerator (struct chmFile *, struct chmUnitInfo *ui, void *context)
{
((QValueVector<QString> *) context)->push_back (QString::fromLocal8Bit (ui->path));
return CHM_ENUMERATOR_CONTINUE;
}
void ProtocolMSITS::listDir (const KURL & url)
{
QString filepath;
kdDebug() << "kio_msits::listDir (const KURL& url) " << url.path() << endl;
if ( !parseLoadAndLookup ( url, filepath ) )
return; // error() has been called by parseLoadAndLookup
filepath += "/";
if ( !isDirectory (filepath) )
{
error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path());
return;
}
kdDebug() << "kio_msits::listDir: enumerating directory " << filepath << endl;
QValueVector<QString> listing;
if ( chm_enumerate_dir ( m_chmFile,
filepath.local8Bit(),
CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES | CHM_ENUMERATE_DIRS,
chmlib_enumerator,
&listing ) != 1 )
{
error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path());
return;
}
// totalFiles(listing.size());
UDSEntry entry;
unsigned int striplength = filepath.length();
for ( unsigned int i = 0; i < listing.size(); i++ )
{
// Strip the direcroty name
QString ename = listing[i].mid (striplength);
if ( isDirectory ( ename ) )
app_dir(entry, ename);
else
app_file(entry, ename, 0);
listEntry(entry, false);
}
listEntry(entry, true);
finished();
}
/***************************************************************************
* Copyright (C) 2005 by Georgy Yunaev *
* tim@krasnogorsk.ru *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef MSITS_H
#define MSITS_H
//#include <kio/global.h>
#include <kio/slavebase.h>
#include <kurl.h>
#include <qstring.h>
#include <qcstring.h>
#include "chm_lib.h"
class ProtocolMSITS : public KIO::SlaveBase
{
public:
ProtocolMSITS ( const QCString&, const QCString& );
virtual ~ProtocolMSITS();
virtual void get ( const KURL& );
virtual void listDir (const KURL & url);
virtual void stat (const KURL & url);
private:
// This function does next thing:
// - parses the URL to get a file name and URL inside the file;
// - loads a new CHM file, if needed;
// - returns the parsed URL inside the file;
bool parseLoadAndLookup ( const KURL&, QString& abspath );
// Resolve an object inside a CHM file
inline bool ResolveObject (const QString& fileName, chmUnitInfo *ui)
{
return m_chmFile != NULL && ::chm_resolve_object(m_chmFile, fileName.ascii(), ui) == CHM_RESOLVE_SUCCESS;
}
// Retrieve an object from the CHM file
inline size_t RetrieveObject (chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize)
{
return ::chm_retrieve_object(m_chmFile, ui, buffer, fileOffset, bufferSize);
}
// An opened file name, if presend
QString m_openedFile;
// a CHM structure file pointer (from chmlib)
chmFile * m_chmFile;
};
#endif /* MSITS_H */
[Protocol]
exec=kio_msits
protocol=ms-its
input=none
output=filesystem
reading=true
listing=Name,Type,Size
defaultMimetype=text/html
Description=A kioslave for displaying WinHelp files
Description[da]=En kioslave til visning af Windows hjælpefiler
Description[de]=Ein Ein-/Ausgabemodul zur Anzeige von WinHelp-Dateien
Description[es]=Un kioslave para mostrar archivos WinHelp
Description[et]=WinHelp-failide kuvamise IO-moodul
Description[fr]=Un module d'entrée / sortie pour l'affichage des fichiers WinHelp
Description[hu]=KDE-protokoll WinHelp-fájlok megjelenítéséhez
Description[it]=Un kioslave per mostrare i file WinHelp
Description[nl]=Een kioslave voor het weergeven van WinHelp-bestanden
Description[pl]=kioslave do pokazywania plików WinHelp
Description[pt]=A 'kioslave' para mostrar ficheiros WinHelp
Description[pt_BR]=Um kioslave para exibir arquivos WinHelp
Description[ru]=Обработчик ввода-вывода для файлов WinHelp
Description[sv]=En I/O-slav för att visa WinHelp-filer
Description[xx]=xxA kioslave for displaying WinHelp filesxx
Icon=help
noinst_LTLIBRARIES = libchmfile.la
INCLUDES = -I$(srcdir)/../.. -I$(top_builddir)/kpdf $(all_includes)
libchmfile_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -lqt-mt -lchm
libchmfile_la_LIBADD = $(LIB_KDEUI) $(LIB_KIO)
libchmfile_la_SOURCES = kchmtextencoding.cpp xchmfile.cpp iconstorage.cpp kchmurl.cpp
/*
Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net>
Most of the code in this file is a modified version of code from
Pabs' GPL chmdeco project, credits and thanks go to him.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//#define FIXENDIAN16(x) (x = wxUINT16_SWAP_ON_BE(x))
//#define FIXENDIAN32(x) (x = wxUINT32_SWAP_ON_BE(x))
#define FIXENDIAN16(x)
#define FIXENDIAN32(x)
#define UINT16ARRAY(x) ((unsigned char)(x)[0] | ((u_int16_t)(x)[1] << 8))
#define UINT32ARRAY(x) (UINT16ARRAY(x) | ((u_int32_t)(x)[2] << 16) \
| ((u_int32_t)(x)[3] << 24))
inline u_int64_t be_encint(unsigned char* buffer, size_t& length)
{
u_int64_t result = 0;
int shift=0;
length = 0;
do {
result |= ((*buffer) & 0x7f) << shift;
shift += 7;
++length;
} while (*(buffer++) & 0x80);
return result;
}
/*
Finds the first unset bit in memory. Returns the number of set bits found.
Returns -1 if the buffer runs out before we find an unset bit.
*/
inline int ffus(unsigned char* byte, int* bit, size_t& length)
{
int bits = 0;
length = 0;
while(*byte & (1 << *bit)){
if(*bit)
--(*bit);
else {
++byte;
++length;
*bit = 7;
}
++bits;
}
if(*bit)
--(*bit);
else {
++length;
*bit = 7;
}
return bits;
}
inline u_int64_t sr_int(unsigned char* byte, int* bit,
unsigned char s, unsigned char r, size_t& length)
{
u_int64_t ret;
unsigned char mask;
int n, n_bits, num_bits, base, count;
length = 0;
size_t fflen;
if(!bit || *bit > 7 || s != 2)
return ~(u_int64_t)0;
ret = 0;
count = ffus(byte, bit, fflen);
length += fflen;
byte += length;
n_bits = n = r + (count ? count-1 : 0) ;
while(n > 0) {
num_bits = n > *bit ? *bit : n-1;
base = n > *bit ? 0 : *bit - (n-1);
switch(num_bits){
case 0:
mask = 1;
break;
case 1:
mask = 3;
break;
case 2:
mask = 7;
break;
case 3:
mask = 0xf;
break;
case 4:
mask = 0x1f;
break;
case 5:
mask = 0x3f;
break;
case 6:
mask = 0x7f;
break;
case 7:
mask = 0xff;
break;
default:
mask = 0xff;
break;
}
mask <<= base;
ret = (ret << (num_bits+1)) |
(u_int64_t)((*byte & mask) >> base);
if( n > *bit ){
++byte;
++length;
n -= *bit+1;
*bit = 7;
} else {
*bit -= n;
n = 0;
}
}
if(count)
ret |= (u_int64_t)1 << n_bits;
return ret;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/***************************************************************************
* Copyright (C) 2005 by tim *
* tim@krasnogorsk.ru *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef ICON_STORAGE_H
#define ICON_STORAGE_H
#include <qmap.h>
#include <qpixmap.h>
static const unsigned int MAX_BUILTIN_ICONS = 42;
class KCHMIconStorage
{
public:
typedef struct
{
unsigned int size;
const char * data;