Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / dtrans / source / win32 / misc / ImplHelper.cxx
blobe4e8d1cb0ba7545ec405cc0111c3699983ee4eda
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 #define FORMATETC_EXACT_MATCH 1
37 #define FORMATETC_PARTIAL_MATCH -1
38 #define FORMATETC_NO_MATCH 0
40 // returns a windows codepage appropriate to the
41 // given mime charset parameter value
43 sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset )
45 sal_uInt32 winCP = GetACP( );
47 if ( charset.getLength( ) )
49 OString osCharset(
50 charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
52 rtl_TextEncoding txtEnc =
53 rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
55 sal_uIntPtr winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
57 CHARSETINFO chrsInf;
58 bool bRet = TranslateCharsetInfo( reinterpret_cast<DWORD*>(winChrs), &chrsInf, TCI_SRCCHARSET );
60 // if one of the above functions fails
61 // we will return the current ANSI codepage
62 // of this thread
63 if ( bRet )
64 winCP = chrsInf.ciACP;
67 return winCP;
70 // returns a windows codepage appropriate to the
71 // given locale and locale type
73 OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
75 OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
77 // we set an default value
78 OUString winCP;
80 // set an default value
81 if ( LOCALE_IDEFAULTCODEPAGE == lctype )
83 winCP = OUString::number( static_cast<sal_Int32>(GetOEMCP( )) );
85 else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
87 winCP = OUString::number( static_cast<sal_Int32>(GetACP( )) );
89 else
90 OSL_ASSERT( false );
92 // we use the GetLocaleInfoA because don't want to provide
93 // a unicode wrapper function for Win9x in sal/systools
94 char buff[6];
95 sal_Int32 nResult = GetLocaleInfoA(
96 lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) );
98 OSL_ASSERT( nResult );
100 if ( nResult )
102 sal_Int32 len = MultiByteToWideChar(
103 CP_ACP, 0, buff, -1, nullptr, 0 );
105 OSL_ASSERT( len > 0 );
107 std::vector< sal_Unicode > lpwchBuff(len);
109 len = MultiByteToWideChar(
110 CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(&lpwchBuff[0]), len );
112 winCP = OUString( &lpwchBuff[0], (len - 1) );
115 return winCP;
118 // returns a mime charset parameter value appropriate
119 // to the given codepage, optional a prefix can be
120 // given, e.g. "windows-" or "cp"
122 OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
124 return aPrefix + cptostr( cp );
127 // returns a mime charset parameter value appropriate
128 // to the given locale id and locale type, optional a
129 // prefix can be given, e.g. "windows-" or "cp"
131 OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix )
133 OUString charset = getWinCPFromLocaleId( lcid, lctype );
134 return aPrefix + charset;
137 // IsOEMCP
139 bool SAL_CALL IsOEMCP( sal_uInt32 codepage )
141 OSL_ASSERT( IsValidCodePage( codepage ) );
143 sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
144 775, 850, 852, 855, 857, 860,
145 861, 862, 863, 864, 865, 866,
146 869, 874, 932, 936, 949, 950, 1361 };
148 for ( size_t i = 0; i < SAL_N_ELEMENTS( arrOEMCP ); ++i )
149 if ( arrOEMCP[i] == codepage )
150 return true;
152 return false;
155 // converts a codepage into its string representation
157 OUString SAL_CALL cptostr( sal_uInt32 codepage )
159 OSL_ASSERT( IsValidCodePage( codepage ) );
161 return OUString::number( static_cast<sal_Int64>( codepage ) );
164 // OleStdDeleteTargetDevice()
166 // Purpose:
168 // Parameters:
170 // Return Value:
171 // SCODE - S_OK if successful
172 void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd )
174 __try
176 CoTaskMemFree( ptd );
178 __except( EXCEPTION_EXECUTE_HANDLER )
180 OSL_FAIL( "Error DeleteTargetDevice" );
184 // OleStdCopyTargetDevice()
186 // Purpose:
187 // duplicate a TARGETDEVICE struct. this function allocates memory for
188 // the copy. the caller MUST free the allocated copy when done with it
189 // using the standard allocator returned from CoGetMalloc.
190 // (OleStdFree can be used to free the copy).
192 // Parameters:
193 // ptdSrc pointer to source TARGETDEVICE
195 // Return Value:
196 // pointer to allocated copy of ptdSrc
197 // if ptdSrc==NULL then returns NULL is returned.
198 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
199 DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
201 DVTARGETDEVICE* ptdDest = nullptr;
203 __try
205 if ( nullptr != ptdSrc )
207 ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
208 memcpy( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
211 __except( EXCEPTION_EXECUTE_HANDLER )
215 return ptdDest;
218 // OleStdCopyFormatEtc()
220 // Purpose:
221 // Copies the contents of a FORMATETC structure. this function takes
222 // special care to copy correctly copying the pointer to the TARGETDEVICE
223 // contained within the source FORMATETC structure.
224 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
225 // of the TARGETDEVICE will be allocated for the destination of the
226 // FORMATETC (petcDest).
228 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
229 // within the destination FORMATETC when done with it
230 // using the standard allocator returned from CoGetMalloc.
231 // (OleStdFree can be used to free the copy).
233 // Parameters:
234 // petcDest pointer to destination FORMATETC
235 // petcSrc pointer to source FORMATETC
237 // Return Value:
238 // returns TRUE if copy was successful;
239 // returns FALSE if not successful, e.g. one or both of the pointers
240 // were invalid or the pointers were equal
241 bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
243 bool bRet = false;
245 __try
247 if ( petcDest != petcSrc )
250 petcDest->cfFormat = petcSrc->cfFormat;
252 petcDest->ptd = nullptr;
253 if ( nullptr != petcSrc->ptd )
254 petcDest->ptd = CopyTargetDevice(petcSrc->ptd);
256 petcDest->dwAspect = petcSrc->dwAspect;
257 petcDest->lindex = petcSrc->lindex;
258 petcDest->tymed = petcSrc->tymed;
260 bRet = true;
263 __except( EXCEPTION_EXECUTE_HANDLER )
265 OSL_FAIL( "Error CopyFormatEtc" );
268 return bRet;
271 // returns:
272 // 1 for exact match,
273 // 0 for no match,
274 // -1 for partial match (which is defined to mean the left is a subset
275 // of the right: fewer aspects, null target device, fewer medium).
277 sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
279 sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
281 __try
283 if ( pFetcLhs != pFetcRhs )
285 if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
286 ( pFetcLhs->lindex != pFetcRhs->lindex ) ||
287 !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
289 nMatch = FORMATETC_NO_MATCH;
292 else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
293 // same aspects; equal
295 else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
297 // left not subset of aspects of right; not equal
298 nMatch = FORMATETC_NO_MATCH;
300 else
301 // left subset of right
302 nMatch = FORMATETC_PARTIAL_MATCH;
304 if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
306 if ( pFetcLhs->tymed == pFetcRhs->tymed )
307 // same medium flags; equal
309 else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
311 // left not subset of medium flags of right; not equal
312 nMatch = FORMATETC_NO_MATCH;
314 else
315 // left subset of right
316 nMatch = FORMATETC_PARTIAL_MATCH;
320 __except( EXCEPTION_EXECUTE_HANDLER )
322 OSL_FAIL( "Error CompareFormatEtc" );
323 nMatch = FORMATETC_NO_MATCH;
326 return nMatch;
329 bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight )
331 bool bRet = false;
333 __try
335 if ( ptdLeft == ptdRight )
337 // same address of td; must be same (handles NULL case)
338 bRet = true;
341 // one ot the two is NULL
342 else if ( ( nullptr != ptdRight ) && ( nullptr != ptdLeft ) )
344 if ( ptdLeft->tdSize == ptdRight->tdSize )
346 if ( memcmp( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
347 bRet = true;
349 __except( EXCEPTION_EXECUTE_HANDLER )
351 OSL_FAIL( "Error CompareTargetDevice" );
352 bRet = false;
355 return bRet;
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */