[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 2 commits - sc/qa sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Tue Nov 5 17:55:36 CET 2013
sc/qa/unit/ucalc.hxx | 2
sc/qa/unit/ucalc_formula.cxx | 56 +++++++++++++++++++++++++++
sc/source/core/tool/address.cxx | 67 +++++++++++++++++++++++++--------
sc/source/filter/oox/formulabuffer.cxx | 2
4 files changed, 111 insertions(+), 16 deletions(-)
New commits:
commit 4d2666fa2b40b17673589e7b226907e9353f7e9d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 11:55:57 2013 -0500
Avoid using an extra buffer when the name doesn't contain double-quotes.
Change-Id: Idc76ccad114e5964f80c5a3c8c8da2a64c1a2b86
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 039b256..495c9a0 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -47,6 +47,44 @@ ScAddress::Details::Details ( const ScDocument* pDoc,
{
}
+namespace {
+
+const sal_Unicode* parseQuotedNameWithBuffer( const sal_Unicode* pStart, const sal_Unicode* p, OUString& rName )
+{
+ // The current character must be on the 2nd quote.
+
+ // Push all the characters up to the current, but skip the very first
+ // character which is the opening quote.
+ OUStringBuffer aBuf(OUString(pStart+1, p-pStart-1));
+
+ ++p; // Skip the 2nd quote.
+ sal_Unicode cPrev = 0;
+ for (; *p; ++p)
+ {
+ if (*p == '\'')
+ {
+ if (cPrev == '\'')
+ {
+ // double single-quote equals one single quote.
+ aBuf.append(*p);
+ cPrev = 0;
+ continue;
+ }
+ }
+ else if (cPrev == '\'')
+ {
+ // We are past the closing quote. We're done!
+ rName = aBuf.makeStringAndClear();
+ return p;
+ }
+ else
+ aBuf.append(*p);
+ cPrev = *p;
+ }
+
+ return pStart;
+}
+
/**
* Parse from the opening single quote to the closing single quote. Inside
* the quotes, a single quote character is encoded by double single-quote
@@ -59,13 +97,11 @@ ScAddress::Details::Details ( const ScDocument* pDoc,
* @return pointer to the character immediately after the closing single
* quote.
*/
-static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& rName )
+const sal_Unicode* parseQuotedName( const sal_Unicode* p, OUString& rName )
{
- rName = "";
if (*p != '\'')
return p;
- OUStringBuffer aBuf;
const sal_Unicode* pStart = p;
sal_Unicode cPrev = 0;
for (++p; *p; ++p)
@@ -75,25 +111,26 @@ static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& r
if (cPrev == '\'')
{
// double single-quote equals one single quote.
- aBuf.append(*p);
- cPrev = 0;
- continue;
+ return parseQuotedNameWithBuffer(pStart, p, rName);
}
}
else if (cPrev == '\'')
{
- // We are past the closing quote. We're done!
- rName = aBuf.makeStringAndClear();
+ // We are past the closing quote. We're done! Skip the opening
+ // and closing quotes.
+ rName = OUString(pStart+1, p - pStart-2);
return p;
}
- else
- aBuf.append(*p);
+
cPrev = *p;
}
+ rName = "";
return pStart;
}
+}
+
static long int
sal_Unicode_strtol ( const sal_Unicode* p,
const sal_Unicode** pEnd )
@@ -265,7 +302,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode* start,
}
else if( *p == '\'')
{
- p = lcl_ParseQuotedName(p, aTabName);
+ p = parseQuotedName(p, aTabName);
if (aTabName.isEmpty())
return NULL;
}
@@ -415,7 +452,7 @@ const sal_Unicode* ScRange::Parse_XL_Header(
// single quote text inside the quoted text.
if (*p == '\'')
{
- p = lcl_ParseQuotedName(p, rExternDocName);
+ p = parseQuotedName(p, rExternDocName);
if (!*p || *p != ']' || rExternDocName.isEmpty())
{
rExternDocName = "";
@@ -447,7 +484,7 @@ const sal_Unicode* ScRange::Parse_XL_Header(
// Excel does not allow [ and ] characters in sheet names though.
// But, more sickness comes with MOOXML as there may be
// '[1]Sheet 4'!$A$1 where [1] is the external doc's index.
- p = lcl_ParseQuotedName(p, rExternDocName);
+ p = parseQuotedName(p, rExternDocName);
if (!*p || *p != '!')
{
rExternDocName = "";
@@ -1003,7 +1040,7 @@ lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAdd
{
const sal_Unicode* pStart = p;
OUString aTmp;
- p = lcl_ParseQuotedName(p, aTmp);
+ p = parseQuotedName(p, aTmp);
aDocName = aTmp;
if (*p++ == SC_COMPILER_FILE_TAB_SEP)
bExtDoc = true;
@@ -1036,7 +1073,7 @@ lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAdd
// Tokens that start at ' can have anything in them until a final
// ' but '' marks an escaped '. We've earlier guaranteed that a
// string containing '' will be surrounded by '.
- p = lcl_ParseQuotedName(p, aTab);
+ p = parseQuotedName(p, aTab);
}
else
{
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index bc074a2..68e1d2e 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -90,11 +90,11 @@ void FormulaBuffer::finalizeImport()
void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
{
ScDocumentImport& rDoc = getDocImport();
+ ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
{
ScAddress aPos;
ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
- ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
ScCompiler aCompiler(&rDoc.getDoc(), aPos);
aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);
commit e5f2c9f1c244f199ba0765e26161a7b674bee75d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Nov 5 11:00:05 2013 -0500
Add new test for parsing OOo A1 style single references.
Change-Id: I7644338bd536d16777d330a64764eb26ecda5da5
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index b9c1d42..19c94d7 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -84,6 +84,7 @@ public:
void testRangeList();
void testInput();
+ void testFormulaParseReference();
void testFetchVectorRefArray();
void testFormulaHashAndTag();
void testFormulaRefData();
@@ -292,6 +293,7 @@ public:
CPPUNIT_TEST(testSharedStringPool);
CPPUNIT_TEST(testRangeList);
CPPUNIT_TEST(testInput);
+ CPPUNIT_TEST(testFormulaParseReference);
CPPUNIT_TEST(testFetchVectorRefArray);
CPPUNIT_TEST(testFormulaHashAndTag);
CPPUNIT_TEST(testFormulaRefData);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 9f824e5..ce407e7 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -73,6 +73,62 @@ bool equals( const formula::VectorRefArray& rArray, size_t nPos, const OUString&
}
+void Test::testFormulaParseReference()
+{
+ OUString aTab1("90's Music"), aTab2("90's and 70's"), aTab3("All Others"), aTab4("NoQuote");
+ m_pDoc->InsertTab(0, "Dummy"); // just to shift the sheet indices...
+ m_pDoc->InsertTab(1, aTab1); // name with a single quote.
+ m_pDoc->InsertTab(2, aTab2); // name with 2 single quotes.
+ m_pDoc->InsertTab(3, aTab3); // name without single quotes.
+ m_pDoc->InsertTab(4, aTab4); // name that doesn't require to be quoted.
+
+ OUString aTabName;
+ m_pDoc->GetName(1, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab1, aTabName);
+ m_pDoc->GetName(2, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab2, aTabName);
+ m_pDoc->GetName(3, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab3, aTabName);
+ m_pDoc->GetName(4, aTabName);
+ CPPUNIT_ASSERT_EQUAL(aTab4, aTabName);
+
+ ScAddress aPos;
+ ScAddress::ExternalInfo aExtInfo;
+ sal_uInt16 nRes = aPos.Parse("'90''s Music'.D10", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(1), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(3), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ nRes = aPos.Parse("'90''s and 70''s'.C100", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(2), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(2), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(99), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ nRes = aPos.Parse("'All Others'.B3", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(3), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(1), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ nRes = aPos.Parse("NoQuote.E13", m_pDoc, formula::FormulaGrammar::CONV_OOO, &aExtInfo);
+ CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & SCA_VALID) != 0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCTAB>(4), aPos.Tab());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCCOL>(4), aPos.Col());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), aPos.Row());
+ CPPUNIT_ASSERT_MESSAGE("This is not an external address.", !aExtInfo.mbExternal);
+
+ m_pDoc->DeleteTab(4);
+ m_pDoc->DeleteTab(3);
+ m_pDoc->DeleteTab(2);
+ m_pDoc->DeleteTab(1);
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testFetchVectorRefArray()
{
m_pDoc->InsertTab(0, "Test");
More information about the Libreoffice-commits
mailing list