From 52bcd2e082fb05a4d1e334e8df1eea6344bca15f Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 28 Mar 2012 11:20:22 +0200 Subject: [PATCH] msvcp90: Added numpunct implementation. --- dlls/msvcp90/locale.c | 170 ++++++++++++++++++++++++++++++++++++++----------- dlls/msvcp90/msvcp90.h | 2 + 2 files changed, 135 insertions(+), 37 deletions(-) diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c index d2e7798b997..d54b794039a 100644 --- a/dlls/msvcp90/locale.c +++ b/dlls/msvcp90/locale.c @@ -2450,7 +2450,6 @@ extern const vtable_ptr MSVCP_numpunct_char_vtable; DEFINE_THISCALL_WRAPPER(numpunct_char__Init, 12) void __thiscall numpunct_char__Init(numpunct_char *this, _Locinfo *locinfo, MSVCP_bool isdef) { - const struct lconv *lc = _Locinfo__Getlconv(locinfo); int len; TRACE("(%p %p %d)\n", this, locinfo, isdef); @@ -2473,6 +2472,8 @@ void __thiscall numpunct_char__Init(numpunct_char *this, _Locinfo *locinfo, MSVC this->dp = '.'; this->sep = ','; } else { + const struct lconv *lc = _Locinfo__Getlconv(locinfo); + len = strlen(lc->grouping)+1; this->grouping = MSVCRT_operator_new(len); if(this->grouping) @@ -2721,7 +2722,55 @@ extern const vtable_ptr MSVCP_numpunct_short_vtable; DEFINE_THISCALL_WRAPPER(numpunct_wchar__Init, 12) void __thiscall numpunct_wchar__Init(numpunct_wchar *this, _Locinfo *locinfo, MSVCP_bool isdef) { - FIXME("(%p %p %d) stub\n", this, locinfo, isdef); + const char *to_convert; + _Cvtvec cvt; + int len; + + TRACE("(%p %p %d)\n", this, locinfo, isdef); + + _Locinfo__Getcvt(locinfo, &cvt); + + to_convert = _Locinfo__Getfalse(locinfo); + len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0); + this->false_name = MSVCRT_operator_new(len*sizeof(WCHAR)); + if(this->false_name) + MultiByteToWideChar(cvt.page, 0, to_convert, -1, + (wchar_t*)this->false_name, len); + + to_convert = _Locinfo__Gettrue(locinfo); + len = MultiByteToWideChar(cvt.page, 0, to_convert, -1, NULL, 0); + this->true_name = MSVCRT_operator_new(len*sizeof(WCHAR)); + if(this->true_name) + MultiByteToWideChar(cvt.page, 0, to_convert, -1, + (wchar_t*)this->true_name, len); + + if(isdef) { + this->grouping = MSVCRT_operator_new(1); + if(this->grouping) + *(char*)this->grouping = 0; + + this->dp = '.'; + this->sep = ','; + } else { + const struct lconv *lc = _Locinfo__Getlconv(locinfo); + + len = strlen(lc->grouping)+1; + this->grouping = MSVCRT_operator_new(len); + if(this->grouping) + memcpy((char*)this->grouping, lc->grouping, len); + + this->dp = lc->decimal_point[0]; + this->sep = lc->thousands_sep[0]; + } + + if(!this->false_name || !this->true_name || !this->grouping) { + MSVCRT_operator_delete((char*)this->grouping); + MSVCRT_operator_delete((wchar_t*)this->false_name); + MSVCRT_operator_delete((wchar_t*)this->true_name); + + ERR("Out of memory\n"); + throw_exception(EXCEPTION_BAD_ALLOC, NULL); + } } /* ?_Tidy@?$numpunct@_W@std@@AAEXXZ */ @@ -2731,7 +2780,11 @@ void __thiscall numpunct_wchar__Init(numpunct_wchar *this, _Locinfo *locinfo, MS DEFINE_THISCALL_WRAPPER(numpunct_wchar__Tidy, 4) void __thiscall numpunct_wchar__Tidy(numpunct_wchar *this) { - FIXME("(%p) stub\n", this); + TRACE("(%p)\n", this); + + MSVCRT_operator_delete((char*)this->grouping); + MSVCRT_operator_delete((wchar_t*)this->false_name); + MSVCRT_operator_delete((wchar_t*)this->true_name); } /* ??0?$numpunct@_W@std@@QAE@ABV_Locinfo@1@I_N@Z */ @@ -2740,9 +2793,11 @@ DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_locinfo, 16) numpunct_wchar* __thiscall numpunct_wchar_ctor_locinfo(numpunct_wchar *this, _Locinfo *locinfo, MSVCP_size_t refs, MSVCP_bool usedef) { - FIXME("(%p %p %lu %d) stub\n", this, locinfo, refs, usedef); + TRACE("(%p %p %lu %d)\n", this, locinfo, refs, usedef); + locale_facet_ctor_refs(&this->facet, refs); this->facet.vtable = &MSVCP_numpunct_wchar_vtable; - return NULL; + numpunct_wchar__Init(this, locinfo, usedef); + return this; } /* ??0?$numpunct@G@std@@QAE@ABV_Locinfo@1@I_N@Z */ @@ -2762,14 +2817,21 @@ DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_name, 16) numpunct_wchar* __thiscall numpunct_wchar_ctor_name(numpunct_wchar *this, const char *name, MSVCP_size_t refs, MSVCP_bool usedef) { - FIXME("(%p %s %lu %d) stub\n", this, debugstr_a(name), refs, usedef); + _Locinfo locinfo; + + TRACE("(%p %s %lu %d)\n", this, debugstr_a(name), refs, usedef); + locale_facet_ctor_refs(&this->facet, refs); this->facet.vtable = &MSVCP_numpunct_wchar_vtable; - return NULL; + + _Locinfo_ctor_cstr(&locinfo, name); + numpunct_wchar__Init(this, &locinfo, usedef); + _Locinfo_dtor(&locinfo); + return this; } /* ??0?$numpunct@G@std@@IAE@PBDI_N@Z */ /* ??0?$numpunct@G@std@@IEAA@PEBD_K_N@Z */ -DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_name, 16) + DEFINE_THISCALL_WRAPPER(numpunct_short_ctor_name, 16) numpunct_wchar* __thiscall numpunct_short_ctor_name(numpunct_wchar *this, const char *name, MSVCP_size_t refs, MSVCP_bool usedef) { @@ -2780,12 +2842,11 @@ numpunct_wchar* __thiscall numpunct_short_ctor_name(numpunct_wchar *this, /* ??0?$numpunct@_W@std@@QAE@I@Z */ /* ??0?$numpunct@_W@std@@QEAA@_K@Z */ -DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_refs, 8) + DEFINE_THISCALL_WRAPPER(numpunct_wchar_ctor_refs, 8) numpunct_wchar* __thiscall numpunct_wchar_ctor_refs(numpunct_wchar *this, MSVCP_size_t refs) { - FIXME("(%p %lu) stub\n", this, refs); - this->facet.vtable = &MSVCP_numpunct_wchar_vtable; - return NULL; + TRACE("(%p %lu)\n", this, refs); + return numpunct_wchar_ctor_name(this, "C", refs, FALSE); } /* ??0?$numpunct@G@std@@QAE@I@Z */ @@ -2821,7 +2882,8 @@ numpunct_wchar* __thiscall numpunct_short_ctor(numpunct_wchar *this) DEFINE_THISCALL_WRAPPER(numpunct_wchar_dtor, 4) void __thiscall numpunct_wchar_dtor(numpunct_wchar *this) { - FIXME("(%p) stub\n", this); + TRACE("(%p)\n", this); + numpunct_wchar__Tidy(this); } DEFINE_THISCALL_WRAPPER(MSVCP_numpunct_wchar_vector_dtor, 8) @@ -2854,16 +2916,40 @@ numpunct_wchar* __thiscall MSVCP_numpunct_short_vector_dtor(numpunct_wchar *this /* ?_Getcat@?$numpunct@_W@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */ MSVCP_size_t __cdecl numpunct_wchar__Getcat(const locale_facet **facet, const locale *loc) { - FIXME("(%p %p) stub\n", facet, loc); - return 0; + TRACE("(%p %p)\n", facet, loc); + + if(facet && !*facet) { + *facet = MSVCRT_operator_new(sizeof(numpunct_wchar)); + if(!*facet) { + ERR("Out of memory\n"); + throw_exception(EXCEPTION_BAD_ALLOC, NULL); + return 0; + } + numpunct_wchar_ctor_name((numpunct_wchar*)*facet, + MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE); + } + + return LC_NUMERIC; } /* ?_Getcat@?$numpunct@G@std@@SAIPAPBVfacet@locale@2@PBV42@@Z */ /* ?_Getcat@?$numpunct@G@std@@SA_KPEAPEBVfacet@locale@2@PEBV42@@Z */ MSVCP_size_t __cdecl numpunct_short__Getcat(const locale_facet **facet, const locale *loc) { - FIXME("(%p %p) stub\n", facet, loc); - return 0; + TRACE("(%p %p)\n", facet, loc); + + if(facet && !*facet) { + *facet = MSVCRT_operator_new(sizeof(numpunct_wchar)); + if(!*facet) { + ERR("Out of memory\n"); + throw_exception(EXCEPTION_BAD_ALLOC, NULL); + return 0; + } + numpunct_short_ctor_name((numpunct_wchar*)*facet, + MSVCP_basic_string_char_c_str(&loc->ptr->name), 0, TRUE); + } + + return LC_NUMERIC; } /* ?do_decimal_point@?$numpunct@_W@std@@MBE_WXZ */ @@ -2871,10 +2957,12 @@ MSVCP_size_t __cdecl numpunct_short__Getcat(const locale_facet **facet, const lo /* ?do_decimal_point@?$numpunct@G@std@@MBEGXZ */ /* ?do_decimal_point@?$numpunct@G@std@@MEBAGXZ */ DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_decimal_point, 4) +#define call_numpunct_wchar_do_decimal_point(this) CALL_VTBL_FUNC(this, 4, \ + wchar_t, (const numpunct_wchar *this), (this)) wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this) { - FIXME("(%p) stub\n", this); - return 0; + TRACE("(%p)\n", this); + return this->dp; } /* ?decimal_point@?$numpunct@_W@std@@QBE_WXZ */ @@ -2884,8 +2972,8 @@ wchar_t __thiscall numpunct_wchar_do_decimal_point(const numpunct_wchar *this) DEFINE_THISCALL_WRAPPER(numpunct_wchar_decimal_point, 4) wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this) { - FIXME("(%p) stub\n", this); - return 0; + TRACE("(%p)\n", this); + return call_numpunct_wchar_do_decimal_point(this); } /* ?do_thousands_sep@?$numpunct@_W@std@@MBE_WXZ */ @@ -2893,10 +2981,12 @@ wchar_t __thiscall numpunct_wchar_decimal_point(const numpunct_wchar *this) /* ?do_thousands_sep@?$numpunct@G@std@@MBEGXZ */ /* ?do_thousands_sep@?$numpunct@G@std@@MEBAGXZ */ DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_thousands_sep, 4) +#define call_numpunct_wchar_do_thousands_sep(this) CALL_VTBL_FUNC(this, 8, \ + wchar_t, (const numpunct_wchar *this), (this)) wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this) { - FIXME("(%p) stub\n", this); - return 0; + TRACE("(%p)\n", this); + return this->sep; } /* ?thousands_sep@?$numpunct@_W@std@@QBE_WXZ */ @@ -2906,8 +2996,8 @@ wchar_t __thiscall numpunct_wchar_do_thousands_sep(const numpunct_wchar *this) DEFINE_THISCALL_WRAPPER(numpunct_wchar_thousands_sep, 4) wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this) { - FIXME("(%p) stub\n", this); - return 0; + TRACE("(%p)\n", this); + return call_numpunct_wchar_do_thousands_sep(this); } /* ?do_grouping@?$numpunct@_W@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */ @@ -2915,10 +3005,12 @@ wchar_t __thiscall numpunct_wchar_thousands_sep(const numpunct_wchar *this) /* ?do_grouping@?$numpunct@G@std@@MBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */ /* ?do_grouping@?$numpunct@G@std@@MEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */ DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_grouping, 8) +#define call_numpunct_wchar_do_grouping(this, ret) CALL_VTBL_FUNC(this, 12, \ + basic_string_char*, (const numpunct_wchar*, basic_string_char*), (this, ret)) basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *this, basic_string_char *ret) { - FIXME("(%p) stub\n", this); - return ret; + TRACE("(%p)\n", this); + return MSVCP_basic_string_char_ctor_cstr(ret, this->grouping); } /* ?grouping@?$numpunct@_W@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ */ @@ -2928,8 +3020,8 @@ basic_string_char* __thiscall numpunct_wchar_do_grouping(const numpunct_wchar *t DEFINE_THISCALL_WRAPPER(numpunct_wchar_grouping, 8) basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this, basic_string_char *ret) { - FIXME("(%p) stub\n", this); - return ret; + TRACE("(%p)\n", this); + return call_numpunct_wchar_do_grouping(this, ret); } /* ?do_falsename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */ @@ -2937,10 +3029,12 @@ basic_string_char* __thiscall numpunct_wchar_grouping(const numpunct_wchar *this /* ?do_falsename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */ /* ?do_falsename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */ DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_falsename, 8) +#define call_numpunct_wchar_do_falsename(this, ret) CALL_VTBL_FUNC(this, 16, \ + basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret)) basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar *this, basic_string_wchar *ret) { - FIXME("(%p) stub\n", this); - return ret; + TRACE("(%p)\n", this); + return MSVCP_basic_string_wchar_ctor_cstr(ret, this->false_name); } /* ?falsename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */ @@ -2950,8 +3044,8 @@ basic_string_wchar* __thiscall numpunct_wchar_do_falsename(const numpunct_wchar DEFINE_THISCALL_WRAPPER(numpunct_wchar_falsename, 8) basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *this, basic_string_wchar *ret) { - FIXME("(%p) stub\n", this); - return ret; + TRACE("(%p)\n", this); + return call_numpunct_wchar_do_falsename(this, ret); } /* ?do_truename@?$numpunct@_W@std@@MBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */ @@ -2959,10 +3053,12 @@ basic_string_wchar* __thiscall numpunct_wchar_falsename(const numpunct_wchar *th /* ?do_truename@?$numpunct@G@std@@MBE?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */ /* ?do_truename@?$numpunct@G@std@@MEBA?AV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@2@XZ */ DEFINE_THISCALL_WRAPPER(numpunct_wchar_do_truename, 8) +#define call_numpunct_wchar_do_truename(this, ret) CALL_VTBL_FUNC(this, 20, \ + basic_string_wchar*, (const numpunct_wchar*, basic_string_wchar*), (this, ret)) basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar *this, basic_string_wchar *ret) { - FIXME("(%p) stub\n", this); - return ret; + TRACE("(%p)\n", this); + return MSVCP_basic_string_wchar_ctor_cstr(ret, this->true_name); } /* ?truename@?$numpunct@_W@std@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@XZ */ @@ -2972,8 +3068,8 @@ basic_string_wchar* __thiscall numpunct_wchar_do_truename(const numpunct_wchar * DEFINE_THISCALL_WRAPPER(numpunct_wchar_truename, 8) basic_string_wchar* __thiscall numpunct_wchar_truename(const numpunct_wchar *this, basic_string_wchar *ret) { - FIXME("(%p) stub\n", this); - return ret; + TRACE("(%p)\n", this); + return call_numpunct_wchar_do_truename(this, ret); } /* ?id@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@2V0locale@2@A */ diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index f59efa68f0f..9dc42ab0d68 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -243,6 +243,8 @@ typedef struct _basic_string_wchar MSVCP_size_t res; } basic_string_wchar; +basic_string_wchar* __stdcall MSVCP_basic_string_wchar_ctor_cstr(basic_string_wchar*, const wchar_t*); + char* __stdcall MSVCP_allocator_char_allocate(void*, MSVCP_size_t); void __stdcall MSVCP_allocator_char_deallocate(void*, char*, MSVCP_size_t); MSVCP_size_t __stdcall MSVCP_allocator_char_max_size(void*); -- 2.11.4.GIT