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