inetcomm: Implement IMimeInternational_GetCharsetInfo.
[wine.git] / dlls / inetcomm / mimeintl.c
blob2db5917e5f8bc2fc2d6bbee26d2da0e575cb9a9e
1 /*
2 * MIME OLE International interface
4 * Copyright 2008 Huw Davies for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define NONAMELESSUNION
24 #include <stdarg.h>
25 #include <stdio.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "objbase.h"
32 #include "ole2.h"
33 #include "mimeole.h"
34 #include "mlang.h"
36 #include "wine/list.h"
37 #include "wine/debug.h"
39 #include "inetcomm_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
43 typedef struct
45 struct list entry;
46 INETCSETINFO cs_info;
47 } charset_entry;
49 typedef struct
51 const IMimeInternationalVtbl *lpVtbl;
52 LONG refs;
53 CRITICAL_SECTION cs;
55 struct list charsets;
56 LONG next_charset_handle;
57 } internat;
59 static inline internat *impl_from_IMimeInternational( IMimeInternational *iface )
61 return (internat *)((char*)iface - FIELD_OFFSET(internat, lpVtbl));
64 static inline HRESULT get_mlang(IMultiLanguage **ml)
66 return CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
67 &IID_IMultiLanguage, (void **)ml);
70 static HRESULT WINAPI MimeInternat_QueryInterface( IMimeInternational *iface, REFIID riid, LPVOID *ppobj )
72 if (IsEqualGUID(riid, &IID_IUnknown) ||
73 IsEqualGUID(riid, &IID_IMimeInternational))
75 IMimeInternational_AddRef( iface );
76 *ppobj = iface;
77 return S_OK;
80 FIXME("interface %s not implemented\n", debugstr_guid(riid));
81 return E_NOINTERFACE;
84 static ULONG WINAPI MimeInternat_AddRef( IMimeInternational *iface )
86 internat *This = impl_from_IMimeInternational( iface );
87 return InterlockedIncrement(&This->refs);
90 static ULONG WINAPI MimeInternat_Release( IMimeInternational *iface )
92 internat *This = impl_from_IMimeInternational( iface );
93 ULONG refs;
95 refs = InterlockedDecrement(&This->refs);
96 if (!refs)
98 charset_entry *charset, *cursor2;
100 LIST_FOR_EACH_ENTRY_SAFE(charset, cursor2, &This->charsets, charset_entry, entry)
102 list_remove(&charset->entry);
103 HeapFree(GetProcessHeap(), 0, charset);
105 HeapFree(GetProcessHeap(), 0, This);
108 return refs;
111 static HRESULT WINAPI MimeInternat_SetDefaultCharset(IMimeInternational *iface, HCHARSET hCharset)
113 FIXME("stub\n");
114 return E_NOTIMPL;
117 static HRESULT WINAPI MimeInternat_GetDefaultCharset(IMimeInternational *iface, LPHCHARSET phCharset)
119 FIXME("stub\n");
120 return E_NOTIMPL;
123 static HRESULT WINAPI MimeInternat_GetCodePageCharset(IMimeInternational *iface, CODEPAGEID cpiCodePage,
124 CHARSETTYPE ctCsetType,
125 LPHCHARSET phCharset)
127 FIXME("stub\n");
128 return E_NOTIMPL;
131 static HRESULT mlang_getcsetinfo(const char *charset, MIMECSETINFO *mlang_info)
133 DWORD len = MultiByteToWideChar(CP_ACP, 0, charset, -1, NULL, 0);
134 BSTR bstr = SysAllocStringLen(NULL, len - 1);
135 HRESULT hr;
136 IMultiLanguage *ml;
138 MultiByteToWideChar(CP_ACP, 0, charset, -1, bstr, len);
140 hr = get_mlang(&ml);
142 if(SUCCEEDED(hr))
144 hr = IMultiLanguage_GetCharsetInfo(ml, bstr, mlang_info);
145 IMultiLanguage_Release(ml);
147 SysFreeString(bstr);
148 if(FAILED(hr)) hr = MIME_E_NOT_FOUND;
149 return hr;
152 static HCHARSET add_charset(struct list *list, MIMECSETINFO *mlang_info, HCHARSET handle)
154 charset_entry *charset = HeapAlloc(GetProcessHeap(), 0, sizeof(*charset));
156 WideCharToMultiByte(CP_ACP, 0, mlang_info->wszCharset, -1,
157 charset->cs_info.szName, sizeof(charset->cs_info.szName), NULL, NULL);
158 charset->cs_info.cpiWindows = mlang_info->uiCodePage;
159 charset->cs_info.cpiInternet = mlang_info->uiInternetEncoding;
160 charset->cs_info.hCharset = handle;
161 charset->cs_info.dwReserved1 = 0;
162 list_add_head(list, &charset->entry);
164 return charset->cs_info.hCharset;
167 static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR pszCharset,
168 LPHCHARSET phCharset)
170 internat *This = impl_from_IMimeInternational( iface );
171 HRESULT hr = MIME_E_NOT_FOUND;
172 charset_entry *charset;
174 TRACE("(%p)->(%s, %p)\n", iface, debugstr_a(pszCharset), phCharset);
176 *phCharset = NULL;
178 EnterCriticalSection(&This->cs);
180 LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry)
182 if(!strcmp(charset->cs_info.szName, pszCharset))
184 *phCharset = charset->cs_info.hCharset;
185 hr = S_OK;
186 break;
190 if(hr == MIME_E_NOT_FOUND)
192 MIMECSETINFO mlang_info;
194 LeaveCriticalSection(&This->cs);
195 hr = mlang_getcsetinfo(pszCharset, &mlang_info);
196 EnterCriticalSection(&This->cs);
198 if(SUCCEEDED(hr))
199 *phCharset = add_charset(&This->charsets, &mlang_info,
200 (HCHARSET)InterlockedIncrement(&This->next_charset_handle));
203 LeaveCriticalSection(&This->cs);
204 return hr;
207 static HRESULT WINAPI MimeInternat_GetCharsetInfo(IMimeInternational *iface, HCHARSET hCharset,
208 LPINETCSETINFO pCsetInfo)
210 internat *This = impl_from_IMimeInternational( iface );
211 HRESULT hr = MIME_E_INVALID_HANDLE;
212 charset_entry *charset;
214 TRACE("(%p)->(%p, %p)\n", iface, hCharset, pCsetInfo);
216 EnterCriticalSection(&This->cs);
218 LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry)
220 if(charset->cs_info.hCharset == hCharset)
222 *pCsetInfo = charset->cs_info;
223 hr = S_OK;
224 break;
228 LeaveCriticalSection(&This->cs);
230 return hr;
233 static HRESULT WINAPI MimeInternat_GetCodePageInfo(IMimeInternational *iface, CODEPAGEID cpiCodePage,
234 LPCODEPAGEINFO pCodePageInfo)
236 FIXME("stub\n");
237 return E_NOTIMPL;
240 static HRESULT WINAPI MimeInternat_DecodeHeader(IMimeInternational *iface, HCHARSET hCharset,
241 LPCSTR pszData,
242 LPPROPVARIANT pDecoded,
243 LPRFC1522INFO pRfc1522Info)
245 FIXME("stub\n");
246 return E_NOTIMPL;
249 static HRESULT WINAPI MimeInternat_EncodeHeader(IMimeInternational *iface, HCHARSET hCharset,
250 LPPROPVARIANT pData,
251 LPSTR *ppszEncoded,
252 LPRFC1522INFO pRfc1522Info)
254 FIXME("stub\n");
255 return E_NOTIMPL;
258 static HRESULT WINAPI MimeInternat_ConvertBuffer(IMimeInternational *iface, CODEPAGEID cpiSource,
259 CODEPAGEID cpiDest,
260 LPBLOB pIn,
261 LPBLOB pOut,
262 ULONG *pcbRead)
264 FIXME("stub\n");
265 return E_NOTIMPL;
268 static HRESULT WINAPI MimeInternat_ConvertString(IMimeInternational *iface, CODEPAGEID cpiSource,
269 CODEPAGEID cpiDest,
270 LPPROPVARIANT pIn,
271 LPPROPVARIANT pOut)
273 FIXME("stub\n");
274 return E_NOTIMPL;
277 static HRESULT WINAPI MimeInternat_MLANG_ConvertInetReset(IMimeInternational *iface)
279 FIXME("stub\n");
280 return E_NOTIMPL;
283 static HRESULT WINAPI MimeInternat_MLANG_ConvertInetString(IMimeInternational *iface, CODEPAGEID cpiSource,
284 CODEPAGEID cpiDest,
285 LPCSTR pSource,
286 int *pnSizeOfSource,
287 LPSTR pDestination,
288 int *pnDstSize)
290 FIXME("stub\n");
291 return E_NOTIMPL;
294 static HRESULT WINAPI MimeInternat_Rfc1522Decode(IMimeInternational *iface, LPCSTR pszValue,
295 LPCSTR pszCharset,
296 ULONG cchmax,
297 LPSTR *ppszDecoded)
299 FIXME("stub\n");
300 return E_NOTIMPL;
303 static HRESULT WINAPI MimeInternat_Rfc1522Encode(IMimeInternational *iface, LPCSTR pszValue,
304 HCHARSET hCharset,
305 LPSTR *ppszEncoded)
307 FIXME("stub\n");
308 return E_NOTIMPL;
311 static IMimeInternationalVtbl mime_internat_vtbl =
313 MimeInternat_QueryInterface,
314 MimeInternat_AddRef,
315 MimeInternat_Release,
316 MimeInternat_SetDefaultCharset,
317 MimeInternat_GetDefaultCharset,
318 MimeInternat_GetCodePageCharset,
319 MimeInternat_FindCharset,
320 MimeInternat_GetCharsetInfo,
321 MimeInternat_GetCodePageInfo,
322 MimeInternat_DecodeHeader,
323 MimeInternat_EncodeHeader,
324 MimeInternat_ConvertBuffer,
325 MimeInternat_ConvertString,
326 MimeInternat_MLANG_ConvertInetReset,
327 MimeInternat_MLANG_ConvertInetString,
328 MimeInternat_Rfc1522Decode,
329 MimeInternat_Rfc1522Encode
332 static internat *global_internat;
334 HRESULT MimeInternational_Construct(IMimeInternational **internat)
336 global_internat = HeapAlloc(GetProcessHeap(), 0, sizeof(*global_internat));
337 global_internat->lpVtbl = &mime_internat_vtbl;
338 global_internat->refs = 0;
339 InitializeCriticalSection(&global_internat->cs);
341 list_init(&global_internat->charsets);
342 global_internat->next_charset_handle = 0;
344 *internat = (IMimeInternational*)&global_internat->lpVtbl;
346 IMimeInternational_AddRef(*internat);
347 return S_OK;
350 HRESULT WINAPI MimeOleGetInternat(IMimeInternational **internat)
352 TRACE("(%p)\n", internat);
354 *internat = (IMimeInternational *)&global_internat->lpVtbl;
355 IMimeInternational_AddRef(*internat);
356 return S_OK;