Update ooo320-m1
[ooovba.git] / sc / source / filter / excel / xestring.cxx
blobc21091132d9e04e7d1247ea4767355052cd1d79f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xestring.cxx,v $
10 * $Revision: 1.13.32.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <algorithm>
35 #include <stdio.h>
36 #include "xestream.hxx"
37 #include "xlstyle.hxx"
38 #include "xestyle.hxx"
39 #include "xestring.hxx"
41 #include <oox/core/tokens.hxx>
43 using ::rtl::OString;
44 using ::rtl::OUString;
46 // ============================================================================
48 namespace {
50 // compare vectors
52 /** Compares two vectors.
53 @return A negative value, if rLeft<rRight; or a positive value, if rLeft>rRight;
54 or 0, if rLeft==rRight. */
55 template< typename Type >
56 int lclCompareVectors( const ::std::vector< Type >& rLeft, const ::std::vector< Type >& rRight )
58 int nResult = 0;
60 // 1st: compare all elements of the vectors
61 typedef typename ::std::vector< Type >::const_iterator CIT;
62 CIT aEndL = rLeft.end(), aEndR = rRight.end();
63 for( CIT aItL = rLeft.begin(), aItR = rRight.begin(); !nResult && (aItL != aEndL) && (aItR != aEndR); ++aItL, ++aItR )
64 nResult = static_cast< int >( *aItL ) - static_cast< int >( *aItR );
66 // 2nd: no differences found so far -> compare the vector sizes. Shorter vector is less
67 if( !nResult )
68 nResult = static_cast< int >( rLeft.size() ) - static_cast< int >( rRight.size() );
70 return nResult;
73 // hashing helpers
75 /** Base class for value hashers.
76 @descr These function objects are used to hash any value to a sal_uInt32 value. */
77 template< typename Type >
78 struct XclHasher : public ::std::unary_function< Type, sal_uInt32 > {};
80 template< typename Type >
81 struct XclDirectHasher : public XclHasher< Type >
83 inline sal_uInt32 operator()( Type nVal ) const { return nVal; }
86 struct XclFormatRunHasher : public XclHasher< const XclFormatRun& >
88 inline sal_uInt32 operator()( const XclFormatRun& rRun ) const
89 { return (rRun.mnChar << 8) ^ rRun.mnFontIdx; }
92 /** Calculates a hash value from a vector.
93 @descr Uses the passed hasher function object to calculate hash values from
94 all vector elements. */
95 template< typename Type, typename ValueHasher >
96 sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec, const ValueHasher& rHasher )
98 sal_uInt32 nHash = rVec.size();
99 typedef typename ::std::vector< Type >::const_iterator CIT;
100 for( CIT aIt = rVec.begin(), aEnd = rVec.end(); aIt != aEnd; ++aIt )
101 (nHash *= 31) += rHasher( *aIt );
102 return static_cast< sal_uInt16 >( nHash ^ (nHash >> 16) );
105 /** Calculates a hash value from a vector. Uses XclDirectHasher to hash the vector elements. */
106 template< typename Type >
107 inline sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec )
109 return lclHashVector( rVec, XclDirectHasher< Type >() );
112 } // namespace
114 // constructors ---------------------------------------------------------------
116 XclExpString::XclExpString( XclStrFlags nFlags, sal_uInt16 nMaxLen )
118 Init( 0, nFlags, nMaxLen, true );
121 XclExpString::XclExpString( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
123 Assign( rString, nFlags, nMaxLen );
126 XclExpString::XclExpString( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
128 Assign( rString, nFlags, nMaxLen );
131 //UNUSED2008-05 XclExpString::XclExpString(
132 //UNUSED2008-05 const String& 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 //UNUSED2008-05
138 //UNUSED2008-05 XclExpString::XclExpString(
139 //UNUSED2008-05 const OUString& rString, const XclFormatRunVec& rFormats,
140 //UNUSED2008-05 XclStrFlags nFlags, sal_uInt16 nMaxLen )
141 //UNUSED2008-05 {
142 //UNUSED2008-05 Assign( rString, rFormats, nFlags, nMaxLen );
143 //UNUSED2008-05 }
145 // assign ---------------------------------------------------------------------
147 void XclExpString::Assign( const String& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
149 Build( rString.GetBuffer(), rString.Len(), nFlags, nMaxLen );
152 void XclExpString::Assign(
153 const String& rString, const XclFormatRunVec& rFormats,
154 XclStrFlags nFlags, sal_uInt16 nMaxLen )
156 Assign( rString, nFlags, nMaxLen );
157 SetFormats( rFormats );
160 void XclExpString::Assign( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
162 Build( rString.getStr(), rString.getLength(), nFlags, nMaxLen );
165 void XclExpString::Assign(
166 const OUString& rString, const XclFormatRunVec& rFormats,
167 XclStrFlags nFlags, sal_uInt16 nMaxLen )
169 Assign( rString, nFlags, nMaxLen );
170 SetFormats( rFormats );
173 void XclExpString::Assign( sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
175 Build( &cChar, 1, nFlags, nMaxLen );
178 void XclExpString::AssignByte(
179 const String& rString, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
181 ByteString aByteStr( rString, eTextEnc ); // length may differ from length of rString
182 Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
185 //UNUSED2008-05 void XclExpString::AssignByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
186 //UNUSED2008-05 {
187 //UNUSED2008-05 if( !cChar )
188 //UNUSED2008-05 {
189 //UNUSED2008-05 sal_Char cByteChar = 0;
190 //UNUSED2008-05 Build( &cByteChar, 1, nFlags, nMaxLen );
191 //UNUSED2008-05 }
192 //UNUSED2008-05 else
193 //UNUSED2008-05 {
194 //UNUSED2008-05 ByteString aByteStr( &cChar, 1, eTextEnc ); // length may be >1
195 //UNUSED2008-05 Build( aByteStr.GetBuffer(), aByteStr.Len(), nFlags, nMaxLen );
196 //UNUSED2008-05 }
197 //UNUSED2008-05 }
199 // append ---------------------------------------------------------------------
201 void XclExpString::Append( const String& rString )
203 BuildAppend( rString.GetBuffer(), rString.Len() );
206 //UNUSED2008-05 void XclExpString::Append( const ::rtl::OUString& rString )
207 //UNUSED2008-05 {
208 //UNUSED2008-05 BuildAppend( rString.getStr(), rString.getLength() );
209 //UNUSED2008-05 }
210 //UNUSED2008-05
211 //UNUSED2008-05 void XclExpString::Append( sal_Unicode cChar )
212 //UNUSED2008-05 {
213 //UNUSED2008-05 BuildAppend( &cChar, 1 );
214 //UNUSED2008-05 }
216 void XclExpString::AppendByte( const String& rString, rtl_TextEncoding eTextEnc )
218 if( rString.Len() > 0 )
220 ByteString aByteStr( rString, eTextEnc ); // length may differ from length of rString
221 BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
225 void XclExpString::AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc )
227 if( !cChar )
229 sal_Char cByteChar = 0;
230 BuildAppend( &cByteChar, 1 );
232 else
234 ByteString aByteStr( &cChar, 1, eTextEnc ); // length may be >1
235 BuildAppend( aByteStr.GetBuffer(), aByteStr.Len() );
239 // formatting runs ------------------------------------------------------------
241 void XclExpString::SetFormats( const XclFormatRunVec& rFormats )
243 maFormats = rFormats;
244 #ifdef DBG_UTIL
245 if( IsRich() )
247 XclFormatRunVec::const_iterator aCurr = maFormats.begin();
248 XclFormatRunVec::const_iterator aPrev = aCurr;
249 XclFormatRunVec::const_iterator aEnd = maFormats.end();
250 for( ++aCurr; aCurr != aEnd; ++aCurr, ++aPrev )
251 DBG_ASSERT( aPrev->mnChar < aCurr->mnChar, "XclExpString::SetFormats - invalid char order" );
252 DBG_ASSERT( aPrev->mnChar <= mnLen, "XclExpString::SetFormats - invalid char index" );
254 #endif
255 LimitFormatCount( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
258 void XclExpString::AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate )
260 DBG_ASSERT( maFormats.empty() || (maFormats.back().mnChar < nChar), "XclExpString::AppendFormat - invalid char index" );
261 size_t nMaxSize = static_cast< size_t >( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
262 if( maFormats.empty() || ((maFormats.size() < nMaxSize) && (!bDropDuplicate || (maFormats.back().mnFontIdx != nFontIdx))) )
263 maFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
266 void XclExpString::AppendTrailingFormat( sal_uInt16 nFontIdx )
268 AppendFormat( mnLen, nFontIdx, false );
271 void XclExpString::LimitFormatCount( sal_uInt16 nMaxCount )
273 if( maFormats.size() > nMaxCount )
274 maFormats.erase( maFormats.begin() + nMaxCount, maFormats.end() );
277 sal_uInt16 XclExpString::RemoveLeadingFont()
279 sal_uInt16 nFontIdx = EXC_FONT_NOTFOUND;
280 if( !maFormats.empty() && (maFormats.front().mnChar == 0) )
282 nFontIdx = maFormats.front().mnFontIdx;
283 maFormats.erase( maFormats.begin() );
285 return nFontIdx;
288 bool XclExpString::IsEqual( const XclExpString& rCmp ) const
290 return
291 (mnLen == rCmp.mnLen) &&
292 (mbIsBiff8 == rCmp.mbIsBiff8) &&
293 (mbIsUnicode == rCmp.mbIsUnicode) &&
294 (mbWrapped == rCmp.mbWrapped) &&
296 ( mbIsBiff8 && (maUniBuffer == rCmp.maUniBuffer)) ||
297 (!mbIsBiff8 && (maCharBuffer == rCmp.maCharBuffer))
298 ) &&
299 (maFormats == rCmp.maFormats);
302 bool XclExpString::IsLessThan( const XclExpString& rCmp ) const
304 int nResult = mbIsBiff8 ?
305 lclCompareVectors( maUniBuffer, rCmp.maUniBuffer ) :
306 lclCompareVectors( maCharBuffer, rCmp.maCharBuffer );
307 return (nResult != 0) ? (nResult < 0) : (maFormats < rCmp.maFormats);
310 // get data -------------------------------------------------------------------
312 sal_uInt16 XclExpString::GetFormatsCount() const
314 return static_cast< sal_uInt16 >( maFormats.size() );
317 sal_uInt8 XclExpString::GetFlagField() const
319 return (mbIsUnicode ? EXC_STRF_16BIT : 0) | (IsWriteFormats() ? EXC_STRF_RICH : 0);
322 sal_uInt16 XclExpString::GetHeaderSize() const
324 return
325 (mb8BitLen ? 1 : 2) + // length field
326 (IsWriteFlags() ? 1 : 0) + // flag field
327 (IsWriteFormats() ? 2 : 0); // richtext formattting count
330 sal_Size XclExpString::GetBufferSize() const
332 return mnLen * (mbIsUnicode ? 2 : 1);
335 sal_Size XclExpString::GetSize() const
337 return
338 GetHeaderSize() + // header
339 GetBufferSize() + // character buffer
340 (IsWriteFormats() ? (4 * GetFormatsCount()) : 0); // richtext formattting
343 sal_uInt16 XclExpString::GetChar( sal_uInt16 nCharIdx ) const
345 DBG_ASSERT( nCharIdx < Len(), "XclExpString::GetChar - invalid character index" );
346 return static_cast< sal_uInt16 >( mbIsBiff8 ? maUniBuffer[ nCharIdx ] : maCharBuffer[ nCharIdx ] );
349 sal_uInt16 XclExpString::GetHash() const
351 return
352 (mbIsBiff8 ? lclHashVector( maUniBuffer ) : lclHashVector( maCharBuffer )) ^
353 lclHashVector( maFormats, XclFormatRunHasher() );
356 // streaming ------------------------------------------------------------------
358 void XclExpString::WriteLenField( XclExpStream& rStrm ) const
360 if( mb8BitLen )
361 rStrm << static_cast< sal_uInt8 >( mnLen );
362 else
363 rStrm << mnLen;
366 void XclExpString::WriteFlagField( XclExpStream& rStrm ) const
368 if( mbIsBiff8 )
370 PrepareWrite( rStrm, 1 );
371 rStrm << GetFlagField();
372 rStrm.SetSliceSize( 0 );
376 void XclExpString::WriteHeader( XclExpStream& rStrm ) const
378 DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeader - string too long" );
379 PrepareWrite( rStrm, GetHeaderSize() );
380 // length
381 WriteLenField( rStrm );
382 // flag field
383 if( IsWriteFlags() )
384 rStrm << GetFlagField();
385 // format run count
386 if( IsWriteFormats() )
387 rStrm << GetFormatsCount();
388 rStrm.SetSliceSize( 0 );
391 void XclExpString::WriteBuffer( XclExpStream& rStrm ) const
393 if( mbIsBiff8 )
394 rStrm.WriteUnicodeBuffer( maUniBuffer, GetFlagField() );
395 else
396 rStrm.WriteCharBuffer( maCharBuffer );
399 void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
401 if( IsRich() )
403 XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
404 if( mbIsBiff8 )
406 if( bWriteSize )
407 rStrm << GetFormatsCount();
408 rStrm.SetSliceSize( 4 );
409 for( ; aIt != aEnd; ++aIt )
410 rStrm << aIt->mnChar << aIt->mnFontIdx;
412 else
414 if( bWriteSize )
415 rStrm << static_cast< sal_uInt8 >( GetFormatsCount() );
416 rStrm.SetSliceSize( 2 );
417 for( ; aIt != aEnd; ++aIt )
418 rStrm << static_cast< sal_uInt8 >( aIt->mnChar ) << static_cast< sal_uInt8 >( aIt->mnFontIdx );
420 rStrm.SetSliceSize( 0 );
424 void XclExpString::Write( XclExpStream& rStrm ) const
426 if (!mbSkipHeader)
427 WriteHeader( rStrm );
428 WriteBuffer( rStrm );
429 if( IsWriteFormats() ) // only in BIFF8 included in string
430 WriteFormats( rStrm );
433 void XclExpString::WriteHeaderToMem( sal_uInt8* pnMem ) const
435 DBG_ASSERT( pnMem, "XclExpString::WriteHeaderToMem - no memory to write to" );
436 DBG_ASSERT( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeaderToMem - string too long" );
437 DBG_ASSERT( !IsWriteFormats(), "XclExpString::WriteHeaderToMem - formatted strings not supported" );
438 // length
439 if( mb8BitLen )
441 *pnMem = static_cast< sal_uInt8 >( mnLen );
442 ++pnMem;
444 else
446 ShortToSVBT16( mnLen, pnMem );
447 pnMem += 2;
449 // flag field
450 if( IsWriteFlags() )
451 *pnMem = GetFlagField();
454 void XclExpString::WriteBufferToMem( sal_uInt8* pnMem ) const
456 DBG_ASSERT( pnMem, "XclExpString::WriteBufferToMem - no memory to write to" );
457 if( !IsEmpty() )
459 if( mbIsBiff8 )
461 for( ScfUInt16Vec::const_iterator aIt = maUniBuffer.begin(), aEnd = maUniBuffer.end(); aIt != aEnd; ++aIt )
463 sal_uInt16 nChar = *aIt;
464 *pnMem = static_cast< sal_uInt8 >( nChar );
465 ++pnMem;
466 if( mbIsUnicode )
468 *pnMem = static_cast< sal_uInt8 >( nChar >> 8 );
469 ++pnMem;
473 else
474 memcpy( pnMem, &maCharBuffer[ 0 ], mnLen );
478 void XclExpString::WriteToMem( sal_uInt8* pnMem ) const
480 WriteHeaderToMem( pnMem );
481 WriteBufferToMem( pnMem + GetHeaderSize() );
484 static sal_uInt16 lcl_WriteRun( XclExpXmlStream& rStrm, const ScfUInt16Vec& rBuffer, sal_uInt16 nStart, sal_Int32 nLength, const XclExpFont* pFont )
486 if( nLength == 0 )
487 return nStart;
489 sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
491 rWorksheet->startElement( XML_r, FSEND );
492 if( pFont )
494 const XclFontData& rFontData = pFont->GetFontData();
495 rWorksheet->startElement( XML_rPr, FSEND );
496 rStrm.WriteFontData( rFontData, XML_rFont );
497 rWorksheet->endElement( XML_rPr );
499 rWorksheet->startElement( XML_t,
500 FSNS( XML_xml, XML_space ), "preserve",
501 FSEND );
502 rWorksheet->writeEscaped( XclXmlUtils::ToOUString( rBuffer, nStart, nLength ) );
503 rWorksheet->endElement( XML_t );
504 rWorksheet->endElement( XML_r );
505 return static_cast<sal_uInt16>(nStart + nLength);
508 void XclExpString::WriteXml( XclExpXmlStream& rStrm ) const
510 sax_fastparser::FSHelperPtr rWorksheet = rStrm.GetCurrentStream();
512 if( !IsWriteFormats() )
514 rWorksheet->startElement( XML_t, FSEND );
515 rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *this ) );
516 rWorksheet->endElement( XML_t );
518 else
520 XclExpFontBuffer& rFonts = rStrm.GetRoot().GetFontBuffer();
521 XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
523 sal_uInt16 nStart = 0;
524 const XclExpFont* pFont = NULL;
525 for ( ; aIt != aEnd; ++aIt )
527 nStart = lcl_WriteRun( rStrm, GetUnicodeBuffer(),
528 nStart, aIt->mnChar-nStart, pFont );
529 pFont = rFonts.GetFont( aIt->mnFontIdx );
531 lcl_WriteRun( rStrm, GetUnicodeBuffer(),
532 nStart, GetUnicodeBuffer().size() - nStart, pFont );
536 // ----------------------------------------------------------------------------
538 bool XclExpString::IsWriteFlags() const
540 return mbIsBiff8 && (!IsEmpty() || !mbSmartFlags);
543 bool XclExpString::IsWriteFormats() const
545 return mbIsBiff8 && !mbSkipFormats && IsRich();
548 void XclExpString::SetStrLen( sal_Int32 nNewLen )
550 sal_uInt16 nAllowedLen = (mb8BitLen && (mnMaxLen > 255)) ? 255 : mnMaxLen;
551 mnLen = limit_cast< sal_uInt16 >( nNewLen, 0, nAllowedLen );
554 void XclExpString::CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
556 DBG_ASSERT( maUniBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
557 "XclExpString::CharsToBuffer - char buffer invalid" );
558 ScfUInt16Vec::iterator aBeg = maUniBuffer.begin() + nBegin;
559 ScfUInt16Vec::iterator aEnd = aBeg + nLen;
560 const sal_Unicode* pcSrcChar = pcSource;
561 for( ScfUInt16Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
563 *aIt = static_cast< sal_uInt16 >( *pcSrcChar );
564 if( *aIt & 0xFF00 )
565 mbIsUnicode = true;
567 if( !mbWrapped )
568 mbWrapped = ::std::find( aBeg, aEnd, EXC_LF ) != aEnd;
571 void XclExpString::CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
573 DBG_ASSERT( maCharBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
574 "XclExpString::CharsToBuffer - char buffer invalid" );
575 ScfUInt8Vec::iterator aBeg = maCharBuffer.begin() + nBegin;
576 ScfUInt8Vec::iterator aEnd = aBeg + nLen;
577 const sal_Char* pcSrcChar = pcSource;
578 for( ScfUInt8Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
579 *aIt = static_cast< sal_uInt8 >( *pcSrcChar );
580 mbIsUnicode = false;
581 if( !mbWrapped )
582 mbWrapped = ::std::find( aBeg, aEnd, EXC_LF_C ) != aEnd;
585 void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 )
587 mbIsBiff8 = bBiff8;
588 mbIsUnicode = bBiff8 && ::get_flag( nFlags, EXC_STR_FORCEUNICODE );
589 mb8BitLen = ::get_flag( nFlags, EXC_STR_8BITLENGTH );
590 mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
591 mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
592 mbWrapped = false;
593 mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
594 mnMaxLen = nMaxLen;
595 SetStrLen( nCurrLen );
597 maFormats.clear();
598 if( mbIsBiff8 )
600 maCharBuffer.clear();
601 maUniBuffer.resize( mnLen );
603 else
605 maUniBuffer.clear();
606 maCharBuffer.resize( mnLen );
610 void XclExpString::Build( const sal_Unicode* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
612 Init( nCurrLen, nFlags, nMaxLen, true );
613 CharsToBuffer( pcSource, 0, mnLen );
616 void XclExpString::Build( const sal_Char* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
618 Init( nCurrLen, nFlags, nMaxLen, false );
619 CharsToBuffer( pcSource, 0, mnLen );
622 void XclExpString::InitAppend( sal_Int32 nAddLen )
624 SetStrLen( static_cast< sal_Int32 >( mnLen ) + nAddLen );
625 if( mbIsBiff8 )
626 maUniBuffer.resize( mnLen );
627 else
628 maCharBuffer.resize( mnLen );
631 void XclExpString::BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen )
633 DBG_ASSERT( mbIsBiff8, "XclExpString::BuildAppend - must not be called at byte strings" );
634 if( mbIsBiff8 )
636 sal_uInt16 nOldLen = mnLen;
637 InitAppend( nAddLen );
638 CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
642 void XclExpString::BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen )
644 DBG_ASSERT( !mbIsBiff8, "XclExpString::BuildAppend - must not be called at unicode strings" );
645 if( !mbIsBiff8 )
647 sal_uInt16 nOldLen = mnLen;
648 InitAppend( nAddLen );
649 CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
653 void XclExpString::PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const
655 rStrm.SetSliceSize( nBytes + (mbIsUnicode ? 2 : 1) );
658 // ============================================================================