Branch libreoffice-5-0-4
[LibreOffice.git] / dtrans / source / win32 / misc / ImplHelper.cxx
blobe3a5369808c729f187f8f7f87dbf53ed0b7c8572
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
34 #include <vector>
36 #if defined ( __MINGW32__ )
37 #include <sehandler.hxx>
38 #endif
40 #define FORMATETC_EXACT_MATCH 1
41 #define FORMATETC_PARTIAL_MATCH -1
42 #define FORMATETC_NO_MATCH 0
44 // namespace directives
46 // returns a windows codepage appropriate to the
47 // given mime charset parameter value
49 sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset )
51 sal_uInt32 winCP = GetACP( );
53 if ( charset.getLength( ) )
55 OString osCharset(
56 charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
58 rtl_TextEncoding txtEnc =
59 rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
61 sal_uIntPtr winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
63 CHARSETINFO chrsInf;
64 sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ?
65 sal_True : sal_False;
67 // if one of the above functions fails
68 // we will return the current ANSI codepage
69 // of this thread
70 if ( bRet )
71 winCP = chrsInf.ciACP;
74 return winCP;
77 // returns a windows codepage appropriate to the
78 // given locale and locale type
80 OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
82 OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
84 // we set an default value
85 OUString winCP;
87 // set an default value
88 if ( LOCALE_IDEFAULTCODEPAGE == lctype )
90 winCP = OUString::number( static_cast<sal_Int32>(GetOEMCP( )) );
92 else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
94 winCP = OUString::number( static_cast<sal_Int32>(GetACP( )) );
96 else
97 OSL_ASSERT( sal_False );
99 // we use the GetLocaleInfoA because don't want to provide
100 // a unicode wrapper function for Win9x in sal/systools
101 char buff[6];
102 sal_Int32 nResult = GetLocaleInfoA(
103 lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) );
105 OSL_ASSERT( nResult );
107 if ( nResult )
109 sal_Int32 len = MultiByteToWideChar(
110 CP_ACP, 0, buff, -1, NULL, 0 );
112 OSL_ASSERT( len > 0 );
114 std::vector< sal_Unicode > lpwchBuff(len);
116 len = MultiByteToWideChar(
117 CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(&lpwchBuff[0]), len );
119 winCP = OUString( &lpwchBuff[0], (len - 1) );
122 return winCP;
125 // returns a mime charset parameter value appropriate
126 // to the given codepage, optional a prefix can be
127 // given, e.g. "windows-" or "cp"
129 OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
131 return aPrefix + cptostr( cp );
134 // returns a mime charset parameter value appropriate
135 // to the given locale id and locale type, optional a
136 // prefix can be given, e.g. "windows-" or "cp"
138 OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix )
140 OUString charset = getWinCPFromLocaleId( lcid, lctype );
141 return aPrefix + charset;
144 // IsOEMCP
146 sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage )
148 OSL_ASSERT( IsValidCodePage( codepage ) );
150 sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
151 775, 850, 852, 855, 857, 860,
152 861, 862, 863, 864, 865, 866,
153 869, 874, 932, 936, 949, 950, 1361 };
155 for ( size_t i = 0; i < SAL_N_ELEMENTS( arrOEMCP ); ++i )
156 if ( arrOEMCP[i] == codepage )
157 return sal_True;
159 return sal_False;
162 // converts a codepage into its string representation
164 OUString SAL_CALL cptostr( sal_uInt32 codepage )
166 OSL_ASSERT( IsValidCodePage( codepage ) );
168 return OUString::number( static_cast<sal_Int64>( codepage ) );
171 // OleStdDeleteTargetDevice()
173 // Purpose:
175 // Parameters:
177 // Return Value:
178 // SCODE - S_OK if successful
179 void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd )
181 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
182 jmp_buf jmpbuf;
183 __SEHandler han;
184 if (__builtin_setjmp(jmpbuf) == 0)
186 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
187 #else
188 __try
190 #endif
191 CoTaskMemFree( ptd );
193 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
194 else
195 #else
196 __except( EXCEPTION_EXECUTE_HANDLER )
197 #endif
199 OSL_FAIL( "Error DeleteTargetDevice" );
201 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
202 han.Reset();
203 #endif
206 // OleStdCopyTargetDevice()
208 // Purpose:
209 // duplicate a TARGETDEVICE struct. this function allocates memory for
210 // the copy. the caller MUST free the allocated copy when done with it
211 // using the standard allocator returned from CoGetMalloc.
212 // (OleStdFree can be used to free the copy).
214 // Parameters:
215 // ptdSrc pointer to source TARGETDEVICE
217 // Return Value:
218 // pointer to allocated copy of ptdSrc
219 // if ptdSrc==NULL then retuns NULL is returned.
220 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
221 DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
223 DVTARGETDEVICE* ptdDest = NULL;
225 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
226 jmp_buf jmpbuf;
227 __SEHandler han;
228 if (__builtin_setjmp(jmpbuf) == 0)
230 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
231 #else
232 __try
234 #endif
235 if ( NULL != ptdSrc )
237 ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
238 memcpy( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
241 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
242 han.Reset();
243 #else
244 __except( EXCEPTION_EXECUTE_HANDLER )
247 #endif
249 return ptdDest;
252 // OleStdCopyFormatEtc()
254 // Purpose:
255 // Copies the contents of a FORMATETC structure. this function takes
256 // special care to copy correctly copying the pointer to the TARGETDEVICE
257 // contained within the source FORMATETC structure.
258 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
259 // of the TARGETDEVICE will be allocated for the destination of the
260 // FORMATETC (petcDest).
262 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
263 // within the destination FORMATETC when done with it
264 // using the standard allocator returned from CoGetMalloc.
265 // (OleStdFree can be used to free the copy).
267 // Parameters:
268 // petcDest pointer to destination FORMATETC
269 // petcSrc pointer to source FORMATETC
271 // Return Value:
272 // returns TRUE if copy was successful;
273 // retuns FALSE if not successful, e.g. one or both of the pointers
274 // were invalid or the pointers were equal
275 sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
277 sal_Bool bRet = sal_False;
279 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
280 jmp_buf jmpbuf;
281 __SEHandler han;
282 if (__builtin_setjmp(jmpbuf) == 0)
284 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
285 #else
286 __try
288 #endif
289 if ( petcDest != petcSrc )
292 petcDest->cfFormat = petcSrc->cfFormat;
294 petcDest->ptd = NULL;
295 if ( NULL != petcSrc->ptd )
296 petcDest->ptd = CopyTargetDevice(petcSrc->ptd);
298 petcDest->dwAspect = petcSrc->dwAspect;
299 petcDest->lindex = petcSrc->lindex;
300 petcDest->tymed = petcSrc->tymed;
302 bRet = sal_True;
305 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
306 else
307 #else
308 __except( EXCEPTION_EXECUTE_HANDLER )
309 #endif
311 OSL_FAIL( "Error CopyFormatEtc" );
313 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
314 han.Reset();
315 #endif
317 return bRet;
320 // returns:
321 // 1 for exact match,
322 // 0 for no match,
323 // -1 for partial match (which is defined to mean the left is a subset
324 // of the right: fewer aspects, null target device, fewer medium).
326 sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
328 sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
330 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
331 jmp_buf jmpbuf;
332 __SEHandler han;
333 if (__builtin_setjmp(jmpbuf) == 0)
335 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
336 #else
337 __try
339 #endif
340 if ( pFetcLhs != pFetcRhs )
342 if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
343 ( pFetcLhs->lindex != pFetcRhs->lindex ) ||
344 !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
346 nMatch = FORMATETC_NO_MATCH;
349 else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
350 // same aspects; equal
352 else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
354 // left not subset of aspects of right; not equal
355 nMatch = FORMATETC_NO_MATCH;
357 else
358 // left subset of right
359 nMatch = FORMATETC_PARTIAL_MATCH;
361 if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
363 if ( pFetcLhs->tymed == pFetcRhs->tymed )
364 // same medium flags; equal
366 else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
368 // left not subset of medium flags of right; not equal
369 nMatch = FORMATETC_NO_MATCH;
371 else
372 // left subset of right
373 nMatch = FORMATETC_PARTIAL_MATCH;
377 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
378 else
379 #else
380 __except( EXCEPTION_EXECUTE_HANDLER )
381 #endif
383 OSL_FAIL( "Error CompareFormatEtc" );
384 nMatch = FORMATETC_NO_MATCH;
386 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
387 han.Reset();
388 #endif
390 return nMatch;
393 sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight )
395 sal_Bool bRet = sal_False;
397 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
398 jmp_buf jmpbuf;
399 __SEHandler han;
400 if (__builtin_setjmp(jmpbuf) == 0)
402 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
403 #else
404 __try
406 #endif
407 if ( ptdLeft == ptdRight )
409 // same address of td; must be same (handles NULL case)
410 bRet = sal_True;
413 // one ot the two is NULL
414 else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) )
416 if ( ptdLeft->tdSize == ptdRight->tdSize )
418 if ( memcmp( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
419 bRet = sal_True;
421 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
422 else
423 #else
424 __except( EXCEPTION_EXECUTE_HANDLER )
425 #endif
427 OSL_FAIL( "Error CompareTargetDevice" );
428 bRet = sal_False;
430 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
431 han.Reset();
432 #endif
434 return bRet;
437 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */