Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / dtrans / source / win32 / misc / ImplHelper.cxx
blob0e38b9183d829ff33a3bf6828188c63b3cd63576
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 <o3tl/char16_t2wchar_t.hxx>
24 #include <string.h>
25 #include <memory>
27 #if !defined WIN32_LEAN_AND_MEAN
28 # define WIN32_LEAN_AND_MEAN
29 #endif
30 #include <windows.h>
32 #include <vector>
34 #define FORMATETC_EXACT_MATCH 1
35 #define FORMATETC_PARTIAL_MATCH -1
36 #define FORMATETC_NO_MATCH 0
38 // returns a windows codepage appropriate to the
39 // given mime charset parameter value
41 sal_uInt32 getWinCPFromMimeCharset( const OUString& charset )
43 sal_uInt32 winCP = GetACP( );
45 if ( charset.getLength( ) )
47 OString osCharset(
48 charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
50 rtl_TextEncoding txtEnc =
51 rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
53 sal_uIntPtr winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
55 CHARSETINFO chrsInf;
56 bool bRet = TranslateCharsetInfo( reinterpret_cast<DWORD*>(winChrs), &chrsInf, TCI_SRCCHARSET );
58 // if one of the above functions fails
59 // we will return the current ANSI codepage
60 // of this thread
61 if ( bRet )
62 winCP = chrsInf.ciACP;
65 return winCP;
68 // returns a windows codepage appropriate to the
69 // given locale and locale type
71 OUString getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
73 OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
75 // we set a default value
76 OUString winCP;
78 // set a default value
79 if ( LOCALE_IDEFAULTCODEPAGE == lctype )
81 winCP = OUString::number( static_cast<sal_Int32>(GetOEMCP( )) );
83 else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
85 winCP = OUString::number( static_cast<sal_Int32>(GetACP( )) );
87 else
88 OSL_ASSERT( false );
90 // First, get required buffer size, in characters
91 int nResult = GetLocaleInfoW(
92 lcid, lctype, nullptr, 0 );
94 OSL_ASSERT( nResult );
96 if ( nResult )
98 std::unique_ptr<wchar_t[]> buff( new wchar_t[nResult] );
99 // Now get the actual data
100 nResult = GetLocaleInfoW( lcid, lctype, buff.get(), nResult );
102 OSL_ASSERT(nResult);
104 if (nResult)
105 winCP = o3tl::toU( buff.get() );
109 return winCP;
112 // returns a mime charset parameter value appropriate
113 // to the given codepage, optional a prefix can be
114 // given, e.g. "windows-" or "cp"
116 OUString getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
118 return aPrefix + cptostr( cp );
121 // returns a mime charset parameter value appropriate
122 // to the given locale id and locale type, optional a
123 // prefix can be given, e.g. "windows-" or "cp"
125 OUString getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix )
127 OUString charset = getWinCPFromLocaleId( lcid, lctype );
128 return aPrefix + charset;
131 // IsOEMCP
133 bool IsOEMCP( sal_uInt32 codepage )
135 OSL_ASSERT( IsValidCodePage( codepage ) );
137 sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
138 775, 850, 852, 855, 857, 860,
139 861, 862, 863, 864, 865, 866,
140 869, 874, 932, 936, 949, 950, 1361 };
142 for ( size_t i = 0; i < SAL_N_ELEMENTS( arrOEMCP ); ++i )
143 if ( arrOEMCP[i] == codepage )
144 return true;
146 return false;
149 // converts a codepage into its string representation
151 OUString cptostr( sal_uInt32 codepage )
153 OSL_ASSERT( IsValidCodePage( codepage ) );
155 return OUString::number( static_cast<sal_Int64>( codepage ) );
158 // OleStdDeleteTargetDevice()
160 // Purpose:
162 // Parameters:
164 // Return Value:
165 // SCODE - S_OK if successful
166 void DeleteTargetDevice( DVTARGETDEVICE* ptd )
168 __try
170 CoTaskMemFree( ptd );
172 __except( EXCEPTION_EXECUTE_HANDLER )
174 OSL_FAIL( "Error DeleteTargetDevice" );
178 // OleStdCopyTargetDevice()
180 // Purpose:
181 // duplicate a TARGETDEVICE struct. this function allocates memory for
182 // the copy. the caller MUST free the allocated copy when done with it
183 // using the standard allocator returned from CoGetMalloc.
184 // (OleStdFree can be used to free the copy).
186 // Parameters:
187 // ptdSrc pointer to source TARGETDEVICE
189 // Return Value:
190 // pointer to allocated copy of ptdSrc
191 // if ptdSrc==NULL then returns NULL is returned.
192 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
193 DVTARGETDEVICE* CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
195 DVTARGETDEVICE* ptdDest = nullptr;
197 __try
199 if ( nullptr != ptdSrc )
201 ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
202 memcpy( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
205 __except( EXCEPTION_EXECUTE_HANDLER )
209 return ptdDest;
212 // OleStdCopyFormatEtc()
214 // Purpose:
215 // Copies the contents of a FORMATETC structure. this function takes
216 // special care to copy correctly copying the pointer to the TARGETDEVICE
217 // contained within the source FORMATETC structure.
218 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
219 // of the TARGETDEVICE will be allocated for the destination of the
220 // FORMATETC (petcDest).
222 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
223 // within the destination FORMATETC when done with it
224 // using the standard allocator returned from CoGetMalloc.
225 // (OleStdFree can be used to free the copy).
227 // Parameters:
228 // petcDest pointer to destination FORMATETC
229 // petcSrc pointer to source FORMATETC
231 // Return Value:
232 // returns TRUE if copy was successful;
233 // returns FALSE if not successful, e.g. one or both of the pointers
234 // were invalid or the pointers were equal
235 bool CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
237 bool bRet = false;
239 __try
241 if ( petcDest != petcSrc )
244 petcDest->cfFormat = petcSrc->cfFormat;
246 petcDest->ptd = nullptr;
247 if ( nullptr != petcSrc->ptd )
248 petcDest->ptd = CopyTargetDevice(petcSrc->ptd);
250 petcDest->dwAspect = petcSrc->dwAspect;
251 petcDest->lindex = petcSrc->lindex;
252 petcDest->tymed = petcSrc->tymed;
254 bRet = true;
257 __except( EXCEPTION_EXECUTE_HANDLER )
259 OSL_FAIL( "Error CopyFormatEtc" );
262 return bRet;
265 // returns:
266 // 1 for exact match,
267 // 0 for no match,
268 // -1 for partial match (which is defined to mean the left is a subset
269 // of the right: fewer aspects, null target device, fewer medium).
271 sal_Int32 CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
273 sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
275 __try
277 if ( pFetcLhs != pFetcRhs )
279 if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
280 ( pFetcLhs->lindex != pFetcRhs->lindex ) ||
281 !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
283 nMatch = FORMATETC_NO_MATCH;
286 else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
287 // same aspects; equal
289 else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
291 // left not subset of aspects of right; not equal
292 nMatch = FORMATETC_NO_MATCH;
294 else
295 // left subset of right
296 nMatch = FORMATETC_PARTIAL_MATCH;
298 if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
300 if ( pFetcLhs->tymed == pFetcRhs->tymed )
301 // same medium flags; equal
303 else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
305 // left not subset of medium flags of right; not equal
306 nMatch = FORMATETC_NO_MATCH;
308 else
309 // left subset of right
310 nMatch = FORMATETC_PARTIAL_MATCH;
314 __except( EXCEPTION_EXECUTE_HANDLER )
316 OSL_FAIL( "Error CompareFormatEtc" );
317 nMatch = FORMATETC_NO_MATCH;
320 return nMatch;
323 bool CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE const * ptdRight )
325 bool bRet = false;
327 __try
329 if ( ptdLeft == ptdRight )
331 // same address of td; must be same (handles NULL case)
332 bRet = true;
335 // one of the two is NULL
336 else if ( ( nullptr != ptdRight ) && ( nullptr != ptdLeft ) )
338 if ( ptdLeft->tdSize == ptdRight->tdSize )
340 if ( memcmp( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
341 bRet = true;
343 __except( EXCEPTION_EXECUTE_HANDLER )
345 OSL_FAIL( "Error CompareTargetDevice" );
346 bRet = false;
349 return bRet;
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */