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_sc.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 ()__anon36c283450111::XclDirectHasher76 inline sal_uInt32 operator()( Type nVal ) const { return nVal; }
77 };
78
79 struct XclFormatRunHasher : public XclHasher< const XclFormatRun& >
80 {
operator ()__anon36c283450111::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