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