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