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 ), 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 0 : bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
50 : {
51 0 : return i_rLeft.Year == i_rRight.Year
52 0 : && i_rLeft.Month == i_rRight.Month
53 0 : && i_rLeft.Day == i_rRight.Day
54 0 : && i_rLeft.Hours == i_rRight.Hours
55 0 : && i_rLeft.Minutes == i_rRight.Minutes
56 0 : && i_rLeft.Seconds == i_rRight.Seconds
57 0 : && i_rLeft.NanoSeconds == i_rRight.NanoSeconds
58 0 : && 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 0 : class SfxOleInt32Property : public SfxOlePropertyBase
73 : {
74 : public:
75 : explicit SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue = 0 );
76 :
77 0 : 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 0 : class SfxOleDoubleProperty : public SfxOlePropertyBase
91 : {
92 : public:
93 : explicit SfxOleDoubleProperty( sal_Int32 nPropId, double fValue = 0.0 );
94 :
95 0 : 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 0 : 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 :
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 0 : 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 0 : inline const OUString& GetValue() const { return maValue; }
140 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : class SfxOleThumbnailProperty : public SfxOlePropertyBase
221 : {
222 : public:
223 : explicit SfxOleThumbnailProperty( sal_Int32 nPropId,
224 : const uno::Sequence<sal_uInt8> & i_rData);
225 :
226 0 : 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 0 : class SfxOleBlobProperty : public SfxOlePropertyBase
244 : {
245 : public:
246 : explicit SfxOleBlobProperty( sal_Int32 nPropId,
247 : const uno::Sequence<sal_uInt8> & i_rData);
248 0 : 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 0 : sal_uInt16 SfxOleTextEncoding::GetCodePage() const
261 : {
262 0 : sal_uInt16 nCodePage = IsUnicode() ? CODEPAGE_UNICODE :
263 0 : static_cast< sal_uInt16 >( rtl_getWindowsCodePageFromTextEncoding( *mxTextEnc ) );
264 0 : return (nCodePage == CODEPAGE_UNKNOWN) ? CODEPAGE_UTF8 : nCodePage;
265 : }
266 :
267 0 : void SfxOleTextEncoding::SetCodePage( sal_uInt16 nCodePage )
268 : {
269 0 : if( nCodePage == CODEPAGE_UNICODE )
270 0 : SetUnicode();
271 : else
272 : {
273 0 : rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
274 0 : if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
275 0 : *mxTextEnc = eTextEnc;
276 : }
277 0 : }
278 :
279 :
280 :
281 0 : OUString SfxOleStringHelper::LoadString8( SvStream& rStrm ) const
282 : {
283 0 : return IsUnicode() ? ImplLoadString16( rStrm ) : ImplLoadString8( rStrm );
284 : }
285 :
286 0 : void SfxOleStringHelper::SaveString8( SvStream& rStrm, const OUString& rValue ) const
287 : {
288 0 : if( IsUnicode() )
289 0 : ImplSaveString16( rStrm, rValue );
290 : else
291 0 : ImplSaveString8( rStrm, rValue );
292 0 : }
293 :
294 0 : OUString SfxOleStringHelper::LoadString16( SvStream& rStrm ) const
295 : {
296 0 : return ImplLoadString16( rStrm );
297 : }
298 :
299 0 : void SfxOleStringHelper::SaveString16( SvStream& rStrm, const OUString& rValue ) const
300 : {
301 0 : ImplSaveString16( rStrm, rValue );
302 0 : }
303 :
304 0 : OUString SfxOleStringHelper::ImplLoadString8( SvStream& rStrm ) const
305 : {
306 0 : OUString aValue;
307 : // read size field (signed 32-bit)
308 0 : sal_Int32 nSize(0);
309 0 : 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 0 : if( (0 < nSize) && (nSize <= 0xFFFF) )
315 : {
316 : // load character buffer
317 0 : ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nSize + 1 ), 0 );
318 0 : rStrm.Read( &aBuffer.front(), static_cast< sal_Size >( nSize ) );
319 : // create string from encoded character array
320 0 : aValue = OUString( &aBuffer.front(), strlen( &aBuffer.front() ), GetTextEncoding() );
321 : }
322 0 : return aValue;
323 : }
324 :
325 0 : OUString SfxOleStringHelper::ImplLoadString16( SvStream& rStrm ) const
326 : {
327 0 : OUString aValue;
328 : // read size field (signed 32-bit), may be buffer size or character count
329 0 : sal_Int32 nSize(0);
330 0 : rStrm.ReadInt32( nSize );
331 : DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF), "SfxOleStringHelper::ImplLoadString16 - invalid string" );
332 : // size field includes trailing NUL character
333 0 : if( (0 < nSize) && (nSize <= 0xFFFF) )
334 : {
335 : // load character buffer
336 0 : ::std::vector< sal_Unicode > aBuffer;
337 0 : aBuffer.reserve( static_cast< size_t >( nSize + 1 ) );
338 : sal_uInt16 cChar;
339 0 : for( sal_Int32 nIdx = 0; nIdx < nSize; ++nIdx )
340 : {
341 0 : rStrm.ReadUInt16( cChar );
342 0 : 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 0 : if( (nSize & 1) == 1 )
346 0 : rStrm.SeekRel( 2 );
347 : // create string from character array
348 0 : aBuffer.push_back( 0 );
349 0 : aValue = OUString( &aBuffer.front() );
350 : }
351 0 : return aValue;
352 : }
353 :
354 0 : void SfxOleStringHelper::ImplSaveString8( SvStream& rStrm, const OUString& rValue ) const
355 : {
356 : // encode to byte string
357 0 : OString aEncoded(OUStringToOString(rValue, GetTextEncoding()));
358 : // write size field (including trailing NUL character)
359 0 : sal_Int32 nSize = aEncoded.getLength() + 1;
360 0 : rStrm.WriteInt32( nSize );
361 : // write character array with trailing NUL character
362 0 : rStrm.Write(aEncoded.getStr(), aEncoded.getLength());
363 0 : rStrm.WriteUChar( sal_uInt8( 0 ) );
364 0 : }
365 :
366 0 : void SfxOleStringHelper::ImplSaveString16( SvStream& rStrm, const OUString& rValue ) const
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( static_cast< sal_uInt16 >( rValue[ nIdx ] ) );
374 0 : rStrm.WriteUInt16( sal_uInt16( 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( sal_uInt16( 0 ) );
378 0 : }
379 :
380 :
381 :
382 0 : SfxOleObjectBase::~SfxOleObjectBase()
383 : {
384 0 : }
385 :
386 0 : ErrCode SfxOleObjectBase::Load( SvStream& rStrm )
387 : {
388 0 : mnErrCode = ERRCODE_NONE;
389 0 : ImplLoad( rStrm );
390 0 : SetError( rStrm.GetErrorCode() );
391 0 : return GetError();
392 : }
393 :
394 0 : ErrCode SfxOleObjectBase::Save( SvStream& rStrm )
395 : {
396 0 : mnErrCode = ERRCODE_NONE;
397 0 : ImplSave( rStrm );
398 0 : SetError( rStrm.GetErrorCode() );
399 0 : return GetError();
400 : }
401 :
402 0 : void SfxOleObjectBase::LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj )
403 : {
404 0 : SetError( rObj.Load( rStrm ) );
405 0 : }
406 :
407 0 : void SfxOleObjectBase::SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj )
408 : {
409 0 : SetError( rObj.Save( rStrm ) );
410 0 : }
411 :
412 :
413 :
414 0 : SfxOleCodePageProperty::SfxOleCodePageProperty() :
415 0 : SfxOlePropertyBase( PROPID_CODEPAGE, PROPTYPE_INT16 )
416 : {
417 0 : }
418 :
419 0 : 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 0 : rStrm.ReadUInt16( nCodePage );
424 0 : SetCodePage( nCodePage );
425 0 : }
426 :
427 0 : void SfxOleCodePageProperty::ImplSave( SvStream& rStrm )
428 : {
429 : // property type is signed int16, but we use always unsigned int16 for codepages
430 0 : rStrm.WriteUInt16( GetCodePage() );
431 0 : }
432 :
433 :
434 :
435 0 : SfxOleInt32Property::SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue ) :
436 : SfxOlePropertyBase( nPropId, PROPTYPE_INT32 ),
437 0 : mnValue( nValue )
438 : {
439 0 : }
440 :
441 0 : void SfxOleInt32Property::ImplLoad( SvStream& rStrm )
442 : {
443 0 : rStrm.ReadInt32( mnValue );
444 0 : }
445 :
446 0 : void SfxOleInt32Property::ImplSave( SvStream& rStrm )
447 : {
448 0 : rStrm.WriteInt32( mnValue );
449 0 : }
450 :
451 :
452 :
453 0 : SfxOleDoubleProperty::SfxOleDoubleProperty( sal_Int32 nPropId, double fValue ) :
454 : SfxOlePropertyBase( nPropId, PROPTYPE_DOUBLE ),
455 0 : mfValue( fValue )
456 : {
457 0 : }
458 :
459 0 : void SfxOleDoubleProperty::ImplLoad( SvStream& rStrm )
460 : {
461 0 : rStrm.ReadDouble( mfValue );
462 0 : }
463 :
464 0 : void SfxOleDoubleProperty::ImplSave( SvStream& rStrm )
465 : {
466 0 : rStrm.WriteDouble( mfValue );
467 0 : }
468 :
469 :
470 :
471 0 : SfxOleBoolProperty::SfxOleBoolProperty( sal_Int32 nPropId, bool bValue ) :
472 : SfxOlePropertyBase( nPropId, PROPTYPE_BOOL ),
473 0 : mbValue( bValue )
474 : {
475 0 : }
476 :
477 0 : void SfxOleBoolProperty::ImplLoad( SvStream& rStrm )
478 : {
479 0 : sal_Int16 nValue(0);
480 0 : rStrm.ReadInt16( nValue );
481 0 : mbValue = nValue != 0;
482 0 : }
483 :
484 0 : void SfxOleBoolProperty::ImplSave( SvStream& rStrm )
485 : {
486 0 : rStrm.WriteInt16( static_cast< sal_Int16 >( mbValue ? -1 : 0 ) );
487 0 : }
488 :
489 :
490 :
491 0 : SfxOleStringPropertyBase::SfxOleStringPropertyBase(
492 : sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc ) :
493 : SfxOlePropertyBase( nPropId, nPropType ),
494 0 : SfxOleStringHelper( rTextEnc )
495 : {
496 0 : }
497 :
498 0 : SfxOleStringPropertyBase::SfxOleStringPropertyBase(
499 : sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc, const OUString& rValue ) :
500 : SfxOlePropertyBase( nPropId, nPropType ),
501 : SfxOleStringHelper( rTextEnc ),
502 0 : maValue( rValue )
503 : {
504 0 : }
505 :
506 0 : SfxOleStringPropertyBase::SfxOleStringPropertyBase(
507 : sal_Int32 nPropId, sal_Int32 nPropType, rtl_TextEncoding eTextEnc ) :
508 : SfxOlePropertyBase( nPropId, nPropType ),
509 0 : SfxOleStringHelper( eTextEnc )
510 : {
511 0 : }
512 :
513 :
514 :
515 0 : SfxOleString8Property::SfxOleString8Property(
516 : sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc ) :
517 0 : SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc )
518 : {
519 0 : }
520 :
521 0 : SfxOleString8Property::SfxOleString8Property(
522 : sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc, const OUString& rValue ) :
523 0 : SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc, rValue )
524 : {
525 0 : }
526 :
527 0 : void SfxOleString8Property::ImplLoad( SvStream& rStrm )
528 : {
529 0 : SetValue( LoadString8( rStrm ) );
530 0 : }
531 :
532 0 : void SfxOleString8Property::ImplSave( SvStream& rStrm )
533 : {
534 0 : SaveString8( rStrm, GetValue() );
535 0 : }
536 :
537 :
538 :
539 0 : SfxOleString16Property::SfxOleString16Property( sal_Int32 nPropId ) :
540 0 : SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING16, RTL_TEXTENCODING_UCS2 )
541 : {
542 0 : }
543 :
544 0 : void SfxOleString16Property::ImplLoad( SvStream& rStrm )
545 : {
546 0 : SetValue( LoadString16( rStrm ) );
547 0 : }
548 :
549 0 : void SfxOleString16Property::ImplSave( SvStream& rStrm )
550 : {
551 0 : SaveString16( rStrm, GetValue() );
552 0 : }
553 :
554 :
555 :
556 0 : SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId ) :
557 0 : SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME )
558 : {
559 0 : }
560 :
561 0 : SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime ) :
562 : SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME ),
563 0 : maDateTime( rDateTime )
564 : {
565 0 : }
566 :
567 0 : void SfxOleFileTimeProperty::ImplLoad( SvStream& rStrm )
568 : {
569 0 : sal_uInt32 nLower(0), nUpper(0);
570 0 : rStrm.ReadUInt32( nLower ).ReadUInt32( nUpper );
571 0 : ::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 0 : if ( aDateTime.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() )
577 0 : aDateTime.ConvertToLocalTime();
578 0 : maDateTime.Year = aDateTime.GetYear();
579 0 : maDateTime.Month = aDateTime.GetMonth();
580 0 : maDateTime.Day = aDateTime.GetDay();
581 0 : maDateTime.Hours = aDateTime.GetHour();
582 0 : maDateTime.Minutes = aDateTime.GetMin();
583 0 : maDateTime.Seconds = aDateTime.GetSec();
584 0 : maDateTime.NanoSeconds = aDateTime.GetNanoSec();
585 0 : maDateTime.IsUTC = false;
586 0 : }
587 :
588 0 : 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 : Time(
596 : static_cast< sal_uIntPtr >( maDateTime.Hours ),
597 : static_cast< sal_uIntPtr >( maDateTime.Minutes ),
598 : static_cast< sal_uIntPtr >( maDateTime.Seconds ),
599 0 : 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 0 : if( aDateTimeUtc.IsValidAndGregorian()
604 0 : && aDateTimeUtc.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() ) {
605 0 : aDateTimeUtc.ConvertToUTC();
606 : }
607 : sal_uInt32 nLower, nUpper;
608 0 : aDateTimeUtc.GetWin32FileDateTime( nLower, nUpper );
609 0 : rStrm.WriteUInt32( nLower ).WriteUInt32( nUpper );
610 0 : }
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 0 : SfxOleThumbnailProperty::SfxOleThumbnailProperty(
642 : sal_Int32 nPropId, const uno::Sequence<sal_uInt8> & i_rData) :
643 : SfxOlePropertyBase( nPropId, PROPTYPE_CLIPFMT ),
644 0 : mData(i_rData)
645 : {
646 0 : }
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 0 : 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 0 : if( IsValid() )
676 : {
677 : // clipboard size: clip_format_tag + data_format_tag + bitmap_len
678 0 : sal_Int32 nClipSize = static_cast< sal_Int32 >( 4 + 4 + mData.getLength() );
679 0 : rStrm.WriteInt32( nClipSize ).WriteInt32( CLIPFMT_WIN ).WriteInt32( CLIPDATAFMT_DIB );
680 0 : 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 0 : }
688 :
689 :
690 :
691 0 : SfxOleBlobProperty::SfxOleBlobProperty( sal_Int32 nPropId,
692 : const uno::Sequence<sal_uInt8> & i_rData) :
693 : SfxOlePropertyBase( nPropId, PROPTYPE_BLOB ),
694 0 : mData(i_rData)
695 : {
696 0 : }
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 0 : void SfxOleBlobProperty::ImplSave( SvStream& rStrm )
705 : {
706 0 : if (IsValid()) {
707 0 : 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 0 : }
713 :
714 :
715 :
716 0 : SfxOleDictionaryProperty::SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc ) :
717 : SfxOlePropertyBase( PROPID_DICTIONARY, 0 ),
718 0 : SfxOleStringHelper( rTextEnc )
719 : {
720 0 : }
721 :
722 0 : OUString SfxOleDictionaryProperty::GetPropertyName( sal_Int32 nPropId ) const
723 : {
724 0 : SfxOlePropNameMap::const_iterator aIt = maPropNameMap.find( nPropId );
725 0 : return (aIt == maPropNameMap.end()) ? OUString("") : aIt->second;
726 : }
727 :
728 0 : void SfxOleDictionaryProperty::SetPropertyName( sal_Int32 nPropId, const OUString& rPropName )
729 : {
730 0 : maPropNameMap[ nPropId ] = rPropName;
731 : // dictionary property contains number of pairs in property type field
732 0 : SetPropType( static_cast< sal_Int32 >( maPropNameMap.size() ) );
733 0 : }
734 :
735 0 : void SfxOleDictionaryProperty::ImplLoad( SvStream& rStrm )
736 : {
737 : // dictionary property contains number of pairs in property type field
738 0 : sal_Int32 nNameCount = GetPropType();
739 : // read property ID/name pairs
740 0 : maPropNameMap.clear();
741 0 : for( sal_Int32 nIdx = 0; (nIdx < nNameCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nIdx )
742 : {
743 0 : sal_Int32 nPropId(0);
744 0 : rStrm.ReadInt32( nPropId );
745 : // name always stored as byte string
746 0 : maPropNameMap[ nPropId ] = LoadString8( rStrm );
747 : }
748 0 : }
749 :
750 0 : void SfxOleDictionaryProperty::ImplSave( SvStream& rStrm )
751 : {
752 : // write property ID/name pairs
753 0 : for( SfxOlePropNameMap::const_iterator aIt = maPropNameMap.begin(), aEnd = maPropNameMap.end(); aIt != aEnd; ++aIt )
754 : {
755 0 : rStrm.WriteInt32( aIt->first );
756 : // name always stored as byte string
757 0 : SaveString8( rStrm, aIt->second );
758 : }
759 0 : }
760 :
761 :
762 :
763 0 : SfxOleSection::SfxOleSection( bool bSupportsDict ) :
764 : maDictProp( maCodePageProp ),
765 : mnStartPos( 0 ),
766 0 : mbSupportsDict( bSupportsDict )
767 : {
768 0 : }
769 :
770 0 : SfxOlePropertyRef SfxOleSection::GetProperty( sal_Int32 nPropId ) const
771 : {
772 0 : SfxOlePropertyRef xProp;
773 0 : SfxOlePropMap::const_iterator aIt = maPropMap.find( nPropId );
774 0 : if( aIt != maPropMap.end() )
775 0 : xProp = aIt->second;
776 0 : return xProp;
777 : }
778 :
779 0 : bool SfxOleSection::GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const
780 : {
781 0 : SfxOlePropertyRef xProp = GetProperty( nPropId );
782 : const SfxOleInt32Property* pProp =
783 0 : dynamic_cast< const SfxOleInt32Property* >( xProp.get() );
784 0 : if( pProp )
785 0 : rnValue = pProp->GetValue();
786 0 : return pProp != 0;
787 : }
788 :
789 0 : bool SfxOleSection::GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const
790 : {
791 0 : SfxOlePropertyRef xProp = GetProperty( nPropId );
792 : const SfxOleDoubleProperty* pProp =
793 0 : dynamic_cast< const SfxOleDoubleProperty* >( xProp.get() );
794 0 : if( pProp )
795 0 : rfValue = pProp->GetValue();
796 0 : return pProp != 0;
797 : }
798 :
799 0 : bool SfxOleSection::GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const
800 : {
801 0 : SfxOlePropertyRef xProp = GetProperty( nPropId );
802 : const SfxOleBoolProperty* pProp =
803 0 : dynamic_cast< const SfxOleBoolProperty* >( xProp.get() );
804 0 : if( pProp )
805 0 : rbValue = pProp->GetValue();
806 0 : return pProp != 0;
807 : }
808 :
809 0 : bool SfxOleSection::GetStringValue( OUString& rValue, sal_Int32 nPropId ) const
810 : {
811 0 : SfxOlePropertyRef xProp = GetProperty( nPropId );
812 : const SfxOleStringPropertyBase* pProp =
813 0 : dynamic_cast< const SfxOleStringPropertyBase* >( xProp.get() );
814 0 : if( pProp )
815 0 : rValue = pProp->GetValue();
816 0 : return pProp != 0;
817 : }
818 :
819 0 : bool SfxOleSection::GetFileTimeValue( util::DateTime& rValue, sal_Int32 nPropId ) const
820 : {
821 0 : SfxOlePropertyRef xProp = GetProperty( nPropId );
822 : const SfxOleFileTimeProperty* pProp =
823 0 : dynamic_cast< const SfxOleFileTimeProperty* >( xProp.get() );
824 0 : if( pProp )
825 : {
826 0 : if ( pProp->GetValue() == TIMESTAMP_INVALID_UTILDATETIME )
827 0 : rValue = util::DateTime();
828 : else
829 0 : rValue = pProp->GetValue();
830 : }
831 0 : 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 0 : void SfxOleSection::SetProperty( SfxOlePropertyRef xProp )
850 : {
851 0 : if( xProp.get() )
852 0 : maPropMap[ xProp->GetPropId() ] = xProp;
853 0 : }
854 :
855 0 : void SfxOleSection::SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue )
856 : {
857 0 : SetProperty( SfxOlePropertyRef( new SfxOleInt32Property( nPropId, nValue ) ) );
858 0 : }
859 :
860 0 : void SfxOleSection::SetDoubleValue( sal_Int32 nPropId, double fValue )
861 : {
862 0 : SetProperty( SfxOlePropertyRef( new SfxOleDoubleProperty( nPropId, fValue ) ) );
863 0 : }
864 :
865 0 : void SfxOleSection::SetBoolValue( sal_Int32 nPropId, bool bValue )
866 : {
867 0 : SetProperty( SfxOlePropertyRef( new SfxOleBoolProperty( nPropId, bValue ) ) );
868 0 : }
869 :
870 0 : bool SfxOleSection::SetStringValue( sal_Int32 nPropId, const OUString& rValue, bool bSkipEmpty )
871 : {
872 0 : bool bInserted = !bSkipEmpty || !rValue.isEmpty();
873 0 : if( bInserted )
874 0 : SetProperty( SfxOlePropertyRef( new SfxOleString8Property( nPropId, maCodePageProp, rValue ) ) );
875 0 : return bInserted;
876 : }
877 :
878 0 : void SfxOleSection::SetFileTimeValue( sal_Int32 nPropId, const util::DateTime& rValue )
879 : {
880 0 : if ( rValue.Year == 0 || rValue.Month == 0 || rValue.Day == 0 )
881 0 : SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, TIMESTAMP_INVALID_UTILDATETIME ) ) );
882 : else
883 0 : SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, rValue ) ) );
884 0 : }
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 0 : void SfxOleSection::SetThumbnailValue( sal_Int32 nPropId,
901 : const uno::Sequence<sal_uInt8> & i_rData)
902 : {
903 0 : SfxOleThumbnailProperty* pThumbnail = new SfxOleThumbnailProperty( nPropId, i_rData );
904 0 : SfxOlePropertyRef xProp( pThumbnail ); // take ownership
905 0 : if( pThumbnail->IsValid() )
906 0 : SetProperty( xProp );
907 0 : }
908 :
909 0 : void SfxOleSection::SetBlobValue( sal_Int32 nPropId,
910 : const uno::Sequence<sal_uInt8> & i_rData)
911 : {
912 0 : SfxOleBlobProperty* pBlob( new SfxOleBlobProperty( nPropId, i_rData ) );
913 0 : SfxOlePropertyRef xProp( pBlob );
914 0 : if( pBlob->IsValid() ) {
915 0 : SetProperty( xProp );
916 0 : }
917 0 : }
918 :
919 0 : Any SfxOleSection::GetAnyValue( sal_Int32 nPropId ) const
920 : {
921 0 : Any aValue;
922 0 : sal_Int32 nInt32 = 0;
923 0 : double fDouble = 0.0;
924 0 : bool bBool = false;
925 0 : OUString aString;
926 0 : ::com::sun::star::util::DateTime aApiDateTime;
927 0 : ::com::sun::star::util::Date aApiDate;
928 :
929 0 : if( GetInt32Value( nInt32, nPropId ) )
930 0 : aValue <<= nInt32;
931 0 : else if( GetDoubleValue( fDouble, nPropId ) )
932 0 : aValue <<= fDouble;
933 0 : else if( GetBoolValue( bBool, nPropId ) )
934 0 : ::comphelper::setBOOL( aValue, bBool ? sal_True : sal_False );
935 0 : else if( GetStringValue( aString, nPropId ) )
936 0 : 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 0 : return aValue;
946 : }
947 :
948 0 : bool SfxOleSection::SetAnyValue( sal_Int32 nPropId, const Any& rValue )
949 : {
950 0 : bool bInserted = true;
951 0 : sal_Int32 nInt32 = 0;
952 0 : double fDouble = 0.0;
953 0 : OUString aString;
954 0 : ::com::sun::star::util::DateTime aApiDateTime;
955 0 : ::com::sun::star::util::Date aApiDate;
956 :
957 0 : if( rValue.getValueType() == ::getBooleanCppuType() )
958 0 : SetBoolValue( nPropId, ::comphelper::getBOOL( rValue ) );
959 0 : else if( rValue >>= nInt32 )
960 0 : SetInt32Value( nPropId, nInt32 );
961 0 : else if( rValue >>= fDouble )
962 0 : SetDoubleValue( nPropId, fDouble );
963 0 : else if( rValue >>= aString )
964 0 : 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 0 : return bInserted;
972 : }
973 :
974 0 : OUString SfxOleSection::GetPropertyName( sal_Int32 nPropId ) const
975 : {
976 0 : return maDictProp.GetPropertyName( nPropId );
977 : }
978 :
979 0 : void SfxOleSection::SetPropertyName( sal_Int32 nPropId, const OUString& rPropName )
980 : {
981 0 : maDictProp.SetPropertyName( nPropId, rPropName );
982 0 : }
983 :
984 0 : void SfxOleSection::GetPropertyIds( ::std::vector< sal_Int32 >& rPropIds ) const
985 : {
986 0 : rPropIds.clear();
987 0 : for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt )
988 0 : rPropIds.push_back( aIt->first );
989 0 : }
990 :
991 0 : sal_Int32 SfxOleSection::GetFreePropertyId() const
992 : {
993 0 : return maPropMap.empty() ? PROPID_FIRSTCUSTOM : (maPropMap.rbegin()->first + 1);
994 : }
995 :
996 0 : void SfxOleSection::ImplLoad( SvStream& rStrm )
997 : {
998 : // read section header
999 0 : mnStartPos = rStrm.Tell();
1000 0 : sal_uInt32 nSize(0);
1001 0 : sal_Int32 nPropCount(0);
1002 0 : rStrm.ReadUInt32( nSize ).ReadInt32( nPropCount );
1003 :
1004 : // read property ID/position pairs
1005 : typedef ::std::map< sal_Int32, sal_uInt32 > SfxOlePropPosMap;
1006 0 : SfxOlePropPosMap aPropPosMap;
1007 0 : for( sal_Int32 nPropIdx = 0; (nPropIdx < nPropCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nPropIdx )
1008 : {
1009 0 : sal_Int32 nPropId(0);
1010 0 : sal_uInt32 nPropPos(0);
1011 0 : rStrm.ReadInt32( nPropId ).ReadUInt32( nPropPos );
1012 0 : aPropPosMap[ nPropId ] = nPropPos;
1013 : }
1014 :
1015 : // read codepage property
1016 0 : SfxOlePropPosMap::iterator aCodePageIt = aPropPosMap.find( PROPID_CODEPAGE );
1017 0 : if( (aCodePageIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aCodePageIt->second ) )
1018 : {
1019 : // codepage property must be of type signed int-16
1020 0 : sal_Int32 nPropType(0);
1021 0 : rStrm.ReadInt32( nPropType );
1022 0 : if( nPropType == PROPTYPE_INT16 )
1023 0 : LoadObject( rStrm, maCodePageProp );
1024 : // remove property position
1025 0 : aPropPosMap.erase( aCodePageIt );
1026 : }
1027 :
1028 : // read dictionary property
1029 0 : SfxOlePropPosMap::iterator aDictIt = aPropPosMap.find( PROPID_DICTIONARY );
1030 0 : if( (aDictIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aDictIt->second ) )
1031 : {
1032 : // #i66214# #i66428# applications may write broken dictionary properties in wrong sections
1033 0 : if( mbSupportsDict )
1034 : {
1035 : // dictionary property contains number of pairs in property type field
1036 0 : sal_Int32 nNameCount(0);
1037 0 : rStrm.ReadInt32( nNameCount );
1038 0 : maDictProp.SetNameCount( nNameCount );
1039 0 : LoadObject( rStrm, maDictProp );
1040 : }
1041 : // always remove position of dictionary property (do not try to read it again below)
1042 0 : aPropPosMap.erase( aDictIt );
1043 : }
1044 :
1045 : // read other properties
1046 0 : maPropMap.clear();
1047 0 : for( SfxOlePropPosMap::const_iterator aIt = aPropPosMap.begin(), aEnd = aPropPosMap.end(); aIt != aEnd; ++aIt )
1048 0 : if( SeekToPropertyPos( rStrm, aIt->second ) )
1049 0 : LoadProperty( rStrm, aIt->first );
1050 0 : }
1051 :
1052 0 : 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 0 : maCodePageProp.SetTextEncoding( RTL_TEXTENCODING_UTF8 );
1057 :
1058 : // write section header
1059 0 : mnStartPos = rStrm.Tell();
1060 0 : sal_Int32 nPropCount = static_cast< sal_Int32 >( maPropMap.size() + 1 );
1061 0 : if( maDictProp.HasPropertyNames() )
1062 0 : ++nPropCount;
1063 0 : rStrm.WriteUInt32( sal_uInt32( 0 ) ).WriteInt32( nPropCount );
1064 :
1065 : // write placeholders for property ID/position pairs
1066 0 : sal_Size nPropPosPos = rStrm.Tell();
1067 0 : rStrm.SeekRel( static_cast< sal_sSize >( 8 * nPropCount ) );
1068 :
1069 : // write dictionary property
1070 0 : if( maDictProp.HasPropertyNames() )
1071 0 : SaveProperty( rStrm, maDictProp, nPropPosPos );
1072 : // write codepage property
1073 0 : SaveProperty( rStrm, maCodePageProp, nPropPosPos );
1074 : // write other properties
1075 0 : for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt )
1076 0 : SaveProperty( rStrm, *aIt->second, nPropPosPos );
1077 :
1078 : // write section size (first field in section header)
1079 0 : rStrm.Seek( STREAM_SEEK_TO_END );
1080 0 : sal_uInt32 nSectSize = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos );
1081 0 : rStrm.Seek( mnStartPos );
1082 0 : rStrm.WriteUInt32( nSectSize );
1083 0 : }
1084 :
1085 0 : bool SfxOleSection::SeekToPropertyPos( SvStream& rStrm, sal_uInt32 nPropPos ) const
1086 : {
1087 0 : rStrm.Seek( static_cast< sal_Size >( mnStartPos + nPropPos ) );
1088 0 : return rStrm.GetErrorCode() == SVSTREAM_OK;
1089 : }
1090 :
1091 0 : void SfxOleSection::LoadProperty( SvStream& rStrm, sal_Int32 nPropId )
1092 : {
1093 : // property data type
1094 0 : sal_Int32 nPropType(0);
1095 0 : rStrm.ReadInt32( nPropType );
1096 : // create empty property object
1097 0 : SfxOlePropertyRef xProp;
1098 0 : switch( nPropType )
1099 : {
1100 : case PROPTYPE_INT32:
1101 0 : xProp.reset( new SfxOleInt32Property( nPropId ) );
1102 0 : break;
1103 : case PROPTYPE_DOUBLE:
1104 0 : xProp.reset( new SfxOleDoubleProperty( nPropId ) );
1105 0 : break;
1106 : case PROPTYPE_BOOL:
1107 0 : xProp.reset( new SfxOleBoolProperty( nPropId ) );
1108 0 : break;
1109 : case PROPTYPE_STRING8:
1110 0 : xProp.reset( new SfxOleString8Property( nPropId, maCodePageProp ) );
1111 0 : break;
1112 : case PROPTYPE_STRING16:
1113 0 : xProp.reset( new SfxOleString16Property( nPropId ) );
1114 0 : break;
1115 : case PROPTYPE_FILETIME:
1116 0 : xProp.reset( new SfxOleFileTimeProperty( nPropId ) );
1117 0 : break;
1118 : case PROPTYPE_DATE:
1119 0 : xProp.reset( new SfxOleDateProperty( nPropId ) );
1120 0 : break;
1121 : }
1122 : // load property contents
1123 0 : if( xProp.get() )
1124 : {
1125 0 : SetError( xProp->Load( rStrm ) );
1126 0 : maPropMap[ nPropId ] = xProp;
1127 0 : }
1128 0 : }
1129 :
1130 0 : void SfxOleSection::SaveProperty( SvStream& rStrm, SfxOlePropertyBase& rProp, sal_Size& rnPropPosPos )
1131 : {
1132 0 : rStrm.Seek( STREAM_SEEK_TO_END );
1133 0 : sal_uInt32 nPropPos = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos );
1134 : // property data type
1135 0 : rStrm.WriteInt32( rProp.GetPropType() );
1136 : // write property contents
1137 0 : SaveObject( rStrm, rProp );
1138 : // align to 32-bit
1139 0 : while( (rStrm.Tell() & 3) != 0 )
1140 0 : rStrm.WriteUChar( sal_uInt8( 0 ) );
1141 : // write property ID/position pair
1142 0 : rStrm.Seek( rnPropPosPos );
1143 0 : rStrm.WriteInt32( rProp.GetPropId() ).WriteUInt32( nPropPos );
1144 0 : rnPropPosPos = rStrm.Tell();
1145 0 : }
1146 :
1147 :
1148 :
1149 0 : ErrCode SfxOlePropertySet::LoadPropertySet( SotStorage* pStrg, const OUString& rStrmName )
1150 : {
1151 0 : if( pStrg )
1152 : {
1153 0 : SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_STD_READ );
1154 0 : if( xStrm.Is() && (xStrm->GetError() == SVSTREAM_OK) )
1155 : {
1156 0 : xStrm->SetBufferSize( STREAM_BUFFER_SIZE );
1157 0 : Load( *xStrm );
1158 : }
1159 : else
1160 0 : SetError( ERRCODE_IO_ACCESSDENIED );
1161 : }
1162 : else
1163 0 : SetError( ERRCODE_IO_ACCESSDENIED );
1164 0 : return GetError();
1165 : }
1166 :
1167 0 : ErrCode SfxOlePropertySet::SavePropertySet( SotStorage* pStrg, const OUString& rStrmName )
1168 : {
1169 0 : if( pStrg )
1170 : {
1171 0 : SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_TRUNC | STREAM_STD_WRITE );
1172 0 : if( xStrm.Is() )
1173 0 : Save( *xStrm );
1174 : else
1175 0 : SetError( ERRCODE_IO_ACCESSDENIED );
1176 : }
1177 : else
1178 0 : SetError( ERRCODE_IO_ACCESSDENIED );
1179 0 : return GetError();
1180 : }
1181 :
1182 0 : SfxOleSectionRef SfxOlePropertySet::GetSection( SfxOleSectionType eSection ) const
1183 : {
1184 0 : return GetSection( GetSectionGuid( eSection ) );
1185 : }
1186 :
1187 0 : SfxOleSectionRef SfxOlePropertySet::GetSection( const SvGlobalName& rSectionGuid ) const
1188 : {
1189 0 : SfxOleSectionRef xSection;
1190 0 : SfxOleSectionMap::const_iterator aIt = maSectionMap.find( rSectionGuid );
1191 0 : if( aIt != maSectionMap.end() )
1192 0 : xSection = aIt->second;
1193 0 : return xSection;
1194 : }
1195 :
1196 0 : SfxOleSection& SfxOlePropertySet::AddSection( SfxOleSectionType eSection )
1197 : {
1198 0 : return AddSection( GetSectionGuid( eSection ) );
1199 : }
1200 :
1201 0 : SfxOleSection& SfxOlePropertySet::AddSection( const SvGlobalName& rSectionGuid )
1202 : {
1203 0 : SfxOleSectionRef xSection = GetSection( rSectionGuid );
1204 0 : if( !xSection )
1205 : {
1206 : // #i66214# #i66428# applications may write broken dictionary properties in wrong sections
1207 0 : bool bSupportsDict = rSectionGuid == GetSectionGuid( SECTION_CUSTOM );
1208 0 : xSection.reset( new SfxOleSection( bSupportsDict ) );
1209 0 : maSectionMap[ rSectionGuid ] = xSection;
1210 : }
1211 0 : return *xSection;
1212 : }
1213 :
1214 0 : 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 0 : SvGlobalName aGuid;
1222 0 : sal_Int32 nSectCount(0);
1223 0 : rStrm.ReadUInt16( nByteOrder ).ReadUInt16( nVersion ).ReadUInt16( nOsMinor ).ReadUInt16( nOsType );
1224 0 : rStrm >> aGuid;
1225 0 : rStrm.ReadInt32( nSectCount );
1226 :
1227 : // read sections
1228 0 : sal_Size nSectPosPos = rStrm.Tell();
1229 0 : for( sal_Int32 nSectIdx = 0; (nSectIdx < nSectCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nSectIdx )
1230 : {
1231 : // read section guid/position pair
1232 0 : rStrm.Seek( nSectPosPos );
1233 0 : SvGlobalName aSectGuid;
1234 : sal_uInt32 nSectPos;
1235 0 : rStrm >> aSectGuid;
1236 0 : rStrm.ReadUInt32( nSectPos );
1237 0 : nSectPosPos = rStrm.Tell();
1238 : // read section
1239 0 : rStrm.Seek( static_cast< sal_Size >( nSectPos ) );
1240 0 : if( rStrm.GetErrorCode() == SVSTREAM_OK )
1241 0 : LoadObject( rStrm, AddSection( aSectGuid ) );
1242 0 : }
1243 0 : }
1244 :
1245 0 : void SfxOlePropertySet::ImplSave( SvStream& rStrm )
1246 : {
1247 : // write property set header
1248 0 : SvGlobalName aGuid;
1249 0 : sal_Int32 nSectCount = static_cast< sal_Int32 >( maSectionMap.size() );
1250 0 : rStrm .WriteUInt16( sal_uInt16( 0xFFFE ) ) // byte order
1251 0 : .WriteUInt16( sal_uInt16( 0 ) ) // version
1252 0 : .WriteUInt16( sal_uInt16( 1 ) ) // OS minor version
1253 0 : .WriteUInt16( sal_uInt16( 2 ) ); // OS type always windows for text encoding
1254 0 : WriteSvGlobalName( rStrm, aGuid ); // unused guid
1255 0 : rStrm .WriteInt32( nSectCount ); // number of sections
1256 :
1257 : // write placeholders for section guid/position pairs
1258 0 : sal_Size nSectPosPos = rStrm.Tell();
1259 0 : rStrm.SeekRel( static_cast< sal_sSize >( 20 * nSectCount ) );
1260 :
1261 : // write sections
1262 0 : for( SfxOleSectionMap::const_iterator aIt = maSectionMap.begin(), aEnd = maSectionMap.end(); aIt != aEnd; ++aIt )
1263 : {
1264 0 : SfxOleSection& rSection = *aIt->second;
1265 0 : rStrm.Seek( STREAM_SEEK_TO_END );
1266 0 : sal_uInt32 nSectPos = static_cast< sal_uInt32 >( rStrm.Tell() );
1267 : // write the section
1268 0 : SaveObject( rStrm, rSection );
1269 : // write section guid/position pair
1270 0 : rStrm.Seek( nSectPosPos );
1271 0 : WriteSvGlobalName( rStrm, aIt->first );
1272 0 : rStrm.WriteUInt32( nSectPos );
1273 0 : nSectPosPos = rStrm.Tell();
1274 0 : }
1275 0 : }
1276 :
1277 0 : const SvGlobalName& SfxOlePropertySet::GetSectionGuid( SfxOleSectionType eSection )
1278 : {
1279 0 : static const SvGlobalName saGlobalGuid( 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 );
1280 0 : static const SvGlobalName saBuiltInGuid( 0xD5CDD502, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE );
1281 0 : static const SvGlobalName saCustomGuid( 0xD5CDD505, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE );
1282 0 : static const SvGlobalName saEmptyGuid;
1283 0 : switch( eSection )
1284 : {
1285 0 : case SECTION_GLOBAL: return saGlobalGuid;
1286 0 : case SECTION_BUILTIN: return saBuiltInGuid;
1287 0 : 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: */
|