clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ascfldlg.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/source/ui/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/ui/dialog/ascfldlg.cxx
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | #include <sal/config.h> |
21 | |
22 | #include <utility> |
23 | |
24 | #include <hintids.hxx> |
25 | #include <rtl/textenc.h> |
26 | #include <i18nlangtag/mslangid.hxx> |
27 | #include <com/sun/star/i18n/ScriptType.hpp> |
28 | #include <unotools/lingucfg.hxx> |
29 | #include <unotools/viewoptions.hxx> |
30 | #include <sfx2/sfxsids.hrc> |
31 | #include <sfx2/printer.hxx> |
32 | #include <svl/languageoptions.hxx> |
33 | #include <editeng/langitem.hxx> |
34 | #include <swtypes.hxx> |
35 | #include <ascfldlg.hxx> |
36 | #include <shellio.hxx> |
37 | #include <docsh.hxx> |
38 | #include <doc.hxx> |
39 | #include <IDocumentDeviceAccess.hxx> |
40 | |
41 | #include <vcl/metric.hxx> |
42 | |
43 | using namespace ::com::sun::star; |
44 | |
45 | namespace |
46 | { |
47 | |
48 | const sal_Unicode cDialogExtraDataClose = '}'; |
49 | const char sDialogImpExtraData[] = "EncImpDlg:{"; |
50 | const char sDialogExpExtraData[] = "EncExpDlg:{"; |
51 | const sal_Int32 nDialogExtraDataLen = 11; |
52 | |
53 | } |
54 | |
55 | SwAsciiFilterDlg::SwAsciiFilterDlg( weld::Window* pParent, SwDocShell& rDocSh, |
56 | SvStream* pStream ) |
57 | : SfxDialogController(pParent, "modules/swriter/ui/asciifilterdialog.ui", "AsciiFilterDialog") |
58 | , m_bSaveLineStatus(true) |
59 | , m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder->weld_combo_box("charset"))) |
60 | , m_xFontFT(m_xBuilder->weld_label("fontft")) |
61 | , m_xFontLB(m_xBuilder->weld_combo_box("font")) |
62 | , m_xLanguageFT(m_xBuilder->weld_label("languageft")) |
63 | , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language"))) |
64 | , m_xCRLF_RB(m_xBuilder->weld_radio_button("crlf")) |
65 | , m_xCR_RB(m_xBuilder->weld_radio_button("cr")) |
66 | , m_xLF_RB(m_xBuilder->weld_radio_button("lf")) |
67 | , m_xIncludeBOM_CB(m_xBuilder->weld_check_button("includebom")) |
68 | { |
69 | m_xFontLB->make_sorted(); |
70 | |
71 | SwAsciiOptions aOpt; |
72 | { |
73 | SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8)); |
74 | if (aDlgOpt.Exists()) |
| 1 | Assuming the condition is false | |
|
| |
75 | { |
76 | css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem"); |
77 | aUserItem >>= m_sExtraData; |
78 | } |
79 | |
80 | const OUString sFindNm = OUString::createFromAscii( |
81 | pStream ? sDialogImpExtraData |
| 3 | | Assuming 'pStream' is non-null | |
|
| |
82 | : sDialogExpExtraData); |
83 | sal_Int32 nStt = m_sExtraData.indexOf( sFindNm ); |
84 | if( -1 != nStt ) |
| 5 | | Assuming the condition is false | |
|
| |
85 | { |
86 | nStt += nDialogExtraDataLen; |
87 | sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose, nStt ); |
88 | if( -1 != nEnd ) |
89 | { |
90 | aOpt.ReadUserData(m_sExtraData.copy(nStt, nEnd - nStt)); |
91 | nStt -= nDialogExtraDataLen; |
92 | m_sExtraData = m_sExtraData.replaceAt(nStt, nEnd - nStt + 1, ""); |
93 | } |
94 | } |
95 | } |
96 | |
97 | |
98 | if( pStream ) |
| |
99 | { |
100 | char aBuffer[ 4098 ]; |
101 | const sal_uLong nOldPos = pStream->Tell(); |
102 | const size_t nBytesRead = pStream->ReadBytes(aBuffer, 4096); |
103 | pStream->Seek( nOldPos ); |
104 | |
105 | if( nBytesRead <= 4096 ) |
| 8 | | Assuming 'nBytesRead' is <= 4096 | |
|
| |
106 | { |
107 | aBuffer[ nBytesRead ] = '0'; |
108 | aBuffer[ nBytesRead+1 ] = '0'; |
109 | } |
110 | |
111 | bool bCR = false, bLF = false, bNullChar = false; |
112 | for( sal_uLong nCnt = 0; nCnt < nBytesRead; ++nCnt ) |
| 10 | | Assuming 'nCnt' is >= 'nBytesRead' | |
|
| 11 | | Loop condition is false. Execution continues on line 124 | |
|
113 | switch( aBuffer[ nCnt ] ) |
114 | { |
115 | case 0x0: bNullChar = true; break; |
116 | case 0xA: bLF = true; break; |
117 | case 0xD: bCR = true; break; |
118 | case 0xC: |
119 | case 0x1A: |
120 | case 0x9: break; |
121 | default: break; |
122 | } |
123 | |
124 | if( !bNullChar ) |
| |
125 | { |
126 | if( bCR ) |
| |
127 | { |
128 | if( bLF ) |
129 | { |
130 | aOpt.SetParaFlags( LINEEND_CRLF ); |
131 | } |
132 | else |
133 | { |
134 | aOpt.SetParaFlags( LINEEND_CR ); |
135 | } |
136 | } |
137 | else if( bLF ) |
| |
138 | { |
139 | aOpt.SetParaFlags( LINEEND_LF ); |
140 | } |
141 | } |
142 | |
143 | const sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ); |
144 | SwDoc* pDoc = rDocSh.GetDoc(); |
145 | |
146 | |
147 | { |
148 | if( !aOpt.GetLanguage() ) |
| |
149 | { |
150 | if(pDoc) |
| 16 | | Assuming 'pDoc' is non-null | |
|
| |
151 | { |
152 | const sal_uInt16 nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType); |
153 | aOpt.SetLanguage( static_cast<const SvxLanguageItem&>(pDoc-> |
154 | GetDefault( nWhich )).GetLanguage()); |
155 | } |
156 | else |
157 | { |
158 | SvtLinguOptions aLinguOpt; |
159 | SvtLinguConfig().GetOptions( aLinguOpt ); |
160 | switch(nAppScriptType) |
161 | { |
162 | case css::i18n::ScriptType::ASIAN: |
163 | aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN)); |
164 | break; |
165 | case css::i18n::ScriptType::COMPLEX: |
166 | aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX)); |
167 | break; |
168 | |
169 | default: |
170 | aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN)); |
171 | } |
172 | } |
173 | } |
174 | |
175 | m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL, true ); |
176 | m_xLanguageLB->set_active_id(aOpt.GetLanguage()); |
177 | } |
178 | |
179 | { |
180 | bool bDelPrinter = false; |
181 | VclPtr<SfxPrinter> pPrt = pDoc ? pDoc->getIDocumentDeviceAccess().getPrinter(false) : nullptr; |
| |
182 | if( !pPrt ) |
| |
183 | { |
184 | auto pSet = std::make_unique<SfxItemSet>( rDocSh.GetPool(), |
185 | svl::Items<SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN, |
186 | SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC>{} ); |
187 | pPrt = VclPtr<SfxPrinter>::Create( std::move(pSet) ); |
| 20 | | Calling 'VclPtr::Create' | |
|
| 22 | | Returned allocated memory | |
|
188 | bDelPrinter = true; |
189 | } |
190 | |
191 | |
192 | std::set< OUString > aFontNames; |
193 | int nFontNames = pPrt->GetDevFontCount(); |
194 | for( int i = 0; i < nFontNames; i++ ) |
| 23 | | Assuming 'i' is >= 'nFontNames' | |
|
| 24 | | Loop condition is false. Execution continues on line 201 | |
|
195 | { |
196 | FontMetric aFontMetric( pPrt->GetDevFont( i ) ); |
197 | aFontNames.insert( aFontMetric.GetFamilyName() ); |
198 | } |
199 | |
200 | |
201 | for( const auto& rFontName : aFontNames ) |
202 | { |
203 | m_xFontLB->append_text(rFontName); |
204 | } |
205 | |
206 | if( aOpt.GetFontName().isEmpty() ) |
| |
207 | { |
208 | LanguageType eLang = aOpt.GetLanguage(); |
209 | vcl::Font aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED, eLang, GetDefaultFontFlags::OnlyOne, pPrt)); |
210 | aOpt.SetFontName(aTmpFont.GetFamilyName()); |
211 | } |
212 | |
213 | m_xFontLB->set_active_text(aOpt.GetFontName()); |
214 | |
215 | if( bDelPrinter ) |
| |
216 | pPrt.disposeAndClear(); |
| 27 | | Calling 'VclPtr::disposeAndClear' | |
|
217 | } |
218 | |
219 | |
220 | m_xIncludeBOM_CB->hide(); |
221 | } |
222 | else |
223 | { |
224 | |
225 | m_xFontFT->hide(); |
226 | m_xFontLB->hide(); |
227 | m_xLanguageFT->hide(); |
228 | m_xLanguageLB->hide(); |
229 | |
230 | |
231 | SetIncludeBOM(aOpt.GetIncludeBOM()); |
232 | m_xIncludeBOM_CB->save_state(); |
233 | } |
234 | |
235 | |
236 | m_xCharSetLB->FillFromTextEncodingTable( pStream != nullptr ); |
237 | m_xCharSetLB->SelectTextEncoding( aOpt.GetCharSet() ); |
238 | |
239 | m_xCharSetLB->connect_changed( LINK( this, SwAsciiFilterDlg, CharSetSelHdl )); |
240 | m_xCRLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl )); |
241 | m_xLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl )); |
242 | m_xCR_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl )); |
243 | |
244 | SetCRLF( aOpt.GetParaFlags() ); |
245 | |
246 | m_xCRLF_RB->save_state(); |
247 | m_xLF_RB->save_state(); |
248 | m_xCR_RB->save_state(); |
249 | |
250 | UpdateIncludeBOMSensitiveState(); |
251 | } |
252 | |
253 | SwAsciiFilterDlg::~SwAsciiFilterDlg() |
254 | { |
255 | SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8)); |
256 | aDlgOpt.SetUserItem("UserItem", uno::makeAny(m_sExtraData)); |
257 | } |
258 | |
259 | void SwAsciiFilterDlg::FillOptions( SwAsciiOptions& rOptions ) |
260 | { |
261 | sal_uLong nCCode = m_xCharSetLB->GetSelectTextEncoding(); |
262 | OUString sFont; |
263 | LanguageType nLng = LANGUAGE_SYSTEM; |
264 | if (m_xFontLB->get_visible()) |
265 | { |
266 | sFont = m_xFontLB->get_active_text(); |
267 | nLng = m_xLanguageLB->get_active_id(); |
268 | } |
269 | |
270 | rOptions.SetFontName( sFont ); |
271 | rOptions.SetCharSet( rtl_TextEncoding( nCCode ) ); |
272 | rOptions.SetLanguage( nLng ); |
273 | rOptions.SetParaFlags( GetCRLF() ); |
274 | rOptions.SetIncludeBOM( GetIncludeBOM() ); |
275 | |
276 | |
277 | OUString sData; |
278 | rOptions.WriteUserData( sData ); |
279 | if (sData.isEmpty()) |
280 | return; |
281 | |
282 | const OUString sFindNm = OUString::createFromAscii( |
283 | m_xFontLB->get_visible() ? sDialogImpExtraData |
284 | : sDialogExpExtraData); |
285 | sal_Int32 nStt = m_sExtraData.indexOf( sFindNm ); |
286 | if( -1 != nStt ) |
287 | { |
288 | |
289 | sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose, |
290 | nStt + nDialogExtraDataLen ); |
291 | if( -1 != nEnd ) |
292 | m_sExtraData = m_sExtraData.replaceAt( nStt, nEnd - nStt + 1, "" ); |
293 | } |
294 | m_sExtraData += sFindNm + sData + OUStringChar(cDialogExtraDataClose); |
295 | } |
296 | |
297 | void SwAsciiFilterDlg::SetCRLF( LineEnd eEnd ) |
298 | { |
299 | switch (eEnd) |
300 | { |
301 | case LINEEND_CR: |
302 | m_xCR_RB->set_active(true); |
303 | break; |
304 | case LINEEND_CRLF: |
305 | m_xCRLF_RB->set_active(true); |
306 | break; |
307 | case LINEEND_LF: |
308 | m_xLF_RB->set_active(true); |
309 | break; |
310 | } |
311 | } |
312 | |
313 | LineEnd SwAsciiFilterDlg::GetCRLF() const |
314 | { |
315 | LineEnd eEnd; |
316 | if(m_xCR_RB->get_active()) |
317 | eEnd = LINEEND_CR; |
318 | else if (m_xLF_RB->get_active()) |
319 | eEnd = LINEEND_LF; |
320 | else |
321 | eEnd = LINEEND_CRLF; |
322 | return eEnd; |
323 | } |
324 | |
325 | void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM ) |
326 | { |
327 | m_xIncludeBOM_CB->set_state(bIncludeBOM ? TRISTATE_TRUE : TRISTATE_FALSE); |
328 | } |
329 | |
330 | bool SwAsciiFilterDlg::GetIncludeBOM() const |
331 | { |
332 | return m_xIncludeBOM_CB->get_state() != TRISTATE_FALSE; |
333 | } |
334 | |
335 | void SwAsciiFilterDlg::UpdateIncludeBOMSensitiveState() |
336 | { |
337 | if (!m_xIncludeBOM_CB->get_visible()) |
338 | return; |
339 | |
340 | switch (m_xCharSetLB->GetSelectTextEncoding()) |
341 | { |
342 | case RTL_TEXTENCODING_UTF8: |
343 | case RTL_TEXTENCODING_UCS2: |
344 | m_xIncludeBOM_CB->set_sensitive(true); |
345 | break; |
346 | default: |
347 | m_xIncludeBOM_CB->set_sensitive(false); |
348 | break; |
349 | } |
350 | } |
351 | |
352 | IMPL_LINK_NOARG(SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox&, void) |
353 | { |
354 | LineEnd eOldEnd = GetCRLF(), eEnd = LineEnd(-1); |
355 | LanguageType nLng = m_xFontLB->get_visible() |
356 | ? m_xLanguageLB->get_active_id() |
357 | : LANGUAGE_SYSTEM, |
358 | nOldLng = nLng; |
359 | |
360 | rtl_TextEncoding nChrSet = m_xCharSetLB->GetSelectTextEncoding(); |
361 | if( nChrSet == osl_getThreadTextEncoding() ) |
362 | eEnd = GetSystemLineEnd(); |
363 | else |
364 | { |
365 | switch( nChrSet ) |
366 | { |
367 | case RTL_TEXTENCODING_MS_1252: |
368 | #ifdef UNX |
369 | eEnd = LINEEND_LF; |
370 | #else |
371 | eEnd = LINEEND_CRLF; |
372 | #endif |
373 | break; |
374 | |
375 | case RTL_TEXTENCODING_APPLE_ROMAN: |
376 | eEnd = LINEEND_CR; |
377 | break; |
378 | |
379 | case RTL_TEXTENCODING_IBM_850: |
380 | eEnd = LINEEND_CRLF; |
381 | break; |
382 | |
383 | case RTL_TEXTENCODING_APPLE_ARABIC: |
384 | case RTL_TEXTENCODING_APPLE_CENTEURO: |
385 | case RTL_TEXTENCODING_APPLE_CROATIAN: |
386 | case RTL_TEXTENCODING_APPLE_CYRILLIC: |
387 | case RTL_TEXTENCODING_APPLE_DEVANAGARI: |
388 | case RTL_TEXTENCODING_APPLE_FARSI: |
389 | case RTL_TEXTENCODING_APPLE_GREEK: |
390 | case RTL_TEXTENCODING_APPLE_GUJARATI: |
391 | case RTL_TEXTENCODING_APPLE_GURMUKHI: |
392 | case RTL_TEXTENCODING_APPLE_HEBREW: |
393 | case RTL_TEXTENCODING_APPLE_ICELAND: |
394 | case RTL_TEXTENCODING_APPLE_ROMANIAN: |
395 | case RTL_TEXTENCODING_APPLE_THAI: |
396 | case RTL_TEXTENCODING_APPLE_TURKISH: |
397 | case RTL_TEXTENCODING_APPLE_UKRAINIAN: |
398 | case RTL_TEXTENCODING_APPLE_CHINSIMP: |
399 | case RTL_TEXTENCODING_APPLE_CHINTRAD: |
400 | case RTL_TEXTENCODING_APPLE_JAPANESE: |
401 | case RTL_TEXTENCODING_APPLE_KOREAN: |
402 | eEnd = LINEEND_CR; |
403 | break; |
404 | } |
405 | } |
406 | |
407 | m_bSaveLineStatus = false; |
408 | if( eEnd != LineEnd(-1) ) |
409 | { |
410 | if( eOldEnd != eEnd ) |
411 | SetCRLF( eEnd ); |
412 | } |
413 | else |
414 | { |
415 | |
416 | m_xCRLF_RB->set_state(m_xCRLF_RB->get_saved_state()); |
417 | m_xCR_RB->set_state(m_xCR_RB->get_saved_state()); |
418 | m_xLF_RB->set_state(m_xLF_RB->get_saved_state()); |
419 | } |
420 | m_bSaveLineStatus = true; |
421 | |
422 | if (nOldLng != nLng && m_xFontLB->get_visible()) |
423 | m_xLanguageLB->set_active_id(nLng); |
424 | |
425 | UpdateIncludeBOMSensitiveState(); |
426 | } |
427 | |
428 | IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::ToggleButton&, rBtn, void) |
429 | { |
430 | if (m_bSaveLineStatus) |
431 | rBtn.save_state(); |
432 | } |
433 | |
434 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | #ifndef INCLUDED_VCL_PTR_HXX |
21 | #define INCLUDED_VCL_PTR_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <rtl/ref.hxx> |
26 | |
27 | #include <utility> |
28 | #include <type_traits> |
29 | |
30 | #ifdef DBG_UTIL |
31 | #ifndef _WIN32 |
32 | #include <vcl/vclmain.hxx> |
33 | #endif |
34 | #endif |
35 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase( |
44 | int (*)[sizeof(T)]) |
45 | { return std::is_base_of<VclReferenceBase, T>::value; } |
46 | |
47 | } |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | template <class reference_type> |
57 | class VclPtr |
58 | { |
59 | static_assert( |
60 | vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>( |
61 | nullptr), |
62 | "template argument type must be derived from VclReferenceBase"); |
63 | |
64 | ::rtl::Reference<reference_type> m_rInnerRef; |
65 | |
66 | public: |
67 | |
68 | |
69 | VclPtr() |
70 | : m_rInnerRef() |
71 | {} |
72 | |
73 | |
74 | |
75 | VclPtr (reference_type * pBody) |
76 | : m_rInnerRef(pBody) |
77 | {} |
78 | |
79 | |
80 | |
81 | VclPtr (reference_type * pBody, __sal_NoAcquire) |
82 | : m_rInnerRef(pBody, SAL_NO_ACQUIRE) |
83 | {} |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | template< class derived_type > |
94 | VclPtr( |
95 | const VclPtr< derived_type > & rRef, |
96 | typename std::enable_if< |
97 | std::is_base_of<reference_type, derived_type>::value, int>::type |
98 | = 0 ) |
99 | : m_rInnerRef( static_cast<reference_type*>(rRef) ) |
100 | { |
101 | } |
102 | |
103 | #if defined(DBG_UTIL) && !defined(_WIN32) |
104 | virtual ~VclPtr() |
105 | { |
106 | assert(m_rInnerRef.get() == nullptr || vclmain::isAlive()); |
107 | |
108 | |
109 | assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) |
110 | && "someone forgot to call dispose()"); |
111 | } |
112 | VclPtr(VclPtr const &) = default; |
113 | VclPtr(VclPtr &&) = default; |
114 | VclPtr & operator =(VclPtr const &) = default; |
115 | VclPtr & operator =(VclPtr &&) = default; |
116 | #endif |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg) |
128 | { |
129 | return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ); |
| |
130 | } |
131 | |
132 | |
133 | |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); |
| 28 | | Calling 'Reference::clear' | |
|
| 35 | | Returning; memory was released | |
|
205 | if (aTmp.get()) { |
| 36 | | Calling 'Reference::get' | |
|
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | |
211 | |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) { |
261 | return !(p1 == p2); |
262 | } |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
278 | template<typename... Arg> VclPtrInstance(Arg &&... arg) |
279 | : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
280 | { |
281 | } |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete; |
288 | }; |
289 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
294 | |
295 | |
296 | ScopedVclPtr() |
297 | : VclPtr<reference_type>() |
298 | {} |
299 | |
300 | |
301 | |
302 | ScopedVclPtr (reference_type * pBody) |
303 | : VclPtr<reference_type>(pBody) |
304 | {} |
305 | |
306 | |
307 | |
308 | ScopedVclPtr (const VclPtr<reference_type> & handle) |
309 | : VclPtr<reference_type>(handle) |
310 | {} |
311 | |
312 | |
313 | |
314 | |
315 | void disposeAndReset(reference_type *pBody) |
316 | { |
317 | if (pBody != this->get()) { |
318 | VclPtr<reference_type>::disposeAndClear(); |
319 | VclPtr<reference_type>::set(pBody); |
320 | } |
321 | } |
322 | |
323 | |
324 | |
325 | |
326 | ScopedVclPtr<reference_type>& operator = (reference_type * pBody) |
327 | { |
328 | disposeAndReset(pBody); |
329 | return *this; |
330 | } |
331 | |
332 | |
333 | |
334 | |
335 | |
336 | |
337 | |
338 | |
339 | |
340 | template< class derived_type > |
341 | ScopedVclPtr( |
342 | const VclPtr< derived_type > & rRef, |
343 | typename std::enable_if< |
344 | std::is_base_of<reference_type, derived_type>::value, int>::type |
345 | = 0 ) |
346 | : VclPtr<reference_type>( rRef ) |
347 | { |
348 | } |
349 | |
350 | |
351 | |
352 | |
353 | |
354 | |
355 | |
356 | template<typename derived_type> |
357 | typename std::enable_if< |
358 | std::is_base_of<reference_type, derived_type>::value, |
359 | ScopedVclPtr &>::type |
360 | operator =(VclPtr<derived_type> const & rRef) |
361 | { |
362 | disposeAndReset(rRef.get()); |
363 | return *this; |
364 | } |
365 | |
366 | |
367 | |
368 | |
369 | |
370 | template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete; |
371 | |
372 | ~ScopedVclPtr() |
373 | { |
374 | VclPtr<reference_type>::disposeAndClear(); |
375 | assert(VclPtr<reference_type>::get() == nullptr); |
376 | } |
377 | |
378 | private: |
379 | |
380 | ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete; |
381 | |
382 | ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete; |
383 | |
384 | void reset() = delete; |
385 | void reset(reference_type *pBody) = delete; |
386 | |
387 | protected: |
388 | ScopedVclPtr (reference_type * pBody, __sal_NoAcquire) |
389 | : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE) |
390 | {} |
391 | }; |
392 | |
393 | |
394 | |
395 | |
396 | |
397 | |
398 | |
399 | |
400 | |
401 | |
402 | #if defined _MSC_VER |
403 | #pragma warning(push) |
404 | #pragma warning(disable: 4521) // " multiple copy constructors specified" |
405 | #endif |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
410 | template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg) |
411 | : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
412 | { |
413 | } |
414 | |
415 | |
416 | |
417 | |
418 | |
419 | template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete; |
420 | |
421 | private: |
422 | |
423 | |
424 | |
425 | |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | |
432 | |
433 | ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete; |
434 | ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete; |
435 | }; |
436 | #if defined _MSC_VER |
437 | #pragma warning(pop) |
438 | #endif |
439 | |
440 | #endif // INCLUDED_VCL_PTR_HXX |
441 | |
442 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | #ifndef INCLUDED_RTL_REF_HXX |
21 | #define INCLUDED_RTL_REF_HXX |
22 | |
23 | #include "sal/config.h" |
24 | |
25 | #include <cassert> |
26 | #include <cstddef> |
27 | #include <functional> |
28 | #ifdef LIBO_INTERNAL_ONLY |
29 | #include <type_traits> |
30 | #endif |
31 | |
32 | #include "sal/types.h" |
33 | |
34 | namespace rtl |
35 | { |
36 | |
37 | |
38 | |
39 | template <class reference_type> |
40 | class Reference |
41 | { |
42 | |
43 | |
44 | reference_type * m_pBody; |
45 | |
46 | |
47 | public: |
48 | |
49 | |
50 | Reference() |
51 | : m_pBody (NULL) |
52 | {} |
53 | |
54 | |
55 | |
56 | |
57 | Reference (reference_type * pBody, __sal_NoAcquire) |
58 | : m_pBody (pBody) |
59 | { |
60 | } |
61 | |
62 | |
63 | |
64 | Reference (reference_type * pBody) |
65 | : m_pBody (pBody) |
66 | { |
67 | if (m_pBody) |
68 | m_pBody->acquire(); |
69 | } |
70 | |
71 | |
72 | |
73 | Reference (const Reference<reference_type> & handle) |
74 | : m_pBody (handle.m_pBody) |
75 | { |
76 | if (m_pBody) |
77 | m_pBody->acquire(); |
78 | } |
79 | |
80 | #ifdef LIBO_INTERNAL_ONLY |
81 | |
82 | |
83 | Reference (Reference<reference_type> && handle) noexcept |
84 | : m_pBody (handle.m_pBody) |
85 | { |
86 | handle.m_pBody = nullptr; |
87 | } |
88 | #endif |
89 | |
90 | #if defined LIBO_INTERNAL_ONLY |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | template< class derived_type > |
98 | inline Reference( |
99 | const Reference< derived_type > & rRef, |
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) |
101 | : m_pBody (rRef.get()) |
102 | { |
103 | if (m_pBody) |
104 | m_pBody->acquire(); |
105 | } |
106 | #endif |
107 | |
108 | |
109 | |
110 | ~Reference() COVERITY_NOEXCEPT_FALSE |
111 | { |
112 | if (m_pBody) |
113 | m_pBody->release(); |
114 | } |
115 | |
116 | |
117 | |
118 | |
119 | Reference<reference_type> & |
120 | SAL_CALL set (reference_type * pBody) |
121 | { |
122 | if (pBody) |
123 | pBody->acquire(); |
124 | reference_type * const pOld = m_pBody; |
125 | m_pBody = pBody; |
126 | if (pOld) |
127 | pOld->release(); |
128 | return *this; |
129 | } |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | Reference<reference_type> & |
136 | SAL_CALL operator= (const Reference<reference_type> & handle) |
137 | { |
138 | return set( handle.m_pBody ); |
139 | } |
140 | |
141 | #ifdef LIBO_INTERNAL_ONLY |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | Reference<reference_type> & |
148 | operator= (Reference<reference_type> && handle) |
149 | { |
150 | |
151 | if (m_pBody) |
152 | m_pBody->release(); |
153 | m_pBody = handle.m_pBody; |
154 | handle.m_pBody = nullptr; |
155 | return *this; |
156 | } |
157 | #endif |
158 | |
159 | |
160 | |
161 | Reference<reference_type> & |
162 | SAL_CALL operator= (reference_type * pBody) |
163 | { |
164 | return set( pBody ); |
165 | } |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | Reference<reference_type> & SAL_CALL clear() |
175 | { |
176 | if (m_pBody) |
| |
177 | { |
178 | reference_type * const pOld = m_pBody; |
179 | m_pBody = NULL; |
180 | pOld->release(); |
| 30 | | Calling 'VclReferenceBase::release' | |
|
| 34 | | Returning; memory was released | |
|
181 | } |
182 | return *this; |
183 | } |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | reference_type * SAL_CALL get() const |
191 | { |
192 | return m_pBody; |
| 37 | | Use of memory after it is freed |
|
193 | } |
194 | |
195 | |
196 | |
197 | |
198 | reference_type * SAL_CALL operator->() const |
199 | { |
200 | assert(m_pBody != NULL); |
201 | return m_pBody; |
202 | } |
203 | |
204 | |
205 | |
206 | |
207 | reference_type & SAL_CALL operator*() const |
208 | { |
209 | assert(m_pBody != NULL); |
210 | return *m_pBody; |
211 | } |
212 | |
213 | |
214 | |
215 | |
216 | bool SAL_CALL is() const |
217 | { |
218 | return (m_pBody != NULL); |
219 | } |
220 | |
221 | #if defined LIBO_INTERNAL_ONLY |
222 | |
223 | |
224 | explicit operator bool() const |
225 | { |
226 | return is(); |
227 | } |
228 | #endif |
229 | |
230 | |
231 | |
232 | bool SAL_CALL operator== (const reference_type * pBody) const |
233 | { |
234 | return (m_pBody == pBody); |
235 | } |
236 | |
237 | |
238 | |
239 | |
240 | bool |
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const |
242 | { |
243 | return (m_pBody == handle.m_pBody); |
244 | } |
245 | |
246 | |
247 | |
248 | |
249 | bool |
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const |
251 | { |
252 | return (m_pBody != handle.m_pBody); |
253 | } |
254 | |
255 | |
256 | |
257 | |
258 | bool |
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const |
260 | { |
261 | return (m_pBody < handle.m_pBody); |
262 | } |
263 | |
264 | |
265 | |
266 | |
267 | bool |
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const |
269 | { |
270 | return (m_pBody > handle.m_pBody); |
271 | } |
272 | }; |
273 | |
274 | } |
275 | |
276 | #if defined LIBO_INTERNAL_ONLY |
277 | namespace std |
278 | { |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | |
285 | |
286 | template<typename T> |
287 | struct hash<::rtl::Reference<T>> |
288 | { |
289 | std::size_t operator()(::rtl::Reference<T> const & s) const |
290 | { return std::size_t(s.get()); } |
291 | }; |
292 | |
293 | |
294 | } |
295 | |
296 | #endif |
297 | |
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ |
299 | |
300 | |