Expose raw char array and use it to avoid OUString allocations.

In SheetDataContext::importCell().

Change-Id: I52db64219f672ea5fbbda17686bf1173ceac5926
This commit is contained in:
Kohei Yoshida 2013-11-20 22:09:45 -05:00
parent f9041c386c
commit 22ea573b74
7 changed files with 135 additions and 3 deletions

View File

@ -75,6 +75,12 @@ public:
class OOX_DLLPUBLIC AttributeList
{
public:
struct Char
{
const char* mpPos;
size_t mnSize;
};
explicit AttributeList(
const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs );
@ -132,6 +138,9 @@ public:
passed default string if the attribute is missing. */
OUString getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const;
Char getChar( sal_Int32 nAttrToken ) const;
/** Returns the double value of the specified attribute, or the passed
default value if the attribute is missing or not convertible to a double. */
double getDouble( sal_Int32 nAttrToken, double fDefault ) const;

View File

@ -76,6 +76,7 @@ public:
// performance sensitive shortcuts to avoid allocation ...
bool getAsInteger( sal_Int32 nToken, sal_Int32 &rInt);
bool getAsDouble( sal_Int32 nToken, double &rDouble);
bool getAsChar( sal_Int32 nToken, const char*& rPos, size_t& rLen ) const;
// XFastAttributeList
virtual ::sal_Bool SAL_CALL hasAttribute( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException);

View File

@ -261,6 +261,18 @@ OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefau
return getXString( nAttrToken ).get( rDefault );
}
AttributeList::Char AttributeList::getChar( sal_Int32 nAttrToken ) const
{
Char aRet;
bool bValid = getAttribList()->getAsChar(nAttrToken, aRet.mpPos, aRet.mnSize);
if (!bValid)
{
aRet.mpPos = NULL;
aRet.mnSize = 0;
}
return aRet;
}
double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const
{
return getDouble( nAttrToken ).get( fDefault );

View File

@ -157,6 +157,27 @@ bool FastAttributeList::getAsDouble( sal_Int32 nToken, double &rDouble)
return false;
}
bool FastAttributeList::getAsChar( sal_Int32 nToken, const char*& rPos, size_t& rLen ) const
{
for (size_t i = 0, n = maAttributeTokens.size(); i < n; ++i)
{
if (maAttributeTokens[i] != nToken)
continue;
sal_Int32 nOffset = maAttributeValues[i];
rPos = mpChunk + nOffset;
if (i + 1 < maAttributeValues.size())
rLen = maAttributeValues[i+1] - nOffset - 1;
else
rLen = mnChunkLength - nOffset - 1;
return true;
}
return false;
}
OUString FastAttributeList::getValue( ::sal_Int32 Token ) throw (SAXException, RuntimeException)
{
for (size_t i = 0; i < maAttributeTokens.size(); ++i)

View File

@ -213,6 +213,9 @@ public:
sal_Int32 nStart = 0,
sal_Int32 nLength = SAL_MAX_INT32 );
static bool parseOoxAddress2d(
sal_Int32& ornColumn, sal_Int32& ornRow, const char* pStr, sal_Int32 nStrLen );
/** Tries to parse the passed string for a 2d cell range in A1 notation.
This function accepts all strings that match the regular expression
@ -316,6 +319,10 @@ public:
const OUString& rString,
sal_Int16 nSheet );
bool convertToCellAddressUnchecked(
com::sun::star::table::CellAddress& orAddress,
const char* pStr, size_t nStrLen, sal_Int16 nSheet ) const;
/** Tries to convert the passed string to a single cell address.
@param orAddress (out-parameter) Returns the converted cell address.
@ -331,6 +338,10 @@ public:
sal_Int16 nSheet,
bool bTrackOverflow );
bool convertToCellAddress(
com::sun::star::table::CellAddress& rAddress,
const char* pStr, size_t nStrLen, sal_Int16 nSheet, bool bTrackOverflow );
/** Returns a valid cell address by moving it into allowed dimensions.
@param rString Cell address string in A1 notation.

View File

@ -226,6 +226,64 @@ bool AddressConverter::parseOoxAddress2d(
return (ornColumn >= 0) && (ornRow >= 0);
}
bool AddressConverter::parseOoxAddress2d(
sal_Int32& ornColumn, sal_Int32& ornRow, const char* pStr, sal_Int32 nStrLen )
{
ornColumn = ornRow = 0;
const char* pStrEnd = pStr + nStrLen;
enum { STATE_COL, STATE_ROW } eState = STATE_COL;
while (pStr < pStrEnd)
{
char cChar = *pStr;
switch( eState )
{
case STATE_COL:
{
if( ('a' <= cChar) && (cChar <= 'z') )
(cChar -= 'a') += 'A';
if( ('A' <= cChar) && (cChar <= 'Z') )
{
/* Return, if 1-based column index is already 6 characters
long (12356631 is column index for column AAAAAA). */
if( ornColumn >= 12356631 )
return false;
(ornColumn *= 26) += (cChar - 'A' + 1);
}
else if( ornColumn > 0 )
{
--pStr;
eState = STATE_ROW;
}
else
return false;
}
break;
case STATE_ROW:
{
if( ('0' <= cChar) && (cChar <= '9') )
{
// return, if 1-based row is already 9 digits long
if( ornRow >= 100000000 )
return false;
(ornRow *= 10) += (cChar - '0');
}
else
return false;
}
break;
}
++pStr;
}
--ornColumn;
--ornRow;
return (ornColumn >= 0) && (ornRow >= 0);
}
bool AddressConverter::parseOoxRange2d(
sal_Int32& ornStartColumn, sal_Int32& ornStartRow,
sal_Int32& ornEndColumn, sal_Int32& ornEndRow,
@ -297,6 +355,14 @@ bool AddressConverter::convertToCellAddressUnchecked( CellAddress& orAddress,
return parseOoxAddress2d( orAddress.Column, orAddress.Row, rString );
}
bool AddressConverter::convertToCellAddressUnchecked(
com::sun::star::table::CellAddress& orAddress,
const char* pStr, size_t nStrLen, sal_Int16 nSheet ) const
{
orAddress.Sheet = nSheet;
return parseOoxAddress2d(orAddress.Column, orAddress.Row, pStr, nStrLen);
}
bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
{
@ -305,6 +371,16 @@ bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
checkCellAddress( orAddress, bTrackOverflow );
}
bool AddressConverter::convertToCellAddress(
com::sun::star::table::CellAddress& rAddress,
const char* pStr, size_t nStrLen, sal_Int16 nSheet, bool bTrackOverflow )
{
if (!convertToCellAddressUnchecked(rAddress, pStr, nStrLen, nSheet))
return false;
return checkCellAddress(rAddress, bTrackOverflow);
}
CellAddress AddressConverter::createValidCellAddress(
const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
{

View File

@ -310,16 +310,18 @@ void SheetDataContext::importRow( const AttributeList& rAttribs )
bool SheetDataContext::importCell( const AttributeList& rAttribs )
{
OUString aCellAddrStr = rAttribs.getString( XML_r, OUString() );
bool bValid = true;
if(aCellAddrStr.isEmpty())
AttributeList::Char aChar = rAttribs.getChar(XML_r);
if (!aChar.mpPos)
{
++mnCol;
maCellData.maCellAddr = CellAddress( mnSheet, mnCol, mnRow );
}
else
{
bValid = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, aCellAddrStr, mnSheet, true );
bValid = mrAddressConv.convertToCellAddress(
maCellData.maCellAddr, aChar.mpPos, aChar.mnSize, mnSheet, true);
mnCol = maCellData.maCellAddr.Column;
}