Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <algorithm>
21 :
22 : #include <osl/diagnose.h>
23 : #include "xlstyle.hxx"
24 : #include "xestyle.hxx"
25 : #include "xestream.hxx"
26 : #include "xestring.hxx"
27 :
28 : using namespace ::oox;
29 :
30 : namespace {
31 :
32 : // compare vectors
33 :
34 : /** Compares two vectors.
35 : @return A negative value, if rLeft<rRight; or a positive value, if rLeft>rRight;
36 : or 0, if rLeft==rRight. */
37 : template< typename Type >
38 83 : int lclCompareVectors( const ::std::vector< Type >& rLeft, const ::std::vector< Type >& rRight )
39 : {
40 83 : int nResult = 0;
41 :
42 : // 1st: compare all elements of the vectors
43 : typedef typename ::std::vector< Type >::const_iterator CIT;
44 83 : CIT aEndL = rLeft.end(), aEndR = rRight.end();
45 760 : for( CIT aItL = rLeft.begin(), aItR = rRight.begin(); !nResult && (aItL != aEndL) && (aItR != aEndR); ++aItL, ++aItR )
46 677 : nResult = static_cast< int >( *aItL ) - static_cast< int >( *aItR );
47 :
48 : // 2nd: no differences found so far -> compare the vector sizes. Shorter vector is less
49 83 : if( !nResult )
50 77 : nResult = static_cast< int >( rLeft.size() ) - static_cast< int >( rRight.size() );
51 :
52 83 : return nResult;
53 : }
54 :
55 : // hashing helpers
56 :
57 : /** Base class for value hashers.
58 : @descr These function objects are used to hash any value to a sal_uInt32 value. */
59 : template< typename Type >
60 : struct XclHasher : public ::std::unary_function< Type, sal_uInt32 > {};
61 :
62 : template< typename Type >
63 : struct XclDirectHasher : public XclHasher< Type >
64 : {
65 5043 : inline sal_uInt32 operator()( Type nVal ) const { return nVal; }
66 : };
67 :
68 : struct XclFormatRunHasher : public XclHasher< const XclFormatRun& >
69 : {
70 3 : inline sal_uInt32 operator()( const XclFormatRun& rRun ) const
71 3 : { return (rRun.mnChar << 8) ^ rRun.mnFontIdx; }
72 : };
73 :
74 : /** Calculates a hash value from a vector.
75 : @descr Uses the passed hasher function object to calculate hash values from
76 : all vector elements. */
77 : template< typename Type, typename ValueHasher >
78 898 : sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec, const ValueHasher& rHasher )
79 : {
80 898 : sal_uInt32 nHash = rVec.size();
81 : typedef typename ::std::vector< Type >::const_iterator CIT;
82 5944 : for( CIT aIt = rVec.begin(), aEnd = rVec.end(); aIt != aEnd; ++aIt )
83 5046 : (nHash *= 31) += rHasher( *aIt );
84 898 : return static_cast< sal_uInt16 >( nHash ^ (nHash >> 16) );
85 : }
86 :
87 : /** Calculates a hash value from a vector. Uses XclDirectHasher to hash the vector elements. */
88 : template< typename Type >
89 449 : inline sal_uInt16 lclHashVector( const ::std::vector< Type >& rVec )
90 : {
91 449 : return lclHashVector( rVec, XclDirectHasher< Type >() );
92 : }
93 :
94 : } // namespace
95 :
96 : // constructors ---------------------------------------------------------------
97 :
98 766 : XclExpString::XclExpString( XclStrFlags nFlags, sal_uInt16 nMaxLen )
99 : {
100 766 : Init( 0, nFlags, nMaxLen, true );
101 766 : }
102 :
103 76 : XclExpString::XclExpString( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
104 : {
105 76 : Assign( rString, nFlags, nMaxLen );
106 76 : }
107 :
108 : // assign ---------------------------------------------------------------------
109 :
110 767 : void XclExpString::Assign( const OUString& rString, XclStrFlags nFlags, sal_uInt16 nMaxLen )
111 : {
112 767 : Build( rString.getStr(), rString.getLength(), nFlags, nMaxLen );
113 767 : }
114 :
115 0 : void XclExpString::Assign( sal_Unicode cChar, XclStrFlags nFlags, sal_uInt16 nMaxLen )
116 : {
117 0 : Build( &cChar, 1, nFlags, nMaxLen );
118 0 : }
119 :
120 0 : void XclExpString::AssignByte(
121 : const OUString& rString, rtl_TextEncoding eTextEnc, XclStrFlags nFlags, sal_uInt16 nMaxLen )
122 : {
123 : // length may differ from length of rString
124 0 : OString aByteStr(OUStringToOString(rString, eTextEnc));
125 0 : Build(aByteStr.getStr(), aByteStr.getLength(), nFlags, nMaxLen);
126 0 : }
127 :
128 : // append ---------------------------------------------------------------------
129 :
130 484 : void XclExpString::Append( const OUString& rString )
131 : {
132 484 : BuildAppend( rString.getStr(), rString.getLength() );
133 484 : }
134 :
135 0 : void XclExpString::AppendByte( const OUString& rString, rtl_TextEncoding eTextEnc )
136 : {
137 0 : if (!rString.isEmpty())
138 : {
139 : // length may differ from length of rString
140 0 : OString aByteStr(OUStringToOString(rString, eTextEnc));
141 0 : BuildAppend(aByteStr.getStr(), aByteStr.getLength());
142 : }
143 0 : }
144 :
145 0 : void XclExpString::AppendByte( sal_Unicode cChar, rtl_TextEncoding eTextEnc )
146 : {
147 0 : if( !cChar )
148 : {
149 0 : sal_Char cByteChar = 0;
150 0 : BuildAppend( &cByteChar, 1 );
151 : }
152 : else
153 : {
154 0 : OString aByteStr( &cChar, 1, eTextEnc ); // length may be >1
155 0 : BuildAppend( aByteStr.getStr(), aByteStr.getLength() );
156 : }
157 0 : }
158 :
159 : // formatting runs ------------------------------------------------------------
160 :
161 499 : void XclExpString::AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIdx, bool bDropDuplicate )
162 : {
163 : OSL_ENSURE( maFormats.empty() || (maFormats.back().mnChar < nChar), "XclExpString::AppendFormat - invalid char index" );
164 499 : size_t nMaxSize = static_cast< size_t >( mbIsBiff8 ? EXC_STR_MAXLEN : EXC_STR_MAXLEN_8BIT );
165 499 : if( maFormats.empty() || ((maFormats.size() < nMaxSize) && (!bDropDuplicate || (maFormats.back().mnFontIdx != nFontIdx))) )
166 499 : maFormats.push_back( XclFormatRun( nChar, nFontIdx ) );
167 499 : }
168 :
169 15 : void XclExpString::AppendTrailingFormat( sal_uInt16 nFontIdx )
170 : {
171 15 : AppendFormat( mnLen, nFontIdx, false );
172 15 : }
173 :
174 15 : void XclExpString::LimitFormatCount( sal_uInt16 nMaxCount )
175 : {
176 15 : if( maFormats.size() > nMaxCount )
177 0 : maFormats.erase( maFormats.begin() + nMaxCount, maFormats.end() );
178 15 : }
179 :
180 464 : sal_uInt16 XclExpString::RemoveLeadingFont()
181 : {
182 464 : sal_uInt16 nFontIdx = EXC_FONT_NOTFOUND;
183 464 : if( !maFormats.empty() && (maFormats.front().mnChar == 0) )
184 : {
185 464 : nFontIdx = maFormats.front().mnFontIdx;
186 464 : maFormats.erase( maFormats.begin() );
187 : }
188 464 : return nFontIdx;
189 : }
190 :
191 79 : bool XclExpString::IsEqual( const XclExpString& rCmp ) const
192 : {
193 : return
194 158 : (mnLen == rCmp.mnLen) &&
195 158 : (mbIsBiff8 == rCmp.mbIsBiff8) &&
196 158 : (mbIsUnicode == rCmp.mbIsUnicode) &&
197 158 : (mbWrapped == rCmp.mbWrapped) &&
198 : (
199 79 : ( mbIsBiff8 && (maUniBuffer == rCmp.maUniBuffer)) ||
200 0 : (!mbIsBiff8 && (maCharBuffer == rCmp.maCharBuffer))
201 158 : ) &&
202 158 : (maFormats == rCmp.maFormats);
203 : }
204 :
205 83 : bool XclExpString::IsLessThan( const XclExpString& rCmp ) const
206 : {
207 : int nResult = mbIsBiff8 ?
208 83 : lclCompareVectors( maUniBuffer, rCmp.maUniBuffer ) :
209 166 : lclCompareVectors( maCharBuffer, rCmp.maCharBuffer );
210 83 : return (nResult != 0) ? (nResult < 0) : (maFormats < rCmp.maFormats);
211 : }
212 :
213 : // get data -------------------------------------------------------------------
214 :
215 6 : sal_uInt16 XclExpString::GetFormatsCount() const
216 : {
217 6 : return static_cast< sal_uInt16 >( maFormats.size() );
218 : }
219 :
220 741 : sal_uInt8 XclExpString::GetFlagField() const
221 : {
222 741 : return (mbIsUnicode ? EXC_STRF_16BIT : 0) | (IsWriteFormats() ? EXC_STRF_RICH : 0);
223 : }
224 :
225 406 : sal_uInt16 XclExpString::GetHeaderSize() const
226 : {
227 : return
228 : (mb8BitLen ? 1 : 2) + // length field
229 406 : (IsWriteFlags() ? 1 : 0) + // flag field
230 812 : (IsWriteFormats() ? 2 : 0); // richtext formattting count
231 : }
232 :
233 138 : sal_Size XclExpString::GetBufferSize() const
234 : {
235 138 : return static_cast<sal_Size>(mnLen) * (mbIsUnicode ? 2 : 1);
236 : }
237 :
238 100 : sal_Size XclExpString::GetSize() const
239 : {
240 : return
241 200 : GetHeaderSize() + // header
242 200 : GetBufferSize() + // character buffer
243 200 : (IsWriteFormats() ? (4 * GetFormatsCount()) : 0); // richtext formattting
244 : }
245 :
246 0 : sal_uInt16 XclExpString::GetChar( sal_uInt16 nCharIdx ) const
247 : {
248 : OSL_ENSURE( nCharIdx < Len(), "XclExpString::GetChar - invalid character index" );
249 0 : return static_cast< sal_uInt16 >( mbIsBiff8 ? maUniBuffer[ nCharIdx ] : maCharBuffer[ nCharIdx ] );
250 : }
251 :
252 449 : sal_uInt16 XclExpString::GetHash() const
253 : {
254 : return
255 449 : (mbIsBiff8 ? lclHashVector( maUniBuffer ) : lclHashVector( maCharBuffer )) ^
256 898 : lclHashVector( maFormats, XclFormatRunHasher() );
257 : }
258 :
259 : // streaming ------------------------------------------------------------------
260 :
261 364 : void XclExpString::WriteLenField( XclExpStream& rStrm ) const
262 : {
263 364 : if( mb8BitLen )
264 170 : rStrm << static_cast< sal_uInt8 >( mnLen );
265 : else
266 194 : rStrm << mnLen;
267 364 : }
268 :
269 62 : void XclExpString::WriteFlagField( XclExpStream& rStrm ) const
270 : {
271 62 : if( mbIsBiff8 )
272 : {
273 62 : PrepareWrite( rStrm, 1 );
274 62 : rStrm << GetFlagField();
275 62 : rStrm.SetSliceSize( 0 );
276 : }
277 62 : }
278 :
279 302 : void XclExpString::WriteHeader( XclExpStream& rStrm ) const
280 : {
281 : OSL_ENSURE( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeader - string too long" );
282 302 : PrepareWrite( rStrm, GetHeaderSize() );
283 : // length
284 302 : WriteLenField( rStrm );
285 : // flag field
286 302 : if( IsWriteFlags() )
287 302 : rStrm << GetFlagField();
288 : // format run count
289 302 : if( IsWriteFormats() )
290 0 : rStrm << GetFormatsCount();
291 302 : rStrm.SetSliceSize( 0 );
292 302 : }
293 :
294 370 : void XclExpString::WriteBuffer( XclExpStream& rStrm ) const
295 : {
296 370 : if( mbIsBiff8 )
297 370 : rStrm.WriteUnicodeBuffer( maUniBuffer, GetFlagField() );
298 : else
299 0 : rStrm.WriteCharBuffer( maCharBuffer );
300 370 : }
301 :
302 0 : void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
303 : {
304 0 : if( IsRich() )
305 : {
306 0 : XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
307 0 : if( mbIsBiff8 )
308 : {
309 0 : if( bWriteSize )
310 0 : rStrm << GetFormatsCount();
311 0 : rStrm.SetSliceSize( 4 );
312 0 : for( ; aIt != aEnd; ++aIt )
313 0 : rStrm << aIt->mnChar << aIt->mnFontIdx;
314 : }
315 : else
316 : {
317 0 : if( bWriteSize )
318 0 : rStrm << static_cast< sal_uInt8 >( GetFormatsCount() );
319 0 : rStrm.SetSliceSize( 2 );
320 0 : for( ; aIt != aEnd; ++aIt )
321 0 : rStrm << static_cast< sal_uInt8 >( aIt->mnChar ) << static_cast< sal_uInt8 >( aIt->mnFontIdx );
322 : }
323 0 : rStrm.SetSliceSize( 0 );
324 : }
325 0 : }
326 :
327 302 : void XclExpString::Write( XclExpStream& rStrm ) const
328 : {
329 302 : if (!mbSkipHeader)
330 302 : WriteHeader( rStrm );
331 302 : WriteBuffer( rStrm );
332 302 : if( IsWriteFormats() ) // only in BIFF8 included in string
333 0 : WriteFormats( rStrm );
334 302 : }
335 :
336 4 : void XclExpString::WriteHeaderToMem( sal_uInt8* pnMem ) const
337 : {
338 : OSL_ENSURE( pnMem, "XclExpString::WriteHeaderToMem - no memory to write to" );
339 : OSL_ENSURE( !mb8BitLen || (mnLen < 256), "XclExpString::WriteHeaderToMem - string too long" );
340 : OSL_ENSURE( !IsWriteFormats(), "XclExpString::WriteHeaderToMem - formatted strings not supported" );
341 : // length
342 4 : if( mb8BitLen )
343 : {
344 4 : *pnMem = static_cast< sal_uInt8 >( mnLen );
345 4 : ++pnMem;
346 : }
347 : else
348 : {
349 0 : ShortToSVBT16( mnLen, pnMem );
350 0 : pnMem += 2;
351 : }
352 : // flag field
353 4 : if( IsWriteFlags() )
354 4 : *pnMem = GetFlagField();
355 4 : }
356 :
357 4 : void XclExpString::WriteBufferToMem( sal_uInt8* pnMem ) const
358 : {
359 : OSL_ENSURE( pnMem, "XclExpString::WriteBufferToMem - no memory to write to" );
360 4 : if( !IsEmpty() )
361 : {
362 4 : if( mbIsBiff8 )
363 : {
364 32 : for( ScfUInt16Vec::const_iterator aIt = maUniBuffer.begin(), aEnd = maUniBuffer.end(); aIt != aEnd; ++aIt )
365 : {
366 28 : sal_uInt16 nChar = *aIt;
367 28 : *pnMem = static_cast< sal_uInt8 >( nChar );
368 28 : ++pnMem;
369 28 : if( mbIsUnicode )
370 : {
371 0 : *pnMem = static_cast< sal_uInt8 >( nChar >> 8 );
372 0 : ++pnMem;
373 : }
374 : }
375 : }
376 : else
377 0 : memcpy( pnMem, &maCharBuffer[ 0 ], mnLen );
378 : }
379 4 : }
380 :
381 4 : void XclExpString::WriteToMem( sal_uInt8* pnMem ) const
382 : {
383 4 : WriteHeaderToMem( pnMem );
384 4 : WriteBufferToMem( pnMem + GetHeaderSize() );
385 4 : }
386 :
387 7 : static sal_uInt16 lcl_WriteRun( XclExpXmlStream& rStrm, const ScfUInt16Vec& rBuffer, sal_uInt16 nStart, sal_Int32 nLength, const XclExpFont* pFont )
388 : {
389 7 : if( nLength == 0 )
390 1 : return nStart;
391 :
392 6 : sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
393 :
394 6 : rWorksheet->startElement( XML_r, FSEND );
395 6 : if( pFont )
396 : {
397 6 : const XclFontData& rFontData = pFont->GetFontData();
398 6 : rWorksheet->startElement( XML_rPr, FSEND );
399 6 : XclXmlUtils::WriteFontData( rWorksheet, rFontData, XML_rFont );
400 6 : rWorksheet->endElement( XML_rPr );
401 : }
402 : rWorksheet->startElement( XML_t,
403 6 : FSEND );
404 6 : rWorksheet->writeEscaped( XclXmlUtils::ToOUString( rBuffer, nStart, nLength ) );
405 6 : rWorksheet->endElement( XML_t );
406 6 : rWorksheet->endElement( XML_r );
407 6 : return nStart + nLength;
408 : }
409 :
410 237 : void XclExpString::WriteXml( XclExpXmlStream& rStrm ) const
411 : {
412 237 : sax_fastparser::FSHelperPtr rWorksheet = rStrm.GetCurrentStream();
413 :
414 237 : if( !IsWriteFormats() )
415 : {
416 234 : rWorksheet->startElement( XML_t, FSEND );
417 234 : rWorksheet->writeEscaped( XclXmlUtils::ToOUString( *this ) );
418 234 : rWorksheet->endElement( XML_t );
419 : }
420 : else
421 : {
422 3 : XclExpFontBuffer& rFonts = rStrm.GetRoot().GetFontBuffer();
423 3 : XclFormatRunVec::const_iterator aIt = maFormats.begin(), aEnd = maFormats.end();
424 :
425 3 : sal_uInt16 nStart = 0;
426 3 : const XclExpFont* pFont = NULL;
427 7 : for ( ; aIt != aEnd; ++aIt )
428 : {
429 : // pFont getting first then pass it to run otherwise pFont is NULL.
430 4 : pFont = rFonts.GetFont( aIt->mnFontIdx );
431 4 : nStart = lcl_WriteRun( rStrm, GetUnicodeBuffer(),
432 8 : nStart, aIt->mnChar-nStart, pFont );
433 : }
434 3 : lcl_WriteRun( rStrm, GetUnicodeBuffer(),
435 6 : nStart, GetUnicodeBuffer().size() - nStart, pFont );
436 237 : }
437 237 : }
438 :
439 712 : bool XclExpString::IsWriteFlags() const
440 : {
441 712 : return mbIsBiff8 && (!IsEmpty() || !mbSmartFlags);
442 : }
443 :
444 2088 : bool XclExpString::IsWriteFormats() const
445 : {
446 2088 : return mbIsBiff8 && !mbSkipFormats && IsRich();
447 : }
448 :
449 2017 : void XclExpString::SetStrLen( sal_Int32 nNewLen )
450 : {
451 2017 : sal_uInt16 nAllowedLen = (mb8BitLen && (mnMaxLen > 255)) ? 255 : mnMaxLen;
452 2017 : mnLen = limit_cast< sal_uInt16 >( nNewLen, 0, nAllowedLen );
453 2017 : }
454 :
455 1251 : void XclExpString::CharsToBuffer( const sal_Unicode* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
456 : {
457 : OSL_ENSURE( maUniBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
458 : "XclExpString::CharsToBuffer - char buffer invalid" );
459 1251 : ScfUInt16Vec::iterator aBeg = maUniBuffer.begin() + nBegin;
460 1251 : ScfUInt16Vec::iterator aEnd = aBeg + nLen;
461 1251 : const sal_Unicode* pcSrcChar = pcSource;
462 9157 : for( ScfUInt16Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
463 : {
464 7906 : *aIt = static_cast< sal_uInt16 >( *pcSrcChar );
465 7906 : if( *aIt & 0xFF00 )
466 0 : mbIsUnicode = true;
467 : }
468 1251 : if( !mbWrapped )
469 1251 : mbWrapped = ::std::find( aBeg, aEnd, EXC_LF ) != aEnd;
470 1251 : }
471 :
472 0 : void XclExpString::CharsToBuffer( const sal_Char* pcSource, sal_Int32 nBegin, sal_Int32 nLen )
473 : {
474 : OSL_ENSURE( maCharBuffer.size() >= static_cast< size_t >( nBegin + nLen ),
475 : "XclExpString::CharsToBuffer - char buffer invalid" );
476 0 : ScfUInt8Vec::iterator aBeg = maCharBuffer.begin() + nBegin;
477 0 : ScfUInt8Vec::iterator aEnd = aBeg + nLen;
478 0 : const sal_Char* pcSrcChar = pcSource;
479 0 : for( ScfUInt8Vec::iterator aIt = aBeg; aIt != aEnd; ++aIt, ++pcSrcChar )
480 0 : *aIt = static_cast< sal_uInt8 >( *pcSrcChar );
481 0 : mbIsUnicode = false;
482 0 : if( !mbWrapped )
483 0 : mbWrapped = ::std::find( aBeg, aEnd, EXC_LF_C ) != aEnd;
484 0 : }
485 :
486 1533 : void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen, bool bBiff8 )
487 : {
488 1533 : mbIsBiff8 = bBiff8;
489 1533 : mbIsUnicode = bBiff8 && ::get_flag( nFlags, EXC_STR_FORCEUNICODE );
490 1533 : mb8BitLen = ::get_flag( nFlags, EXC_STR_8BITLENGTH );
491 1533 : mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
492 1533 : mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
493 1533 : mbWrapped = false;
494 1533 : mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
495 1533 : mnMaxLen = nMaxLen;
496 1533 : SetStrLen( nCurrLen );
497 :
498 1533 : maFormats.clear();
499 1533 : if( mbIsBiff8 )
500 : {
501 1533 : maCharBuffer.clear();
502 1533 : maUniBuffer.resize( mnLen );
503 : }
504 : else
505 : {
506 0 : maUniBuffer.clear();
507 0 : maCharBuffer.resize( mnLen );
508 : }
509 1533 : }
510 :
511 767 : void XclExpString::Build( const sal_Unicode* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
512 : {
513 767 : Init( nCurrLen, nFlags, nMaxLen, true );
514 767 : CharsToBuffer( pcSource, 0, mnLen );
515 767 : }
516 :
517 0 : void XclExpString::Build( const sal_Char* pcSource, sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMaxLen )
518 : {
519 0 : Init( nCurrLen, nFlags, nMaxLen, false );
520 0 : CharsToBuffer( pcSource, 0, mnLen );
521 0 : }
522 :
523 484 : void XclExpString::InitAppend( sal_Int32 nAddLen )
524 : {
525 484 : SetStrLen( static_cast< sal_Int32 >( mnLen ) + nAddLen );
526 484 : if( mbIsBiff8 )
527 484 : maUniBuffer.resize( mnLen );
528 : else
529 0 : maCharBuffer.resize( mnLen );
530 484 : }
531 :
532 484 : void XclExpString::BuildAppend( const sal_Unicode* pcSource, sal_Int32 nAddLen )
533 : {
534 : OSL_ENSURE( mbIsBiff8, "XclExpString::BuildAppend - must not be called at byte strings" );
535 484 : if( mbIsBiff8 )
536 : {
537 484 : sal_uInt16 nOldLen = mnLen;
538 484 : InitAppend( nAddLen );
539 484 : CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
540 : }
541 484 : }
542 :
543 0 : void XclExpString::BuildAppend( const sal_Char* pcSource, sal_Int32 nAddLen )
544 : {
545 : OSL_ENSURE( !mbIsBiff8, "XclExpString::BuildAppend - must not be called at unicode strings" );
546 0 : if( !mbIsBiff8 )
547 : {
548 0 : sal_uInt16 nOldLen = mnLen;
549 0 : InitAppend( nAddLen );
550 0 : CharsToBuffer( pcSource, nOldLen, mnLen - nOldLen );
551 : }
552 0 : }
553 :
554 364 : void XclExpString::PrepareWrite( XclExpStream& rStrm, sal_uInt16 nBytes ) const
555 : {
556 364 : rStrm.SetSliceSize( nBytes + (mbIsUnicode ? 2 : 1) );
557 394 : }
558 :
559 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|