20#include <XMLRangeHelper.hxx>
21#include <rtl/character.hxx>
22#include <rtl/ustrbuf.hxx>
23#include <osl/diagnose.h>
37 explicit lcl_Escape( OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
43 if( aChar == s_aQuote ||
44 aChar == s_aBackslash )
45 m_aResultBuffer.append( s_aBackslash );
46 m_aResultBuffer.append( aChar );
50 OUStringBuffer & m_aResultBuffer;
60 explicit lcl_UnEscape( OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
65 if( aChar != s_aBackslash )
66 m_aResultBuffer.append( aChar );
70 OUStringBuffer & m_aResultBuffer;
73void lcl_getXMLStringForCell( const ::chart::XMLRangeHelper::Cell & rCell, OUStringBuffer * output )
75 OSL_ASSERT(output !=
nullptr);
80 sal_Int32 nCol = rCell.nColumn;
81 output->append(
'.' );
82 if( ! rCell.bRelativeColumn )
83 output->append(
'$' );
87 output->append(
static_cast<sal_Unicode>(
'A' + nCol) );
90 output->append(
static_cast<sal_Unicode>(
'A' + nCol / 26 - 1 ));
91 output->append(
static_cast<sal_Unicode>(
'A' + nCol % 26) );
95 output->append(
static_cast<sal_Unicode>(
'A' + nCol / 702 - 1 ));
96 output->append(
static_cast<sal_Unicode>(
'A' + (nCol % 702) / 26 ));
97 output->append(
static_cast<sal_Unicode>(
'A' + nCol % 26) );
101 if( ! rCell.bRelativeRow )
102 output->append(
'$' );
103 output->append( rCell.nRow + sal_Int32(1) );
106void lcl_getSingleCellAddressFromXMLString(
107 std::u16string_view rXMLString,
108 sal_Int32 nStartPos, sal_Int32 nEndPos,
115 OUString aCellStr = OUString(rXMLString.substr( nStartPos, nEndPos - nStartPos + 1 )).toAsciiUpperCase();
117 sal_Int32
nLength = aCellStr.getLength();
118 sal_Int32
i =
nLength - 1, nColumn = 0;
121 while( rtl::isAsciiDigit( pStrArray[ i ] ) && i >= 0 )
125 if( pStrArray[ i ] == aDollar )
134 sal_Int32 nPower = 1;
135 while( rtl::isAsciiAlpha( pStrArray[ i ] ))
137 nColumn += (pStrArray[
i ] - aLetterA + 1) * nPower;
141 rOutCell.
nColumn = nColumn - 1;
145 pStrArray[ i ] == aDollar )
150bool lcl_getCellAddressFromXMLString(
151 const OUString& rXMLString,
152 sal_Int32 nStartPos, sal_Int32 nEndPos,
154 OUString& rOutTableName )
160 sal_Int32 nNextDelimiterPos = nStartPos;
162 sal_Int32 nDelimiterPos = nStartPos;
163 bool bInQuotation =
false;
165 while( nDelimiterPos < nEndPos &&
166 ( bInQuotation || rXMLString[ nDelimiterPos ] != aDot ))
169 if( rXMLString[ nDelimiterPos ] == aBackslash )
172 else if( rXMLString[ nDelimiterPos ] == aQuote )
173 bInQuotation = ! bInQuotation;
178 if( nDelimiterPos == -1 )
181 if( nDelimiterPos > nStartPos && nDelimiterPos < nEndPos )
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 nDelimiterPos = nStartPos;
207 for( sal_Int32 i = 0;
208 nNextDelimiterPos < nEndPos;
209 nDelimiterPos = nNextDelimiterPos,
i++ )
211 nNextDelimiterPos = rXMLString.indexOf( aDot, nDelimiterPos + 1 );
212 if( nNextDelimiterPos == -1 ||
213 nNextDelimiterPos > nEndPos )
214 nNextDelimiterPos = nEndPos + 1;
218 lcl_getSingleCellAddressFromXMLString(
219 rXMLString, nDelimiterPos + 1, nNextDelimiterPos - 1, rOutCell );
225bool lcl_getCellRangeAddressFromXMLString(
226 const OUString& rXMLString,
227 sal_Int32 nStartPos, sal_Int32 nEndPos,
235 sal_Int32 nDelimiterPos = nStartPos;
236 bool bInQuotation =
false;
238 while( nDelimiterPos < nEndPos &&
239 ( bInQuotation || rXMLString[ nDelimiterPos ] != aColon ))
242 if( rXMLString[ nDelimiterPos ] == aBackslash )
245 else if( rXMLString[ nDelimiterPos ] == aQuote )
246 bInQuotation = ! bInQuotation;
251 if( nDelimiterPos == nEndPos )
254 bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nEndPos,
263 bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nDelimiterPos - 1,
269 OUString sTableSecondName;
272 bResult = lcl_getCellAddressFromXMLString( rXMLString, nDelimiterPos + 1, nEndPos,
277 !sTableSecondName.isEmpty() &&
298 const sal_Int32
nLength = rXMLString.getLength();
304 for( sal_Int32 nStartPos = 0, nEndPos = nStartPos;
306 nStartPos = ++nEndPos )
311 if( rXMLString[ nEndPos ] == aDollar)
314 bool bInQuotation =
false;
317 ( bInQuotation || rXMLString[ nEndPos ] != aSpace ))
320 if( rXMLString[ nEndPos ] == aBackslash )
323 else if( rXMLString[ nEndPos ] == aQuote )
324 bInQuotation = ! bInQuotation;
329 if( ! lcl_getCellRangeAddressFromXMLString(
331 nStartPos, nEndPos - 1,
351 bool bNeedsEscaping = ( rRange.
aTableName.indexOf( aQuote ) > -1 );
352 bool bNeedsQuoting = bNeedsEscaping || ( rRange.
aTableName.indexOf( aSpace ) > -1 );
366 std::for_each( pTableNameBeg,
367 pTableNameBeg + rRange.
aTableName.getLength(),
388 return aBuffer.makeStringAndClear();
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