[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - include/oox include/sax oox/source sax/source sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Nov 20 19:12:25 PST 2013


Rebased ref, commits from common ancestor:
commit 51c4d66a2b8938831d5c2afb2ff5d38cfdc9b0ed
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Nov 20 22:09:45 2013 -0500

    Expose raw char array and use it to avoid OUString allocations.
    
    In SheetDataContext::importCell().
    
    Change-Id: I52db64219f672ea5fbbda17686bf1173ceac5926

diff --git a/include/oox/helper/attributelist.hxx b/include/oox/helper/attributelist.hxx
index 6aa035a..78ea83e 100644
--- a/include/oox/helper/attributelist.hxx
+++ b/include/oox/helper/attributelist.hxx
@@ -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;
diff --git a/include/sax/fastattribs.hxx b/include/sax/fastattribs.hxx
index fd87a94..f47da07 100644
--- a/include/sax/fastattribs.hxx
+++ b/include/sax/fastattribs.hxx
@@ -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);
diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx
index 7c41d8e..e57dd1d 100644
--- a/oox/source/helper/attributelist.cxx
+++ b/oox/source/helper/attributelist.cxx
@@ -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 );
diff --git a/sax/source/tools/fastattribs.cxx b/sax/source/tools/fastattribs.cxx
index 1705c30..17b9a3f 100644
--- a/sax/source/tools/fastattribs.cxx
+++ b/sax/source/tools/fastattribs.cxx
@@ -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)
diff --git a/sc/source/filter/inc/addressconverter.hxx b/sc/source/filter/inc/addressconverter.hxx
index dded94e..886e074 100644
--- a/sc/source/filter/inc/addressconverter.hxx
+++ b/sc/source/filter/inc/addressconverter.hxx
@@ -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.
diff --git a/sc/source/filter/oox/addressconverter.cxx b/sc/source/filter/oox/addressconverter.cxx
index 6c71b49..b9dbc53 100644
--- a/sc/source/filter/oox/addressconverter.cxx
+++ b/sc/source/filter/oox/addressconverter.cxx
@@ -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 )
 {
diff --git a/sc/source/filter/oox/sheetdatacontext.cxx b/sc/source/filter/oox/sheetdatacontext.cxx
index da234c1..ca55119 100644
--- a/sc/source/filter/oox/sheetdatacontext.cxx
+++ b/sc/source/filter/oox/sheetdatacontext.cxx
@@ -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;
     }


More information about the Libreoffice-commits mailing list