21#include <rtl/character.hxx>
22#include <rtl/ustrbuf.hxx>
35 explicit lcl_Escape( OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
41 if( aChar == s_aQuote ||
42 aChar == s_aBackslash )
43 m_aResultBuffer.append( s_aBackslash );
44 m_aResultBuffer.append( aChar );
48 OUStringBuffer & m_aResultBuffer;
58 explicit lcl_UnEscape( OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
63 if( aChar != s_aBackslash )
64 m_aResultBuffer.append( aChar );
68 OUStringBuffer & m_aResultBuffer;
73 assert(output !=
nullptr);
79 output->append(
'.' );
81 output->append(
'$' );
85 output->append(
static_cast<sal_Unicode>(
'A' + nCol) );
88 output->append(
static_cast<sal_Unicode>(
'A' + nCol / 26 - 1 ));
89 output->append(
static_cast<sal_Unicode>(
'A' + nCol % 26) );
93 output->append(
static_cast<sal_Unicode>(
'A' + nCol / 702 - 1 ));
94 output->append(
static_cast<sal_Unicode>(
'A' + (nCol % 702) / 26 ));
95 output->append(
static_cast<sal_Unicode>(
'A' + nCol % 26) );
100 output->append(
'$' );
101 output->append( rCell.
nRow + sal_Int32(1) );
104void lcl_getSingleCellAddressFromXMLString(
105 std::u16string_view rXMLString,
106 sal_Int32 nStartPos, sal_Int32 nEndPos,
113 OUString aCellStr = OUString(rXMLString.substr( nStartPos, nEndPos - nStartPos + 1 )).toAsciiUpperCase();
115 sal_Int32
nLength = aCellStr.getLength();
116 sal_Int32
i =
nLength - 1, nColumn = 0;
119 while( rtl::isAsciiDigit( pStrArray[ i ] ) && i >= 0 )
123 if( pStrArray[ i ] == aDollar )
132 sal_Int32 nPower = 1;
133 while( rtl::isAsciiAlpha( pStrArray[ i ] ))
135 nColumn += (pStrArray[
i ] - aLetterA + 1) * nPower;
139 rOutCell.
nColumn = nColumn - 1;
143 pStrArray[ i ] == aDollar )
148bool lcl_getCellAddressFromXMLString(
149 const OUString& rXMLString,
150 sal_Int32 nStartPos, sal_Int32 nEndPos,
152 OUString& rOutTableName )
158 sal_Int32 nNextDelimiterPos = nStartPos;
160 sal_Int32 nDelimiterPos = nStartPos;
161 bool bInQuotation =
false;
163 while( nDelimiterPos < nEndPos &&
164 ( bInQuotation || rXMLString[ nDelimiterPos ] != aDot ))
167 if( rXMLString[ nDelimiterPos ] == aBackslash )
170 else if( rXMLString[ nDelimiterPos ] == aQuote )
171 bInQuotation = ! bInQuotation;
176 if( nDelimiterPos == -1 ||
177 nDelimiterPos >= nEndPos )
181 if( nDelimiterPos > nStartPos )
185 OUStringBuffer aTableNameBuffer;
186 const sal_Unicode * pTableName = rXMLString.getStr();
189 std::for_each( pTableName + nStartPos,
190 pTableName + nDelimiterPos,
191 lcl_UnEscape( aTableNameBuffer ));
194 const sal_Unicode * pBuf = aTableNameBuffer.getStr();
195 if( pBuf[ 0 ] == aQuote &&
196 pBuf[ aTableNameBuffer.getLength() - 1 ] == aQuote )
198 OUString
aName = aTableNameBuffer.makeStringAndClear();
199 rOutTableName =
aName.copy( 1,
aName.getLength() - 2 );
202 rOutTableName = aTableNameBuffer.makeStringAndClear();
205 for( sal_Int32 i = 0;
206 nNextDelimiterPos < nEndPos;
207 nDelimiterPos = nNextDelimiterPos,
i++ )
209 nNextDelimiterPos = rXMLString.indexOf( aDot, nDelimiterPos + 1 );
210 if( nNextDelimiterPos == -1 ||
211 nNextDelimiterPos > nEndPos )
212 nNextDelimiterPos = nEndPos + 1;
216 lcl_getSingleCellAddressFromXMLString(
217 rXMLString, nDelimiterPos + 1, nNextDelimiterPos - 1, rOutCell );
223bool lcl_getCellRangeAddressFromXMLString(
224 const OUString& rXMLString,
225 sal_Int32 nStartPos, sal_Int32 nEndPos,
233 sal_Int32 nDelimiterPos = nStartPos;
234 bool bInQuotation =
false;
236 while( nDelimiterPos < nEndPos &&
237 ( bInQuotation || rXMLString[ nDelimiterPos ] != aColon ))
240 if( rXMLString[ nDelimiterPos ] == aBackslash )
243 else if( rXMLString[ nDelimiterPos ] == aQuote )
244 bInQuotation = ! bInQuotation;
249 if( nDelimiterPos == nEndPos )
252 bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nEndPos,
259 bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nDelimiterPos - 1,
262 OUString sTableSecondName;
265 bResult = lcl_getCellAddressFromXMLString( rXMLString, nDelimiterPos + 1, nEndPos,
270 !sTableSecondName.isEmpty() &&
290 sal_Int32 nStartPos = 0;
291 sal_Int32 nEndPos = nStartPos;
292 const sal_Int32
nLength = rXMLString.getLength();
298 for( sal_Int32
i = 0;
300 nStartPos = ++nEndPos,
i++ )
305 if( rXMLString[ nEndPos ] == aDollar)
308 bool bInQuotation =
false;
311 ( bInQuotation || rXMLString[ nEndPos ] != aSpace ))
314 if( rXMLString[ nEndPos ] == aBackslash )
317 else if( rXMLString[ nEndPos ] == aQuote )
318 bInQuotation = ! bInQuotation;
323 if( ! lcl_getCellRangeAddressFromXMLString(
325 nStartPos, nEndPos - 1,
345 bool bNeedsEscaping = ( rRange.
aTableName.indexOf( aQuote ) > -1 );
346 bool bNeedsQuoting = bNeedsEscaping || ( rRange.
aTableName.indexOf( aSpace ) > -1 );
360 std::for_each( pTableNameBeg,
361 pTableNameBeg + rRange.
aTableName.getLength(),
382 return aBuffer.makeStringAndClear();
! ! This file is an exact copy of the same file in chart2 project !
OUString getXMLStringFromCellRange(const CellRange &rRange)
CellRange getCellRangeFromXMLString(const OUString &rXMLString)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::unique_ptr< char[]> aBuffer