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