bump product version to 4.1.6.2
[LibreOffice.git] / dtrans / source / win32 / misc / ImplHelper.cxx
blob7e8d5f79d8c1547374739692344644cb515f1bf4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/diagnose.h>
21 #include "ImplHelper.hxx"
22 #include <rtl/tencinfo.h>
23 #include <string.h>
24 #include <memory>
26 #if defined _MSC_VER
27 #pragma warning(push,1)
28 #endif
29 #include <windows.h>
30 #if defined _MSC_VER
31 #pragma warning(pop)
32 #endif
33 #ifdef __MINGW32__
34 #include <sehandler.hxx>
35 #endif
37 #include <vector>
39 #define FORMATETC_EXACT_MATCH 1
40 #define FORMATETC_PARTIAL_MATCH -1
41 #define FORMATETC_NO_MATCH 0
43 //------------------------------------------------------------------------
44 // namespace directives
45 //------------------------------------------------------------------------
48 //------------------------------------------------------------------------
49 // returns a windows codepage appropriate to the
50 // given mime charset parameter value
51 //------------------------------------------------------------------------
53 sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset )
55 sal_uInt32 winCP = GetACP( );
57 if ( charset.getLength( ) )
59 OString osCharset(
60 charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
62 rtl_TextEncoding txtEnc =
63 rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
65 sal_uInt32 winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
67 CHARSETINFO chrsInf;
68 sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ?
69 sal_True : sal_False;
71 // if one of the above functions fails
72 // we will return the current ANSI codepage
73 // of this thread
74 if ( bRet )
75 winCP = chrsInf.ciACP;
78 return winCP;
81 //--------------------------------------------------
82 // returns a windows codepage appropriate to the
83 // given locale and locale type
84 //--------------------------------------------------
86 OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
88 OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
90 // we set an default value
91 OUString winCP;
93 // set an default value
94 if ( LOCALE_IDEFAULTCODEPAGE == lctype )
96 winCP = OUString::valueOf( static_cast<sal_Int32>(GetOEMCP( )), 10 );
98 else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
100 winCP = OUString::valueOf( static_cast<sal_Int32>(GetACP( )), 10 );
102 else
103 OSL_ASSERT( sal_False );
105 // we use the GetLocaleInfoA because don't want to provide
106 // a unicode wrapper function for Win9x in sal/systools
107 char buff[6];
108 sal_Int32 nResult = GetLocaleInfoA(
109 lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) );
111 OSL_ASSERT( nResult );
113 if ( nResult )
115 sal_Int32 len = MultiByteToWideChar(
116 CP_ACP, 0, buff, -1, NULL, 0 );
118 OSL_ASSERT( len > 0 );
120 std::vector< sal_Unicode > lpwchBuff(len);
122 len = MultiByteToWideChar(
123 CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(&lpwchBuff[0]), len );
125 winCP = OUString( &lpwchBuff[0], (len - 1) );
128 return winCP;
131 //--------------------------------------------------
132 // returns a mime charset parameter value appropriate
133 // to the given codepage, optional a prefix can be
134 // given, e.g. "windows-" or "cp"
135 //--------------------------------------------------
137 OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
139 return aPrefix + cptostr( cp );
142 //--------------------------------------------------
143 // returns a mime charset parameter value appropriate
144 // to the given locale id and locale type, optional a
145 // prefix can be given, e.g. "windows-" or "cp"
146 //--------------------------------------------------
148 OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix )
150 OUString charset = getWinCPFromLocaleId( lcid, lctype );
151 return aPrefix + charset;
154 //------------------------------------------------------------------------
155 // IsOEMCP
156 //------------------------------------------------------------------------
158 sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage )
160 OSL_ASSERT( IsValidCodePage( codepage ) );
162 sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
163 775, 850, 852, 855, 857, 860,
164 861, 862, 863, 864, 865, 866,
165 869, 874, 932, 936, 949, 950, 1361 };
167 for ( size_t i = 0; i < SAL_N_ELEMENTS( arrOEMCP ); ++i )
168 if ( arrOEMCP[i] == codepage )
169 return sal_True;
171 return sal_False;
174 //------------------------------------------------------------------------
175 // converts a codepage into its string representation
176 //------------------------------------------------------------------------
178 OUString SAL_CALL cptostr( sal_uInt32 codepage )
180 OSL_ASSERT( IsValidCodePage( codepage ) );
182 return OUString::valueOf( static_cast<sal_Int64>( codepage ), 10 );
185 //-------------------------------------------------------------------------
186 // OleStdDeleteTargetDevice()
188 // Purpose:
190 // Parameters:
192 // Return Value:
193 // SCODE - S_OK if successful
194 //-------------------------------------------------------------------------
196 void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd )
198 #ifdef __MINGW32__
199 jmp_buf jmpbuf;
200 __SEHandler han;
201 if (__builtin_setjmp(jmpbuf) == 0)
203 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
204 #else
205 __try
207 #endif
208 CoTaskMemFree( ptd );
210 #ifdef __MINGW32__
211 else
212 #else
213 __except( EXCEPTION_EXECUTE_HANDLER )
214 #endif
216 OSL_FAIL( "Error DeleteTargetDevice" );
218 #ifdef __MINGW32__
219 han.Reset();
220 #endif
225 //-------------------------------------------------------------------------
226 // OleStdCopyTargetDevice()
228 // Purpose:
229 // duplicate a TARGETDEVICE struct. this function allocates memory for
230 // the copy. the caller MUST free the allocated copy when done with it
231 // using the standard allocator returned from CoGetMalloc.
232 // (OleStdFree can be used to free the copy).
234 // Parameters:
235 // ptdSrc pointer to source TARGETDEVICE
237 // Return Value:
238 // pointer to allocated copy of ptdSrc
239 // if ptdSrc==NULL then retuns NULL is returned.
240 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
241 //-------------------------------------------------------------------------
243 DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
245 DVTARGETDEVICE* ptdDest = NULL;
247 #ifdef __MINGW32__
248 jmp_buf jmpbuf;
249 __SEHandler han;
250 if (__builtin_setjmp(jmpbuf) == 0)
252 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
253 #else
254 __try
256 #endif
257 if ( NULL != ptdSrc )
259 ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
260 memcpy( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
263 #ifdef __MINGW32__
264 han.Reset();
265 #else
266 __except( EXCEPTION_EXECUTE_HANDLER )
269 #endif
271 return ptdDest;
275 //-------------------------------------------------------------------------
276 // OleStdCopyFormatEtc()
278 // Purpose:
279 // Copies the contents of a FORMATETC structure. this function takes
280 // special care to copy correctly copying the pointer to the TARGETDEVICE
281 // contained within the source FORMATETC structure.
282 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
283 // of the TARGETDEVICE will be allocated for the destination of the
284 // FORMATETC (petcDest).
286 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
287 // within the destination FORMATETC when done with it
288 // using the standard allocator returned from CoGetMalloc.
289 // (OleStdFree can be used to free the copy).
291 // Parameters:
292 // petcDest pointer to destination FORMATETC
293 // petcSrc pointer to source FORMATETC
295 // Return Value:
296 // returns TRUE if copy was successful;
297 // retuns FALSE if not successful, e.g. one or both of the pointers
298 // were invalid or the pointers were equal
299 //-------------------------------------------------------------------------
301 sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
303 sal_Bool bRet = sal_False;
305 #ifdef __MINGW32__
306 jmp_buf jmpbuf;
307 __SEHandler han;
308 if (__builtin_setjmp(jmpbuf) == 0)
310 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
311 #else
312 __try
314 #endif
315 if ( petcDest != petcSrc )
318 petcDest->cfFormat = petcSrc->cfFormat;
320 petcDest->ptd = NULL;
321 if ( NULL != petcSrc->ptd )
322 petcDest->ptd = CopyTargetDevice(petcSrc->ptd);
324 petcDest->dwAspect = petcSrc->dwAspect;
325 petcDest->lindex = petcSrc->lindex;
326 petcDest->tymed = petcSrc->tymed;
328 bRet = sal_True;
331 #ifdef __MINGW32__
332 else
333 #else
334 __except( EXCEPTION_EXECUTE_HANDLER )
335 #endif
337 OSL_FAIL( "Error CopyFormatEtc" );
339 #ifdef __MINGW32__
340 han.Reset();
341 #endif
343 return bRet;
346 //-------------------------------------------------------------------------
347 // returns:
348 // 1 for exact match,
349 // 0 for no match,
350 // -1 for partial match (which is defined to mean the left is a subset
351 // of the right: fewer aspects, null target device, fewer medium).
352 //-------------------------------------------------------------------------
354 sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
356 sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
358 #ifdef __MINGW32__
359 jmp_buf jmpbuf;
360 __SEHandler han;
361 if (__builtin_setjmp(jmpbuf) == 0)
363 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
364 #else
365 __try
367 #endif
368 if ( pFetcLhs != pFetcRhs )
370 if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
371 ( pFetcLhs->lindex != pFetcRhs->lindex ) ||
372 !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
374 nMatch = FORMATETC_NO_MATCH;
377 else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
378 // same aspects; equal
380 else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
382 // left not subset of aspects of right; not equal
383 nMatch = FORMATETC_NO_MATCH;
385 else
386 // left subset of right
387 nMatch = FORMATETC_PARTIAL_MATCH;
389 if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
391 if ( pFetcLhs->tymed == pFetcRhs->tymed )
392 // same medium flags; equal
394 else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
396 // left not subset of medium flags of right; not equal
397 nMatch = FORMATETC_NO_MATCH;
399 else
400 // left subset of right
401 nMatch = FORMATETC_PARTIAL_MATCH;
405 #ifdef __MINGW32__
406 else
407 #else
408 __except( EXCEPTION_EXECUTE_HANDLER )
409 #endif
411 OSL_FAIL( "Error CompareFormatEtc" );
412 nMatch = FORMATETC_NO_MATCH;
414 #ifdef __MINGW32__
415 han.Reset();
416 #endif
418 return nMatch;
422 //-------------------------------------------------------------------------
424 //-------------------------------------------------------------------------
426 sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight )
428 sal_Bool bRet = sal_False;
430 #ifdef __MINGW32__
431 jmp_buf jmpbuf;
432 __SEHandler han;
433 if (__builtin_setjmp(jmpbuf) == 0)
435 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
436 #else
437 __try
439 #endif
440 if ( ptdLeft == ptdRight )
442 // same address of td; must be same (handles NULL case)
443 bRet = sal_True;
446 // one ot the two is NULL
447 else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) )
449 if ( ptdLeft->tdSize == ptdRight->tdSize )
451 if ( memcmp( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
452 bRet = sal_True;
454 #ifdef __MINGW32__
455 else
456 #else
457 __except( EXCEPTION_EXECUTE_HANDLER )
458 #endif
460 OSL_FAIL( "Error CompareTargetDevice" );
461 bRet = sal_False;
463 #ifdef __MINGW32__
464 han.Reset();
465 #endif
467 return bRet;
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */