Kaydet (Commit) 22eb78b6 authored tarafından Miklos Vajna's avatar Miklos Vajna

fdo#44736 speed up RTF import a bit by sorting keywords

If we sort the keywords once in the constructor, then we can do binary
search when looking up RTF keywords, and that speeds up the import by
about 20% using the first testcase from the bug.
üst da07d3a7
......@@ -27,6 +27,7 @@
#include <rtfcontrolwords.hxx>
#include <sal/macros.h>
#include <string.h>
namespace writerfilter {
namespace rtftok {
......@@ -1856,6 +1857,23 @@ RTFSymbol aRTFControlWords[] = {
};
int nRTFControlWords = SAL_N_ELEMENTS(aRTFControlWords);
bool RTFSymbol::operator<(const RTFSymbol& rOther) const
{
return strcmp(sKeyword, rOther.sKeyword) < 0;
}
RTFSymbol::RTFSymbol(const char* pKeyword)
: sKeyword(pKeyword)
{
}
RTFSymbol::RTFSymbol(const char *pKeyword, int pControlType, RTFKeyword pIndex)
: sKeyword(pKeyword),
nControlType(pControlType),
nIndex(pIndex)
{
}
} // namespace rtftok
} // namespace writerfilter
......
......@@ -1866,6 +1866,10 @@ struct RTFSymbol
const char *sKeyword;
int nControlType;
RTFKeyword nIndex;
bool operator<(const RTFSymbol& rOther) const;
RTFSymbol(const char* pKeyword);
RTFSymbol(const char *pKeyword, int pControlType, RTFKeyword pIndex);
};
extern RTFSymbol aRTFControlWords[];
......
......@@ -45,8 +45,10 @@ namespace rtftok {
RTFTokenizer::RTFTokenizer(RTFDocumentImpl& rImport, SvStream* pInStream, uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
: m_rImport(rImport),
m_pInStream(pInStream),
m_xStatusIndicator(xStatusIndicator)
m_xStatusIndicator(xStatusIndicator),
m_aRTFControlWords(std::vector<RTFSymbol>(aRTFControlWords, aRTFControlWords + nRTFControlWords))
{
std::sort(m_aRTFControlWords.begin(), m_aRTFControlWords.end());
}
RTFTokenizer::~RTFTokenizer()
......@@ -266,13 +268,10 @@ int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam)
return 0;
/*SAL_INFO("writefilter", OSL_THIS_FUNC << ": keyword '\\" << rKeyword.getStr() <<
"' with param? " << (bParam ? 1 : 0) <<" param val: '" << (bParam ? nParam : 0) << "'");*/
int i, ret;
for (i = 0; i < nRTFControlWords; i++)
{
if (!strcmp(rKeyword.getStr(), aRTFControlWords[i].sKeyword))
break;
}
if (i == nRTFControlWords)
RTFSymbol aSymbol(rKeyword.getStr());
std::vector<RTFSymbol>::iterator low = std::lower_bound(m_aRTFControlWords.begin(), m_aRTFControlWords.end(), aSymbol);
int i = low - m_aRTFControlWords.begin();
if (low == m_aRTFControlWords.end() || aSymbol < *low)
{
SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unknown keyword '\\" << rKeyword.getStr() << "'");
RTFSkipDestination aSkip(m_rImport);
......@@ -280,35 +279,36 @@ int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam)
return 0;
}
switch (aRTFControlWords[i].nControlType)
int ret;
switch (m_aRTFControlWords[i].nControlType)
{
case CONTROL_FLAG:
// flags ignore any parameter by definition
ret = m_rImport.dispatchFlag(aRTFControlWords[i].nIndex);
ret = m_rImport.dispatchFlag(m_aRTFControlWords[i].nIndex);
if (ret)
return ret;
break;
case CONTROL_DESTINATION:
// same for destinations
ret = m_rImport.dispatchDestination(aRTFControlWords[i].nIndex);
ret = m_rImport.dispatchDestination(m_aRTFControlWords[i].nIndex);
if (ret)
return ret;
break;
case CONTROL_SYMBOL:
// and symbols
ret = m_rImport.dispatchSymbol(aRTFControlWords[i].nIndex);
ret = m_rImport.dispatchSymbol(m_aRTFControlWords[i].nIndex);
if (ret)
return ret;
break;
case CONTROL_TOGGLE:
ret = m_rImport.dispatchToggle(aRTFControlWords[i].nIndex, bParam, nParam);
ret = m_rImport.dispatchToggle(m_aRTFControlWords[i].nIndex, bParam, nParam);
if (ret)
return ret;
break;
case CONTROL_VALUE:
// values require a parameter by definition
if (bParam) {
ret = m_rImport.dispatchValue(aRTFControlWords[i].nIndex, nParam);
ret = m_rImport.dispatchValue(m_aRTFControlWords[i].nIndex, nParam);
if (ret)
return ret;
}
......
......@@ -51,6 +51,8 @@ namespace writerfilter {
RTFDocumentImpl& m_rImport;
SvStream* m_pInStream;
uno::Reference<task::XStatusIndicator> const& m_xStatusIndicator;
// This is the same as m_aRTFControlWords, but sorted
std::vector<RTFSymbol> m_aRTFControlWords;
};
} // namespace rtftok
} // namespace writerfilter
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment