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