1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ImplHelper.cxx,v $
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 //------------------------------------------------------------------------
37 //------------------------------------------------------------------------
38 #include <osl/diagnose.h>
39 #include "ImplHelper.hxx"
40 #include <rtl/tencinfo.h>
41 #include <rtl/memory.h>
45 #pragma warning(push,1)
55 //------------------------------------------------------------------------
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
;
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( ) )
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
);
90 sal_Bool bRet
= TranslateCharsetInfo( (DWORD
*)winChrs
, &chrsInf
, TCI_SRCCHARSET
) ?
93 // if one of the above functions fails
94 // we will return the current ANSI codepage
97 winCP
= chrsInf
.ciACP
;
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
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 );
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
130 sal_Int32 nResult
= GetLocaleInfoA(
131 lcid
, lctype
| LOCALE_USE_CP_ACP
, buff
, sizeof( buff
) );
133 OSL_ASSERT( 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) );
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 //------------------------------------------------------------------------
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
)
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()
218 // SCODE - S_OK if successful
219 //-------------------------------------------------------------------------
221 void SAL_CALL
DeleteTargetDevice( DVTARGETDEVICE
* ptd
)
226 if (__builtin_setjmp(jmpbuf
) == 0)
228 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
233 CoTaskMemFree( ptd
);
238 __except( EXCEPTION_EXECUTE_HANDLER
)
241 OSL_ENSURE( sal_False
, "Error DeleteTargetDevice" );
250 //-------------------------------------------------------------------------
251 // OleStdCopyTargetDevice()
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).
260 // ptdSrc pointer to source TARGETDEVICE
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
;
275 if (__builtin_setjmp(jmpbuf
) == 0)
277 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
282 if ( NULL
!= ptdSrc
)
284 ptdDest
= static_cast< DVTARGETDEVICE
* >( CoTaskMemAlloc( ptdSrc
->tdSize
) );
285 rtl_copyMemory( ptdDest
, ptdSrc
, static_cast< size_t >( ptdSrc
->tdSize
) );
291 __except( EXCEPTION_EXECUTE_HANDLER
)
300 //-------------------------------------------------------------------------
301 // OleStdCopyFormatEtc()
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).
317 // petcDest pointer to destination FORMATETC
318 // petcSrc pointer to source FORMATETC
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
;
333 if (__builtin_setjmp(jmpbuf
) == 0)
335 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
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
;
359 __except( EXCEPTION_EXECUTE_HANDLER
)
362 OSL_ENSURE( sal_False
, "Error CopyFormatEtc" );
371 //-------------------------------------------------------------------------
373 // 1 for exact 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
;
386 if (__builtin_setjmp(jmpbuf
) == 0)
388 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
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
;
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
;
425 // left subset of right
426 nMatch
= FORMATETC_PARTIAL_MATCH
;
432 __except( EXCEPTION_EXECUTE_HANDLER
)
435 OSL_ENSURE( sal_False
, "Error CompareFormatEtc" );
436 nMatch
= FORMATETC_NO_MATCH
;
446 //-------------------------------------------------------------------------
448 //-------------------------------------------------------------------------
450 sal_Bool SAL_CALL
CompareTargetDevice( DVTARGETDEVICE
* ptdLeft
, DVTARGETDEVICE
* ptdRight
)
452 sal_Bool bRet
= sal_False
;
457 if (__builtin_setjmp(jmpbuf
) == 0)
459 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
464 if ( ptdLeft
== ptdRight
)
466 // same address of td; must be same (handles NULL case)
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 )
481 __except( EXCEPTION_EXECUTE_HANDLER
)
484 OSL_ENSURE( sal_False
, "Error CompareTargetDevice" );