Avoid using an extra buffer when the name doesn't contain double-quotes.

Change-Id: Idc76ccad114e5964f80c5a3c8c8da2a64c1a2b86
This commit is contained in:
Kohei Yoshida
2013-11-05 11:55:57 -05:00
parent dd9b59ef18
commit 9611851a53
2 changed files with 63 additions and 26 deletions

View File

@@ -47,28 +47,19 @@ ScAddress::Details::Details ( const ScDocument* pDoc,
{ {
} }
/** namespace {
* Parse from the opening single quote to the closing single quote. Inside
* the quotes, a single quote character is encoded by double single-quote
* characters.
*
* @param p pointer to the first character to begin parsing.
* @param rName (reference) parsed name within the quotes. If the name is
* empty, either the parsing failed or it's an empty quote.
*
* @return pointer to the character immediately after the closing single
* quote.
*/
static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& rName )
{
rName = "";
if (*p != '\'')
return p;
OUStringBuffer aBuf; const sal_Unicode* parseQuotedNameWithBuffer( const sal_Unicode* pStart, const sal_Unicode* p, OUString& rName )
const sal_Unicode* pStart = p; {
// 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; sal_Unicode cPrev = 0;
for (++p; *p; ++p) for (; *p; ++p)
{ {
if (*p == '\'') if (*p == '\'')
{ {
@@ -94,6 +85,52 @@ static const sal_Unicode* lcl_ParseQuotedName( const sal_Unicode* p, OUString& r
return pStart; 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
* characters.
*
* @param p pointer to the first character to begin parsing.
* @param rName (reference) parsed name within the quotes. If the name is
* empty, either the parsing failed or it's an empty quote.
*
* @return pointer to the character immediately after the closing single
* quote.
*/
const sal_Unicode* parseQuotedName( const sal_Unicode* p, OUString& rName )
{
if (*p != '\'')
return p;
const sal_Unicode* pStart = p;
sal_Unicode cPrev = 0;
for (++p; *p; ++p)
{
if (*p == '\'')
{
if (cPrev == '\'')
{
// double single-quote equals one single quote.
return parseQuotedNameWithBuffer(pStart, p, rName);
}
}
else if (cPrev == '\'')
{
// We are past the closing quote. We're done! Skip the opening
// and closing quotes.
rName = OUString(pStart+1, p - pStart-2);
return p;
}
cPrev = *p;
}
rName = "";
return pStart;
}
}
static long int static long int
sal_Unicode_strtol ( const sal_Unicode* p, sal_Unicode_strtol ( const sal_Unicode* p,
const sal_Unicode** pEnd ) const sal_Unicode** pEnd )
@@ -265,7 +302,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode* start,
} }
else if( *p == '\'') else if( *p == '\'')
{ {
p = lcl_ParseQuotedName(p, aTabName); p = parseQuotedName(p, aTabName);
if (aTabName.isEmpty()) if (aTabName.isEmpty())
return NULL; return NULL;
} }
@@ -415,7 +452,7 @@ const sal_Unicode* ScRange::Parse_XL_Header(
// single quote text inside the quoted text. // single quote text inside the quoted text.
if (*p == '\'') if (*p == '\'')
{ {
p = lcl_ParseQuotedName(p, rExternDocName); p = parseQuotedName(p, rExternDocName);
if (!*p || *p != ']' || rExternDocName.isEmpty()) if (!*p || *p != ']' || rExternDocName.isEmpty())
{ {
rExternDocName = ""; rExternDocName = "";
@@ -447,7 +484,7 @@ const sal_Unicode* ScRange::Parse_XL_Header(
// Excel does not allow [ and ] characters in sheet names though. // Excel does not allow [ and ] characters in sheet names though.
// But, more sickness comes with MOOXML as there may be // But, more sickness comes with MOOXML as there may be
// '[1]Sheet 4'!$A$1 where [1] is the external doc's index. // '[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 != '!') if (!*p || *p != '!')
{ {
rExternDocName = ""; rExternDocName = "";
@@ -1003,7 +1040,7 @@ lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAdd
{ {
const sal_Unicode* pStart = p; const sal_Unicode* pStart = p;
OUString aTmp; OUString aTmp;
p = lcl_ParseQuotedName(p, aTmp); p = parseQuotedName(p, aTmp);
aDocName = aTmp; aDocName = aTmp;
if (*p++ == SC_COMPILER_FILE_TAB_SEP) if (*p++ == SC_COMPILER_FILE_TAB_SEP)
bExtDoc = true; 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 // Tokens that start at ' can have anything in them until a final
// ' but '' marks an escaped '. We've earlier guaranteed that a // ' but '' marks an escaped '. We've earlier guaranteed that a
// string containing '' will be surrounded by '. // string containing '' will be surrounded by '.
p = lcl_ParseQuotedName(p, aTab); p = parseQuotedName(p, aTab);
} }
else else
{ {

View File

@@ -90,11 +90,11 @@ void FormulaBuffer::finalizeImport()
void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector ) void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
{ {
ScDocumentImport& rDoc = getDocImport(); 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 ) for ( std::vector< TokenAddressItem >::const_iterator it = rVector.begin(), it_end = rVector.end(); it != it_end; ++it )
{ {
ScAddress aPos; ScAddress aPos;
ScUnoConversion::FillScAddress(aPos, it->maCellAddress); ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
ScCompiler aCompiler(&rDoc.getDoc(), aPos); ScCompiler aCompiler(&rDoc.getDoc(), aPos);
aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX); aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr); ScTokenArray* pCode = aCompiler.CompileString(it->maTokenStr);