diff --git a/src/common/globalbroadcaster.hh b/src/common/globalbroadcaster.hh index 4dfd7ba3..2999f9ed 100644 --- a/src/common/globalbroadcaster.hh +++ b/src/common/globalbroadcaster.hh @@ -5,6 +5,7 @@ #include #include "config.hh" #include "pronounceengine.hh" +#include struct ActiveDictIds { @@ -40,6 +41,7 @@ public: QMap< QString, QSet< QString > > folderFavoritesMap; QMap< unsigned, QString > groupFolderMap; PronounceEngine pronounce_engine; + QCache< QString, QByteArray > cache; signals: void dictionaryChanges( ActiveDictIds ad ); diff --git a/src/dict/mdx.cc b/src/dict/mdx.cc index c6edf0f2..5da94d90 100644 --- a/src/dict/mdx.cc +++ b/src/dict/mdx.cc @@ -690,6 +690,7 @@ public: f = QtConcurrent::run( [ this ]() { this->run(); } ); } + QByteArray isolate_css(); void run(); void cancel() override @@ -704,6 +705,45 @@ public: } }; +QByteArray MddResourceRequest::isolate_css() +{ + + const QString id = QString::fromUtf8( dict.getId().c_str() ); + + QString css = QString::fromUtf8( data.data(), data.size() ); + + int pos = 0; + + QString newCSS; + QRegularExpressionMatchIterator it = RX::Mdx::links.globalMatch( css ); + while ( it.hasNext() ) { + QRegularExpressionMatch match = it.next(); + newCSS += css.mid( pos, match.capturedStart() - pos ); + pos = match.capturedEnd(); + QString url = match.captured( 2 ); + + + if ( url.indexOf( ":/" ) >= 0 || url.indexOf( "data:" ) >= 0 ) { + // External link or base64-encoded data + newCSS += match.captured(); + + continue; + } + + QString newUrl = QString( "url(" ) + match.captured( 1 ) + "bres://" + id + "/" + url + match.captured( 3 ) + ")"; + newCSS += newUrl; + } + if ( pos ) { + newCSS += css.mid( pos ); + css = newCSS; + newCSS.clear(); + } + dict.isolateCSS( css, ".mdict" ); + auto bytes = css.toUtf8(); + + return bytes; +} + void MddResourceRequest::run() { if ( Utils::AtomicInt::loadAcquire( isCancelled ) ) @@ -739,6 +779,24 @@ void MddResourceRequest::run() QMutexLocker _( &dataMutex ); data.clear(); + //check the global cache + //generate resource unique key + const QString id = QString::fromUtf8( dict.getId().c_str() ); + + const QString unique_key = id + QString::fromStdString( u8ResourceName ); + if ( GlobalBroadcaster::instance()->cache.contains( unique_key ) ) { + //take first ,then insert again . the object() method may become null anytime. + auto bytes = GlobalBroadcaster::instance()->cache.take( unique_key ); + if ( bytes ) { + hasAnyData = true; + data.resize( bytes->size() ); + memcpy( &data.front(), bytes->constData(), bytes->size() ); + GlobalBroadcaster::instance()->cache.insert( unique_key, bytes ); + break; + } + } + + dict.loadResourceFile( resourceName, data ); // Check if this file has a redirection @@ -768,46 +826,12 @@ void MddResourceRequest::run() if ( Filetype::isNameOfCSS( u8ResourceName ) ) { - QString css = QString::fromUtf8( data.data(), data.size() ); + QByteArray bytes = isolate_css(); - // QRegularExpression links( "url\\(\\s*(['\"]?)([^'\"]*)(['\"]?)\\s*\\)", - // QRegularExpression::CaseInsensitiveOption ); - - QString id = QString::fromUtf8( dict.getId().c_str() ); - int pos = 0; - - QString newCSS; - QRegularExpressionMatchIterator it = RX::Mdx::links.globalMatch( css ); - while ( it.hasNext() ) - { - QRegularExpressionMatch match = it.next(); - newCSS += css.mid( pos, match.capturedStart() - pos ); - pos = match.capturedEnd(); - QString url = match.captured( 2 ); - - - if( url.indexOf( ":/" ) >= 0 || url.indexOf( "data:" ) >= 0) - { - // External link or base64-encoded data - newCSS += match.captured(); - - continue; - } - - QString newUrl = QString( "url(" ) + match.captured( 1 ) + "bres://" - + id + "/" + url + match.captured( 3 ) + ")"; - newCSS += newUrl; - } - if( pos ) - { - newCSS += css.mid( pos ); - css = newCSS; - newCSS.clear(); - } - dict.isolateCSS( css, ".mdict" ); - QByteArray bytes = css.toUtf8(); data.resize( bytes.size() ); memcpy( &data.front(), bytes.constData(), bytes.size() ); + //cache the processed css result to avoid process again. + GlobalBroadcaster::instance()->cache.insert( unique_key, new QByteArray( bytes ) ); } if( Filetype::isNameOfTiff( u8ResourceName ) ) {