Huw Davies : inetcomm: Implement IMimeInternational_FindCharset.
Alexandre Julliard
julliard at winehq.org
Thu Sep 11 08:01:13 CDT 2008
Module: wine
Branch: master
Commit: ed3ca13613cbf794fd10cdc7451df9ca61dd0839
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ed3ca13613cbf794fd10cdc7451df9ca61dd0839
Author: Huw Davies <huw at codeweavers.com>
Date: Wed Sep 10 12:37:40 2008 +0100
inetcomm: Implement IMimeInternational_FindCharset.
---
dlls/inetcomm/Makefile.in | 2 +-
dlls/inetcomm/mimeintl.c | 101 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/dlls/inetcomm/Makefile.in b/dlls/inetcomm/Makefile.in
index ee03db0..171b98d 100644
--- a/dlls/inetcomm/Makefile.in
+++ b/dlls/inetcomm/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = inetcomm.dll
IMPORTLIB = inetcomm
-IMPORTS = uuid ole32 ws2_32 user32 advapi32 kernel32
+IMPORTS = uuid oleaut32 ole32 ws2_32 user32 advapi32 kernel32
C_SRCS = \
inetcomm_main.c \
diff --git a/dlls/inetcomm/mimeintl.c b/dlls/inetcomm/mimeintl.c
index 6cc1d96..a7a8313 100644
--- a/dlls/inetcomm/mimeintl.c
+++ b/dlls/inetcomm/mimeintl.c
@@ -31,6 +31,7 @@
#include "objbase.h"
#include "ole2.h"
#include "mimeole.h"
+#include "mlang.h"
#include "wine/list.h"
#include "wine/debug.h"
@@ -41,8 +42,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
typedef struct
{
+ struct list entry;
+ INETCSETINFO cs_info;
+} charset_entry;
+
+typedef struct
+{
const IMimeInternationalVtbl *lpVtbl;
LONG refs;
+ CRITICAL_SECTION cs;
+
+ struct list charsets;
+ LONG next_charset_handle;
} internat;
static inline internat *impl_from_IMimeInternational( IMimeInternational *iface )
@@ -50,6 +61,12 @@ static inline internat *impl_from_IMimeInternational( IMimeInternational *iface
return (internat *)((char*)iface - FIELD_OFFSET(internat, lpVtbl));
}
+static inline HRESULT get_mlang(IMultiLanguage **ml)
+{
+ return CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
+ &IID_IMultiLanguage, (void **)ml);
+}
+
static HRESULT WINAPI MimeInternat_QueryInterface( IMimeInternational *iface, REFIID riid, LPVOID *ppobj )
{
if (IsEqualGUID(riid, &IID_IUnknown) ||
@@ -78,6 +95,13 @@ static ULONG WINAPI MimeInternat_Release( IMimeInternational *iface )
refs = InterlockedDecrement(&This->refs);
if (!refs)
{
+ charset_entry *charset, *cursor2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(charset, cursor2, &This->charsets, charset_entry, entry)
+ {
+ list_remove(&charset->entry);
+ HeapFree(GetProcessHeap(), 0, charset);
+ }
HeapFree(GetProcessHeap(), 0, This);
}
@@ -104,11 +128,80 @@ static HRESULT WINAPI MimeInternat_GetCodePageCharset(IMimeInternational *iface,
return E_NOTIMPL;
}
+static HRESULT mlang_getcsetinfo(const char *charset, MIMECSETINFO *mlang_info)
+{
+ DWORD len = MultiByteToWideChar(CP_ACP, 0, charset, -1, NULL, 0);
+ BSTR bstr = SysAllocStringLen(NULL, len - 1);
+ HRESULT hr;
+ IMultiLanguage *ml;
+
+ MultiByteToWideChar(CP_ACP, 0, charset, -1, bstr, len);
+
+ hr = get_mlang(&ml);
+
+ if(SUCCEEDED(hr))
+ {
+ hr = IMultiLanguage_GetCharsetInfo(ml, bstr, mlang_info);
+ IMultiLanguage_Release(ml);
+ }
+ SysFreeString(bstr);
+ if(FAILED(hr)) hr = MIME_E_NOT_FOUND;
+ return hr;
+}
+
+static HCHARSET add_charset(struct list *list, MIMECSETINFO *mlang_info, HCHARSET handle)
+{
+ charset_entry *charset = HeapAlloc(GetProcessHeap(), 0, sizeof(*charset));
+
+ WideCharToMultiByte(CP_ACP, 0, mlang_info->wszCharset, -1,
+ charset->cs_info.szName, sizeof(charset->cs_info.szName), NULL, NULL);
+ charset->cs_info.cpiWindows = mlang_info->uiCodePage;
+ charset->cs_info.cpiInternet = mlang_info->uiInternetEncoding;
+ charset->cs_info.hCharset = handle;
+ charset->cs_info.dwReserved1 = 0;
+ list_add_head(list, &charset->entry);
+
+ return charset->cs_info.hCharset;
+}
+
static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR pszCharset,
LPHCHARSET phCharset)
{
- FIXME("stub\n");
- return E_NOTIMPL;
+ internat *This = impl_from_IMimeInternational( iface );
+ HRESULT hr = MIME_E_NOT_FOUND;
+ charset_entry *charset;
+
+ TRACE("(%p)->(%s, %p)\n", iface, debugstr_a(pszCharset), phCharset);
+
+ *phCharset = NULL;
+
+ EnterCriticalSection(&This->cs);
+
+ LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry)
+ {
+ if(!strcmp(charset->cs_info.szName, pszCharset))
+ {
+ *phCharset = charset->cs_info.hCharset;
+ hr = S_OK;
+ break;
+ }
+ }
+
+ if(hr == MIME_E_NOT_FOUND)
+ {
+ MIMECSETINFO mlang_info;
+
+ LeaveCriticalSection(&This->cs);
+ hr = mlang_getcsetinfo(pszCharset, &mlang_info);
+ EnterCriticalSection(&This->cs);
+
+ if(SUCCEEDED(hr))
+ *phCharset = add_charset(&This->charsets, &mlang_info,
+ (HCHARSET)InterlockedIncrement(&This->next_charset_handle));
+ }
+
+ LeaveCriticalSection(&This->cs);
+ return hr;
}
static HRESULT WINAPI MimeInternat_GetCharsetInfo(IMimeInternational *iface, HCHARSET hCharset,
@@ -224,6 +317,10 @@ HRESULT MimeInternational_Construct(IMimeInternational **internat)
global_internat = HeapAlloc(GetProcessHeap(), 0, sizeof(*global_internat));
global_internat->lpVtbl = &mime_internat_vtbl;
global_internat->refs = 0;
+ InitializeCriticalSection(&global_internat->cs);
+
+ list_init(&global_internat->charsets);
+ global_internat->next_charset_handle = 0;
*internat = (IMimeInternational*)&global_internat->lpVtbl;
More information about the wine-cvs
mailing list