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_sfx2.hxx" 26 27 #include "oleprops.hxx" 28 29 #include <comphelper/types.hxx> 30 #include <tools/debug.hxx> 31 #include <tools/datetime.hxx> 32 #include <rtl/tencinfo.h> 33 34 // ============================================================================ 35 36 37 // ============================================================================ 38 39 #define VERSION 11 40 #define STREAM_BUFFER_SIZE 2048 41 42 // usings 43 using ::rtl::OUString; 44 using ::com::sun::star::uno::Any; 45 using ::com::sun::star::uno::makeAny; 46 47 using namespace ::com::sun::star; 48 49 #define TIMESTAMP_INVALID_DATETIME ( DateTime ( Date ( 1, 1, 1601 ), Time ( 0, 0, 0 ) ) ) /// Invalid value for date and time to create invalid instance of TimeStamp. 50 #define TIMESTAMP_INVALID_UTILDATETIME ( util::DateTime ( 0, 0, 0, 0, 1, 1, 1601 ) ) /// Invalid value for date and time to create invalid instance of TimeStamp. 51 52 static 53 bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight) 54 { 55 return i_rLeft.Year == i_rRight.Year 56 && i_rLeft.Month == i_rRight.Month 57 && i_rLeft.Day == i_rRight.Day 58 && i_rLeft.Hours == i_rRight.Hours 59 && i_rLeft.Minutes == i_rRight.Minutes 60 && i_rLeft.Seconds == i_rRight.Seconds 61 && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds; 62 } 63 64 // ============================================================================ 65 66 /** Property representing a signed 32-bit integer value. */ 67 class SfxOleInt32Property : public SfxOlePropertyBase 68 { 69 public: 70 explicit SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue = 0 ); 71 72 inline sal_Int32 GetValue() const { return mnValue; } 73 inline void SetValue( sal_Int32 nValue ) { mnValue = nValue; } 74 75 private: 76 virtual void ImplLoad( SvStream& rStrm ); 77 virtual void ImplSave( SvStream& rStrm ); 78 79 private: 80 sal_Int32 mnValue; 81 }; 82 83 // ============================================================================ 84 85 /** Property representing a floating-point value. */ 86 class SfxOleDoubleProperty : public SfxOlePropertyBase 87 { 88 public: 89 explicit SfxOleDoubleProperty( sal_Int32 nPropId, double fValue = 0.0 ); 90 91 inline double GetValue() const { return mfValue; } 92 inline void SetValue( double fValue ) { mfValue = fValue; } 93 94 private: 95 virtual void ImplLoad( SvStream& rStrm ); 96 virtual void ImplSave( SvStream& rStrm ); 97 98 private: 99 double mfValue; 100 }; 101 102 // ============================================================================ 103 104 /** Property representing a boolean value. */ 105 class SfxOleBoolProperty : public SfxOlePropertyBase 106 { 107 public: 108 explicit SfxOleBoolProperty( sal_Int32 nPropId, bool bValue = false ); 109 110 inline bool GetValue() const { return mbValue; } 111 inline void SetValue( bool bValue ) { mbValue = bValue; } 112 113 private: 114 virtual void ImplLoad( SvStream& rStrm ); 115 virtual void ImplSave( SvStream& rStrm ); 116 117 private: 118 bool mbValue; 119 }; 120 121 // ============================================================================ 122 123 /** Base class for properties that contain a single string value. */ 124 class SfxOleStringPropertyBase : public SfxOlePropertyBase, public SfxOleStringHelper 125 { 126 public: 127 explicit SfxOleStringPropertyBase( 128 sal_Int32 nPropId, sal_Int32 nPropType, 129 const SfxOleTextEncoding& rTextEnc ); 130 explicit SfxOleStringPropertyBase( 131 sal_Int32 nPropId, sal_Int32 nPropType, 132 const SfxOleTextEncoding& rTextEnc, const String& rValue ); 133 explicit SfxOleStringPropertyBase( 134 sal_Int32 nPropId, sal_Int32 nPropType, 135 rtl_TextEncoding eTextEnc ); 136 explicit SfxOleStringPropertyBase( 137 sal_Int32 nPropId, sal_Int32 nPropType, 138 rtl_TextEncoding eTextEnc, const String& rValue ); 139 140 inline const String& GetValue() const { return maValue; } 141 inline void SetValue( const String& rValue ) { maValue = rValue; } 142 143 private: 144 String maValue; 145 }; 146 147 // ============================================================================ 148 149 /** Property representing a bytestring value. */ 150 class SfxOleString8Property : public SfxOleStringPropertyBase 151 { 152 public: 153 explicit SfxOleString8Property( 154 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc ); 155 explicit SfxOleString8Property( 156 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc, 157 const String& rValue ); 158 159 private: 160 virtual void ImplLoad( SvStream& rStrm ); 161 virtual void ImplSave( SvStream& rStrm ); 162 }; 163 164 // ============================================================================ 165 166 /** Property representing a Unicode string value. */ 167 class SfxOleString16Property : public SfxOleStringPropertyBase 168 { 169 public: 170 explicit SfxOleString16Property( sal_Int32 nPropId ); 171 explicit SfxOleString16Property( sal_Int32 nPropId, const String& rValue ); 172 173 private: 174 virtual void ImplLoad( SvStream& rStrm ); 175 virtual void ImplSave( SvStream& rStrm ); 176 }; 177 178 // ============================================================================ 179 180 /** Property representing a filetime value as defined by the Windows API. */ 181 class SfxOleFileTimeProperty : public SfxOlePropertyBase 182 { 183 public: 184 explicit SfxOleFileTimeProperty( sal_Int32 nPropId ); 185 /** @param rDateTime Date and time as LOCAL time. */ 186 explicit SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime ); 187 188 /** Returns the time value as LOCAL time. */ 189 inline const util::DateTime& GetValue() const { return maDateTime; } 190 /** @param rDateTime Date and time as LOCAL time. */ 191 inline void SetValue( const util::DateTime& rDateTime ) { maDateTime = rDateTime; } 192 193 private: 194 virtual void ImplLoad( SvStream& rStrm ); 195 virtual void ImplSave( SvStream& rStrm ); 196 197 private: 198 util::DateTime maDateTime; 199 }; 200 201 // ============================================================================ 202 203 /** Property representing a thumbnail picture. 204 205 Currently, only saving this property is implemented. 206 */ 207 class SfxOleThumbnailProperty : public SfxOlePropertyBase 208 { 209 public: 210 explicit SfxOleThumbnailProperty( sal_Int32 nPropId, 211 const uno::Sequence<sal_uInt8> & i_rData); 212 213 inline bool IsValid() const { return mData.getLength() > 0; } 214 215 private: 216 virtual void ImplLoad( SvStream& rStrm ); 217 virtual void ImplSave( SvStream& rStrm ); 218 219 private: 220 uno::Sequence<sal_uInt8> mData; 221 }; 222 223 // ============================================================================ 224 225 /** Property representing a BLOB (which presumably stands for binary large 226 object). 227 228 Currently, only saving this property is implemented. 229 */ 230 class SfxOleBlobProperty : public SfxOlePropertyBase 231 { 232 public: 233 explicit SfxOleBlobProperty( sal_Int32 nPropId, 234 const uno::Sequence<sal_uInt8> & i_rData); 235 inline bool IsValid() const { return mData.getLength() > 0; } 236 237 private: 238 virtual void ImplLoad( SvStream& rStrm ); 239 virtual void ImplSave( SvStream& rStrm ); 240 241 private: 242 uno::Sequence<sal_uInt8> mData; 243 }; 244 245 // ============================================================================ 246 247 sal_uInt16 SfxOleTextEncoding::GetCodePage() const 248 { 249 sal_uInt16 nCodePage = IsUnicode() ? CODEPAGE_UNICODE : 250 static_cast< sal_uInt16 >( rtl_getWindowsCodePageFromTextEncoding( *mxTextEnc ) ); 251 return (nCodePage == CODEPAGE_UNKNOWN) ? CODEPAGE_UTF8 : nCodePage; 252 } 253 254 void SfxOleTextEncoding::SetCodePage( sal_uInt16 nCodePage ) 255 { 256 if( nCodePage == CODEPAGE_UNICODE ) 257 SetUnicode(); 258 else 259 { 260 rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); 261 if( eTextEnc != RTL_TEXTENCODING_DONTKNOW ) 262 *mxTextEnc = eTextEnc; 263 } 264 } 265 266 // ---------------------------------------------------------------------------- 267 268 String SfxOleStringHelper::LoadString8( SvStream& rStrm ) const 269 { 270 return IsUnicode() ? ImplLoadString16( rStrm ) : ImplLoadString8( rStrm ); 271 } 272 273 void SfxOleStringHelper::SaveString8( SvStream& rStrm, const String& rValue ) const 274 { 275 if( IsUnicode() ) 276 ImplSaveString16( rStrm, rValue ); 277 else 278 ImplSaveString8( rStrm, rValue ); 279 } 280 281 String SfxOleStringHelper::LoadString16( SvStream& rStrm ) const 282 { 283 return ImplLoadString16( rStrm ); 284 } 285 286 void SfxOleStringHelper::SaveString16( SvStream& rStrm, const String& rValue ) const 287 { 288 ImplSaveString16( rStrm, rValue ); 289 } 290 291 String SfxOleStringHelper::ImplLoadString8( SvStream& rStrm ) const 292 { 293 String aValue; 294 // read size field (signed 32-bit) 295 sal_Int32 nSize; 296 rStrm >> nSize; 297 // size field includes trailing NUL character 298 DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF), "SfxOleStringHelper::ImplLoadString8 - invalid string" ); 299 if( (0 < nSize) && (nSize <= 0xFFFF) ) 300 { 301 // load character buffer 302 ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nSize + 1 ), 0 ); 303 rStrm.Read( &aBuffer.front(), static_cast< sal_Size >( nSize ) ); 304 // create string from encoded character array 305 aValue = String( &aBuffer.front(), GetTextEncoding() ); 306 } 307 return aValue; 308 } 309 310 String SfxOleStringHelper::ImplLoadString16( SvStream& rStrm ) const 311 { 312 String aValue; 313 // read size field (signed 32-bit), may be buffer size or character count 314 sal_Int32 nSize; 315 rStrm >> nSize; 316 DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF), "SfxOleStringHelper::ImplLoadString16 - invalid string" ); 317 // size field includes trailing NUL character 318 if( (0 < nSize) && (nSize <= 0xFFFF) ) 319 { 320 // load character buffer 321 ::std::vector< sal_Unicode > aBuffer; 322 aBuffer.reserve( static_cast< size_t >( nSize + 1 ) ); 323 sal_uInt16 cChar; 324 for( sal_Int32 nIdx = 0; nIdx < nSize; ++nIdx ) 325 { 326 rStrm >> cChar; 327 aBuffer.push_back( static_cast< sal_Unicode >( cChar ) ); 328 } 329 // stream is always padded to 32-bit boundary, skip 2 bytes on odd character count 330 if( (nSize & 1) == 1 ) 331 rStrm.SeekRel( 2 ); 332 // create string from character array 333 aBuffer.push_back( 0 ); 334 aValue = String( &aBuffer.front() ); 335 } 336 return aValue; 337 } 338 339 void SfxOleStringHelper::ImplSaveString8( SvStream& rStrm, const String& rValue ) const 340 { 341 // encode to byte string 342 ByteString aEncoded( rValue, GetTextEncoding() ); 343 // write size field (including trailing NUL character) 344 sal_Int32 nSize = static_cast< sal_Int32 >( aEncoded.Len() + 1 ); 345 rStrm << nSize; 346 // write character array with trailing NUL character 347 rStrm.Write( aEncoded.GetBuffer(), aEncoded.Len() ); 348 rStrm << sal_uInt8( 0 ); 349 } 350 351 void SfxOleStringHelper::ImplSaveString16( SvStream& rStrm, const String& rValue ) const 352 { 353 // write size field (including trailing NUL character) 354 sal_Int32 nSize = static_cast< sal_Int32 >( rValue.Len() + 1 ); 355 rStrm << nSize; 356 // write character array with trailing NUL character 357 for( xub_StrLen nIdx = 0; nIdx < rValue.Len(); ++nIdx ) 358 rStrm << static_cast< sal_uInt16 >( rValue.GetChar( nIdx ) ); 359 rStrm << sal_uInt16( 0 ); 360 // stream is always padded to 32-bit boundary, add 2 bytes on odd character count 361 if( (nSize & 1) == 1 ) 362 rStrm << sal_uInt16( 0 ); 363 } 364 365 // ---------------------------------------------------------------------------- 366 367 SfxOleObjectBase::~SfxOleObjectBase() 368 { 369 } 370 371 ErrCode SfxOleObjectBase::Load( SvStream& rStrm ) 372 { 373 mnErrCode = ERRCODE_NONE; 374 ImplLoad( rStrm ); 375 SetError( rStrm.GetErrorCode() ); 376 return GetError(); 377 } 378 379 ErrCode SfxOleObjectBase::Save( SvStream& rStrm ) 380 { 381 mnErrCode = ERRCODE_NONE; 382 ImplSave( rStrm ); 383 SetError( rStrm.GetErrorCode() ); 384 return GetError(); 385 } 386 387 void SfxOleObjectBase::LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj ) 388 { 389 SetError( rObj.Load( rStrm ) ); 390 } 391 392 void SfxOleObjectBase::SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj ) 393 { 394 SetError( rObj.Save( rStrm ) ); 395 } 396 397 // ---------------------------------------------------------------------------- 398 399 SfxOleCodePageProperty::SfxOleCodePageProperty() : 400 SfxOlePropertyBase( PROPID_CODEPAGE, PROPTYPE_INT16 ) 401 { 402 } 403 404 void SfxOleCodePageProperty::ImplLoad( SvStream& rStrm ) 405 { 406 // property type is signed int16, but we use always unsigned int16 for codepages 407 sal_uInt16 nCodePage; 408 rStrm >> nCodePage; 409 SetCodePage( nCodePage ); 410 } 411 412 void SfxOleCodePageProperty::ImplSave( SvStream& rStrm ) 413 { 414 // property type is signed int16, but we use always unsigned int16 for codepages 415 rStrm << GetCodePage(); 416 } 417 418 // ---------------------------------------------------------------------------- 419 420 SfxOleInt32Property::SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue ) : 421 SfxOlePropertyBase( nPropId, PROPTYPE_INT32 ), 422 mnValue( nValue ) 423 { 424 } 425 426 void SfxOleInt32Property::ImplLoad( SvStream& rStrm ) 427 { 428 rStrm >> mnValue; 429 } 430 431 void SfxOleInt32Property::ImplSave( SvStream& rStrm ) 432 { 433 rStrm << mnValue; 434 } 435 436 // ---------------------------------------------------------------------------- 437 438 SfxOleDoubleProperty::SfxOleDoubleProperty( sal_Int32 nPropId, double fValue ) : 439 SfxOlePropertyBase( nPropId, PROPTYPE_DOUBLE ), 440 mfValue( fValue ) 441 { 442 } 443 444 void SfxOleDoubleProperty::ImplLoad( SvStream& rStrm ) 445 { 446 rStrm >> mfValue; 447 } 448 449 void SfxOleDoubleProperty::ImplSave( SvStream& rStrm ) 450 { 451 rStrm << mfValue; 452 } 453 454 // ---------------------------------------------------------------------------- 455 456 SfxOleBoolProperty::SfxOleBoolProperty( sal_Int32 nPropId, bool bValue ) : 457 SfxOlePropertyBase( nPropId, PROPTYPE_BOOL ), 458 mbValue( bValue ) 459 { 460 } 461 462 void SfxOleBoolProperty::ImplLoad( SvStream& rStrm ) 463 { 464 sal_Int16 nValue; 465 rStrm >> nValue; 466 mbValue = nValue != 0; 467 } 468 469 void SfxOleBoolProperty::ImplSave( SvStream& rStrm ) 470 { 471 rStrm << static_cast< sal_Int16 >( mbValue ? -1 : 0 ); 472 } 473 474 // ---------------------------------------------------------------------------- 475 476 SfxOleStringPropertyBase::SfxOleStringPropertyBase( 477 sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc ) : 478 SfxOlePropertyBase( nPropId, nPropType ), 479 SfxOleStringHelper( rTextEnc ) 480 { 481 } 482 483 SfxOleStringPropertyBase::SfxOleStringPropertyBase( 484 sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc, const String& rValue ) : 485 SfxOlePropertyBase( nPropId, nPropType ), 486 SfxOleStringHelper( rTextEnc ), 487 maValue( rValue ) 488 { 489 } 490 491 SfxOleStringPropertyBase::SfxOleStringPropertyBase( 492 sal_Int32 nPropId, sal_Int32 nPropType, rtl_TextEncoding eTextEnc ) : 493 SfxOlePropertyBase( nPropId, nPropType ), 494 SfxOleStringHelper( eTextEnc ) 495 { 496 } 497 498 SfxOleStringPropertyBase::SfxOleStringPropertyBase( 499 sal_Int32 nPropId, sal_Int32 nPropType, rtl_TextEncoding eTextEnc, const String& rValue ) : 500 SfxOlePropertyBase( nPropId, nPropType ), 501 SfxOleStringHelper( eTextEnc ), 502 maValue( rValue ) 503 { 504 } 505 506 // ---------------------------------------------------------------------------- 507 508 SfxOleString8Property::SfxOleString8Property( 509 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc ) : 510 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc ) 511 { 512 } 513 514 SfxOleString8Property::SfxOleString8Property( 515 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc, const String& rValue ) : 516 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc, rValue ) 517 { 518 } 519 520 void SfxOleString8Property::ImplLoad( SvStream& rStrm ) 521 { 522 SetValue( LoadString8( rStrm ) ); 523 } 524 525 void SfxOleString8Property::ImplSave( SvStream& rStrm ) 526 { 527 SaveString8( rStrm, GetValue() ); 528 } 529 530 // ---------------------------------------------------------------------------- 531 532 SfxOleString16Property::SfxOleString16Property( sal_Int32 nPropId ) : 533 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING16, RTL_TEXTENCODING_UCS2 ) 534 { 535 } 536 537 SfxOleString16Property::SfxOleString16Property( sal_Int32 nPropId, const String& rValue ) : 538 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING16, RTL_TEXTENCODING_UCS2, rValue ) 539 { 540 } 541 542 void SfxOleString16Property::ImplLoad( SvStream& rStrm ) 543 { 544 SetValue( LoadString16( rStrm ) ); 545 } 546 547 void SfxOleString16Property::ImplSave( SvStream& rStrm ) 548 { 549 SaveString16( rStrm, GetValue() ); 550 } 551 552 // ---------------------------------------------------------------------------- 553 554 SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId ) : 555 SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME ) 556 { 557 } 558 559 SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime ) : 560 SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME ), 561 maDateTime( rDateTime ) 562 { 563 } 564 565 void SfxOleFileTimeProperty::ImplLoad( SvStream& rStrm ) 566 { 567 sal_uInt32 nLower, nUpper; 568 rStrm >> nLower >> nUpper; 569 ::DateTime aDateTime = DateTime::CreateFromWin32FileDateTime( nLower, nUpper ); 570 // note: editing duration is stored as offset to TIMESTAMP_INVALID_DATETIME 571 // of course we should not convert the time zone of a duration! 572 // heuristic to detect editing durations (which we assume to be < 1 year): 573 // check only the year, not the entire date 574 if ( aDateTime.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() ) 575 aDateTime.ConvertToLocalTime(); 576 maDateTime.Year = aDateTime.GetYear(); 577 maDateTime.Month = aDateTime.GetMonth(); 578 maDateTime.Day = aDateTime.GetDay(); 579 maDateTime.Hours = aDateTime.GetHour(); 580 maDateTime.Minutes = aDateTime.GetMin(); 581 maDateTime.Seconds = aDateTime.GetSec(); 582 maDateTime.HundredthSeconds = aDateTime.Get100Sec(); 583 } 584 585 void SfxOleFileTimeProperty::ImplSave( SvStream& rStrm ) 586 { 587 DateTime aDateTimeUtc( 588 Date( 589 static_cast< sal_uInt16 >( maDateTime.Day ), 590 static_cast< sal_uInt16 >( maDateTime.Month ), 591 static_cast< sal_uInt16 >( maDateTime.Year ) ), 592 Time( 593 static_cast< sal_uIntPtr >( maDateTime.Hours ), 594 static_cast< sal_uIntPtr >( maDateTime.Minutes ), 595 static_cast< sal_uIntPtr >( maDateTime.Seconds ), 596 static_cast< sal_uIntPtr >( maDateTime.HundredthSeconds ) ) ); 597 // invalid time stamp is not converted to UTC 598 // heuristic to detect editing durations (which we assume to be < 1 year): 599 // check only the year, not the entire date 600 if( aDateTimeUtc.IsValid() 601 && aDateTimeUtc.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() ) { 602 aDateTimeUtc.ConvertToUTC(); 603 } 604 sal_uInt32 nLower, nUpper; 605 aDateTimeUtc.GetWin32FileDateTime( nLower, nUpper ); 606 rStrm << nLower << nUpper; 607 } 608 609 // ---------------------------------------------------------------------------- 610 611 SfxOleThumbnailProperty::SfxOleThumbnailProperty( 612 sal_Int32 nPropId, const uno::Sequence<sal_uInt8> & i_rData) : 613 SfxOlePropertyBase( nPropId, PROPTYPE_CLIPFMT ), 614 mData(i_rData) 615 { 616 } 617 618 void SfxOleThumbnailProperty::ImplLoad( SvStream& ) 619 { 620 DBG_ERRORFILE( "SfxOleThumbnailProperty::ImplLoad - not implemented" ); 621 SetError( SVSTREAM_INVALID_ACCESS ); 622 } 623 624 void SfxOleThumbnailProperty::ImplSave( SvStream& rStrm ) 625 { 626 /* Type Contents 627 ----------------------------------------------------------------------- 628 int32 size of following data 629 int32 clipboard format tag (see below) 630 byte[] clipboard data (see below) 631 632 Clipboard format tag: 633 -1 = Windows clipboard format 634 -2 = Macintosh clipboard format 635 -3 = GUID that contains a format identifier (FMTID) 636 >0 = custom clipboard format name plus data (see msdn site below) 637 0 = no data 638 639 References: 640 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/propvariant.asp 641 http://jakarta.apache.org/poi/hpsf/thumbnails.html 642 http://linux.com.hk/docs/poi/org/apache/poi/hpsf/Thumbnail.html 643 http://sparks.discreet.com/knowledgebase/public/solutions/ExtractThumbnailImg.htm 644 */ 645 if( IsValid() ) 646 { 647 // clipboard size: clip_format_tag + data_format_tag + bitmap_len 648 sal_Int32 nClipSize = static_cast< sal_Int32 >( 4 + 4 + mData.getLength() ); 649 rStrm << nClipSize << CLIPFMT_WIN << CLIPDATAFMT_DIB; 650 rStrm.Write( mData.getConstArray(), mData.getLength() ); 651 } 652 else 653 { 654 DBG_ERRORFILE( "SfxOleThumbnailProperty::ImplSave - invalid thumbnail property" ); 655 SetError( SVSTREAM_INVALID_ACCESS ); 656 } 657 } 658 659 // ---------------------------------------------------------------------------- 660 661 SfxOleBlobProperty::SfxOleBlobProperty( sal_Int32 nPropId, 662 const uno::Sequence<sal_uInt8> & i_rData) : 663 SfxOlePropertyBase( nPropId, PROPTYPE_BLOB ), 664 mData(i_rData) 665 { 666 } 667 668 void SfxOleBlobProperty::ImplLoad( SvStream& ) 669 { 670 DBG_ERRORFILE( "SfxOleBlobProperty::ImplLoad - not implemented" ); 671 SetError( SVSTREAM_INVALID_ACCESS ); 672 } 673 674 void SfxOleBlobProperty::ImplSave( SvStream& rStrm ) 675 { 676 if (IsValid()) { 677 rStrm.Write( mData.getConstArray(), mData.getLength() ); 678 } else { 679 DBG_ERRORFILE( "SfxOleBlobProperty::ImplSave - invalid BLOB property" ); 680 SetError( SVSTREAM_INVALID_ACCESS ); 681 } 682 } 683 684 // ---------------------------------------------------------------------------- 685 686 SfxOleDictionaryProperty::SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc ) : 687 SfxOlePropertyBase( PROPID_DICTIONARY, 0 ), 688 SfxOleStringHelper( rTextEnc ) 689 { 690 } 691 692 const String& SfxOleDictionaryProperty::GetPropertyName( sal_Int32 nPropId ) const 693 { 694 SfxOlePropNameMap::const_iterator aIt = maPropNameMap.find( nPropId ); 695 return (aIt == maPropNameMap.end()) ? String::EmptyString() : aIt->second; 696 } 697 698 void SfxOleDictionaryProperty::SetPropertyName( sal_Int32 nPropId, const String& rPropName ) 699 { 700 maPropNameMap[ nPropId ] = rPropName; 701 // dictionary property contains number of pairs in property type field 702 SetPropType( static_cast< sal_Int32 >( maPropNameMap.size() ) ); 703 } 704 705 void SfxOleDictionaryProperty::ImplLoad( SvStream& rStrm ) 706 { 707 // dictionary property contains number of pairs in property type field 708 sal_Int32 nNameCount = GetPropType(); 709 // read property ID/name pairs 710 maPropNameMap.clear(); 711 for( sal_Int32 nIdx = 0; (nIdx < nNameCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nIdx ) 712 { 713 sal_Int32 nPropId; 714 rStrm >> nPropId; 715 // name always stored as byte string 716 maPropNameMap[ nPropId ] = LoadString8( rStrm ); 717 } 718 } 719 720 void SfxOleDictionaryProperty::ImplSave( SvStream& rStrm ) 721 { 722 // write property ID/name pairs 723 for( SfxOlePropNameMap::const_iterator aIt = maPropNameMap.begin(), aEnd = maPropNameMap.end(); aIt != aEnd; ++aIt ) 724 { 725 rStrm << aIt->first; 726 // name always stored as byte string 727 SaveString8( rStrm, aIt->second ); 728 } 729 } 730 731 // ---------------------------------------------------------------------------- 732 733 SfxOleSection::SfxOleSection( bool bSupportsDict ) : 734 maDictProp( maCodePageProp ), 735 mnStartPos( 0 ), 736 mbSupportsDict( bSupportsDict ) 737 { 738 } 739 740 SfxOlePropertyRef SfxOleSection::GetProperty( sal_Int32 nPropId ) const 741 { 742 SfxOlePropertyRef xProp; 743 SfxOlePropMap::const_iterator aIt = maPropMap.find( nPropId ); 744 if( aIt != maPropMap.end() ) 745 xProp = aIt->second; 746 return xProp; 747 } 748 749 bool SfxOleSection::GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const 750 { 751 SfxOlePropertyRef xProp = GetProperty( nPropId ); 752 const SfxOleInt32Property* pProp = 753 dynamic_cast< const SfxOleInt32Property* >( xProp.get() ); 754 if( pProp ) 755 rnValue = pProp->GetValue(); 756 return pProp != 0; 757 } 758 759 bool SfxOleSection::GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const 760 { 761 SfxOlePropertyRef xProp = GetProperty( nPropId ); 762 const SfxOleDoubleProperty* pProp = 763 dynamic_cast< const SfxOleDoubleProperty* >( xProp.get() ); 764 if( pProp ) 765 rfValue = pProp->GetValue(); 766 return pProp != 0; 767 } 768 769 bool SfxOleSection::GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const 770 { 771 SfxOlePropertyRef xProp = GetProperty( nPropId ); 772 const SfxOleBoolProperty* pProp = 773 dynamic_cast< const SfxOleBoolProperty* >( xProp.get() ); 774 if( pProp ) 775 rbValue = pProp->GetValue(); 776 return pProp != 0; 777 } 778 779 bool SfxOleSection::GetStringValue( String& rValue, sal_Int32 nPropId ) const 780 { 781 SfxOlePropertyRef xProp = GetProperty( nPropId ); 782 const SfxOleStringPropertyBase* pProp = 783 dynamic_cast< const SfxOleStringPropertyBase* >( xProp.get() ); 784 if( pProp ) 785 rValue = pProp->GetValue(); 786 return pProp != 0; 787 } 788 789 bool SfxOleSection::GetFileTimeValue( util::DateTime& rValue, sal_Int32 nPropId ) const 790 { 791 SfxOlePropertyRef xProp = GetProperty( nPropId ); 792 const SfxOleFileTimeProperty* pProp = 793 dynamic_cast< const SfxOleFileTimeProperty* >( xProp.get() ); 794 if( pProp ) 795 { 796 if ( pProp->GetValue() == TIMESTAMP_INVALID_UTILDATETIME ) 797 rValue = util::DateTime(); 798 else 799 rValue = pProp->GetValue(); 800 } 801 return pProp != 0; 802 } 803 804 void SfxOleSection::SetProperty( SfxOlePropertyRef xProp ) 805 { 806 if( xProp.get() ) 807 maPropMap[ xProp->GetPropId() ] = xProp; 808 } 809 810 void SfxOleSection::SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue ) 811 { 812 SetProperty( SfxOlePropertyRef( new SfxOleInt32Property( nPropId, nValue ) ) ); 813 } 814 815 void SfxOleSection::SetDoubleValue( sal_Int32 nPropId, double fValue ) 816 { 817 SetProperty( SfxOlePropertyRef( new SfxOleDoubleProperty( nPropId, fValue ) ) ); 818 } 819 820 void SfxOleSection::SetBoolValue( sal_Int32 nPropId, bool bValue ) 821 { 822 SetProperty( SfxOlePropertyRef( new SfxOleBoolProperty( nPropId, bValue ) ) ); 823 } 824 825 bool SfxOleSection::SetStringValue( sal_Int32 nPropId, const String& rValue, bool bSkipEmpty ) 826 { 827 bool bInserted = !bSkipEmpty || (rValue.Len() > 0); 828 if( bInserted ) 829 SetProperty( SfxOlePropertyRef( new SfxOleString8Property( nPropId, maCodePageProp, rValue ) ) ); 830 return bInserted; 831 } 832 833 void SfxOleSection::SetFileTimeValue( sal_Int32 nPropId, const util::DateTime& rValue ) 834 { 835 if ( rValue.Year == 0 || rValue.Month == 0 || rValue.Day == 0 ) 836 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, TIMESTAMP_INVALID_UTILDATETIME ) ) ); 837 else 838 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, rValue ) ) ); 839 } 840 841 void SfxOleSection::SetThumbnailValue( sal_Int32 nPropId, 842 const uno::Sequence<sal_uInt8> & i_rData) 843 { 844 SfxOleThumbnailProperty* pThumbnail = new SfxOleThumbnailProperty( nPropId, i_rData ); 845 SfxOlePropertyRef xProp( pThumbnail ); // take ownership 846 if( pThumbnail->IsValid() ) 847 SetProperty( xProp ); 848 } 849 850 void SfxOleSection::SetBlobValue( sal_Int32 nPropId, 851 const uno::Sequence<sal_uInt8> & i_rData) 852 { 853 SfxOleBlobProperty* pBlob( new SfxOleBlobProperty( nPropId, i_rData ) ); 854 SfxOlePropertyRef xProp( pBlob ); 855 if( pBlob->IsValid() ) { 856 SetProperty( xProp ); 857 } 858 } 859 860 Any SfxOleSection::GetAnyValue( sal_Int32 nPropId ) const 861 { 862 Any aValue; 863 sal_Int32 nInt32 = 0; 864 double fDouble = 0.0; 865 bool bBool = false; 866 String aString; 867 ::com::sun::star::util::DateTime aApiDateTime; 868 869 if( GetInt32Value( nInt32, nPropId ) ) 870 aValue <<= nInt32; 871 else if( GetDoubleValue( fDouble, nPropId ) ) 872 aValue <<= fDouble; 873 else if( GetBoolValue( bBool, nPropId ) ) 874 ::comphelper::setBOOL( aValue, bBool ? sal_True : sal_False ); 875 else if( GetStringValue( aString, nPropId ) ) 876 aValue <<= OUString( aString ); 877 else if( GetFileTimeValue( aApiDateTime, nPropId ) ) 878 { 879 aValue <<= aApiDateTime; 880 } 881 return aValue; 882 } 883 884 bool SfxOleSection::SetAnyValue( sal_Int32 nPropId, const Any& rValue ) 885 { 886 bool bInserted = true; 887 sal_Int32 nInt32 = 0; 888 double fDouble = 0.0; 889 OUString aString; 890 ::com::sun::star::util::DateTime aApiDateTime; 891 892 if( rValue.getValueType() == ::getBooleanCppuType() ) 893 SetBoolValue( nPropId, ::comphelper::getBOOL( rValue ) == sal_True ); 894 else if( rValue >>= nInt32 ) 895 SetInt32Value( nPropId, nInt32 ); 896 else if( rValue >>= fDouble ) 897 SetDoubleValue( nPropId, fDouble ); 898 else if( rValue >>= aString ) 899 bInserted = SetStringValue( nPropId, aString ); 900 else if( rValue >>= aApiDateTime ) 901 { 902 SetFileTimeValue( nPropId, aApiDateTime ); 903 } 904 else 905 bInserted = false; 906 return bInserted; 907 } 908 909 const String& SfxOleSection::GetPropertyName( sal_Int32 nPropId ) const 910 { 911 return maDictProp.GetPropertyName( nPropId ); 912 } 913 914 void SfxOleSection::SetPropertyName( sal_Int32 nPropId, const String& rPropName ) 915 { 916 maDictProp.SetPropertyName( nPropId, rPropName ); 917 } 918 919 void SfxOleSection::GetPropertyIds( ::std::vector< sal_Int32 >& rPropIds ) const 920 { 921 rPropIds.clear(); 922 for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt ) 923 rPropIds.push_back( aIt->first ); 924 } 925 926 sal_Int32 SfxOleSection::GetFreePropertyId() const 927 { 928 return maPropMap.empty() ? PROPID_FIRSTCUSTOM : (maPropMap.rbegin()->first + 1); 929 } 930 931 void SfxOleSection::ImplLoad( SvStream& rStrm ) 932 { 933 // read section header 934 mnStartPos = rStrm.Tell(); 935 sal_uInt32 nSize; 936 sal_Int32 nPropCount; 937 rStrm >> nSize >> nPropCount; 938 939 // read property ID/position pairs 940 typedef ::std::map< sal_Int32, sal_uInt32 > SfxOlePropPosMap; 941 SfxOlePropPosMap aPropPosMap; 942 for( sal_Int32 nPropIdx = 0; (nPropIdx < nPropCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nPropIdx ) 943 { 944 sal_Int32 nPropId; 945 sal_uInt32 nPropPos; 946 rStrm >> nPropId >> nPropPos; 947 aPropPosMap[ nPropId ] = nPropPos; 948 } 949 950 // read codepage property 951 SfxOlePropPosMap::iterator aCodePageIt = aPropPosMap.find( PROPID_CODEPAGE ); 952 if( (aCodePageIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aCodePageIt->second ) ) 953 { 954 // codepage property must be of type signed int-16 955 sal_Int32 nPropType; 956 rStrm >> nPropType; 957 if( nPropType == PROPTYPE_INT16 ) 958 LoadObject( rStrm, maCodePageProp ); 959 // remove property position 960 aPropPosMap.erase( aCodePageIt ); 961 } 962 963 // read dictionary property 964 SfxOlePropPosMap::iterator aDictIt = aPropPosMap.find( PROPID_DICTIONARY ); 965 if( (aDictIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aDictIt->second ) ) 966 { 967 // #i66214# #i66428# applications may write broken dictionary properties in wrong sections 968 if( mbSupportsDict ) 969 { 970 // dictionary property contains number of pairs in property type field 971 sal_Int32 nNameCount; 972 rStrm >> nNameCount; 973 maDictProp.SetNameCount( nNameCount ); 974 LoadObject( rStrm, maDictProp ); 975 } 976 // always remove position of dictionary property (do not try to read it again below) 977 aPropPosMap.erase( aDictIt ); 978 } 979 980 // read other properties 981 maPropMap.clear(); 982 for( SfxOlePropPosMap::const_iterator aIt = aPropPosMap.begin(), aEnd = aPropPosMap.end(); aIt != aEnd; ++aIt ) 983 if( SeekToPropertyPos( rStrm, aIt->second ) ) 984 LoadProperty( rStrm, aIt->first ); 985 } 986 987 void SfxOleSection::ImplSave( SvStream& rStrm ) 988 { 989 /* Always export with UTF-8 encoding. All dependent properties (bytestring 990 and dictionary) will be updated automatically. */ 991 maCodePageProp.SetTextEncoding( RTL_TEXTENCODING_UTF8 ); 992 993 // write section header 994 mnStartPos = rStrm.Tell(); 995 sal_Int32 nPropCount = static_cast< sal_Int32 >( maPropMap.size() + 1 ); 996 if( maDictProp.HasPropertyNames() ) 997 ++nPropCount; 998 rStrm << sal_uInt32( 0 ) << nPropCount; 999 1000 // write placeholders for property ID/position pairs 1001 sal_Size nPropPosPos = rStrm.Tell(); 1002 rStrm.SeekRel( static_cast< sal_sSize >( 8 * nPropCount ) ); 1003 1004 // write dictionary property 1005 if( maDictProp.HasPropertyNames() ) 1006 SaveProperty( rStrm, maDictProp, nPropPosPos ); 1007 // write codepage property 1008 SaveProperty( rStrm, maCodePageProp, nPropPosPos ); 1009 // write other properties 1010 for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt ) 1011 SaveProperty( rStrm, *aIt->second, nPropPosPos ); 1012 1013 // write section size (first field in section header) 1014 rStrm.Seek( STREAM_SEEK_TO_END ); 1015 sal_uInt32 nSectSize = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos ); 1016 rStrm.Seek( mnStartPos ); 1017 rStrm << nSectSize; 1018 } 1019 1020 bool SfxOleSection::SeekToPropertyPos( SvStream& rStrm, sal_uInt32 nPropPos ) const 1021 { 1022 rStrm.Seek( static_cast< sal_Size >( mnStartPos + nPropPos ) ); 1023 return rStrm.GetErrorCode() == SVSTREAM_OK; 1024 } 1025 1026 void SfxOleSection::LoadProperty( SvStream& rStrm, sal_Int32 nPropId ) 1027 { 1028 // property data type 1029 sal_Int32 nPropType; 1030 rStrm >> nPropType; 1031 // create empty property object 1032 SfxOlePropertyRef xProp; 1033 switch( nPropType ) 1034 { 1035 case PROPTYPE_INT32: 1036 xProp.reset( new SfxOleInt32Property( nPropId ) ); 1037 break; 1038 case PROPTYPE_DOUBLE: 1039 xProp.reset( new SfxOleDoubleProperty( nPropId ) ); 1040 break; 1041 case PROPTYPE_BOOL: 1042 xProp.reset( new SfxOleBoolProperty( nPropId ) ); 1043 break; 1044 case PROPTYPE_STRING8: 1045 xProp.reset( new SfxOleString8Property( nPropId, maCodePageProp ) ); 1046 break; 1047 case PROPTYPE_STRING16: 1048 xProp.reset( new SfxOleString16Property( nPropId ) ); 1049 break; 1050 case PROPTYPE_FILETIME: 1051 xProp.reset( new SfxOleFileTimeProperty( nPropId ) ); 1052 break; 1053 } 1054 // load property contents 1055 if( xProp.get() ) 1056 { 1057 SetError( xProp->Load( rStrm ) ); 1058 maPropMap[ nPropId ] = xProp; 1059 } 1060 } 1061 1062 void SfxOleSection::SaveProperty( SvStream& rStrm, SfxOlePropertyBase& rProp, sal_Size& rnPropPosPos ) 1063 { 1064 rStrm.Seek( STREAM_SEEK_TO_END ); 1065 sal_uInt32 nPropPos = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos ); 1066 // property data type 1067 rStrm << rProp.GetPropType(); 1068 // write property contents 1069 SaveObject( rStrm, rProp ); 1070 // align to 32-bit 1071 while( (rStrm.Tell() & 3) != 0 ) 1072 rStrm << sal_uInt8( 0 ); 1073 // write property ID/position pair 1074 rStrm.Seek( rnPropPosPos ); 1075 rStrm << rProp.GetPropId() << nPropPos; 1076 rnPropPosPos = rStrm.Tell(); 1077 } 1078 1079 // ---------------------------------------------------------------------------- 1080 1081 ErrCode SfxOlePropertySet::LoadPropertySet( SotStorage* pStrg, const String& rStrmName ) 1082 { 1083 if( pStrg ) 1084 { 1085 SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_STD_READ ); 1086 if( xStrm.Is() && (xStrm->GetError() == SVSTREAM_OK) ) 1087 { 1088 xStrm->SetBufferSize( STREAM_BUFFER_SIZE ); 1089 Load( *xStrm ); 1090 } 1091 else 1092 SetError( ERRCODE_IO_ACCESSDENIED ); 1093 } 1094 else 1095 SetError( ERRCODE_IO_ACCESSDENIED ); 1096 return GetError(); 1097 } 1098 1099 ErrCode SfxOlePropertySet::SavePropertySet( SotStorage* pStrg, const String& rStrmName ) 1100 { 1101 if( pStrg ) 1102 { 1103 SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_TRUNC | STREAM_STD_WRITE ); 1104 if( xStrm.Is() ) 1105 Save( *xStrm ); 1106 else 1107 SetError( ERRCODE_IO_ACCESSDENIED ); 1108 } 1109 else 1110 SetError( ERRCODE_IO_ACCESSDENIED ); 1111 return GetError(); 1112 } 1113 1114 SfxOleSectionRef SfxOlePropertySet::GetSection( SfxOleSectionType eSection ) const 1115 { 1116 return GetSection( GetSectionGuid( eSection ) ); 1117 } 1118 1119 SfxOleSectionRef SfxOlePropertySet::GetSection( const SvGlobalName& rSectionGuid ) const 1120 { 1121 SfxOleSectionRef xSection; 1122 SfxOleSectionMap::const_iterator aIt = maSectionMap.find( rSectionGuid ); 1123 if( aIt != maSectionMap.end() ) 1124 xSection = aIt->second; 1125 return xSection; 1126 } 1127 1128 SfxOleSection& SfxOlePropertySet::AddSection( SfxOleSectionType eSection ) 1129 { 1130 return AddSection( GetSectionGuid( eSection ) ); 1131 } 1132 1133 SfxOleSection& SfxOlePropertySet::AddSection( const SvGlobalName& rSectionGuid ) 1134 { 1135 SfxOleSectionRef xSection = GetSection( rSectionGuid ); 1136 if( !xSection ) 1137 { 1138 // #i66214# #i66428# applications may write broken dictionary properties in wrong sections 1139 bool bSupportsDict = rSectionGuid == GetSectionGuid( SECTION_CUSTOM ); 1140 xSection.reset( new SfxOleSection( bSupportsDict ) ); 1141 maSectionMap[ rSectionGuid ] = xSection; 1142 } 1143 return *xSection; 1144 } 1145 1146 void SfxOlePropertySet::ImplLoad( SvStream& rStrm ) 1147 { 1148 // read property set header 1149 sal_uInt16 nByteOrder; 1150 sal_uInt16 nVersion; 1151 sal_uInt16 nOsMinor; 1152 sal_uInt16 nOsType; 1153 SvGlobalName aGuid; 1154 sal_Int32 nSectCount; 1155 rStrm >> nByteOrder >> nVersion >> nOsMinor >> nOsType >> aGuid >> nSectCount; 1156 1157 // read sections 1158 sal_Size nSectPosPos = rStrm.Tell(); 1159 for( sal_Int32 nSectIdx = 0; (nSectIdx < nSectCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nSectIdx ) 1160 { 1161 // read section guid/position pair 1162 rStrm.Seek( nSectPosPos ); 1163 SvGlobalName aSectGuid; 1164 sal_uInt32 nSectPos; 1165 rStrm >> aSectGuid >> nSectPos; 1166 nSectPosPos = rStrm.Tell(); 1167 // read section 1168 rStrm.Seek( static_cast< sal_Size >( nSectPos ) ); 1169 if( rStrm.GetErrorCode() == SVSTREAM_OK ) 1170 LoadObject( rStrm, AddSection( aSectGuid ) ); 1171 } 1172 } 1173 1174 void SfxOlePropertySet::ImplSave( SvStream& rStrm ) 1175 { 1176 // write property set header 1177 SvGlobalName aGuid; 1178 sal_Int32 nSectCount = static_cast< sal_Int32 >( maSectionMap.size() ); 1179 rStrm << sal_uInt16( 0xFFFE ) // byte order 1180 << sal_uInt16( 0 ) // version 1181 << sal_uInt16( 1 ) // OS minor version 1182 << sal_uInt16( 2 ) // OS type always windows for text encoding 1183 << aGuid // unused guid 1184 << nSectCount; // number of sections 1185 1186 // write placeholders for section guid/position pairs 1187 sal_Size nSectPosPos = rStrm.Tell(); 1188 rStrm.SeekRel( static_cast< sal_sSize >( 20 * nSectCount ) ); 1189 1190 // write sections 1191 for( SfxOleSectionMap::const_iterator aIt = maSectionMap.begin(), aEnd = maSectionMap.end(); aIt != aEnd; ++aIt ) 1192 { 1193 SfxOleSection& rSection = *aIt->second; 1194 rStrm.Seek( STREAM_SEEK_TO_END ); 1195 sal_uInt32 nSectPos = static_cast< sal_uInt32 >( rStrm.Tell() ); 1196 // write the section 1197 SaveObject( rStrm, rSection ); 1198 // write section guid/position pair 1199 rStrm.Seek( nSectPosPos ); 1200 rStrm << aIt->first << nSectPos; 1201 nSectPosPos = rStrm.Tell(); 1202 } 1203 } 1204 1205 const SvGlobalName& SfxOlePropertySet::GetSectionGuid( SfxOleSectionType eSection ) 1206 { 1207 static const SvGlobalName saGlobalGuid( 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 ); 1208 static const SvGlobalName saBuiltInGuid( 0xD5CDD502, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE ); 1209 static const SvGlobalName saCustomGuid( 0xD5CDD505, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE ); 1210 static const SvGlobalName saEmptyGuid; 1211 switch( eSection ) 1212 { 1213 case SECTION_GLOBAL: return saGlobalGuid; 1214 case SECTION_BUILTIN: return saBuiltInGuid; 1215 case SECTION_CUSTOM: return saCustomGuid; 1216 default: DBG_ERRORFILE( "SfxOlePropertySet::GetSectionGuid - unknown section type" ); 1217 } 1218 return saEmptyGuid; 1219 } 1220 1221 // ============================================================================ 1222 1223 //} // namespace 1224