Update ooo320-m1
[ooovba.git] / dtrans / source / win32 / misc / ImplHelper.cxx
blobf4b1962e67aa5ec66530099353a7c1c774892fc7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ImplHelper.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dtrans.hxx"
35 //------------------------------------------------------------------------
36 // includes
37 //------------------------------------------------------------------------
38 #include <osl/diagnose.h>
39 #include "ImplHelper.hxx"
40 #include <rtl/tencinfo.h>
41 #include <rtl/memory.h>
43 #include <memory>
44 #if defined _MSC_VER
45 #pragma warning(push,1)
46 #endif
47 #include <windows.h>
48 #if defined _MSC_VER
49 #pragma warning(pop)
50 #endif
51 #ifdef __MINGW32__
52 #include <excpt.h>
53 #endif
55 //------------------------------------------------------------------------
56 // defines
57 //------------------------------------------------------------------------
59 #define FORMATETC_EXACT_MATCH 1
60 #define FORMATETC_PARTIAL_MATCH -1
61 #define FORMATETC_NO_MATCH 0
63 //------------------------------------------------------------------------
64 // namespace directives
65 //------------------------------------------------------------------------
67 using ::rtl::OUString;
68 using ::rtl::OString;
70 //------------------------------------------------------------------------
71 // returns a windows codepage appropriate to the
72 // given mime charset parameter value
73 //------------------------------------------------------------------------
75 sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset )
77 sal_uInt32 winCP = GetACP( );
79 if ( charset.getLength( ) )
81 OString osCharset(
82 charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
84 rtl_TextEncoding txtEnc =
85 rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
87 sal_uInt32 winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
89 CHARSETINFO chrsInf;
90 sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ?
91 sal_True : sal_False;
93 // if one of the above functions fails
94 // we will return the current ANSI codepage
95 // of this thread
96 if ( bRet )
97 winCP = chrsInf.ciACP;
100 return winCP;
103 //--------------------------------------------------
104 // returns a windows codepage appropriate to the
105 // given locale and locale type
106 //--------------------------------------------------
108 OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
110 OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
112 // we set an default value
113 OUString winCP;
115 // set an default value
116 if ( LOCALE_IDEFAULTCODEPAGE == lctype )
118 winCP = OUString::valueOf( static_cast<sal_Int32>(GetOEMCP( )), 10 );
120 else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
122 winCP = OUString::valueOf( static_cast<sal_Int32>(GetACP( )), 10 );
124 else
125 OSL_ASSERT( sal_False );
127 // we use the GetLocaleInfoA because don't want to provide
128 // a unicode wrapper function for Win9x in sal/systools
129 char buff[6];
130 sal_Int32 nResult = GetLocaleInfoA(
131 lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) );
133 OSL_ASSERT( nResult );
135 if ( nResult )
137 sal_Int32 len = MultiByteToWideChar(
138 CP_ACP, 0, buff, -1, NULL, 0 );
140 OSL_ASSERT( len > 0 );
142 std::auto_ptr< sal_Unicode > lpwchBuff( new sal_Unicode[len] );
144 if ( NULL != lpwchBuff.get( ) )
146 len = MultiByteToWideChar(
147 CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(lpwchBuff.get( )), len );
149 winCP = OUString( lpwchBuff.get( ), (len - 1) );
153 return winCP;
156 //--------------------------------------------------
157 // returns a mime charset parameter value appropriate
158 // to the given codepage, optional a prefix can be
159 // given, e.g. "windows-" or "cp"
160 //--------------------------------------------------
162 OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
164 return aPrefix + cptostr( cp );
167 //--------------------------------------------------
168 // returns a mime charset parameter value appropriate
169 // to the given locale id and locale type, optional a
170 // prefix can be given, e.g. "windows-" or "cp"
171 //--------------------------------------------------
173 OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix )
175 OUString charset = getWinCPFromLocaleId( lcid, lctype );
176 return aPrefix + charset;
179 //------------------------------------------------------------------------
180 // IsOEMCP
181 //------------------------------------------------------------------------
183 sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage )
185 OSL_ASSERT( IsValidCodePage( codepage ) );
187 sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
188 775, 850, 852, 855, 857, 860,
189 861, 862, 863, 864, 865, 866,
190 869, 874, 932, 936, 949, 950, 1361 };
192 for ( sal_Int8 i = 0; i < ( sizeof( arrOEMCP )/sizeof( sal_uInt32 ) ); ++i )
193 if ( arrOEMCP[i] == codepage )
194 return sal_True;
196 return sal_False;
199 //------------------------------------------------------------------------
200 // converts a codepage into its string representation
201 //------------------------------------------------------------------------
203 OUString SAL_CALL cptostr( sal_uInt32 codepage )
205 OSL_ASSERT( IsValidCodePage( codepage ) );
207 return OUString::valueOf( static_cast<sal_Int64>( codepage ), 10 );
210 //-------------------------------------------------------------------------
211 // OleStdDeleteTargetDevice()
213 // Purpose:
215 // Parameters:
217 // Return Value:
218 // SCODE - S_OK if successful
219 //-------------------------------------------------------------------------
221 void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd )
223 #ifdef __MINGW32__
224 jmp_buf jmpbuf;
225 __SEHandler han;
226 if (__builtin_setjmp(jmpbuf) == 0)
228 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
229 #else
230 __try
232 #endif
233 CoTaskMemFree( ptd );
235 #ifdef __MINGW32__
236 else
237 #else
238 __except( EXCEPTION_EXECUTE_HANDLER )
239 #endif
241 OSL_ENSURE( sal_False, "Error DeleteTargetDevice" );
243 #ifdef __MINGW32__
244 han.Reset();
245 #endif
250 //-------------------------------------------------------------------------
251 // OleStdCopyTargetDevice()
253 // Purpose:
254 // duplicate a TARGETDEVICE struct. this function allocates memory for
255 // the copy. the caller MUST free the allocated copy when done with it
256 // using the standard allocator returned from CoGetMalloc.
257 // (OleStdFree can be used to free the copy).
259 // Parameters:
260 // ptdSrc pointer to source TARGETDEVICE
262 // Return Value:
263 // pointer to allocated copy of ptdSrc
264 // if ptdSrc==NULL then retuns NULL is returned.
265 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
266 //-------------------------------------------------------------------------
268 DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
270 DVTARGETDEVICE* ptdDest = NULL;
272 #ifdef __MINGW32__
273 jmp_buf jmpbuf;
274 __SEHandler han;
275 if (__builtin_setjmp(jmpbuf) == 0)
277 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
278 #else
279 __try
281 #endif
282 if ( NULL != ptdSrc )
284 ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
285 rtl_copyMemory( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
288 #ifdef __MINGW32__
289 han.Reset();
290 #else
291 __except( EXCEPTION_EXECUTE_HANDLER )
294 #endif
296 return ptdDest;
300 //-------------------------------------------------------------------------
301 // OleStdCopyFormatEtc()
303 // Purpose:
304 // Copies the contents of a FORMATETC structure. this function takes
305 // special care to copy correctly copying the pointer to the TARGETDEVICE
306 // contained within the source FORMATETC structure.
307 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
308 // of the TARGETDEVICE will be allocated for the destination of the
309 // FORMATETC (petcDest).
311 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
312 // within the destination FORMATETC when done with it
313 // using the standard allocator returned from CoGetMalloc.
314 // (OleStdFree can be used to free the copy).
316 // Parameters:
317 // petcDest pointer to destination FORMATETC
318 // petcSrc pointer to source FORMATETC
320 // Return Value:
321 // returns TRUE if copy was successful;
322 // retuns FALSE if not successful, e.g. one or both of the pointers
323 // were invalid or the pointers were equal
324 //-------------------------------------------------------------------------
326 sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
328 sal_Bool bRet = sal_False;
330 #ifdef __MINGW32__
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 ( petcDest != petcSrc )
343 petcDest->cfFormat = petcSrc->cfFormat;
345 petcDest->ptd = NULL;
346 if ( NULL != petcSrc->ptd )
347 petcDest->ptd = CopyTargetDevice(petcSrc->ptd);
349 petcDest->dwAspect = petcSrc->dwAspect;
350 petcDest->lindex = petcSrc->lindex;
351 petcDest->tymed = petcSrc->tymed;
353 bRet = sal_True;
356 #ifdef __MINGW32__
357 else
358 #else
359 __except( EXCEPTION_EXECUTE_HANDLER )
360 #endif
362 OSL_ENSURE( sal_False, "Error CopyFormatEtc" );
364 #ifdef __MINGW32__
365 han.Reset();
366 #endif
368 return bRet;
371 //-------------------------------------------------------------------------
372 // returns:
373 // 1 for exact match,
374 // 0 for no match,
375 // -1 for partial match (which is defined to mean the left is a subset
376 // of the right: fewer aspects, null target device, fewer medium).
377 //-------------------------------------------------------------------------
379 sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
381 sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
383 #ifdef __MINGW32__
384 jmp_buf jmpbuf;
385 __SEHandler han;
386 if (__builtin_setjmp(jmpbuf) == 0)
388 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
389 #else
390 __try
392 #endif
393 if ( pFetcLhs != pFetcRhs )
395 if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
396 ( pFetcLhs->lindex != pFetcRhs->lindex ) ||
397 !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
399 nMatch = FORMATETC_NO_MATCH;
402 else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
403 // same aspects; equal
405 else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
407 // left not subset of aspects of right; not equal
408 nMatch = FORMATETC_NO_MATCH;
410 else
411 // left subset of right
412 nMatch = FORMATETC_PARTIAL_MATCH;
414 if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
416 if ( pFetcLhs->tymed == pFetcRhs->tymed )
417 // same medium flags; equal
419 else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
421 // left not subset of medium flags of right; not equal
422 nMatch = FORMATETC_NO_MATCH;
424 else
425 // left subset of right
426 nMatch = FORMATETC_PARTIAL_MATCH;
429 #ifdef __MINGW32__
430 else
431 #else
432 __except( EXCEPTION_EXECUTE_HANDLER )
433 #endif
435 OSL_ENSURE( sal_False, "Error CompareFormatEtc" );
436 nMatch = FORMATETC_NO_MATCH;
438 #ifdef __MINGW32__
439 han.Reset();
440 #endif
442 return nMatch;
446 //-------------------------------------------------------------------------
448 //-------------------------------------------------------------------------
450 sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight )
452 sal_Bool bRet = sal_False;
454 #ifdef __MINGW32__
455 jmp_buf jmpbuf;
456 __SEHandler han;
457 if (__builtin_setjmp(jmpbuf) == 0)
459 han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
460 #else
461 __try
463 #endif
464 if ( ptdLeft == ptdRight )
466 // same address of td; must be same (handles NULL case)
467 bRet = sal_True;
470 // one ot the two is NULL
471 else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) )
473 if ( ptdLeft->tdSize == ptdRight->tdSize )
475 if ( rtl_compareMemory( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
476 bRet = sal_True;
478 #ifdef __MINGW32__
479 else
480 #else
481 __except( EXCEPTION_EXECUTE_HANDLER )
482 #endif
484 OSL_ENSURE( sal_False, "Error CompareTargetDevice" );
485 bRet = sal_False;
487 #ifdef __MINGW32__
488 han.Reset();
489 #endif
491 return bRet;