decoder.cpp
来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 284 行
CPP
284 行
/* This file is part of the KDE libraries Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de) 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.*///----------------------------------------------------------------------------//// KDE HTML Widget -- decoder for input stream// $Id: decoder.cpp,v 1.50 2001/07/29 16:26:38 mueller Exp $#undef DECODE_DEBUG//#define DECODE_DEBUG#include "decoder.h"using namespace khtml;#include "htmlhashes.h"#include <qregexp.h>#include <qtextcodec.h>#include <kglobal.h>#include <kcharsets.h>#include <ctype.h>#include <kdebug.h>Decoder::Decoder(){ // latin1 m_codec = QTextCodec::codecForMib(4); m_decoder = m_codec->makeDecoder(); enc = 0; body = false; beginning = true; visualRTL = false; haveEncoding = false;}Decoder::~Decoder(){ delete m_decoder;}void Decoder::setEncoding(const char *_encoding, bool force){#ifdef DECODE_DEBUG kdDebug(6005) << "setEncoding " << _encoding << " " << force << endl;#endif enc = _encoding; QTextCodec *old = m_codec;#ifdef DECODE_DEBUG kdDebug(6005) << "old encoding is:" << m_codec->name() << endl;#endif enc = enc.lower();#ifdef DECODE_DEBUG kdDebug(6005) << "requesting:" << enc << endl;#endif if(enc.isNull() || enc.isEmpty()) return; if(enc == "visual") // hebrew visually ordered enc = "iso8859-8"; bool b; m_codec = KGlobal::charsets()->codecForName(enc, b); if(m_codec->mibEnum() == 11) { // iso8859-8 (visually ordered) m_codec = QTextCodec::codecForName("iso8859-8-i"); visualRTL = true; } if( !b ) // in case the codec didn't exist, we keep the old one (fixes some sites specifying invalid codecs) m_codec = old; else haveEncoding = force; delete m_decoder; m_decoder = m_codec->makeDecoder();#ifdef DECODE_DEBUG kdDebug(6005) << "Decoder::encoding used is" << m_codec->name() << endl;#endif}const char *Decoder::encoding() const{ return enc;}QString Decoder::decode(const char *data, int len){ // this is not completely efficient, since the function might go // through the html head several times... if(!haveEncoding && !body) {#ifdef DECODE_DEBUG kdDebug(6005) << "looking for charset definition" << endl;#endif // check for UTF-16 uchar * uchars = (uchar *) data; if( uchars[0] == 0xfe && uchars[1] == 0xff || uchars[0] == 0xff && uchars[1] == 0xfe ) { enc = "ISO-10646-UCS-2"; haveEncoding = true; m_codec = QTextCodec::codecForMib(1000); delete m_decoder; m_decoder = m_codec->makeDecoder(); } else { if(m_codec->mibEnum() != 1000) // utf16 { // ### hack for a bug in QTextCodec. It cut's the input stream // in case there are \0 in it. ZDNET has them inside... :-( char *d = const_cast<char *>(data); int i = len - 1; while(i >= 0) { if(*(d+i) == 0) *(d+i) = ' '; i--; } } buffer += QCString(data, len+1); // we still don't have an encoding, and are in the head // the following tags are allowed in <head>: // SCRIPT|STYLE|META|LINK|OBJECT|TITLE|BASE const char *ptr = buffer.data(); while(*ptr != '\0') { if(*ptr == '<') { bool end = false; ptr++; if(*ptr == '/') ptr++, end=true; char tmp[20]; int len = 0; while ( ((*ptr >= 'a') && (*ptr <= 'z') || (*ptr >= 'A') && (*ptr <= 'Z') || (*ptr >= '0') && (*ptr <= '9')) && len < 19 ) { tmp[len] = tolower( *ptr ); ptr++; len++; } tmp[len] = 0; int id = khtml::getTagID(tmp, len); if(end) id += ID_CLOSE_TAG; switch( id ) { case ID_META: { // found a meta tag... //ptr += 5; const char * end = ptr; while(*end != '>' && *end != '\0') end++; if ( *end == '\0' ) break; QCString str( ptr, (end-ptr)+1); str = str.lower(); int pos = 0; //if( (pos = str.find("http-equiv", pos)) == -1) break; //if( (pos = str.find("content-type", pos)) == -1) break; while( pos < ( int ) str.length() ) { if( (pos = str.find("charset", pos)) == -1) break; pos += 7; // skip whitespace.. while( pos < (int)str.length() && str[pos] <= ' ' ) pos++; if ( pos == ( int )str.length()) break; if ( str[pos++] != '=' ) continue; while ( pos < ( int )str.length() && ( str[pos] <= ' ' ) || str[pos] == '=' || str[pos] == '"' || str[pos] == '\'') pos++; // end ? if ( pos == ( int )str.length() ) break; uint endpos = pos; while( endpos < str.length() && (str[endpos] != ' ' && str[endpos] != '"' && str[endpos] != '\'' && str[endpos] != ';' && str[endpos] != '>') ) endpos++; enc = str.mid(pos, endpos-pos);#ifdef DECODE_DEBUG kdDebug( 6005 ) << "Decoder: found charset: " << enc.data() << endl;#endif setEncoding(enc, true); if( haveEncoding ) goto found; if ( endpos >= str.length() || str[endpos] == '/' || str[endpos] == '>' ) break; pos = endpos + 1; } } case ID_SCRIPT: case (ID_SCRIPT+ID_CLOSE_TAG): case ID_STYLE: case (ID_STYLE+ID_CLOSE_TAG): case ID_LINK: case (ID_LINK+ID_CLOSE_TAG): case ID_OBJECT: case (ID_OBJECT+ID_CLOSE_TAG): case ID_TITLE: case (ID_TITLE+ID_CLOSE_TAG): case ID_BASE: case (ID_BASE+ID_CLOSE_TAG): case ID_HTML: case ID_HEAD: case 0: case (0 + ID_CLOSE_TAG ): break; default: body = true;#ifdef DECODE_DEBUG kdDebug( 6005 ) << "Decoder: no charset found, using latin1. Id=" << id << endl;#endif goto found; } } else ptr++; } return QString::null; } } found: // if we still haven't found an encoding latin1 will be used... // this is according to HTML4.0 specs if (!m_codec) { if(enc.isEmpty()) enc = "iso8859-1"; m_codec = QTextCodec::codecForName(enc); // be sure not to crash if(!m_codec) { m_codec = QTextCodec::codecForMib(4); enc = "iso8859-1"; } delete m_decoder; m_decoder = m_codec->makeDecoder(); } QString out; if(!buffer.isEmpty() && enc != "ISO-10646-UCS-2") { out = m_decoder->toUnicode(buffer, buffer.length()); buffer = ""; } else { if(m_codec->mibEnum() != 1000) // utf16 { // ### hack for a bug in QTextCodec. It cut's the input stream // in case there are \0 in it. ZDNET has them inside... :-( char *d = const_cast<char *>(data); int i = len - 1; while(i >= 0) { if(*(d+i) == 0) *(d+i) = ' '; i--; } } out = m_decoder->toUnicode(data, len); } // the hell knows, why the output does sometimes have a QChar::null at // the end... if(out[out.length()-1] == QChar::null) out.truncate(out.length() - 1); return out;}QString Decoder::flush() const{ return m_decoder->toUnicode(buffer, buffer.length());}// -----------------------------------------------------------------------------#undef DECODE_DEBUG
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?