⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mimehandler.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
字号:
/*  This file is part of the KDE project    Copyright (C) 2002 Paul Chitescu <paulc-devel@null.ro>    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    As a special exception this program may be linked with Qt non-commercial     edition, the resulting executable be distributed, without including the     source code for the Qt non-commercial edition in the source distribution.*/#include <config.h>#include <kglobal.h>#include <kconfig.h>#include "mimehandler.h"#include <qbuffer.h>#include <qimage.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <kdebug.h>using namespace KIO;ExternalFilter* ExternalFilter::Create( const QString &app, const QString& type, const KURL &url ){    kdDebug() << "ExternalFilter::Create(\"" << app << "\",\"" 	      << type << "\",\"" << url.url() << "\")" << endl;    // HACK: archive handlers should create a query by prepending the    //  internal archive filename with "??" (and possible other options)    QString otype;    if ( url.query().startsWith( "??" ) )    {	QString s = url.query().mid( 2 );	if ( !s.startsWith( "/" ) )	    s.prepend( '/' );	const MimeHandler* mime = MimeHandler::Find( KURL( s ) );	if ( mime )	    otype = mime->isAlias() ? mime->isAlias()->outputType() : mime->Preferred();    }    int m_pipe_in[2], m_pipe_out[2];    if ( ::pipe( m_pipe_out ) == 0 )    {	if ( ::pipe( m_pipe_in ) == 0 )	{	    int pid = fork();	    if ( pid == -1 )	    {		::close( m_pipe_in[0] );		::close( m_pipe_in[1] );	    }	    else if ( pid == 0 )	    {		int i;		::dup2( m_pipe_in[1], 1 );		::dup2( m_pipe_out[0], 0 );		for ( i = ::getdtablesize(); i >= 3 ; i-- )		    ::close( i );		::setenv( "FILTER_MIME_IN", type.latin1(), TRUE );		if ( !otype.isEmpty() )		    ::setenv( "FILTER_MIME_OUT", otype.latin1(), TRUE );		::setenv( "FILTER_URL", url.url().latin1(), TRUE );		const char *exe = app.latin1();		::execlp( exe, exe, 0 );		::exit( errno );	    }	    else	    {		::close( m_pipe_in[1] );		::close( m_pipe_out[0] );		::fcntl( m_pipe_in[0], F_SETFL, O_NONBLOCK );		::fcntl( m_pipe_out[1], F_SETFL, O_NONBLOCK );		return new ExternalFilter( m_pipe_in[0], m_pipe_out[1], pid, otype );	    }	}	::close( m_pipe_out[0] );	::close( m_pipe_out[1] );    }    return 0;}ExternalFilter::~ExternalFilter(){    if ( m_file_in >= 0)    {	::close( m_file_in );	m_file_in = -1;    }    if ( m_file_out >= 0)    {	::close( m_file_out );	m_file_out = -1;    }}void ExternalFilter::dataInput( const QByteArray &dat ){    // TODO: implement is asynchronously, would help A LOT    uint i;    if ( dat.isEmpty() )    {	closeOutput();	return;    }    if ( m_file_out >= 0 )    {	for ( i = 0; i < dat.count(); )	{	    pumpData();	    int n = dat.count() - i;	    if ( n > 1024 )		n = 1024;	    n = ::write( m_file_out, dat.data() + i, n );	    if ( n < 0 )	    {		if ( errno != EAGAIN )		{		    closeOutput();		    break;		}	    }	    else		i += n;	}    }    pumpData();}bool ExternalFilter::pumpData(){    if ( m_file_in < 0 )	return false;    for ( ;; )    {	QByteArray buff( 4096 );	int n = ::read( m_file_in, buff.data(), buff.size() );	if ( n < 0 )	    return (errno == EAGAIN);	else	{	    buff.truncate( n );	    emit dataOutput( buff );	    if ( n == 0 )	    {		::close( m_file_in );		m_file_in = -1;		break;	    }	}    }    return false;}void ExternalFilter::closeOutput(){    if ( m_file_out >= 0 )    {	::close( m_file_out );	m_file_out = -1;    }    for ( ; pumpData(); );}QPtrList<MimeHandler> MimeHandler::s_handlers;const MimeHandler* MimeHandler::Find( const QString &type ){    const MimeHandler* retval = 0;    int slash = type.find( '/' );    for ( int i = 0; !retval && i < 3; i++ )    {	QString test_type = type.lower();        switch ( i )	{	    case 1:		if ( slash < 1 )		    continue;		test_type.replace( 0, slash, "*" );		break;	    case 2:		if ( slash < 1 )		    continue;		test_type.replace( slash+1, 0xffff, "*" );		break;	    case 3:		test_type = "*/*";		break;	}	QPtrListIterator<MimeHandler> it( s_handlers );	int best = 0;	int len;	for ( ; it.current(); ++it )	    if ( ( len = it.current()->Matches( test_type ) ) > best )	    {		best = len;		retval = it.current();	    }    }    return retval;}const MimeHandler* MimeHandler::Find( const KURL &url ){    const MimeHandler* retval = 0;    QPtrListIterator<MimeHandler> it( s_handlers );    int best = 0;    int len;    for ( ; it.current(); ++it )	if ( ( len = it.current()->Matches( url ) ) > best )	{	    best = len;	    retval = it.current();	}    return retval;}const MimeHandler* MimeHandler::Find( const QByteArray &data ){    QPtrListIterator<MimeHandler> it( s_handlers );    for ( ; it.current(); ++it )	if ( it.current()->Matches( data ) )	    return it.current();    return 0;}int MimeHandler::Matches( const QString &type ) const{    int best = 0;    for ( QStringList::ConstIterator it = m_types.begin(); it != m_types.end(); it++ )    {	if ( type.startsWith( *it ) )	{	    int len = (*it).length();	    QChar c = type.at( len );	    if ( len > best && ( c == '\0' || c == ' ' || c == ';' ) )		best = len;	}    }    return best;}int MimeHandler::Matches( const KURL &url ) const{    int best = 0;    QString ext = url.path().lower();    int i = ext.findRev( '/' );    if ( i >= 0 )	ext.remove( 0, i+1 );    i = ext.find( '.' );    if ( i < 0 )	return false;    else if ( i > 0)	ext.remove( 0, i );    for ( QStringList::ConstIterator it = m_types.begin(); it != m_types.end(); it++ )    {	int len = (*it).length();	if ( len > best && *it == ext.right( len ) )	    best = len;    }    return best;}bool MimeInternalImage::Matches( const QByteArray &data ) const{    QBuffer buffer( data );    buffer.open( IO_ReadOnly );    return ( QImageIO::imageFormat( &buffer ) != 0 );}void MimeHandler::Initialize(){    // We should add internal handlers for built-in types    // The first one should be the cannonical type    AddHandler( new MimeInternalImage( "image/*" ) );    QStringList tmp;    tmp << "text/html" << ".html" << ".htm";    tmp << "application/xhtml+xml" << "application/xhtml" << ".xhtml" << ".xht";    AddHandler( new MimeInternal( tmp ) );    tmp.clear();    tmp << "text/xml" << "application/xml" << ".xml";    AddHandler( new MimeInternal( tmp ) );    tmp.clear();    tmp << "text/javascript" << "application/x-javascript" << ".js";    AddHandler( new MimeInternal( tmp ) );    tmp.clear();    tmp << "text/css" << ".css";    AddHandler( new MimeInternal( tmp ) );    typedef QMap<QString,QString> EntryMap;    KConfig *config = KGlobal::config();    EntryMap list=config->entryMap( "MIME Handlers" );    EntryMap::Iterator item;    for ( item = list.begin(); item != list.end(); item++ )    {	QStringList types = QStringList::split( ',', item.key().lower() );	QString data = item.data();	switch ( data.at( 0 ).latin1() )	{	    case '-':		AddHandler( new MimeUnknown( types ) );		break;	    case '@':		AddHandler( new MimeAlias( types, data.mid( 1 ) ) );		break;	    case '|':		tmp = QStringList::split( '|', data, true );		AddHandler( new MimeExtFilter( types, tmp[2], tmp[1] ) );		break;	    case '*':		AddHandler( new MimeExtApp( types, data.mid( 1 ), true ) );		break;	    default:		AddHandler( new MimeExtApp( types, data, false ) );		break;	}    }}DataFilter* MimeExtFilter::createFilter ( const QString& type, const KURL &url ) const{    return ExternalFilter::Create( m_path, type.isEmpty() ? Preferred() : type, url );}#include "mimehandler.moc"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -