blob: 9f1d6311706a1b74917a0b703621630f5cddbba9 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dtrans.hxx"
//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------
#include <osl/diagnose.h>
#include "ImplHelper.hxx"
#include <rtl/tencinfo.h>
#include <rtl/memory.h>
#include <memory>
#if defined _MSC_VER
#pragma warning(push,1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#ifdef __MINGW32__
#include <excpt.h>
#endif
//------------------------------------------------------------------------
// defines
//------------------------------------------------------------------------
#define FORMATETC_EXACT_MATCH 1
#define FORMATETC_PARTIAL_MATCH -1
#define FORMATETC_NO_MATCH 0
//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------
using ::rtl::OUString;
using ::rtl::OString;
//------------------------------------------------------------------------
// returns a windows codepage appropriate to the
// given mime charset parameter value
//------------------------------------------------------------------------
sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset )
{
sal_uInt32 winCP = GetACP( );
if ( charset.getLength( ) )
{
OString osCharset(
charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
rtl_TextEncoding txtEnc =
rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
sal_uInt32 winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
CHARSETINFO chrsInf;
sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ?
sal_True : sal_False;
// if one of the above functions fails
// we will return the current ANSI codepage
// of this thread
if ( bRet )
winCP = chrsInf.ciACP;
}
return winCP;
}
//--------------------------------------------------
// returns a windows codepage appropriate to the
// given locale and locale type
//--------------------------------------------------
OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
{
OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
// we set an default value
OUString winCP;
// set an default value
if ( LOCALE_IDEFAULTCODEPAGE == lctype )
{
winCP = OUString::valueOf( static_cast<sal_Int32>(GetOEMCP( )), 10 );
}
else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
{
winCP = OUString::valueOf( static_cast<sal_Int32>(GetACP( )), 10 );
}
else
OSL_ASSERT( sal_False );
// we use the GetLocaleInfoA because don't want to provide
// a unicode wrapper function for Win9x in sal/systools
char buff[6];
sal_Int32 nResult = GetLocaleInfoA(
lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) );
OSL_ASSERT( nResult );
if ( nResult )
{
sal_Int32 len = MultiByteToWideChar(
CP_ACP, 0, buff, -1, NULL, 0 );
OSL_ASSERT( len > 0 );
std::auto_ptr< sal_Unicode > lpwchBuff( new sal_Unicode[len] );
if ( NULL != lpwchBuff.get( ) )
{
len = MultiByteToWideChar(
CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(lpwchBuff.get( )), len );
winCP = OUString( lpwchBuff.get( ), (len - 1) );
}
}
return winCP;
}
//--------------------------------------------------
// returns a mime charset parameter value appropriate
// to the given codepage, optional a prefix can be
// given, e.g. "windows-" or "cp"
//--------------------------------------------------
OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
{
return aPrefix + cptostr( cp );
}
//--------------------------------------------------
// returns a mime charset parameter value appropriate
// to the given locale id and locale type, optional a
// prefix can be given, e.g. "windows-" or "cp"
//--------------------------------------------------
OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix )
{
OUString charset = getWinCPFromLocaleId( lcid, lctype );
return aPrefix + charset;
}
//------------------------------------------------------------------------
// IsOEMCP
//------------------------------------------------------------------------
sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage )
{
OSL_ASSERT( IsValidCodePage( codepage ) );
sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
775, 850, 852, 855, 857, 860,
861, 862, 863, 864, 865, 866,
869, 874, 932, 936, 949, 950, 1361 };
for ( sal_Int8 i = 0; i < ( sizeof( arrOEMCP )/sizeof( sal_uInt32 ) ); ++i )
if ( arrOEMCP[i] == codepage )
return sal_True;
return sal_False;
}
//------------------------------------------------------------------------
// converts a codepage into its string representation
//------------------------------------------------------------------------
OUString SAL_CALL cptostr( sal_uInt32 codepage )
{
OSL_ASSERT( IsValidCodePage( codepage ) );
return OUString::valueOf( static_cast<sal_Int64>( codepage ), 10 );
}
//-------------------------------------------------------------------------
// OleStdDeleteTargetDevice()
//
// Purpose:
//
// Parameters:
//
// Return Value:
// SCODE - S_OK if successful
//-------------------------------------------------------------------------
void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd )
{
#ifdef __MINGW32__
jmp_buf jmpbuf;
__SEHandler han;
if (__builtin_setjmp(jmpbuf) == 0)
{
han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
__try
{
#endif
CoTaskMemFree( ptd );
}
#ifdef __MINGW32__
else
#else
__except( EXCEPTION_EXECUTE_HANDLER )
#endif
{
OSL_ENSURE( sal_False, "Error DeleteTargetDevice" );
}
#ifdef __MINGW32__
han.Reset();
#endif
}
//-------------------------------------------------------------------------
// OleStdCopyTargetDevice()
//
// Purpose:
// duplicate a TARGETDEVICE struct. this function allocates memory for
// the copy. the caller MUST free the allocated copy when done with it
// using the standard allocator returned from CoGetMalloc.
// (OleStdFree can be used to free the copy).
//
// Parameters:
// ptdSrc pointer to source TARGETDEVICE
//
// Return Value:
// pointer to allocated copy of ptdSrc
// if ptdSrc==NULL then retuns NULL is returned.
// if ptdSrc!=NULL and memory allocation fails, then NULL is returned
//-------------------------------------------------------------------------
DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
{
DVTARGETDEVICE* ptdDest = NULL;
#ifdef __MINGW32__
jmp_buf jmpbuf;
__SEHandler han;
if (__builtin_setjmp(jmpbuf) == 0)
{
han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
__try
{
#endif
if ( NULL != ptdSrc )
{
ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
rtl_copyMemory( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
}
}
#ifdef __MINGW32__
han.Reset();
#else
__except( EXCEPTION_EXECUTE_HANDLER )
{
}
#endif
return ptdDest;
}
//-------------------------------------------------------------------------
// OleStdCopyFormatEtc()
//
// Purpose:
// Copies the contents of a FORMATETC structure. this function takes
// special care to copy correctly copying the pointer to the TARGETDEVICE
// contained within the source FORMATETC structure.
// if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
// of the TARGETDEVICE will be allocated for the destination of the
// FORMATETC (petcDest).
//
// NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
// within the destination FORMATETC when done with it
// using the standard allocator returned from CoGetMalloc.
// (OleStdFree can be used to free the copy).
//
// Parameters:
// petcDest pointer to destination FORMATETC
// petcSrc pointer to source FORMATETC
//
// Return Value:
// returns TRUE if copy was successful;
// retuns FALSE if not successful, e.g. one or both of the pointers
// were invalid or the pointers were equal
//-------------------------------------------------------------------------
sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
{
sal_Bool bRet = sal_False;
#ifdef __MINGW32__
jmp_buf jmpbuf;
__SEHandler han;
if (__builtin_setjmp(jmpbuf) == 0)
{
han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
__try
{
#endif
if ( petcDest != petcSrc )
{
petcDest->cfFormat = petcSrc->cfFormat;
petcDest->ptd = NULL;
if ( NULL != petcSrc->ptd )
petcDest->ptd = CopyTargetDevice(petcSrc->ptd);
petcDest->dwAspect = petcSrc->dwAspect;
petcDest->lindex = petcSrc->lindex;
petcDest->tymed = petcSrc->tymed;
bRet = sal_True;
}
}
#ifdef __MINGW32__
else
#else
__except( EXCEPTION_EXECUTE_HANDLER )
#endif
{
OSL_ENSURE( sal_False, "Error CopyFormatEtc" );
}
#ifdef __MINGW32__
han.Reset();
#endif
return bRet;
}
//-------------------------------------------------------------------------
// returns:
// 1 for exact match,
// 0 for no match,
// -1 for partial match (which is defined to mean the left is a subset
// of the right: fewer aspects, null target device, fewer medium).
//-------------------------------------------------------------------------
sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
{
sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
#ifdef __MINGW32__
jmp_buf jmpbuf;
__SEHandler han;
if (__builtin_setjmp(jmpbuf) == 0)
{
han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
__try
{
#endif
if ( pFetcLhs != pFetcRhs )
if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
( pFetcLhs->lindex != pFetcRhs->lindex ) ||
!CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
{
nMatch = FORMATETC_NO_MATCH;
}
else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
// same aspects; equal
;
else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
{
// left not subset of aspects of right; not equal
nMatch = FORMATETC_NO_MATCH;
}
else
// left subset of right
nMatch = FORMATETC_PARTIAL_MATCH;
if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
{
if ( pFetcLhs->tymed == pFetcRhs->tymed )
// same medium flags; equal
;
else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
{
// left not subset of medium flags of right; not equal
nMatch = FORMATETC_NO_MATCH;
}
else
// left subset of right
nMatch = FORMATETC_PARTIAL_MATCH;
}
}
#ifdef __MINGW32__
else
#else
__except( EXCEPTION_EXECUTE_HANDLER )
#endif
{
OSL_ENSURE( sal_False, "Error CompareFormatEtc" );
nMatch = FORMATETC_NO_MATCH;
}
#ifdef __MINGW32__
han.Reset();
#endif
return nMatch;
}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight )
{
sal_Bool bRet = sal_False;
#ifdef __MINGW32__
jmp_buf jmpbuf;
__SEHandler han;
if (__builtin_setjmp(jmpbuf) == 0)
{
han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
#else
__try
{
#endif
if ( ptdLeft == ptdRight )
{
// same address of td; must be same (handles NULL case)
bRet = sal_True;
}
// one ot the two is NULL
else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) )
if ( ptdLeft->tdSize == ptdRight->tdSize )
if ( rtl_compareMemory( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
bRet = sal_True;
}
#ifdef __MINGW32__
else
#else
__except( EXCEPTION_EXECUTE_HANDLER )
#endif
{
OSL_ENSURE( sal_False, "Error CompareTargetDevice" );
bRet = sal_False;
}
#ifdef __MINGW32__
han.Reset();
#endif
return bRet;
}