summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/deployment/registry/help/dp_help.cxx40
-rw-r--r--xmlhelp/source/com/sun/star/help/HelpIndexer.java60
-rw-r--r--xmlhelp/source/com/sun/star/help/HelpLinker.cxx109
-rw-r--r--xmlhelp/source/cxxhelp/provider/databases.cxx596
-rw-r--r--xmlhelp/source/cxxhelp/provider/databases.hxx26
-rw-r--r--xmlhelp/source/cxxhelp/provider/db.cxx453
-rw-r--r--xmlhelp/source/cxxhelp/provider/db.hxx99
-rw-r--r--xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx7
-rw-r--r--xmlhelp/source/cxxhelp/provider/urlparameter.cxx41
-rw-r--r--xmlhelp/source/treeview/tvread.cxx58
-rw-r--r--xmlhelp/source/treeview/tvread.hxx3
11 files changed, 1233 insertions, 259 deletions
diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx
index 127c96c21a..175d83934d 100644
--- a/desktop/source/deployment/registry/help/dp_help.cxx
+++ b/desktop/source/deployment/registry/help/dp_help.cxx
@@ -94,6 +94,7 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
void implProcessHelp( Reference< deployment::XPackage > xPackage, bool doRegisterPackage );
void implCollectXhpFiles( const rtl::OUString& aDir,
std::vector< rtl::OUString >& o_rXhpFileVector );
+ rtl::OUString getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr );
rtl::OUString getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage );
rtl::OUString getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage );
rtl::OUString expandURL( const rtl::OUString& aURL );
@@ -264,9 +265,16 @@ void BackendImpl::implProcessHelp
Reference< script::XInvocation > xInvocation;
if( xContext.is() )
{
- xInvocation = Reference< script::XInvocation >(
- xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
- "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY );
+ try
+ {
+ xInvocation = Reference< script::XInvocation >(
+ xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY );
+ }
+ catch (Exception &)
+ {
+ // i98680: Survive missing lucene
+ }
}
// Scan languages
@@ -351,8 +359,13 @@ void BackendImpl::implProcessHelp
Sequence<uno::Any> aParamsSeq( 6 );
aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) );
- rtl::OUString aLang; // TODO
- aLang = rtl::OUString::createFromAscii( "de" ); // TODO
+
+ rtl::OUString aLang;
+ sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ aLang = aLangURL.copy( nLastSlash + 1 );
+ else
+ aLang = rtl::OUString::createFromAscii( "en" );
aParamsSeq[1] = uno::makeAny( aLang );
aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) );
@@ -441,26 +454,25 @@ void BackendImpl::implProcessHelp
}
}
-rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage )
+rtl::OUString BackendImpl::getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr )
{
rtl::OUString aRetURL;
if( !xPackage.is() )
return aRetURL;
rtl::OUString aHelpURL = xPackage->getURL();
aRetURL = expandURL( aHelpURL );
- aRetURL += rtl::OUString::createFromAscii( "/RegisteredFlag" );
+ aRetURL += rtl::OUString::createFromAscii( pFlagStr );
return aRetURL;
}
+rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage )
+{
+ return getFlagFileURL( xPackage, "/RegisteredFlag" );
+}
+
rtl::OUString BackendImpl::getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage )
{
- rtl::OUString aRetURL;
- if( !xPackage.is() )
- return aRetURL;
- rtl::OUString aHelpURL = xPackage->getURL();
- aRetURL = expandURL( aHelpURL );
- aRetURL += rtl::OUString::createFromAscii( "/CompiledFlag" );
- return aRetURL;
+ return getFlagFileURL( xPackage, "/CompiledFlag" );
}
rtl::OUString BackendImpl::expandURL( const rtl::OUString& aURL )
diff --git a/xmlhelp/source/com/sun/star/help/HelpIndexer.java b/xmlhelp/source/com/sun/star/help/HelpIndexer.java
index 6f00bcd4aa..03f0611b69 100644
--- a/xmlhelp/source/com/sun/star/help/HelpIndexer.java
+++ b/xmlhelp/source/com/sun/star/help/HelpIndexer.java
@@ -82,6 +82,7 @@ public class HelpIndexer extends WeakBase
private static void mainImpl( String[] args, boolean bExtensionMode )
{
String aDirToZipStr = "";
+ String aSrcDirStr = "";
String aLanguageStr = "";
String aModule = "";
String aTargetZipFileStr = "";
@@ -90,6 +91,7 @@ public class HelpIndexer extends WeakBase
boolean bLang = false;
boolean bMod = false;
boolean bZipDir = false;
+ boolean bSrcDir = false;
boolean bOutput = false;
int nArgCount = args.length;
@@ -122,6 +124,15 @@ public class HelpIndexer extends WeakBase
}
i++;
}
+ else if( "-srcdir".equals(args[i]) )
+ {
+ if( i + 1 < nArgCount )
+ {
+ aSrcDirStr = args[i + 1];
+ bSrcDir = true;
+ }
+ i++;
+ }
else if( "-o".equals(args[i]) )
{
if( i + 1 < nArgCount )
@@ -142,45 +153,55 @@ public class HelpIndexer extends WeakBase
System.exit( -1 );
}
- File docDir = new File( aDirToZipStr );
String aIndexDirName = aModule + ".idxl";
File aIndexDir = new File( aDirToZipStr + File.separator + aIndexDirName );
- File aCaptionFilesDir = new File( aDirToZipStr + File.separator + "caption" );
- File aContentFilesDir = new File( aDirToZipStr + File.separator + "content" );
+ if( !bSrcDir )
+ aSrcDirStr = aDirToZipStr;
+ File aCaptionFilesDir = new File( aSrcDirStr + File.separator + "caption" );
+ File aContentFilesDir = new File( aSrcDirStr + File.separator + "content" );
try
{
Date start = new Date();
Analyzer analyzer = aLanguageStr.equals("ja") ? (Analyzer)new CJKAnalyzer() : (Analyzer)new StandardAnalyzer();
IndexWriter writer = new IndexWriter( aIndexDir, analyzer, true );
- System.out.println( "Lucene: Indexing to directory '" + aIndexDir + "'..." );
- int nRet = indexDocs( writer, aModule, aCaptionFilesDir, aContentFilesDir );
+ if( !bExtensionMode )
+ System.out.println( "Lucene: Indexing to directory '" + aIndexDir + "'..." );
+ int nRet = indexDocs( writer, aModule, bExtensionMode, aCaptionFilesDir, aContentFilesDir );
if( nRet != -1 )
{
- System.out.println();
- System.out.println( "Optimizing ..." );
+ if( !bExtensionMode )
+ {
+ System.out.println();
+ System.out.println( "Optimizing ..." );
+ }
writer.optimize();
}
writer.close();
if( bExtensionMode )
{
- deleteRecursively( aCaptionFilesDir );
- deleteRecursively( aContentFilesDir );
+ if( !bSrcDir )
+ {
+ deleteRecursively( aCaptionFilesDir );
+ deleteRecursively( aContentFilesDir );
+ }
}
else
{
if( nRet == -1 )
deleteRecursively( aIndexDir );
- System.out.println( "Zipping ..." );
+ if( !bExtensionMode )
+ System.out.println( "Zipping ..." );
File aDirToZipFile = new File( aDirToZipStr );
createZipFile( aDirToZipFile, aTargetZipFileStr );
deleteRecursively( aDirToZipFile );
}
Date end = new Date();
- System.out.println(end.getTime() - start.getTime() + " total milliseconds");
+ if( !bExtensionMode )
+ System.out.println(end.getTime() - start.getTime() + " total milliseconds");
}
catch (IOException e)
{
@@ -193,17 +214,19 @@ public class HelpIndexer extends WeakBase
}
}
- private static int indexDocs(IndexWriter writer, String aModule,
+ private static int indexDocs(IndexWriter writer, String aModule, boolean bExtensionMode,
File aCaptionFilesDir, File aContentFilesDir) throws IOException
{
if( !aCaptionFilesDir.canRead() || !aCaptionFilesDir.isDirectory() )
{
- System.out.println( "Not found: " + aCaptionFilesDir );
+ if( !bExtensionMode )
+ System.out.println( "Not found: " + aCaptionFilesDir );
return -1;
}
if( !aContentFilesDir.canRead() || !aContentFilesDir.isDirectory() )
{
- System.out.println( "Not found: " + aContentFilesDir );
+ if( !bExtensionMode )
+ System.out.println( "Not found: " + aContentFilesDir );
return -1;
}
@@ -216,7 +239,8 @@ public class HelpIndexer extends WeakBase
HashSet aContentFilesHashSet = new HashSet( aContentFilesList );
// Loop over caption files and find corresponding content file
- System.out.println( "Indexing, adding files" );
+ if( !bExtensionMode )
+ System.out.println( "Indexing, adding files" );
int nCaptionFilesLen = aCaptionFiles.length;
for( int i = 0 ; i < nCaptionFilesLen ; i++ )
{
@@ -226,7 +250,8 @@ public class HelpIndexer extends WeakBase
if( aContentFilesHashSet.contains( aCaptionFileStr ) )
aContentFile = new File( aContentFilesDir, aCaptionFileStr );
- System.out.print( "." );
+ if( !bExtensionMode )
+ System.out.print( "." );
writer.addDocument( HelpFileDocument.Document( aModule, aCaptionFile, aContentFile ) );
}
@@ -240,7 +265,8 @@ public class HelpIndexer extends WeakBase
// Not already handled in caption files loop
File aCaptionFile = null;
File aContentFile = new File( aContentFilesDir, aContentFileStr );
- System.out.print( "." );
+ if( !bExtensionMode )
+ System.out.print( "." );
writer.addDocument( HelpFileDocument.Document( aModule, aCaptionFile, aContentFile ) );
}
}
diff --git a/xmlhelp/source/com/sun/star/help/HelpLinker.cxx b/xmlhelp/source/com/sun/star/help/HelpLinker.cxx
index 541522e4dd..357f05aeb5 100644
--- a/xmlhelp/source/com/sun/star/help/HelpLinker.cxx
+++ b/xmlhelp/source/com/sun/star/help/HelpLinker.cxx
@@ -51,6 +51,9 @@
#include <expat/xmlparse.h>
#endif
+#define DBHELP_ONLY
+
+
class IndexerPreProcessor
{
private:
@@ -166,6 +169,22 @@ struct Data
}
};
+void writeKeyValue_DBHelp( FILE* pFile, const std::string& aKeyStr, const std::string& aValueStr )
+{
+ if( pFile == NULL )
+ return;
+ char cLF = 10;
+ int nKeyLen = aKeyStr.length();
+ int nValueLen = aValueStr.length();
+ fprintf( pFile, "%x ", nKeyLen );
+ if( nKeyLen > 0 )
+ fwrite( aKeyStr.c_str(), 1, nKeyLen, pFile );
+ fprintf( pFile, " %x ", nValueLen );
+ if( nValueLen > 0 )
+ fwrite( aValueStr.c_str(), 1, nValueLen, pFile );
+ fprintf( pFile, "%c", cLF );
+}
+
class HelpKeyword
{
private:
@@ -200,6 +219,19 @@ public:
table->put(table, NULL, &key, &value, 0);
}
}
+
+ void dump_DBHelp( const std::string& rFileName )
+ {
+ FILE* pFile = fopen( rFileName.c_str(), "wb" );
+ if( pFile == NULL )
+ return;
+
+ DataHashtable::const_iterator aEnd = _hash.end();
+ for (DataHashtable::const_iterator aIter = _hash.begin(); aIter != aEnd; ++aIter)
+ writeKeyValue_DBHelp( pFile, aIter->first, aIter->second.getString() );
+
+ fclose( pFile );
+ }
};
class HelpLinker
@@ -237,7 +269,7 @@ private:
IndexerPreProcessor* m_pIndexerPreProcessor;
void initIndexerPreProcessor();
void link() throw( HelpProcessingException );
- void addBookmark( DB* dbBase, std::string thishid,
+ void addBookmark( DB* dbBase, FILE* pFile_DBHelp, std::string thishid,
const std::string& fileB, const std::string& anchorB,
const std::string& jarfileB, const std::string& titleB );
#if 0
@@ -277,7 +309,7 @@ namespace URLEncoder
}
}
-void HelpLinker::addBookmark( DB* dbBase, std::string thishid,
+void HelpLinker::addBookmark( DB* dbBase, FILE* pFile_DBHelp, std::string thishid,
const std::string& fileB, const std::string& anchorB,
const std::string& jarfileB, const std::string& titleB)
{
@@ -327,7 +359,14 @@ void HelpLinker::addBookmark( DB* dbBase, std::string thishid,
data.data = &dataB[0];
data.size = dataB.size();
- dbBase->put(dbBase, NULL, &key, &data, 0);
+ if( dbBase != NULL )
+ dbBase->put(dbBase, NULL, &key, &data, 0);
+
+ if( pFile_DBHelp != NULL )
+ {
+ std::string aValueStr( dataB.begin(), dataB.end() );
+ writeKeyValue_DBHelp( pFile_DBHelp, thishid, aValueStr );
+ }
}
void HelpLinker::initIndexerPreProcessor()
@@ -346,7 +385,7 @@ void HelpLinker::initIndexerPreProcessor()
void HelpLinker::link() throw( HelpProcessingException )
{
bool bIndexForExtension = true;
-
+
if( bExtensionMode )
{
indexDirParentName = sourceRoot;
@@ -371,23 +410,45 @@ void HelpLinker::link() throw( HelpProcessingException )
if (appl[0] == 's')
appl = appl.substr(1);
- fs::path helpTextFileName(indexDirParentName / (mod + ".ht"));
+ bool bUse_ = true;
+#ifdef DBHELP_ONLY
+ if( !bExtensionMode )
+ bUse_ = false;
+#endif
+
DB* helpText(0);
+#ifndef DBHELP_ONLY
+ fs::path helpTextFileName(indexDirParentName / (mod + ".ht"));
db_create(&helpText,0,0);
helpText->open(helpText, NULL, helpTextFileName.native_file_string().c_str(), NULL, DB_BTREE,
DB_CREATE | DB_TRUNCATE, 0644);
+#endif
+
+ fs::path helpTextFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".ht_" : ".ht")));
+ FILE* pFileHelpText_DBHelp = fopen
+ ( helpTextFileName_DBHelp.native_file_string().c_str(), "wb" );
- fs::path dbBaseFileName(indexDirParentName / (mod + ".db"));
DB* dbBase(0);
+#ifndef DBHELP_ONLY
+ fs::path dbBaseFileName(indexDirParentName / (mod + ".db"));
db_create(&dbBase,0,0);
dbBase->open(dbBase, NULL, dbBaseFileName.native_file_string().c_str(), NULL, DB_BTREE,
DB_CREATE | DB_TRUNCATE, 0644);
+#endif
- fs::path keyWordFileName(indexDirParentName / (mod + ".key"));
+ fs::path dbBaseFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".db_" : ".db")));
+ FILE* pFileDbBase_DBHelp = fopen
+ ( dbBaseFileName_DBHelp.native_file_string().c_str(), "wb" );
+
+#ifndef DBHELP_ONLY
DB* keyWord(0);
+ fs::path keyWordFileName(indexDirParentName / (mod + ".key"));
db_create(&keyWord,0,0);
keyWord->open(keyWord, NULL, keyWordFileName.native_file_string().c_str(), NULL, DB_BTREE,
DB_CREATE | DB_TRUNCATE, 0644);
+#endif
+
+ fs::path keyWordFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".key_" : ".key")));
HelpKeyword helpKeyword;
@@ -423,8 +484,11 @@ void HelpLinker::link() throw( HelpProcessingException )
HashSet::iterator end = helpFiles.end();
for (HashSet::iterator iter = helpFiles.begin(); iter != end; ++iter)
{
- std::cout << ".";
- std::cout.flush();
+ if( !bExtensionMode )
+ {
+ std::cout << ".";
+ std::cout.flush();
+ }
// process one file
// streamTable contains the streams in the hzip file
@@ -500,7 +564,7 @@ void HelpLinker::link() throw( HelpProcessingException )
std::string& titleB = documentTitle;
// add once this as its own id.
- addBookmark(dbBase, documentPath, fileB, std::string(), jarfileB, titleB);
+ addBookmark(dbBase, pFileDbBase_DBHelp, documentPath, fileB, std::string(), jarfileB, titleB);
// first the database *.db
// ByteArrayInputStream bais = null;
@@ -525,7 +589,7 @@ void HelpLinker::link() throw( HelpProcessingException )
anchorB = thishid.substr(1 + index);
thishid = thishid.substr(0, index);
}
- addBookmark(dbBase, thishid, fileB, anchorB, jarfileB, titleB);
+ addBookmark(dbBase, pFileDbBase_DBHelp, thishid, fileB, anchorB, jarfileB, titleB);
}
}
@@ -541,7 +605,7 @@ void HelpLinker::link() throw( HelpProcessingException )
enumer != aEnd; ++enumer)
{
const std::string &anchor = enumer->first;
- addBookmark(dbBase, documentPath, fileB,
+ addBookmark(dbBase, pFileDbBase_DBHelp, documentPath, fileB,
anchor, jarfileB, titleB);
std::string totalId = fakedHid + "#" + anchor;
// std::cerr << hzipFileName << std::endl;
@@ -587,7 +651,12 @@ void HelpLinker::link() throw( HelpProcessingException )
memset(&textDbt, 0, sizeof(textDbt));
textDbt.data = const_cast<char*>(helpTextText.c_str());
textDbt.size = helpTextText.length();
- helpText->put(helpText, NULL, &keyDbt, &textDbt, 0);
+
+ if( helpText != NULL )
+ helpText->put(helpText, NULL, &keyDbt, &textDbt, 0);
+
+ if( pFileHelpText_DBHelp != NULL )
+ writeKeyValue_DBHelp( pFileHelpText_DBHelp, helpTextId, helpTextText );
}
}
@@ -614,16 +683,30 @@ void HelpLinker::link() throw( HelpProcessingException )
catch( HelpProcessingException& )
{
// catch HelpProcessingException to avoid locking data bases
+#ifndef DBHELP_ONLY
helpText->close(helpText, 0);
dbBase->close(dbBase, 0);
keyWord->close(keyWord, 0);
+#endif
+ if( pFileHelpText_DBHelp != NULL )
+ fclose( pFileHelpText_DBHelp );
+ if( pFileDbBase_DBHelp != NULL )
+ fclose( pFileDbBase_DBHelp );
throw;
}
+#ifndef DBHELP_ONLY
helpText->close(helpText, 0);
dbBase->close(dbBase, 0);
helpKeyword.dump(keyWord);
keyWord->close(keyWord, 0);
+#endif
+ if( pFileHelpText_DBHelp != NULL )
+ fclose( pFileHelpText_DBHelp );
+ if( pFileDbBase_DBHelp != NULL )
+ fclose( pFileDbBase_DBHelp );
+
+ helpKeyword.dump_DBHelp( keyWordFileName_DBHelp.native_file_string() );
if( !bExtensionMode )
{
diff --git a/xmlhelp/source/cxxhelp/provider/databases.cxx b/xmlhelp/source/cxxhelp/provider/databases.cxx
index 386329a9a8..ec6b75857f 100644
--- a/xmlhelp/source/cxxhelp/provider/databases.cxx
+++ b/xmlhelp/source/cxxhelp/provider/databases.cxx
@@ -56,6 +56,8 @@
#include <com/sun/star/util/XMacroExpander.hpp>
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <comphelper/locale.hxx>
#include <xmlhelp/compilehelp.hxx>
@@ -76,7 +78,6 @@ using namespace com::sun::star::beans;
static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) );
-static rtl::OUString aEnglishFallbackLang( rtl::OUString::createFromAscii( "en" ) );
static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) );
rtl::OUString Databases::expandURL( const rtl::OUString& aURL )
@@ -180,34 +181,10 @@ Databases::Databases( sal_Bool showBasic,
m_vReplacement[6] = productVersion;
setInstallPath( instPath );
-}
-void Databases::implCollectXhpFiles( const rtl::OUString& aDir,
- std::vector< rtl::OUString >& o_rXhpFileVector,
- Reference< ucb::XSimpleFileAccess > xSFA )
-{
- // Scan xhp files recursively
- Sequence< rtl::OUString > aSeq = xSFA->getFolderContents( aDir, true );
- sal_Int32 nCount = aSeq.getLength();
- const rtl::OUString* pSeq = aSeq.getConstArray();
- for( sal_Int32 i = 0 ; i < nCount ; ++i )
- {
- rtl::OUString aURL = pSeq[i];
- if( xSFA->isFolder( aURL ) )
- {
- implCollectXhpFiles( aURL, o_rXhpFileVector, xSFA );
- }
- else
- {
- sal_Int32 nLastDot = aURL.lastIndexOf( '.' );
- if( nLastDot != -1 )
- {
- rtl::OUString aExt = aURL.copy( nLastDot + 1 );
- if( aExt.equalsIgnoreAsciiCase( rtl::OUString::createFromAscii( "xhp" ) ) )
- o_rXhpFileVector.push_back( aURL );
- }
- }
- }
+ m_xSFA = Reference< ucb::XSimpleFileAccess >(
+ m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
+ m_xContext ), UNO_QUERY_THROW );
}
Databases::~Databases()
@@ -425,7 +402,7 @@ const std::vector< rtl::OUString >& Databases::getModuleList( const rtl::OUStrin
{
if( m_avModules.size() == 0 )
{
- rtl::OUString fileName,dirName = getInstallPathAsURL() + lang( Language );
+ rtl::OUString fileName,dirName = getInstallPathAsURL() + processLang( Language );
osl::Directory dirFile( dirName );
osl::DirectoryItem aDirItem;
@@ -473,7 +450,7 @@ StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OU
{
osl::MutexGuard aGuard( m_aMutex );
- rtl::OUString key = lang(Language) + rtl::OUString::createFromAscii( "/" ) + Module;
+ rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Module;
std::pair< ModInfoTable::iterator,bool > aPair =
m_aModInfo.insert( ModInfoTable::value_type( key,0 ) );
@@ -564,13 +541,10 @@ StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OU
-rtl::OUString Databases::lang( const rtl::OUString& Language )
+rtl::OUString Databases::processLang( const rtl::OUString& Language )
{
osl::MutexGuard aGuard( m_aMutex );
- if( Language.equals( aEnglishFallbackLang ) )
- return Language;
-
rtl::OUString ret;
LangSetTable::iterator it = m_aLangSet.find( Language );
@@ -612,16 +586,6 @@ rtl::OUString Databases::country( const rtl::OUString& Language )
-rtl::OUString Databases::variant( const rtl::OUString& System )
-{
- if( System.compareToAscii( "WIN" ) == 0 ||
- System.compareToAscii( "MAC" ) )
- return System;
- else
- return rtl::OUString::createFromAscii( "POSIX" );
-}
-
-
Db* Databases::getBerkeley( const rtl::OUString& Database,
const rtl::OUString& Language, bool helpText,
const rtl::OUString* pExtensionPath )
@@ -633,18 +597,12 @@ Db* Databases::getBerkeley( const rtl::OUString& Database,
rtl::OUString aFileExt( rtl::OUString::createFromAscii( helpText ? ".ht" : ".db" ) );
- rtl::OUString aCorrectedLanguage = lang( Language ); // TODO?: Check special handling for Extensions?
- rtl::OUString keyBase =
- aCorrectedLanguage +
- aSlash +
- Database +
- aFileExt;
-
+ rtl::OUString dbFileName = aSlash + Database + aFileExt;
rtl::OUString key;
if( pExtensionPath == NULL )
- key = keyBase;
+ key = processLang( Language ) + dbFileName;
else
- key = *pExtensionPath + keyBase; // make unique
+ key = *pExtensionPath + Language + dbFileName; // make unique, don't change language
std::pair< DatabasesTable::iterator,bool > aPair =
m_aDatabases.insert( DatabasesTable::value_type( key,0 ) );
@@ -659,16 +617,33 @@ Db* Databases::getBerkeley( const rtl::OUString& Database,
if( pExtensionPath )
{
rtl::OUString aExpandedURL = expandURL( *pExtensionPath );
+ aExpandedURL += Language + dbFileName;
osl::FileBase::getSystemPathFromFileURL( aExpandedURL, fileNameOU );
}
else
- fileNameOU = getInstallPathAsSystemPath();
+ fileNameOU = getInstallPathAsSystemPath() + key;
+
- fileNameOU += keyBase;
-
rtl::OString fileName( fileNameOU.getStr(),fileNameOU.getLength(),osl_getThreadTextEncoding() );
-
- if( table->open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
+
+ rtl::OUString fileNameDBHelp( fileNameOU );
+ if( pExtensionPath != NULL )
+ fileNameDBHelp += rtl::OUString::createFromAscii( "_" );
+ if( m_xSFA->exists( fileNameDBHelp ) )
+ {
+ DBHelp* pDBHelp = new DBHelp( fileNameDBHelp, m_xSFA );
+ table->setDBHelp( pDBHelp );
+
+#ifdef TEST_DBHELP
+ bool bSuccess;
+ bool bOldDbAccess = false;
+ bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess );
+
+ bOldDbAccess = true;
+ bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess );
+#endif
+ }
+ else if( table->open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
{
table->close( 0 );
delete table;
@@ -700,7 +675,7 @@ Databases::getCollator( const rtl::OUString& Language,
Reference< XCollator > (
m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ),
m_xContext ), UNO_QUERY );
- rtl::OUString langStr = lang(Language);
+ rtl::OUString langStr = processLang(Language);
rtl::OUString countryStr = country(Language);
if( !countryStr.getLength() )
{
@@ -818,20 +793,44 @@ void KeywordInfo::KeywordElement::init( Databases *pDatabases,Db* pDb,const rtl:
listId.realloc( id.size() );
listAnchor.realloc( id.size() );
listTitle.realloc( id.size() );
+
+ int nSize = 0;
+ const sal_Char* pData = NULL;
+ const sal_Char pEmpty[] = "";
+
for( sal_uInt32 i = 0; i < id.size(); ++i )
{
listId[i] = id[i];
listAnchor[i] = anchor[i];
- rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 );
- Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ),
- idi.getLength() );
- Dbt data;
+ nSize = 0;
+ pData = pEmpty;
if( pDb )
- pDb->get( 0,&key_,&data,0 );
+ {
+ rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 );
+ DBHelp* pDBHelp = pDb->getDBHelp();
+ if( pDBHelp != NULL )
+ {
+ DBData aDBData;
+ bool bSuccess = pDBHelp->getValueForKey( idi, aDBData );
+ if( bSuccess )
+ {
+ nSize = aDBData.getSize();
+ pData = aDBData.getData();
+ }
+ }
+ else
+ {
+ Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ),
+ idi.getLength() );
+ Dbt data;
+ pDb->get( 0,&key_,&data,0 );
+ nSize = data.get_size();
+ pData = static_cast<sal_Char*>( data.get_data() );
+ }
+ }
- DbtToStringConverter converter( static_cast< sal_Char* >( data.get_data() ),
- data.get_size() );
+ DbtToStringConverter converter( pData, nSize );
rtl::OUString title = converter.getTitle();
pDatabases->replaceName( title );
@@ -856,12 +855,61 @@ KeywordInfo::KeywordInfo( const std::vector< KeywordElement >& aVec )
}
}
+bool Databases::checkModuleMatchForExtension
+ ( const rtl::OUString& Database, const rtl::OUString& doclist )
+{
+ bool bBelongsToDatabase = true;
+
+ // Analyse doclist string to find module assignments
+ bool bFoundAtLeastOneModule = false;
+ bool bModuleMatch = false;
+ sal_Int32 nLen = doclist.getLength();
+ sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') );
+ if( nLastFound == -1 )
+ nLastFound = nLen;
+ const sal_Unicode* pStr = doclist.getStr();
+ sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') );
+ while( nFound != -1 )
+ {
+ // Simple optimization, stop if '_' is followed by "id"
+ if( nLen - nFound > 2 )
+ {
+ if( pStr[ nFound + 1 ] == sal_Unicode('i') &&
+ pStr[ nFound + 2 ] == sal_Unicode('d') )
+ break;
+ }
+
+ rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 );
+ std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule );
+ if( result != m_avModules.end() )
+ {
+ bFoundAtLeastOneModule = true;
+ if( Database == aModule )
+ {
+ bModuleMatch = true;
+ break;
+ }
+ }
+
+ nLastFound = nFound;
+ if( nLastFound == 0 )
+ break;
+ nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 );
+ }
+
+ if( bFoundAtLeastOneModule && !bModuleMatch )
+ bBelongsToDatabase = false;
+
+ return bBelongsToDatabase;
+}
+
+
KeywordInfo* Databases::getKeyword( const rtl::OUString& Database,
const rtl::OUString& Language )
{
osl::MutexGuard aGuard( m_aMutex );
- rtl::OUString key = lang(Language) + rtl::OUString::createFromAscii( "/" ) + Database;
+ rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Database;
std::pair< KeywordInfoTable::iterator,bool > aPair =
m_aKeywordInfo.insert( KeywordInfoTable::value_type( key,0 ) );
@@ -869,7 +917,7 @@ KeywordInfo* Databases::getKeyword( const rtl::OUString& Database,
KeywordInfoTable::iterator it = aPair.first;
if( aPair.second && ! it->second )
- {
+ {
std::vector<KeywordInfo::KeywordElement> aVector;
KeyDataBaseFileIterator aDbFileIt( m_xContext, *this, Database, Language );
@@ -880,9 +928,68 @@ KeywordInfo* Databases::getKeyword( const rtl::OUString& Database,
rtl::OString fileName( fileNameOU.getStr(),
fileNameOU.getLength(),
osl_getThreadTextEncoding() );
-
+
Db table;
- if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
+
+ rtl::OUString fileNameDBHelp( fileNameOU );
+ if( bExtension )
+ fileNameDBHelp += rtl::OUString::createFromAscii( "_" );
+ if( m_xSFA->exists( fileNameDBHelp ) )
+ {
+ DBHelp aDBHelp( fileNameDBHelp, m_xSFA );
+
+ DBData aKey;
+ DBData aValue;
+ if( aDBHelp.startIteration() )
+ {
+ Db* idmap = getBerkeley( Database,Language );
+
+ DBHelp* pDBHelp = idmap->getDBHelp();
+ if( pDBHelp != NULL )
+ {
+ bool bOptimizeForPerformance = true;
+ pDBHelp->releaseHashMap();
+ pDBHelp->createHashMap( bOptimizeForPerformance );
+ }
+
+ while( aDBHelp.getNextKeyAndValue( aKey, aValue ) )
+ {
+ rtl::OUString keyword( aKey.getData(), aKey.getSize(),
+ RTL_TEXTENCODING_UTF8 );
+ rtl::OUString doclist( aValue.getData(), aValue.getSize(),
+ RTL_TEXTENCODING_UTF8 );
+
+ bool bBelongsToDatabase = true;
+ if( bExtension )
+ bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist );
+
+ if( !bBelongsToDatabase )
+ continue;
+
+ aVector.push_back( KeywordInfo::KeywordElement( this,
+ idmap,
+ keyword,
+ doclist ) );
+ }
+ aDBHelp.stopIteration();
+
+ if( pDBHelp != NULL )
+ pDBHelp->releaseHashMap();
+ }
+
+#ifdef TEST_DBHELP
+ bool bSuccess;
+ bool bOldDbAccess = false;
+ bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess );
+
+ bOldDbAccess = true;
+ bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess );
+
+ int nDummy = 0;
+#endif
+ }
+
+ else if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
{
Db* idmap = getBerkeley( Database,Language );
@@ -904,47 +1011,7 @@ KeywordInfo* Databases::getKeyword( const rtl::OUString& Database,
bool bBelongsToDatabase = true;
if( bExtension )
- {
- // Analyse doclist string to find module assignments
- bool bFoundAtLeastOneModule = false;
- bool bModuleMatch = false;
- sal_Int32 nLen = doclist.getLength();
- sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') );
- if( nLastFound == -1 )
- nLastFound = nLen;
- const sal_Unicode* pStr = doclist.getStr();
- sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') );
- while( nFound != -1 )
- {
- // Simple optimization, stop if '_' is followed by "id"
- if( nLen - nFound > 2 )
- {
- if( pStr[ nFound + 1 ] == sal_Unicode('i') &&
- pStr[ nFound + 2 ] == sal_Unicode('d') )
- break;
- }
-
- rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 );
- std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule );
- if( result != m_avModules.end() )
- {
- bFoundAtLeastOneModule = true;
- if( Database == aModule )
- {
- bModuleMatch = true;
- break;
- }
- }
-
- nLastFound = nFound;
- if( nLastFound == 0 )
- break;
- nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 );
- }
-
- if( bFoundAtLeastOneModule && !bModuleMatch )
- bBelongsToDatabase = false;
- }
+ bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist );
if( !bBelongsToDatabase )
continue;
@@ -986,7 +1053,7 @@ Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& ja
{
return Reference< XHierarchicalNameAccess >( 0 );
}
- rtl::OUString key = lang(Language) + aSlash + jar;
+ rtl::OUString key = processLang(Language) + aSlash + jar;
osl::MutexGuard aGuard( m_aMutex );
@@ -1009,8 +1076,6 @@ Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& ja
rtl::OUStringBuffer aStrBuf;
aStrBuf.append( aExtensionPath );
aStrBuf.append( aSlash );
- aStrBuf.append( lang(Language) );
- aStrBuf.append( aSlash );
aStrBuf.append( aPureJar );
zipFile = expandURL( aStrBuf.makeStringAndClear() );
@@ -1183,7 +1248,7 @@ void Databases::cascadingStylesheet( const rtl::OUString& Language,
if( retry == 2 )
fileURL =
getInstallPathAsURL() +
- lang( Language ) +
+ processLang( Language ) +
rtl::OUString::createFromAscii( "/" ) +
m_aCSS +
rtl::OUString::createFromAscii( ".css" );
@@ -1235,53 +1300,66 @@ void Databases::setActiveText( const rtl::OUString& Module,
int* byteCount )
{
DataBaseIterator aDbIt( m_xContext, *this, Module, Language, true );
- bool bSuccess = false;
// #i84550 Cache information about failed ids
rtl::OString id( Id.getStr(),Id.getLength(),RTL_TEXTENCODING_UTF8 );
EmptyActiveTextSet::iterator it = m_aEmptyActiveTextSet.find( id );
bool bFoundAsEmpty = ( it != m_aEmptyActiveTextSet.end() );
Dbt data;
+ DBData aDBData;
+
+ int nSize = 0;
+ const sal_Char* pData = NULL;
+
+ bool bSuccess = false;
if( !bFoundAsEmpty )
{
Db* db;
Dbt key( static_cast< void* >( const_cast< sal_Char* >( id.getStr() ) ),id.getLength() );
- while( (db = aDbIt.nextDb()) != NULL )
+ while( !bSuccess && (db = aDbIt.nextDb()) != NULL )
{
- int err = db->get( 0, &key, &data, 0 );
- if( err == 0 )
+ DBHelp* pDBHelp = db->getDBHelp();
+ if( pDBHelp != NULL )
{
- bSuccess = true;
- break;
+ bSuccess = pDBHelp->getValueForKey( id, aDBData );
+ nSize = aDBData.getSize();
+ pData = aDBData.getData();
+ }
+ else
+ {
+ int err = db->get( 0, &key, &data, 0 );
+ if( err == 0 )
+ {
+ bSuccess = true;
+ nSize = data.get_size();
+ pData = static_cast<sal_Char*>( data.get_data() );
+ }
}
}
}
if( bSuccess )
{
- int len = data.get_size();
- const sal_Char* ptr = static_cast<sal_Char*>( data.get_data() );
-
// ensure existence of tmp after for
rtl::OString tmp;
- for( int i = 0; i < len; ++i )
- if( ptr[i] == '%' || ptr[i] == '$' )
+ for( int i = 0; i < nSize; ++i )
+ if( pData[i] == '%' || pData[i] == '$' )
{
// need of replacement
- rtl::OUString temp = rtl::OUString( ptr,len,RTL_TEXTENCODING_UTF8 );
+ rtl::OUString temp = rtl::OUString( pData, nSize, RTL_TEXTENCODING_UTF8 );
replaceName( temp );
tmp = rtl::OString( temp.getStr(),
temp.getLength(),
RTL_TEXTENCODING_UTF8 );
- len = tmp.getLength();
- ptr = tmp.getStr();
+ nSize = tmp.getLength();
+ pData = tmp.getStr();
break;
}
- *byteCount = len;
- *buffer = new char[ 1 + len ];
- (*buffer)[len] = 0;
- rtl_copyMemory( *buffer,ptr,len );
+ *byteCount = nSize;
+ *buffer = new char[ 1 + nSize ];
+ (*buffer)[nSize] = 0;
+ rtl_copyMemory( *buffer, pData, nSize );
}
else
{
@@ -1321,7 +1399,6 @@ ExtensionIteratorBase::ExtensionIteratorBase( Reference< XComponentContext > xCo
, m_eState( INITIAL_MODULE )
, m_aInitialModule( aInitialModule )
, m_aLanguage( aLanguage )
- , m_aCorrectedLanguage( rDatabases.lang( aLanguage ) )
{
init();
}
@@ -1332,7 +1409,6 @@ ExtensionIteratorBase::ExtensionIteratorBase( Databases& rDatabases,
, m_eState( INITIAL_MODULE )
, m_aInitialModule( aInitialModule )
, m_aLanguage( aLanguage )
- , m_aCorrectedLanguage( rDatabases.lang( aLanguage ) )
{
init();
}
@@ -1492,34 +1568,87 @@ Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPa
return xHelpPackage;
}
-rtl::OUString ExtensionIteratorBase::implGetFileFromPackage( const rtl::OUString& rFileExtension,
- com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
+rtl::OUString ExtensionIteratorBase::implGetFileFromPackage(
+ const rtl::OUString& rFileExtension, Reference< deployment::XPackage > xPackage )
{
+ // No extension -> search for pure language folder
+ bool bLangFolderOnly = (rFileExtension.getLength() == 0);
+
rtl::OUString aFile;
- rtl::OUString aLanguage = m_aCorrectedLanguage;
+ rtl::OUString aLanguage = m_aLanguage;
for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
{
rtl::OUStringBuffer aStrBuf;
aStrBuf.append( xPackage->getURL() );
aStrBuf.append( aSlash );
aStrBuf.append( aLanguage );
- aStrBuf.append( aSlash );
- aStrBuf.append( aHelpFilesBaseName );
- aStrBuf.append( rFileExtension );
+ if( !bLangFolderOnly )
+ {
+ aStrBuf.append( aSlash );
+ aStrBuf.append( aHelpFilesBaseName );
+ aStrBuf.append( rFileExtension );
+ }
aFile = m_rDatabases.expandURL( aStrBuf.makeStringAndClear() );
if( iPass == 0 )
{
if( m_xSFA->exists( aFile ) )
break;
- if( m_aCorrectedLanguage.equals( aEnglishFallbackLang ) )
- break;
- aLanguage = aEnglishFallbackLang;
+
+ ::std::vector< ::rtl::OUString > av;
+ implGetLanguageVectorFromPackage( av, xPackage );
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
+ try
+ {
+ pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
+ }
+ catch( ::comphelper::Locale::MalFormedLocaleException& )
+ {}
+ if( pFound != av.end() )
+ aLanguage = *pFound;
}
}
return aFile;
}
+inline bool isLetter( sal_Unicode c )
+{
+ bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+ return bLetter;
+}
+
+void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
+{
+ rv.clear();
+ rtl::OUString aExtensionPath = xPackage->getURL();
+ Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );
+
+ const rtl::OUString* pSeq = aEntrySeq.getConstArray();
+ sal_Int32 nCount = aEntrySeq.getLength();
+ for( sal_Int32 i = 0 ; i < nCount ; ++i )
+ {
+ rtl::OUString aEntry = pSeq[i];
+ if( m_xSFA->isFolder( aEntry ) )
+ {
+ sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ {
+ rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
+
+ // Check language sceme
+ int nLen = aPureEntry.getLength();
+ const sal_Unicode* pc = aPureEntry.getStr();
+ bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
+ bool bIsLanguage = bStartCanBeLanguage &&
+ ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
+ if( bIsLanguage )
+ rv.push_back( aPureEntry );
+ }
+ }
+ }
+}
+
//===================================================================
// class DataBaseIterator
@@ -1574,16 +1703,35 @@ Db* DataBaseIterator::implGetDbFromPackage( Reference< deployment::XPackage > xP
rtl::OUString* o_pExtensionPath )
{
rtl::OUString aExtensionPath = xPackage->getURL();
- if( o_pExtensionPath )
- *o_pExtensionPath = aExtensionPath;
+ //if( o_pExtensionPath )
+ //*o_pExtensionPath = aExtensionPath;
aExtensionPath += aSlash;
- Db* pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, m_aLanguage,
+ rtl::OUString aUsedLanguage = m_aLanguage;
+ Db* pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage,
m_bHelpText, &aExtensionPath );
- // Fallback to en
- if( !pRetDb && !m_aCorrectedLanguage.equals( aEnglishFallbackLang ) )
- pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aEnglishFallbackLang, m_bHelpText, &aExtensionPath );
+ // Language fallback
+ if( !pRetDb )
+ {
+ ::std::vector< ::rtl::OUString > av;
+ implGetLanguageVectorFromPackage( av, xPackage );
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
+ try
+ {
+ pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
+ }
+ catch( ::comphelper::Locale::MalFormedLocaleException& )
+ {}
+ if( pFound != av.end() )
+ {
+ aUsedLanguage = *pFound;
+ pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aExtensionPath );
+ }
+ }
+
+ if( o_pExtensionPath )
+ *o_pExtensionPath = aExtensionPath + aUsedLanguage;
return pRetDb;
}
@@ -1603,7 +1751,7 @@ rtl::OUString KeyDataBaseFileIterator::nextDbFile( bool& o_rbExtension )
case INITIAL_MODULE:
aRetFile =
m_rDatabases.getInstallPathAsSystemPath() +
- m_aCorrectedLanguage + aSlash + m_aInitialModule +
+ m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule +
rtl::OUString::createFromAscii( ".key" );
o_rbExtension = false;
@@ -1687,9 +1835,7 @@ Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile
if( !xHelpPackage.is() )
break;
- xNA = implGetJarFromPackage( xHelpPackage );
- if( xNA.is() && o_pExtensionPath != NULL )
- *o_pExtensionPath = xHelpPackage->getURL();
+ xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath );
break;
}
@@ -1699,9 +1845,7 @@ Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile
if( !xHelpPackage.is() )
break;
- xNA = implGetJarFromPackage( xHelpPackage );
- if( xNA.is() && o_pExtensionPath != NULL )
- *o_pExtensionPath = xHelpPackage->getURL();
+ xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath );
break;
}
case END_REACHED:
@@ -1714,7 +1858,7 @@ Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile
}
Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage
- ( Reference< deployment::XPackage > xPackage )
+ ( Reference< deployment::XPackage > xPackage, rtl::OUString* o_pExtensionPath )
{
Reference< XHierarchicalNameAccess > xNA;
@@ -1726,9 +1870,6 @@ Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage
Sequence< Any > aArguments( 1 );
aArguments[ 0 ] <<= zipFile;
- // ??? To be used also in Extension context?
- //XInputStream_impl* p = new XInputStream_impl( zipFile );
-
Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
Reference< XInterface > xIfc
= xSMgr->createInstanceWithArgumentsAndContext(
@@ -1749,6 +1890,14 @@ Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage
{}
catch ( Exception & )
{}
+
+ if( xNA.is() && o_pExtensionPath != NULL )
+ {
+ // Extract path including language from file name
+ sal_Int32 nLastSlash = zipFile.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ *o_pExtensionPath = zipFile.copy( 0, nLastSlash );
+ }
return xNA;
}
@@ -1757,7 +1906,7 @@ Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage
//===================================================================
// class IndexFolderIterator
-rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension )
+rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary )
{
rtl::OUString aIndexFolder;
@@ -1768,9 +1917,10 @@ rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension )
case INITIAL_MODULE:
aIndexFolder =
m_rDatabases.getInstallPathAsURL() +
- m_aCorrectedLanguage + aSlash + m_aInitialModule +
+ m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule +
rtl::OUString::createFromAscii( ".idxl" );
+ o_rbTemporary = false;
o_rbExtension = false;
m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
@@ -1787,7 +1937,7 @@ rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension )
if( !xHelpPackage.is() )
break;
- aIndexFolder = implGetIndexFolderFromPackage( xHelpPackage );
+ aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
o_rbExtension = true;
break;
}
@@ -1799,7 +1949,7 @@ rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension )
if( !xHelpPackage.is() )
break;
- aIndexFolder = implGetIndexFolderFromPackage( xHelpPackage );
+ aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
o_rbExtension = true;
break;
}
@@ -1812,10 +1962,124 @@ rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension )
return aIndexFolder;
}
-rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( Reference< deployment::XPackage > xPackage )
+rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( bool& o_rbTemporary, Reference< deployment::XPackage > xPackage )
{
rtl::OUString aIndexFolder =
implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage );
+
+ o_rbTemporary = false;
+ if( !m_xSFA->isFolder( aIndexFolder ) )
+ {
+ // i98680: Missing index? Try to generate now
+ rtl::OUString aLangURL = implGetFileFromPackage( rtl::OUString(), xPackage );
+ if( m_xSFA->isFolder( aLangURL ) )
+ {
+ // Test write access (shared extension may be read only)
+ bool bIsWriteAccess = false;
+ try
+ {
+ rtl::OUString aCreateTestFolder = aLangURL + rtl::OUString::createFromAscii( "CreateTestFolder" );
+ m_xSFA->createFolder( aCreateTestFolder );
+ if( m_xSFA->isFolder( aCreateTestFolder ) )
+ bIsWriteAccess = true;
+
+ m_xSFA->kill( aCreateTestFolder );
+ }
+ catch (Exception &)
+ {}
+
+ // TEST
+ //bIsWriteAccess = false;
+
+ Reference< script::XInvocation > xInvocation;
+ Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
+ try
+ {
+ xInvocation = Reference< script::XInvocation >(
+ m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.help.HelpIndexer" ), m_xContext ) , UNO_QUERY );
+
+ if( xInvocation.is() )
+ {
+ Sequence<uno::Any> aParamsSeq( bIsWriteAccess ? 6 : 8 );
+
+ aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) );
+
+ rtl::OUString aLang;
+ sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ aLang = aLangURL.copy( nLastSlash + 1 );
+ else
+ aLang = rtl::OUString::createFromAscii( "en" );
+ aParamsSeq[1] = uno::makeAny( aLang );
+
+ aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) );
+ aParamsSeq[3] = uno::makeAny( rtl::OUString::createFromAscii( "help" ) );
+
+ rtl::OUString aZipDir = aLangURL;
+ if( !bIsWriteAccess )
+ {
+ rtl::OUString aTempFileURL;
+ ::osl::FileBase::RC eErr = ::osl::File::createTempFile( 0, 0, &aTempFileURL );
+ if( eErr == ::osl::FileBase::E_None )
+ {
+ rtl::OUString aTempDirURL = aTempFileURL;
+ try
+ {
+ m_xSFA->kill( aTempDirURL );
+ }
+ catch (Exception &)
+ {}
+ m_xSFA->createFolder( aTempDirURL );
+
+ aZipDir = aTempDirURL;
+ o_rbTemporary = true;
+ }
+ }
+
+ aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) );
+ rtl::OUString aSystemPath;
+ osl::FileBase::getSystemPathFromFileURL( aZipDir, aSystemPath );
+ aParamsSeq[5] = uno::makeAny( aSystemPath );
+
+ if( !bIsWriteAccess )
+ {
+ aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-srcdir" ) );
+ rtl::OUString aSrcDirVal;
+ osl::FileBase::getSystemPathFromFileURL( aLangURL, aSrcDirVal );
+ aParamsSeq[7] = uno::makeAny( aSrcDirVal );
+ }
+
+ Sequence< sal_Int16 > aOutParamIndex;
+ Sequence< uno::Any > aOutParam;
+ uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ),
+ aParamsSeq, aOutParamIndex, aOutParam );
+
+ if( bIsWriteAccess )
+ aIndexFolder = implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage );
+ else
+ aIndexFolder = aZipDir + rtl::OUString::createFromAscii( "/help.idxl" );
+ }
+ }
+ catch (Exception &)
+ {}
+ }
+ }
+
return aIndexFolder;
}
+void IndexFolderIterator::deleteTempIndexFolder( const rtl::OUString& aIndexFolder )
+{
+ sal_Int32 nLastSlash = aIndexFolder.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ {
+ rtl::OUString aTmpFolder = aIndexFolder.copy( 0, nLastSlash );
+ try
+ {
+ m_xSFA->kill( aTmpFolder );
+ }
+ catch (Exception &)
+ {}
+ }
+}
diff --git a/xmlhelp/source/cxxhelp/provider/databases.hxx b/xmlhelp/source/cxxhelp/provider/databases.hxx
index 9abbadf30c..b213930719 100644
--- a/xmlhelp/source/cxxhelp/provider/databases.hxx
+++ b/xmlhelp/source/cxxhelp/provider/databases.hxx
@@ -211,6 +211,7 @@ namespace chelp {
StaticModuleInformation* getStaticInformationForModule( const rtl::OUString& Module,
const rtl::OUString& Language );
+ bool checkModuleMatchForExtension( const rtl::OUString& Database, const rtl::OUString& doclist );
KeywordInfo* getKeyword( const rtl::OUString& Module,
const rtl::OUString& Language );
@@ -278,7 +279,7 @@ namespace chelp {
* Maps a given language-locale combination to language.
*/
- rtl::OUString lang( const rtl::OUString& Language );
+ rtl::OUString processLang( const rtl::OUString& Language );
/**
@@ -289,13 +290,6 @@ namespace chelp {
rtl::OUString country( const rtl::OUString& Language );
- /**
- * Maps a given System to the variant part of a locale.
- */
-
- rtl::OUString variant( const rtl::OUString& System );
-
-
void replaceName( rtl::OUString& oustring ) const;
rtl::OUString getProductName() const { return m_vReplacement[0]; }
@@ -314,6 +308,7 @@ namespace chelp {
osl::Mutex m_aMutex;
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext;
com::sun::star::uno::Reference< com::sun::star::lang::XMultiComponentFactory > m_xSMgr;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA;
sal_Bool m_bShowBasic;
int m_nErrorDocLength;
@@ -401,10 +396,6 @@ namespace chelp {
// methods
void setInstallPath( const rtl::OUString& aInstallDirectory );
-
- static void implCollectXhpFiles( const rtl::OUString& aDir,
- std::vector< rtl::OUString >& o_rXhpFileVector,
- com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > xSFA );
}; // end class Databases
@@ -453,6 +444,8 @@ namespace chelp {
( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );
rtl::OUString implGetFileFromPackage( const rtl::OUString& rFileExtension,
com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );
+ void implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext;
com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA;
@@ -463,7 +456,6 @@ namespace chelp {
rtl::OUString m_aInitialModule;
rtl::OUString m_aLanguage;
- rtl::OUString m_aCorrectedLanguage;
com::sun::star::uno::Sequence< com::sun::star::uno::Reference
< com::sun::star::deployment::XPackage > > m_aUserPackagesSeq;
@@ -538,7 +530,8 @@ namespace chelp {
private:
com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >
- implGetJarFromPackage(com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );
+ implGetJarFromPackage(com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage,
+ rtl::OUString* o_pExtensionPath = NULL );
}; // end class JarFileIterator
@@ -550,10 +543,11 @@ namespace chelp {
: ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage )
{}
- rtl::OUString nextIndexFolder( bool& o_rbExtension );
+ rtl::OUString nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary );
+ void deleteTempIndexFolder( const rtl::OUString& aIndexFolder );
private:
- rtl::OUString implGetIndexFolderFromPackage(
+ rtl::OUString implGetIndexFolderFromPackage( bool& o_rbTemporary,
com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );
}; // end class KeyDataBaseFileIterator
diff --git a/xmlhelp/source/cxxhelp/provider/db.cxx b/xmlhelp/source/cxxhelp/provider/db.cxx
index c98f51eab3..a8d8769882 100644
--- a/xmlhelp/source/cxxhelp/provider/db.cxx
+++ b/xmlhelp/source/cxxhelp/provider/db.cxx
@@ -36,25 +36,459 @@
#include <rtl/alloc.h>
#include <cstring>
+#include "com/sun/star/io/XSeekable.hpp"
+
+#ifdef TEST_DBHELP
+#include <osl/time.h>
+#endif
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+
namespace berkeleydbproxy {
//----------------------------------------------------------------------------
- namespace db_internal
+namespace db_internal
+{
+ // static void raise_error(int dberr, const char * where);
+
+ static inline int check_error(int dberr, const char * where)
+ {
+ (void)where;
+
+ // if (dberr) raise_error(dberr,where);
+ return dberr;
+ }
+}
+
+void DBData::copyToBuffer( const char* pSrcData, int nSize )
+{
+ m_nSize = nSize;
+ delete m_pBuffer;
+ m_pBuffer = new char[m_nSize+1];
+ memcpy( m_pBuffer, pSrcData, m_nSize );
+ m_pBuffer[m_nSize] = 0;
+}
+
+
+// DBHelp
+
+bool DBHelp::implReadLenAndData( const char* pData, int& riPos, DBData& rValue )
+{
+ bool bSuccess = false;
+
+ // Read key len
+ const char* pStartPtr = pData + riPos;
+ char* pEndPtr;
+ sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 );
+ if( pEndPtr == pStartPtr )
+ return bSuccess;
+ riPos += (pEndPtr - pStartPtr) + 1;
+
+ const char* pKeySrc = pData + riPos;
+ rValue.copyToBuffer( pKeySrc, nKeyLen );
+ riPos += nKeyLen + 1;
+
+ bSuccess = true;
+ return bSuccess;
+}
+
+#ifdef TEST_DBHELP
+
+typedef std::pair< rtl::OString, rtl::OString > KeyValPair;
+typedef std::vector< KeyValPair > KeyValPairVector;
+
+void testWriteKeyValue( FILE* pFile, const KeyValPair& rKeyValPair )
+{
+ if( pFile == NULL )
+ return;
+ char cLF = 10;
+
+ const rtl::OString& aKeyStr = rKeyValPair.first;
+ const rtl::OString& aValueStr = rKeyValPair.second;
+ int nKeyLen = aKeyStr.getLength();
+ int nValueLen = aValueStr.getLength();
+ fprintf( pFile, "%x ", nKeyLen );
+ if( nKeyLen > 0 )
+ fwrite( aKeyStr.getStr(), 1, nKeyLen, pFile );
+ fprintf( pFile, " %x ", nValueLen );
+ if( nValueLen > 0 )
+ fwrite( aValueStr.getStr(), 1, nValueLen, pFile );
+ fprintf( pFile, "%c", cLF );
+}
+
+bool DBHelp::testAgainstDb( const rtl::OString& fileName, bool bOldDbAccess )
+{
+ bool bSuccess = true;
+
+ KeyValPairVector avKeyValPair;
+
+ rtl::OString aOutFileName = fileName;
+ aOutFileName += "_TestOut";
+ if( bOldDbAccess )
+ aOutFileName += "_Old";
+ FILE* pFile = fopen( aOutFileName.getStr(), "wb" );
+
+ // Get all values
+ Db table;
+ if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
{
- // static void raise_error(int dberr, const char * where);
+ bool first = true;
- static inline int check_error(int dberr, const char * where)
+ Dbc* cursor = 0;
+ table.cursor( 0,&cursor,0 );
+ Dbt key_,data;
+ key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory
+ data.set_flags( DB_DBT_MALLOC );
+
+ while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) )
{
- (void)where;
-
- // if (dberr) raise_error(dberr,where);
- return dberr;
+ rtl::OString keyword( static_cast<sal_Char*>(key_.get_data()),
+ key_.get_size() );
+ rtl::OString value( static_cast<sal_Char*>(data.get_data()),
+ data.get_size() );
+
+ KeyValPair aPair( keyword, value );
+ avKeyValPair.push_back( aPair );
+ if( pFile != NULL )
+ testWriteKeyValue( pFile, aPair );
+
+ if( first )
+ {
+ key_.set_flags( DB_DBT_REALLOC );
+ data.set_flags( DB_DBT_REALLOC );
+ first = false;
+ }
}
+
+ if( cursor ) cursor->close();
+ }
+ table.close( 0 );
+
+ // TEST
+ DBData aDBData;
+ Db tableTest;
+ Dbt data;
+
+ int nOkCount = 0;
+ int nErrCount = 0;
+
+ bool bTestSuccess;
+ const char* pTestReadData = NULL;
+ int nTestReadDataSize = 0;
+
+ sal_uInt32 starttime = osl_getGlobalTimer();
+ sal_uInt32 afterfirsttime = starttime;
+
+ if( pFile != NULL )
+ {
+ if( bOldDbAccess )
+ fprintf( pFile, "\nTesting old access:\n" );
+ else
+ fprintf( pFile, "\nTesting new access:\n" );
}
+ KeyValPairVector::const_iterator it;
+ bool bFirst = true;
+ for( it = avKeyValPair.begin() ; it != avKeyValPair.end() ; ++it )
+ {
+ const KeyValPair& rKeyValPair = *it;
+
+ const rtl::OString& aKeyStr = rKeyValPair.first;
+ const rtl::OString& aValueStr = rKeyValPair.second;
+ int nKeyLen = aKeyStr.getLength();
+ int nValueLen = aValueStr.getLength();
+
+ const sal_Char* ptr = aValueStr.getStr();
+
+ bTestSuccess = false;
+ pTestReadData = NULL;
+ nTestReadDataSize = 0;
+ if( bOldDbAccess )
+ {
+ if( bFirst )
+ {
+ if( tableTest.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
+ {
+ if( pFile != NULL )
+ fprintf( pFile, "Cannot open database\n" );
+
+ break;
+ }
+ }
+
+ Dbt key( static_cast< void* >( const_cast< sal_Char* >( aKeyStr.getStr() ) ), aKeyStr.getLength() );
+ int err = tableTest.get( 0, &key, &data, 0 );
+ if( err == 0 )
+ {
+ bTestSuccess = true;
+ pTestReadData = static_cast< sal_Char* >( data.get_data() );
+ nTestReadDataSize = data.get_size();
+ }
+ }
+ else
+ {
+ bTestSuccess = getValueForKey( aKeyStr, aDBData );
+ if( bTestSuccess )
+ {
+ pTestReadData = aDBData.getData();
+ nTestReadDataSize = aDBData.getSize();
+ }
+ }
+ if( bFirst )
+ {
+ afterfirsttime = osl_getGlobalTimer();
+ bFirst = false;
+ }
+ int nError = 0;
+ if( bTestSuccess && pTestReadData != NULL )
+ {
+ int nCmp = memcmp( ptr, pTestReadData, nValueLen );
+ if( nCmp == 0 )
+ ++nOkCount;
+ else
+ nError = 1;
+
+ if( nValueLen != nTestReadDataSize )
+ nError = 2;
+ }
+ else
+ nError = 3;
+
+ if( nError != 0 )
+ {
+ bSuccess = false;
+ ++nErrCount;
+
+ if( pFile != NULL )
+ {
+ fprintf( pFile, "ERROR, not found:\n" );
+ testWriteKeyValue( pFile, rKeyValPair );
+ fprintf( pFile, "\nError Code: %d\n", nError );
+ }
+ }
+ }
+ tableTest.close( 0 );
+
+ sal_uInt32 endtime = osl_getGlobalTimer();
+ double dDiffTime = (endtime-starttime) / 1000.0;
+ double dDiffFirstTime = (afterfirsttime-starttime) / 1000.0;
+ if( pFile != NULL )
+ {
+ int nCount = avKeyValPair.size();
+ fprintf( pFile, "%d key/values in total, read %d correctly, %d errors\n",
+ nCount, nOkCount, nErrCount );
+ fprintf( pFile, "Time taken: %g s (First access %g s)\n", dDiffTime, dDiffFirstTime );
+ fprintf( pFile, "Average time per access: %g s\n", dDiffTime / nCount );
+ }
+
+ if( pFile != NULL )
+ fclose( pFile );
+
+ return bSuccess;
+}
+
+#endif
+
+
+void DBHelp::createHashMap( bool bOptimizeForPerformance )
+{
+ releaseHashMap();
+ if( bOptimizeForPerformance )
+ {
+ if( m_pStringToDataMap != NULL )
+ return;
+ m_pStringToDataMap = new StringToDataMap();
+ }
+ else
+ {
+ if( m_pStringToValPosMap != NULL )
+ return;
+ m_pStringToValPosMap = new StringToValPosMap();
+ }
+
+ Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName );
+ if( xIn.is() )
+ {
+ Sequence< sal_Int8 > aData;
+ sal_Int32 nSize = m_xSFA->getSize( m_aFileName );
+ sal_Int32 nRead = xIn->readBytes( aData, nSize );
+
+ const char* pData = (const char*)aData.getConstArray();
+ int iPos = 0;
+ while( iPos < nRead )
+ {
+ DBData aDBKey;
+ if( !implReadLenAndData( pData, iPos, aDBKey ) )
+ break;
+
+ rtl::OString aOKeyStr = aDBKey.getData();
+
+ // Read val len
+ const char* pStartPtr = pData + iPos;
+ char* pEndPtr;
+ sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 );
+ if( pEndPtr == pStartPtr )
+ break;
+
+ iPos += (pEndPtr - pStartPtr) + 1;
+
+ if( bOptimizeForPerformance )
+ {
+ const char* pValSrc = pData + iPos;
+ rtl::OString aValStr( pValSrc, nValLen );
+ (*m_pStringToDataMap)[aOKeyStr] = aValStr;
+ }
+ else
+ {
+ // store value start position
+ (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen );
+ }
+ iPos += nValLen + 1;
+ }
+
+ xIn->closeInput();
+ }
+}
+
+void DBHelp::releaseHashMap( void )
+{
+ if( m_pStringToDataMap != NULL )
+ {
+ delete m_pStringToDataMap;
+ m_pStringToDataMap = NULL;
+ }
+ if( m_pStringToValPosMap != NULL )
+ {
+ delete m_pStringToValPosMap;
+ m_pStringToValPosMap = NULL;
+ }
+}
+
+
+bool DBHelp::getValueForKey( const rtl::OString& rKey, DBData& rValue )
+{
+ bool bSuccess = false;
+ if( !m_xSFA.is() )
+ return bSuccess;
+
+ try
+ {
+
+ if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL )
+ {
+ bool bOptimizeForPerformance = false;
+ createHashMap( bOptimizeForPerformance );
+ }
+
+ if( m_pStringToValPosMap != NULL )
+ {
+ StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey );
+ if( it != m_pStringToValPosMap->end() )
+ {
+ const std::pair<int,int>& rValPair = it->second;
+ int iValuePos = rValPair.first;
+ int nValueLen = rValPair.second;
+
+ Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName );
+ if( xIn.is() )
+ {
+ Reference< XSeekable > xXSeekable( xIn, UNO_QUERY );
+ if( xXSeekable.is() )
+ {
+ xXSeekable->seek( iValuePos );
+
+ Sequence< sal_Int8 > aData;
+ sal_Int32 nRead = xIn->readBytes( aData, nValueLen );
+ if( nRead == nValueLen )
+ {
+ const char* pData = (const sal_Char*)aData.getConstArray();
+ rValue.copyToBuffer( pData, nValueLen );
+ bSuccess = true;
+ }
+ }
+ xIn->closeInput();
+ }
+ }
+ }
+
+ else if( m_pStringToDataMap != NULL )
+ {
+ StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey );
+ if( it != m_pStringToDataMap->end() )
+ {
+ const rtl::OString& rValueStr = it->second;
+ int nValueLen = rValueStr.getLength();
+ const char* pData = rValueStr.getStr();
+ rValue.copyToBuffer( pData, nValueLen );
+ bSuccess = true;
+ }
+ }
+
+ }
+ catch( Exception & )
+ {
+ bSuccess = false;
+ }
+
+ return bSuccess;
+}
+
+bool DBHelp::startIteration( void )
+{
+ bool bSuccess = false;
+
+ sal_Int32 nSize = m_xSFA->getSize( m_aFileName );
+
+ Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName );
+ if( xIn.is() )
+ {
+ m_nItRead = xIn->readBytes( m_aItData, nSize );
+ if( m_nItRead == nSize )
+ {
+ bSuccess = true;
+ m_pItData = (const char*)m_aItData.getConstArray();
+ m_iItPos = 0;
+ }
+ else
+ {
+ stopIteration();
+ }
+ }
+
+ return bSuccess;
+}
+
+bool DBHelp::getNextKeyAndValue( DBData& rKey, DBData& rValue )
+{
+ bool bSuccess = false;
+
+ if( m_iItPos < m_nItRead )
+ {
+ if( implReadLenAndData( m_pItData, m_iItPos, rKey ) )
+ {
+ if( implReadLenAndData( m_pItData, m_iItPos, rValue ) )
+ bSuccess = true;
+ }
+ }
+
+ return bSuccess;
+}
+
+void DBHelp::stopIteration( void )
+{
+ m_aItData = Sequence<sal_Int8>();
+ m_pItData = NULL;
+ m_nItRead = -1;
+ m_iItPos = -1;
+}
+
+
Db::Db()
{
db_internal::check_error( db_create(&m_pDBP,0,0),"Db::Db" );
+ m_pDBHelp = NULL;
}
@@ -65,7 +499,8 @@ Db::~Db()
// should not happen
// TODO: add assert
}
-
+
+ delete m_pDBHelp;
}
@@ -159,6 +594,7 @@ Dbt::Dbt(void *data_arg, u_int32_t size_arg)
this->set_size(size_arg);
}
+/*
Dbt::Dbt(const Dbt & other)
{
using namespace std;
@@ -178,6 +614,7 @@ Dbt& Dbt::operator = (const Dbt & other)
}
return *this;
}
+*/
Dbt::~Dbt()
{
diff --git a/xmlhelp/source/cxxhelp/provider/db.hxx b/xmlhelp/source/cxxhelp/provider/db.hxx
index 338e81bc46..2997ab8e56 100644
--- a/xmlhelp/source/cxxhelp/provider/db.hxx
+++ b/xmlhelp/source/cxxhelp/provider/db.hxx
@@ -36,6 +36,9 @@
#include <berkeleydb/db.h>
#endif
+#include "com/sun/star/ucb/XSimpleFileAccess.hpp"
+
+#include <hash_map>
#include <rtl/string.hxx>
extern "C" {
@@ -75,16 +78,106 @@ namespace berkeleydbproxy {
{ return what_.getStr(); }
};
-
+ struct eq
+ {
+ bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const
+ { return rKey1.compareTo( rKey2 ) == 0; }
+ };
+
+ struct ha
+ {
+ size_t operator()( const rtl::OString& rName ) const
+ { return rName.hashCode(); }
+ };
+
+
+//#define TEST_DBHELP
+
+ class DBData
+ {
+ friend class DBHelp;
+
+ int m_nSize;
+ char* m_pBuffer;
+
+ void copyToBuffer( const char* pSrcData, int nSize );
+
+ public:
+ DBData( void )
+ : m_nSize( 0 )
+ , m_pBuffer( NULL )
+ {}
+ ~DBData()
+ { delete m_pBuffer; }
+
+ int getSize() const
+ { return m_nSize; }
+ const char* getData() const
+ { return m_pBuffer; }
+ };
+
+ typedef std::hash_map< rtl::OString,std::pair<int,int>,ha,eq > StringToValPosMap;
+ typedef std::hash_map< rtl::OString,rtl::OString,ha,eq > StringToDataMap;
+
+ class DBHelp
+ {
+ rtl::OUString m_aFileName;
+ StringToDataMap* m_pStringToDataMap;
+ StringToValPosMap* m_pStringToValPosMap;
+ com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess >
+ m_xSFA;
+
+ com::sun::star::uno::Sequence< sal_Int8 >
+ m_aItData;
+ const char* m_pItData;
+ int m_nItRead;
+ int m_iItPos;
+
+ bool implReadLenAndData( const char* pData, int& riPos, DBData& rValue );
+
+ public:
+ DBHelp( const rtl::OUString& rFileName,
+ com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > xSFA )
+ : m_aFileName( rFileName )
+ , m_pStringToDataMap( NULL )
+ , m_pStringToValPosMap( NULL )
+ , m_xSFA( xSFA )
+ , m_pItData( NULL )
+ , m_nItRead( -1 )
+ , m_iItPos( -1 )
+ {}
+ ~DBHelp()
+ { releaseHashMap(); }
+
+ void createHashMap( bool bOptimizeForPerformance = false );
+ void releaseHashMap( void );
+
+#ifdef TEST_DBHELP
+ bool testAgainstDb( const rtl::OString& fileName, bool bOldDbAccess );
+#endif
+
+ bool getValueForKey( const rtl::OString& rKey, DBData& rValue );
+
+ bool startIteration( void );
+ bool getNextKeyAndValue( DBData& rKey, DBData& rValue );
+ void stopIteration( void );
+ };
+
class Db : db_internal::Noncopyable
{
private:
DB* m_pDBP;
+ DBHelp* m_pDBHelp;
public:
Db();
~Db();
+ void setDBHelp( DBHelp* pDBHelp )
+ { m_pDBHelp = pDBHelp; }
+ DBHelp* getDBHelp( void )
+ { return m_pDBHelp; }
+
int close(u_int32_t flags);
int open(DB_TXN *txnid,
@@ -126,8 +219,8 @@ namespace berkeleydbproxy {
Dbt(void *data_arg, u_int32_t size_arg);
Dbt();
- Dbt(const Dbt & other);
- Dbt & operator=(const Dbt & other);
+ //Dbt(const Dbt & other);
+ //Dbt & operator=(const Dbt & other);
~Dbt();
diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx b/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx
index 0035c4fdf9..e0602f5efa 100644
--- a/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx
+++ b/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx
@@ -152,7 +152,9 @@ ResultSetForQuery::ResultSetForQuery( const uno::Reference< lang::XMultiServiceF
bool bExtension = false;
int iDir = 0;
vector< vector<HitItem>* > aIndexFolderResultVectorVector;
- while( (idxDir = aIndexFolderIt.nextIndexFolder( bExtension )).getLength() > 0 )
+
+ bool bTemporary;
+ while( (idxDir = aIndexFolderIt.nextIndexFolder( bExtension, bTemporary )).getLength() > 0 )
{
vector<HitItem> aIndexFolderResultVector;
@@ -336,6 +338,9 @@ ResultSetForQuery::ResultSetForQuery( const uno::Reference< lang::XMultiServiceF
++iDir;
+ if( bTemporary )
+ aIndexFolderIt.deleteTempIndexFolder( idxDir );
+
} // Iterator
diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
index 4fac24adfd..3c6a8ea0a2 100644
--- a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
+++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
@@ -303,7 +303,11 @@ void URLParameter::readBerkeley()
DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false );
bool bSuccess = false;
+ int nSize = 0;
+ const sal_Char* pData = NULL;
+
Dbt data;
+ DBData aDBData;
rtl::OUString aExtensionPath;
while( true )
{
@@ -312,21 +316,36 @@ void URLParameter::readBerkeley()
break;
rtl::OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 );
- Dbt key( static_cast< void* >( const_cast< sal_Char* >( keyStr.getStr() ) ),
- keyStr.getLength() );
- int err = db->get( 0,&key,&data,0 );
- if( err == 0 )
+ DBHelp* pDBHelp = db->getDBHelp();
+ if( pDBHelp != NULL )
{
- bSuccess = true;
- break;
+ bSuccess = pDBHelp->getValueForKey( keyStr, aDBData );
+ if( bSuccess )
+ {
+ nSize = aDBData.getSize();
+ pData = aDBData.getData();
+ break;
+ }
+ }
+ else
+ {
+ Dbt key( static_cast< void* >( const_cast< sal_Char* >( keyStr.getStr() ) ),
+ keyStr.getLength() );
+ int err = db->get( 0,&key,&data,0 );
+ if( err == 0 )
+ {
+ bSuccess = true;
+ nSize = data.get_size();
+ pData = static_cast<sal_Char*>( data.get_data() );
+ break;
+ }
}
}
if( bSuccess )
{
- DbtToStringConverter converter( static_cast< sal_Char* >( data.get_data() ),
- data.get_size() );
+ DbtToStringConverter converter( pData, nSize );
m_aTitle = converter.getTitle();
m_pDatabases->replaceName( m_aTitle );
m_aPath = converter.getFile();
@@ -1034,12 +1053,6 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam,
rtl::OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionPath, xContext );
rtl::OString aExpandedExtensionPath = rtl::OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() );
- // Add extension language part
- rtl::OString aExtensionLanguage = aPureLanguage;
- if( aExtensionLanguage.getLength() > 2 )
- aExtensionLanguage = aExtensionLanguage.copy( 0, 2 );
- aExpandedExtensionPath += rtl::OString('/');
- aExpandedExtensionPath += aExtensionLanguage;
parString[last++] = "ExtensionPath";
parString[last++] = rtl::OString('\'') + aExpandedExtensionPath + rtl::OString('\'');
diff --git a/xmlhelp/source/treeview/tvread.cxx b/xmlhelp/source/treeview/tvread.cxx
index 3938adb683..bc7af59f5e 100644
--- a/xmlhelp/source/treeview/tvread.cxx
+++ b/xmlhelp/source/treeview/tvread.cxx
@@ -55,6 +55,7 @@
#include <com/sun/star/util/XMacroExpander.hpp>
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
+#include <comphelper/locale.hxx>
namespace treeview {
@@ -967,13 +968,11 @@ void TVChildTarget::subst( const Reference< XMultiServiceFactory >& m_xSMgr,
static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) );
-static rtl::OUString aEnglishFallbackLang( rtl::OUString::createFromAscii( "en" ) );
static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) );
ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString& aLanguage )
: m_eState( USER_EXTENSIONS )
, m_aLanguage( aLanguage )
- , m_aCorrectedLanguage( aLanguage )
{
init();
}
@@ -1119,6 +1118,44 @@ Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPa
return xHelpPackage;
}
+inline bool isLetter( sal_Unicode c )
+{
+ bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+ return bLetter;
+}
+
+void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
+{
+ rv.clear();
+ rtl::OUString aExtensionPath = xPackage->getURL();
+ Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );
+
+ const rtl::OUString* pSeq = aEntrySeq.getConstArray();
+ sal_Int32 nCount = aEntrySeq.getLength();
+ for( sal_Int32 i = 0 ; i < nCount ; ++i )
+ {
+ rtl::OUString aEntry = pSeq[i];
+ if( m_xSFA->isFolder( aEntry ) )
+ {
+ sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ {
+ rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
+
+ // Check language sceme
+ int nLen = aPureEntry.getLength();
+ const sal_Unicode* pc = aPureEntry.getStr();
+ bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
+ bool bIsLanguage = bStartCanBeLanguage &&
+ ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
+ if( bIsLanguage )
+ rv.push_back( aPureEntry );
+ }
+ }
+ }
+}
+
//===================================================================
// class TreeFileIterator
@@ -1212,7 +1249,7 @@ rtl::OUString TreeFileIterator::implGetTreeFileFromPackage
( sal_Int32& rnFileSize, Reference< deployment::XPackage > xPackage )
{
rtl::OUString aRetFile;
- rtl::OUString aLanguage = m_aCorrectedLanguage;
+ rtl::OUString aLanguage = m_aLanguage;
for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
{
rtl::OUStringBuffer aStrBuf;
@@ -1228,9 +1265,18 @@ rtl::OUString TreeFileIterator::implGetTreeFileFromPackage
{
if( m_xSFA->exists( aRetFile ) )
break;
- if( m_aCorrectedLanguage.equals( aEnglishFallbackLang ) )
- break;
- aLanguage = aEnglishFallbackLang;
+
+ ::std::vector< ::rtl::OUString > av;
+ implGetLanguageVectorFromPackage( av, xPackage );
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
+ try
+ {
+ pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
+ }
+ catch( ::comphelper::Locale::MalFormedLocaleException& )
+ {}
+ if( pFound != av.end() )
+ aLanguage = *pFound;
}
}
diff --git a/xmlhelp/source/treeview/tvread.hxx b/xmlhelp/source/treeview/tvread.hxx
index 6b9f2f0f79..f04538a7b6 100644
--- a/xmlhelp/source/treeview/tvread.hxx
+++ b/xmlhelp/source/treeview/tvread.hxx
@@ -350,6 +350,8 @@ namespace treeview {
( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );
com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextSharedHelpPackage
( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );
+ void implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );
osl::Mutex m_aMutex;
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext;
@@ -357,7 +359,6 @@ namespace treeview {
IteratorState m_eState;
rtl::OUString m_aLanguage;
- rtl::OUString m_aCorrectedLanguage;
com::sun::star::uno::Sequence< com::sun::star::uno::Reference
< com::sun::star::deployment::XPackage > > m_aUserPackagesSeq;