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