diff options
-rw-r--r-- | include/oox/helper/attributelist.hxx | 9 | ||||
-rw-r--r-- | include/sax/fastattribs.hxx | 1 | ||||
-rw-r--r-- | oox/source/helper/attributelist.cxx | 12 | ||||
-rw-r--r-- | sax/source/tools/fastattribs.cxx | 21 | ||||
-rw-r--r-- | sc/source/filter/inc/addressconverter.hxx | 11 | ||||
-rw-r--r-- | sc/source/filter/oox/addressconverter.cxx | 76 | ||||
-rw-r--r-- | sc/source/filter/oox/sheetdatacontext.cxx | 8 |
7 files changed, 135 insertions, 3 deletions
diff --git a/include/oox/helper/attributelist.hxx b/include/oox/helper/attributelist.hxx index 6aa035a0b331..78ea83e28ab2 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 fd87a946ea5a..f47da070c1fc 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 7c41d8e967d2..e57dd1d26cf3 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 1705c3089dd4..17b9a3f6c1fd 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 dded94eb74aa..886e074e03c6 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 6c71b4948c9f..b9dbc53124a9 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 da234c13a609..ca55119e57aa 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; } |