Piotr Caban : msvcp90: Added use_facet< codecvt<char> > implementation.

Alexandre Julliard julliard at winehq.org
Tue Jun 12 13:36:33 CDT 2012


Module: wine
Branch: master
Commit: 9c83b6ee42574857d035f1a379cf766003686761
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9c83b6ee42574857d035f1a379cf766003686761

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue Jun 12 18:12:32 2012 +0200

msvcp90: Added use_facet< codecvt<char> > implementation.

---

 dlls/msvcp90/locale.c  |   73 +++++++++++++++++++++++++++++++++++++++++++----
 dlls/msvcp90/msvcp90.h |    6 ++++
 2 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c
index 49d864a..f5fec45 100644
--- a/dlls/msvcp90/locale.c
+++ b/dlls/msvcp90/locale.c
@@ -25,6 +25,8 @@
 #include "errno.h"
 #include "limits.h"
 
+#include "wine/list.h"
+
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
@@ -37,6 +39,7 @@ char* __cdecl _Getmonths(void);
 void* __cdecl _Gettnames(void);
 unsigned int __cdecl ___lc_codepage_func(void);
 LCID* __cdecl ___lc_handle_func(void);
+const locale_facet* __thiscall locale__Getfacet(const locale*, MSVCP_size_t);
 
 typedef int category;
 
@@ -44,11 +47,6 @@ typedef struct {
     MSVCP_size_t id;
 } locale_id;
 
-typedef struct {
-    const vtable_ptr *vtable;
-    MSVCP_size_t refs;
-} locale_facet;
-
 typedef struct _locale__Locimp {
     locale_facet facet;
     locale_facet **facetvec;
@@ -200,6 +198,25 @@ locale_facet* __thiscall MSVCP_locale_facet_vector_dtor(locale_facet *this, unsi
     return this;
 }
 
+typedef struct
+{
+    locale_facet *fac;
+    struct list entry;
+} facets_elem;
+static struct list lazy_facets = LIST_INIT(lazy_facets);
+
+static void locale_facet_register(locale_facet *add)
+{
+    facets_elem *head = MSVCRT_operator_new(sizeof(*head));
+    if(!head) {
+        ERR("Out of memory\n");
+        throw_exception(EXCEPTION_BAD_ALLOC, NULL);
+    }
+
+    head->fac = add;
+    list_add_head(&lazy_facets, &head->entry);
+}
+
 extern const vtable_ptr MSVCP_locale_facet_vtable;
 
 /* ??0id at locale@std@@QAE at I@Z */
@@ -2657,6 +2674,32 @@ MSVCP_size_t __cdecl codecvt_char__Getcat(const locale_facet **facet, const loca
     return LC_CTYPE;
 }
 
+codecvt_char* codecvt_char_use_facet(locale *loc)
+{
+    static codecvt_char *obj = NULL;
+
+    _Lockit lock;
+    const locale_facet *fac;
+
+    _Lockit_ctor_locktype(&lock, _LOCK_LOCALE);
+    fac = locale__Getfacet(loc, codecvt_char_id.id);
+    if(fac) {
+        _Lockit_dtor(&lock);
+        return (codecvt_char*)fac;
+    }
+
+    if(obj)
+        return obj;
+
+    codecvt_char__Getcat(&fac, loc);
+    obj = (codecvt_char*)fac;
+    locale_facet__Incref(&obj->base.facet);
+    locale_facet_register(&obj->base.facet);
+    _Lockit_dtor(&lock);
+
+    return obj;
+}
+
 /* ?do_in@?$codecvt at DDH@std@@MBEHAAHPBD1AAPBDPAD3AAPAD at Z */
 /* ?do_in@?$codecvt at DDH@std@@MEBAHAEAHPEBD1AEAPEBDPEAD3AEAPEAD at Z */
 #define call_codecvt_char_do_in(this, state, from, from_end, from_next, to, to_end, to_next) \
@@ -4525,8 +4568,15 @@ locale* __thiscall locale__Addfac(locale *this, locale_facet *facet, MSVCP_size_
 DEFINE_THISCALL_WRAPPER(locale__Getfacet, 8)
 const locale_facet* __thiscall locale__Getfacet(const locale *this, MSVCP_size_t id)
 {
-    FIXME("(%p %lu) stub\n", this, id);
-    return NULL;
+    locale_facet *fac;
+
+    TRACE("(%p %lu)\n", this, id);
+
+    fac = id < this->ptr->facet_cnt ? this->ptr->facetvec[id] : NULL;
+    if(fac || !this->ptr->transparent)
+        return fac;
+
+    return id < global_locale->facet_cnt ? global_locale->facetvec[id] : NULL;
 }
 
 /* ?_Getgloballocale at locale@std@@CAPAV_Locimp at 12@XZ */
@@ -4711,8 +4761,17 @@ void __asm_dummy_vtables(void) {
 
 void free_locale(void)
 {
+    facets_elem *iter, *safe;
+
     if(global_locale) {
         locale__Locimp_dtor(global_locale);
         locale_dtor(&classic_locale);
     }
+
+    LIST_FOR_EACH_ENTRY_SAFE(iter, safe, &lazy_facets, facets_elem, entry) {
+        list_remove(&iter->entry);
+        if(locale_facet__Decref(iter->fac))
+            call_locale_facet_vector_dtor(iter->fac, 1);
+        MSVCRT_operator_delete(iter);
+    }
 }
diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h
index 47bcc26..aebd034 100644
--- a/dlls/msvcp90/msvcp90.h
+++ b/dlls/msvcp90/msvcp90.h
@@ -257,6 +257,12 @@ wchar_t* __stdcall MSVCP_allocator_wchar_allocate(void*, MSVCP_size_t);
 void __stdcall MSVCP_allocator_wchar_deallocate(void*, wchar_t*, MSVCP_size_t);
 MSVCP_size_t __stdcall MSVCP_allocator_wchar_max_size(void*);
 
+/* class locale::facet */
+typedef struct {
+    const vtable_ptr *vtable;
+    MSVCP_size_t refs;
+} locale_facet;
+
 /* class locale */
 typedef struct
 {




More information about the wine-cvs mailing list