xref: /trunk/main/sc/source/filter/excel/xestring.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 
27 #include <algorithm>
28 #include <stdio.h>
29 #include "xestream.hxx"
30 #include "xlstyle.hxx"
31 #include "xestyle.hxx"
32 #include "xestring.hxx"
33 
34 using namespace ::oox;
35 
36 using ::rtl::OString;
37 using ::rtl::OUString;
38 
39 // ============================================================================
40 
41 namespace {
42 
43 // compare vectors
44 
45 /** Compares two vectors.
46     @return  A negative value, if rLeft<rRight; or a positive value, if rLeft>rRight;
47     or 0, if rLeft==rRight. */
48 template< typename Type >
lclCompareVectors(const::std::vector<Type> & rLeft,const::std::vector<Type> & rRight)49 int lclCompareVectors( const ::std::vector< Type >& rLeft, const ::std::vector< Type >& rRight )
50 {
51     int nResult = 0;
52 
53     // 1st: compare all elements of the vectors
54     typedef typename ::std::vector< Type >::const_iterator CIT;
55     CIT aEndL = rLeft.end(), aEndR = rRight.end();
56     for( CIT aItL = rLeft.begin(), aItR = rRight.begin(); !nResult && (aItL != aEndL) && (aItR != aEndR); ++aItL, ++aItR )
57         nResult = static_cast< int >( *aItL ) - static_cast< int >( *aItR );
58 
59     // 2nd: no differences found so far -> compare the vector sizes. Shorter vector is less
60     if( !nResult )
61         nResult = static_cast< int >( rLeft.size() ) - static_cast< int >( rRight.size() );
62 
63     return nResult;
64 }
65 
66 // hashing helpers
67 
68 /** Base class for value hashers.
69     @descr  These function objects are used to hash any value to a sal_uInt32 value. */
70 template< typename Type >
71 struct XclHasher : public ::std::unary_function< Type, sal_uInt32 > {};
72 
73 template< typename Type >
74 struct XclDirectHasher : public XclHasher< Type >
75 {
operator ()__anon78861a5d0111::XclDirectHasher76     inline sal_uInt32   operator()( Type nVal ) const { return nVal; }
77 };
78 
79 struct XclFormatRunHasher : public XclHasher< const XclFormatRun& >
80 {
operator ()__anon78861a5d0111::XclFormatRunHasher81     inline sal_uInt32   operator()( const XclFormatRun& rRun ) const
82                             { return (rRun.mnChar << 8) ^ rRun.mnFontIdx; }
83 };
84 
85 /** Calculates a hash value from a vector.
86     @descr Uses the passed hasher function object to calculate hash values from
87     all vector elements. */
88 template< typename Type, typename ValueHasher >
lclHashVector(const::std::vector<Type> & rVec,const ValueHasher & rHasher)89 sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec, const ValueHasher& rHasher )
90 {
91     sal_uInt32 nHash = rVec.size();
92     typedef typename ::std::vector< Type >::const_iterator CIT;
93     for( CIT aIt = rVec.begin(), aEnd = rVec.end(); aIt != aEnd; ++aIt )
94         (nHash *= 31) += rHasher( *aIt );
95     return static_cast< sal_uInt16 >( nHash ^ (nHash >> 16) );
96 }
97 
98 /** Calculates a hash value from a vector. Uses XclDirectHasher to hash the vector elements. */
99 template< typename Type >
lclHashVector(const::std::vector<Type> & rVec)100 inline sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec )
101 {
102     return lclHashVector( rVec, XclDirectHasher< Type >() );
103 }
104 
105 } // namespace
106 
107 // constructors ---------------------------------------------------------------
108 
XclExpString(XclStrFlags nFlags,sal_uInt16 nMaxLen)109 XclExpString::XclExpString( XclStrFlags nFlags, sal_uInt16 nMaxLen )
110 {
111     Init( 0, nFlags, nMaxLen, true );
112 }
113 
XclExpString(const String & rString,XclStrFlags nFlags,sal_uInt16 nMaxLen)114 XclExpString::XclExpString( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
115 {
116     Assign( rString, nFlags, nMaxLen );
117 }
118 
XclExpString(const OUString & rString,XclStrFlags nFlags,sal_uInt16 nMaxLen)119 XclExpString::XclExpString( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
120 {
121     Assign( rString, nFlags, nMaxLen );
122 }
123 
124 //UNUSED2008-05  XclExpString::XclExpString(
125 //UNUSED2008-05      const String& rString, const XclFormatRunVec& rFormats,
126 //UNUSED2008-05      XclStrFlags nFlags, sal_uInt16 nMaxLen )
127 //UNUSED2008-05  {
128 //UNUSED2008-05      Assign( rString, rFormats, nFlags, nMaxLen );
129 //UNUSED2008-05  }
130 //UNUSED2008-05
131 //UNUSED2008-05  XclExpString::XclExpString(
132 //UNUSED2008-05          const OUString& rString, const XclFormatRunVec& rFormats,
133 //UNUSED2008-05          XclStrFlags nFlags, sal_uInt16 nMaxLen )
134 //UNUSED2008-05  {
135 //UNUSED2008-05      Assign( rString, rFormats, nFlags, nMaxLen );
136 //UNUSED2008-05  }
137 
138 // assign ---------------------------------------------------------------------
139 
Assign(const String & rString,XclStrFlags nFlags,sal_uInt16 nMaxLen)140 void XclExpString::Assign( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
141 {
142     Build( rString.GetBuffer(), rString.Len(), nFlags, nMaxLen );
143 }
144 
Assign(const String & rString,const XclFormatRunVec & rFormats,XclStrFlags nFlags,sal_uInt16 nMaxLen)145 void XclExpString::Assign(
146         const String& rString, const XclFormatRunVec& rFormats,
147         XclStrFlags nFlags, sal_uInt16 nMaxLen )
148 {
149     Assign( rString, nFlags, nMaxLen );
150     SetFormats( rFormats );
151 }
152 
Assign(const OUString & rString,XclStrFlags nFlags,sal_uInt16 nMaxLen)153 void XclExpString::Assign( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
154 {
155     Build( rString.getStr(), rString.getLength(), nFlags, nMaxLen );
156 }
157 
Assign(const OUString & rString,const XclFormatRunVec & rFormats,XclStrFlags nFlags,sal_uInt16 nMaxLen)158 void XclExpString::Assign(
159         const OUString& rString, const XclFormatRunVec& rFormats,
160         XclStrFlags nFlags, sal_uInt16 nMaxLen )
161 {
162     Assign( rString, nFlags, nMaxLen );
163     SetFormats( rFormats );
164 }
165 
Assign(sal_Unicode cChar,XclStrFlags nFlags,sal_uInt16 nMaxLen)166 void XclExpString::Assign( sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
167 {
168     Build( &cChar, 1, nFlags, nMaxLen );
169 }
170 
AssignByte(const String & rString,rtl_TextEncoding eTextEnc,XclStrFlags nFlags,sal_uInt16 nMaxLen)171 void XclExpString::AssignByte(
172         const String& rString, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
173 {
174     ByteString aByteStr( rString, eTextEnc );   // length may differ from length of rString
175     Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
176 }
177 
178 //UNUSED2008-05  void XclExpString::AssignByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
179 //UNUSED2008-05  {
180 //UNUSED2008-05      if( !cChar )
181 //UNUSED2008-05      {
182 //UNUSED2008-05          sal_Char cByteChar = 0;
183 //UNUSED2008-05          Build( &cByteChar, 1, nFlags, nMaxLen );
184 //UNUSED2008-05      }
185 //UNUSED2008-05      else
186 //UNUSED2008-05      {
187 //UNUSED2008-05          ByteString aByteStr( &cChar, 1, eTextEnc );     // length may be >1
188 //UNUSED2008-05          Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
189 //UNUSED2008-05      }
190 //UNUSED2008-05  }
191 
192 // append ---------------------------------------------------------------------
193 
Append(const String & rString)194 void XclExpString::Append( const String& rString )
195 {
196     BuildAppend( rString.GetBuffer(), rString.Len() );
197 }
198 
199 //UNUSED2008-05  void XclExpString::Append( const ::rtl::OUString& rString )
200 //UNUSED2008-05  {
201 //UNUSED2008-05      BuildAppend( rString.getStr(), rString.getLength() );
202 //UNUSED2008-05  }
203 //UNUSED2008-05
204 //UNUSED2008-05  void XclExpString::Append( sal_Unicode cChar )
205 //UNUSED2008-05  {
206 //UNUSED2008-05      BuildAppend( &cChar, 1 );
207 //UNUSED2008-05  }
208 
AppendByte(const String & rString,rtl_TextEncoding eTextEnc)209 void XclExpString::AppendByte( const String& rString, rtl_TextEncoding eTextEnc )
210 {
211     if( rString.Len() > 0 )
212     {
213         ByteString aByteStr( rString, eTextEnc );   // length may differ from length of rString
214         BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
215     }
216 }
217 
AppendByte(sal_Unicode cChar,rtl_TextEncoding eTextEnc)218 void XclExpString::AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc )
219 {
220     if( !cChar )
221     {
222         sal_Char cByteChar = 0;
223         BuildAppend( &cByteChar, 1 );
224     }
225     else
226     {
227         ByteString aByteStr( &cChar, 1, eTextEnc );     // length may be >1
228         BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
229     }
230 }
231 
232 // formatting runs ------------------------------------------------------------
233 
SetFormats(const XclFormatRunVec & rFormats)234 void XclExpString::SetFormats( const XclFormatRunVec& rFormats )
235 {
236     maFormats = rFormats;
237 #ifdef DBG_UTIL
238     if( IsRich() )
239     {
240         XclFormatRunVec::const_iterator aCurr = maFormats.begin();
241         XclFormatRunVec::const_iterator aPrev = aCurr;
242         XclFormatRunVec::const_iterator aEnd = maFormats.end();
243         for( ++aCurr; aCurr != aEnd; ++aCurr, ++aPrev )
244             DBG_ASSERT( aPrev->mnChar < aCurr->mnChar, "XclExpString::SetFormats - invalid char order" );
245         DBG_ASSERT( aPrev->mnChar <= mnLen, "XclExpString::SetFormats - invalid char index" );
246     }
247 #endif
248     LimitFormatCount( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
249 }
250 
AppendFormat(sal_uInt16 nChar,sal_uInt16 nFontIdx,bool bDropDuplicate)251 void XclExpString::AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate )
252 {
253     DBG_ASSERT( maFormats.empty() || (maFormats.back().mnChar < nChar), "XclExpString::AppendFormat - invalid char index" );
254     size_t nMaxSize = static_cast< size_t >( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
255     if( maFormats.empty() || ((maFormats.size() < nMaxSize) && (!bDropDuplicate || (maFormats.back().mnFontIdx != nFontIdx))) )
256         maFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
257 }
258 
AppendTrailingFormat(sal_uInt16 nFontIdx)259 void XclExpString::AppendTrailingFormat( sal_uInt16 nFontIdx )
260 {
261     AppendFormat( mnLen, nFontIdx, false );
262 }
263 
LimitFormatCount(sal_uInt16 nMaxCount)264 void XclExpString::LimitFormatCount( sal_uInt16 nMaxCount )
265 {
266     if( maFormats.size() > nMaxCount )
267         maFormats.erase( maFormats.begin() + nMaxCount, maFormats.end() );
268 }
269 
RemoveLeadingFont()270 sal_uInt16 XclExpString::RemoveLeadingFont()
271 {
272     sal_uInt16 nFontIdx = EXC_FONT_NOTFOUND;
273     if( !maFormats.empty() && (maFormats.front().mnChar == 0) )
274     {
275         nFontIdx = maFormats.front().mnFontIdx;
276         maFormats.erase( maFormats.begin() );
277     }
278     return nFontIdx;
279 }
280 
IsEqual(const XclExpString & rCmp) const281 bool XclExpString::IsEqual( const XclExpString& rCmp ) const
282 {
283     return
284         (mnLen          == rCmp.mnLen)          &&
285         (mbIsBiff8      == rCmp.mbIsBiff8)      &&
286         (mbIsUnicode    == rCmp.mbIsUnicode)    &&
287         (mbWrapped      == rCmp.mbWrapped)      &&
288         (
289             ( mbIsBiff8 && (maUniBuffer  == rCmp.maUniBuffer)) ||
290             (!mbIsBiff8 && (maCharBuffer == rCmp.maCharBuffer))
291         ) &&
292         (maFormats      == rCmp.maFormats);
293 }
294 
IsLessThan(const XclExpString & rCmp) const295 bool XclExpString::IsLessThan( const XclExpString& rCmp ) const
296 {
297     int nResult = mbIsBiff8 ?
298         lclCompareVectors( maUniBuffer, rCmp.maUniBuffer ) :
299         lclCompareVectors( maCharBuffer, rCmp.maCharBuffer );
300     return (nResult != 0) ? (nResult < 0) : (maFormats < rCmp.maFormats);
301 }
302 
303 // get data -------------------------------------------------------------------
304 
GetFormatsCount() const305 sal_uInt16 XclExpString::GetFormatsCount() const
306 {
307     return static_cast< sal_uInt16 >( maFormats.size() );
308 }
309 
GetFlagField() const310 sal_uInt8 XclExpString::GetFlagField() const
311 {
312     return (mbIsUnicode ? EXC_STRF_16BIT : 0) | (IsWriteFormats() ? EXC_STRF_RICH : 0);
313 }
314 
GetHeaderSize() const315 sal_uInt16 XclExpString::GetHeaderSize() const
316 {
317     return
318         (mb8BitLen ? 1 : 2) +           // length field
319         (IsWriteFlags() ? 1 : 0) +      // flag field
320         (IsWriteFormats() ? 2 : 0);     // richtext formattting count
321 }
322 
GetBufferSize() const323 sal_Size XclExpString::GetBufferSize() const
324 {
325     return mnLen * (mbIsUnicode ? 2 : 1);
326 }
327 
GetSize() const328 sal_Size XclExpString::GetSize() const
329 {
330     return
331         GetHeaderSize() +                                   // header
332         GetBufferSize() +                                   // character buffer
333         (IsWriteFormats() ? (4 * GetFormatsCount()) : 0);   // richtext formattting
334 }
335 
GetChar(sal_uInt16 nCharIdx) const336 sal_uInt16 XclExpString::GetChar( sal_uInt16 nCharIdx ) const
337 {
338     DBG_ASSERT( nCharIdx < Len(), "XclExpString::GetChar - invalid character index" );
339     return static_cast< sal_uInt16 >( mbIsBiff8 ? maUniBuffer[ nCharIdx ] : maCharBuffer[ nCharIdx ] );
340 }
341 
GetHash() const342 sal_uInt16 XclExpString::GetHash() const
343 {
344     return
345         (mbIsBiff8 ? lclHashVector( maUniBuffer ) : lclHashVector( maCharBuffer )) ^
346         lclHashVector( maFormats, XclFormatRunHasher() );
347 }
348 
349 // streaming ------------------------------------------------------------------
350 
WriteLenField(XclExpStream & rStrm) const351 void XclExpString::WriteLenField( XclExpStream& rStrm ) const
352 {
353     if( mb8BitLen )
354         rStrm << static_cast< sal_uInt8 >( mnLen );
355     else
356         rStrm << mnLen;
357 }
358 
WriteFlagField(XclExpStream & rStrm) const359 void XclExpString::WriteFlagField( XclExpStream& rStrm ) const
360 {
361     if( mbIsBiff8 )
362     {
363         PrepareWrite( rStrm, 1 );
364         rStrm << GetFlagField();
365         rStrm.SetSliceSize( 0 );
366     }
367 }
368 
WriteHeader(XclExpStream & rStrm) const369 void XclExpString::WriteHeader( XclExpStream& rStrm ) const
370 {
371     DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeader - string too long" );
372     PrepareWrite( rStrm, GetHeaderSize() );
373     // length
374     WriteLenField( rStrm );
375     // flag field
376     if( IsWriteFlags() )
377         rStrm << GetFlagField();
378     // format run count
379     if( IsWriteFormats() )
380         rStrm << GetFormatsCount();
381     rStrm.SetSliceSize( 0 );
382 }
383 
WriteBuffer(XclExpStream & rStrm) const384 void XclExpString::WriteBuffer( XclExpStream& rStrm ) const
385 {
386     if( mbIsBiff8 )
387         rStrm.WriteUnicodeBuffer( maUniBuffer, GetFlagField() );
388     else
389         rStrm.WriteCharBuffer( maCharBuffer );
390 }
391 
WriteFormats(XclExpStream & rStrm,bool bWriteSize) const392 void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
393 {
394     if( IsRich() )
395     {
396         XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
397         if( mbIsBiff8 )
398         {
399             if( bWriteSize )
400                 rStrm << GetFormatsCount();
401             rStrm.SetSliceSize( 4 );
402             for( ; aIt != aEnd; ++aIt )
403                 rStrm << aIt->mnChar << aIt->mnFontIdx;
404         }
405         else
406         {
407             if( bWriteSize )
408                 rStrm << static_cast< sal_uInt8 >( GetFormatsCount() );
409             rStrm.SetSliceSize( 2 );
410             for( ; aIt != aEnd; ++aIt )
411                 rStrm << static_cast< sal_uInt8 >( aIt->mnChar ) << static_cast< sal_uInt8 >( aIt->mnFontIdx );
412         }
413         rStrm.SetSliceSize( 0 );
414     }
415 }
416 
Write(XclExpStream & rStrm) const417 void XclExpString::Write( XclExpStream& rStrm ) const
418 {
419     if (!mbSkipHeader)
420         WriteHeader( rStrm );
421     WriteBuffer( rStrm );
422     if( IsWriteFormats() )      // only in BIFF8 included in string
423         WriteFormats( rStrm );
424 }
425 
WriteHeaderToMem(sal_uInt8 * pnMem) const426 void XclExpString::WriteHeaderToMem( sal_uInt8* pnMem ) const
427 {
428     DBG_ASSERT( pnMem, "XclExpString::WriteHeaderToMem - no memory to write to" );
429     DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeaderToMem - string too long" );
430     DBG_ASSERT( !IsWriteFormats(), "XclExpString::WriteHeaderToMem - formatted strings not supported" );
431     // length
432     if( mb8BitLen )
433     {
434         *pnMem = static_cast< sal_uInt8 >( mnLen );
435         ++pnMem;
436     }
437     else
438     {
439         ShortToSVBT16( mnLen, pnMem );
440         pnMem += 2;
441     }
442     // flag field
443     if( IsWriteFlags() )
444         *pnMem = GetFlagField();
445 }
446 
WriteBufferToMem(sal_uInt8 * pnMem) const447 void XclExpString::WriteBufferToMem( sal_uInt8* pnMem ) const
448 {
449     DBG_ASSERT( pnMem, "XclExpString::WriteBufferToMem - no memory to write to" );
450     if( !IsEmpty() )
451     {
452         if( mbIsBiff8 )
453         {
454             for( ScfUInt16Vec::const_iterator aIt = maUniBuffer.begin(), aEnd = maUniBuffer.end(); aIt != aEnd; ++aIt )
455             {
456                 sal_uInt16 nChar = *aIt;
457                 *pnMem = static_cast< sal_uInt8 >( nChar );
458                 ++pnMem;
459                 if( mbIsUnicode )
460                 {
461                     *pnMem = static_cast< sal_uInt8 >( nChar >> 8 );
462                     ++pnMem;
463                 }
464             }
465         }
466         else
467             memcpy( pnMem, &maCharBuffer[ 0 ], mnLen );
468     }
469 }
470 
WriteToMem(sal_uInt8 * pnMem) const471 void XclExpString::WriteToMem( sal_uInt8* pnMem ) const
472 {
473     WriteHeaderToMem( pnMem );
474     WriteBufferToMem( pnMem + GetHeaderSize() );
475 }
476 
lcl_WriteRun(XclExpXmlStream & rStrm,const ScfUInt16Vec & rBuffer,sal_uInt16 nStart,sal_Int32 nLength,const XclExpFont * pFont)477 static sal_uInt16 lcl_WriteRun( XclExpXmlStream& rStrm, const ScfUInt16Vec& rBuffer, sal_uInt16 nStart, sal_Int32 nLength, const XclExpFont* pFont )
478 {
479     if( nLength == 0 )
480         return nStart;
481 
482     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
483 
484     rWorksheet->startElement( XML_r, FSEND );
485     if( pFont )
486     {
487         const XclFontData& rFontData = pFont->GetFontData();
488         rWorksheet->startElement( XML_rPr, FSEND );
489         rStrm.WriteFontData( rFontData, XML_rFont );
490         rWorksheet->endElement( XML_rPr );
491     }
492     rWorksheet->startElement( XML_t,
493             FSNS( XML_xml, XML_space ), "preserve",
494             FSEND );
495     rWorksheet->writeEscaped( XclXmlUtils::ToOUString( rBuffer, nStart, nLength ) );
496     rWorksheet->endElement( XML_t );
497     rWorksheet->endElement( XML_r );
498     return static_cast<sal_uInt16>(nStart + nLength);
499 }
500 
WriteXml(XclExpXmlStream & rStrm) const501 void XclExpString::WriteXml( XclExpXmlStream& rStrm ) const
502 {
503     sax_fastparser::FSHelperPtr rWorksheet = rStrm.GetCurrentStream();
504 
505     if( !IsWriteFormats() )
506     {
507         rWorksheet->startElement( XML_t, FSEND );
508         rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *this ) );
509         rWorksheet->endElement( XML_t );
510     }
511     else
512     {
513         XclExpFontBuffer& rFonts = rStrm.GetRoot().GetFontBuffer();
514         XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
515 
516         sal_uInt16  nStart = 0;
517         const XclExpFont* pFont = NULL;
518         for ( ; aIt != aEnd; ++aIt )
519         {
520             nStart = lcl_WriteRun( rStrm, GetUnicodeBuffer(),
521                     nStart, aIt->mnChar-nStart, pFont );
522             pFont = rFonts.GetFont( aIt->mnFontIdx );
523         }
524         lcl_WriteRun( rStrm, GetUnicodeBuffer(),
525                 nStart, GetUnicodeBuffer().size() - nStart, pFont );
526     }
527 }
528 
529 // ----------------------------------------------------------------------------
530 
IsWriteFlags() const531 bool XclExpString::IsWriteFlags() const
532 {
533     return mbIsBiff8 && (!IsEmpty() || !mbSmartFlags);
534 }
535 
IsWriteFormats() const536 bool XclExpString::IsWriteFormats() const
537 {
538     return mbIsBiff8 && !mbSkipFormats && IsRich();
539 }
540 
SetStrLen(sal_Int32 nNewLen)541 void XclExpString::SetStrLen( sal_Int32 nNewLen )
542 {
543     sal_uInt16 nAllowedLen = (mb8BitLen && (mnMaxLen > 255)) ? 255 : mnMaxLen;
544     mnLen = limit_cast< sal_uInt16 >( nNewLen, 0, nAllowedLen );
545 }
546 
CharsToBuffer(const sal_Unicode * pcSource,sal_Int32 nBegin,sal_Int32 nLen)547 void XclExpString::CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
548 {
549     DBG_ASSERT( maUniBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
550         "XclExpString::CharsToBuffer - char buffer invalid" );
551     ScfUInt16Vec::iterator aBeg = maUniBuffer.begin() + nBegin;
552     ScfUInt16Vec::iterator aEnd = aBeg + nLen;
553     const sal_Unicode* pcSrcChar = pcSource;
554     for( ScfUInt16Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
555     {
556         *aIt = static_cast< sal_uInt16 >( *pcSrcChar );
557         if( *aIt & 0xFF00 )
558             mbIsUnicode = true;
559     }
560     if( !mbWrapped )
561         mbWrapped = ::std::find( aBeg, aEnd, EXC_LF ) != aEnd;
562 }
563 
CharsToBuffer(const sal_Char * pcSource,sal_Int32 nBegin,sal_Int32 nLen)564 void XclExpString::CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
565 {
566     DBG_ASSERT( maCharBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
567         "XclExpString::CharsToBuffer - char buffer invalid" );
568     ScfUInt8Vec::iterator aBeg = maCharBuffer.begin() + nBegin;
569     ScfUInt8Vec::iterator aEnd = aBeg + nLen;
570     const sal_Char* pcSrcChar = pcSource;
571     for( ScfUInt8Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
572         *aIt = static_cast< sal_uInt8 >( *pcSrcChar );
573     mbIsUnicode = false;
574     if( !mbWrapped )
575         mbWrapped = ::std::find( aBeg, aEnd, EXC_LF_C ) != aEnd;
576 }
577 
Init(sal_Int32 nCurrLen,XclStrFlags nFlags,sal_uInt16 nMaxLen,bool bBiff8)578 void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 )
579 {
580     mbIsBiff8 = bBiff8;
581     mbIsUnicode = bBiff8 && ::get_flag( nFlags, EXC_STR_FORCEUNICODE );
582     mb8BitLen = ::get_flag( nFlags, EXC_STR_8BITLENGTH );
583     mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
584     mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
585     mbWrapped = false;
586     mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
587     mnMaxLen = nMaxLen;
588     SetStrLen( nCurrLen );
589 
590     maFormats.clear();
591     if( mbIsBiff8 )
592     {
593         maCharBuffer.clear();
594         maUniBuffer.resize( mnLen );
595     }
596     else
597     {
598         maUniBuffer.clear();
599         maCharBuffer.resize( mnLen );
600     }
601 }
602 
Build(const sal_Unicode * pcSource,sal_Int32 nCurrLen,XclStrFlags nFlags,sal_uInt16 nMaxLen)603 void XclExpString::Build( const sal_Unicode* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
604 {
605     Init( nCurrLen, nFlags, nMaxLen, true );
606     CharsToBuffer( pcSource, 0, mnLen );
607 }
608 
Build(const sal_Char * pcSource,sal_Int32 nCurrLen,XclStrFlags nFlags,sal_uInt16 nMaxLen)609 void XclExpString::Build( const sal_Char* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
610 {
611     Init( nCurrLen, nFlags, nMaxLen, false );
612     CharsToBuffer( pcSource, 0, mnLen );
613 }
614 
InitAppend(sal_Int32 nAddLen)615 void XclExpString::InitAppend( sal_Int32 nAddLen )
616 {
617     SetStrLen( static_cast< sal_Int32 >( mnLen ) + nAddLen );
618     if( mbIsBiff8 )
619         maUniBuffer.resize( mnLen );
620     else
621         maCharBuffer.resize( mnLen );
622 }
623 
BuildAppend(const sal_Unicode * pcSource,sal_Int32 nAddLen)624 void XclExpString::BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen )
625 {
626     DBG_ASSERT( mbIsBiff8, "XclExpString::BuildAppend - must not be called at byte strings" );
627     if( mbIsBiff8 )
628     {
629         sal_uInt16 nOldLen = mnLen;
630         InitAppend( nAddLen );
631         CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
632     }
633 }
634 
BuildAppend(const sal_Char * pcSource,sal_Int32 nAddLen)635 void XclExpString::BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen )
636 {
637     DBG_ASSERT( !mbIsBiff8, "XclExpString::BuildAppend - must not be called at unicode strings" );
638     if( !mbIsBiff8 )
639     {
640         sal_uInt16 nOldLen = mnLen;
641         InitAppend( nAddLen );
642         CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
643     }
644 }
645 
PrepareWrite(XclExpStream & rStrm,sal_uInt16 nBytes) const646 void XclExpString::PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const
647 {
648     rStrm.SetSliceSize( nBytes + (mbIsUnicode ? 2 : 1) );
649 }
650 
651 // ============================================================================
652 
653