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