Piotr Caban : msvcp90: Added num_get<wchar>::_Getifld implementation.

Alexandre Julliard julliard at winehq.org
Mon Jun 25 13:24:14 CDT 2012


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Jun 25 15:49:15 2012 +0200

msvcp90: Added num_get<wchar>::_Getifld implementation.

---

 dlls/msvcp90/locale.c |  136 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c
index 6b72c65..e9b931a 100644
--- a/dlls/msvcp90/locale.c
+++ b/dlls/msvcp90/locale.c
@@ -4439,22 +4439,146 @@ int __cdecl num_get_wchar__Getffldx(num_get *this, char *dest, istreambuf_iterat
     return -1;
 }
 
+static int num_get__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
+    istreambuf_iterator_wchar *last, int fmtflags, const locale *loc, numpunct_wchar *numpunct)
+{
+    wchar_t digits[23], *digits_pos, sep;
+    basic_string_char grouping_bstr;
+    int i, basefield, base, groups_no = 0, cur_group = 0;
+    char *dest_beg = dest, *dest_end = dest+24, *groups = NULL;
+    const char *grouping;
+    BOOL error = TRUE, dest_empty = TRUE;
+
+    TRACE("(%p %p %p %04x %p)\n", dest, first, last, fmtflags, loc);
+
+    for(i=0; i<10; i++)
+        digits[i] = mb_to_wc('0'+i, &this->cvt);
+    for(i=0; i<6; i++) {
+        digits[10+i] = mb_to_wc('a'+i, &this->cvt);
+        digits[16+i] = mb_to_wc('A'+i, &this->cvt);
+    }
+
+    numpunct_wchar_grouping(numpunct, &grouping_bstr);
+    grouping = MSVCP_basic_string_char_c_str(&grouping_bstr);
+    sep = grouping[0] ? numpunct_wchar_thousands_sep(numpunct) : '\0';
+
+    basefield = fmtflags & FMTFLAG_basefield;
+    if(basefield == FMTFLAG_oct)
+        base = 8;
+    else if(basefield == FMTFLAG_hex)
+        base = 22; /* equal to the size of digits buffer */
+    else if(!basefield)
+        base = 0;
+    else
+        base = 10;
+
+    istreambuf_iterator_wchar_val(first);
+    if(first->strbuf && first->val==mb_to_wc('-', &this->cvt)) {
+        *dest++ = '-';
+        istreambuf_iterator_wchar_inc(first);
+    }else if(first->strbuf && first->val==mb_to_wc('+', &this->cvt)) {
+        *dest++ = '+';
+        istreambuf_iterator_wchar_inc(first);
+    }
+
+    if(!base && first->strbuf && first->val==digits[0]) {
+        istreambuf_iterator_wchar_inc(first);
+        if(first->strbuf && (first->val==mb_to_wc('x', &this->cvt) || first->val==mb_to_wc('x', &this->cvt))) {
+            istreambuf_iterator_wchar_inc(first);
+            base = 22;
+        }else {
+            error = FALSE;
+            base = 8;
+        }
+    }else {
+        base = 10;
+    }
+    digits[base] = 0;
+
+    if(sep) {
+        groups_no = strlen(grouping)+2;
+        groups = calloc(groups_no, sizeof(char));
+    }
+
+    for(; first->strbuf; istreambuf_iterator_wchar_inc(first)) {
+        if(!(digits_pos = wcschr(digits, first->val))) {
+            if(sep && first->val==sep) {
+                if(cur_group == groups_no+1) {
+                    if(groups[1] != groups[2]) {
+                        error = TRUE;
+                        break;
+                    }else {
+                        memmove(groups+1, groups+2, groups_no);
+                        groups[cur_group] = 0;
+                    }
+                }else {
+                    cur_group++;
+                }
+            }else {
+                break;
+            }
+        }else {
+            error = FALSE;
+            if(dest_empty && first->val == digits[0])
+                continue;
+            dest_empty = FALSE;
+            /* skip digits that can't be copied to dest buffer, other
+             * functions are responsible for detecting overflows */
+            if(dest < dest_end)
+                *dest++ = (digits_pos-digits<10 ? '0'+digits_pos-digits :
+                        (digits_pos-digits<16 ? 'a'+digits_pos-digits-10 :
+                         'A'+digits_pos-digits-16));
+            if(sep && groups[cur_group]<CHAR_MAX)
+                groups[cur_group]++;
+        }
+    }
+
+    if(cur_group && !groups[cur_group])
+        error = TRUE;
+    else if(!cur_group)
+        cur_group--;
+
+    for(; cur_group>=0 && !error; cur_group--) {
+        if(*grouping == CHAR_MAX) {
+            if(cur_group)
+                error = TRUE;
+            break;
+        }else if((cur_group && *grouping!=groups[cur_group])
+                || (!cur_group && *grouping<groups[cur_group])) {
+            error = TRUE;
+            break;
+        }else if(grouping[1]) {
+            grouping++;
+        }
+    }
+    MSVCP_basic_string_char_dtor(&grouping_bstr);
+    free(groups);
+
+    if(error)
+        dest = dest_beg;
+    else if(dest_empty)
+        *dest++ = '0';
+    *dest = '\0';
+
+    return (base==22 ? 16 : base);
+}
+
 /* ?_Getifld@?$num_get at _WV?$istreambuf_iterator at _WU?$char_traits at _W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator at _WU?$char_traits at _W@std@@@2 at 1HABVlocale@2@@Z */
 /* ?_Getifld@?$num_get at _WV?$istreambuf_iterator at _WU?$char_traits at _W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator at _WU?$char_traits at _W@std@@@2 at 1HAEBVlocale@2@@Z */
-int __cdecl num_get_wchar__Getifld(num_get *this, char *dest, istreambuf_iterator_wchar *first,
+int __cdecl num_get_wchar__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
 {
-    FIXME("(%p %p %p %04x %p) stub\n", dest, first, last, fmtflags, loc);
-    return -1;
+    return num_get__Getifld(this, dest, first, last,
+            fmtflags, loc, numpunct_wchar_use_facet(loc));
 }
 
 /* ?_Getifld@?$num_get at GV?$istreambuf_iterator at GU?$char_traits at G@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator at GU?$char_traits at G@std@@@2 at 1HABVlocale@2@@Z */
 /* ?_Getifld@?$num_get at GV?$istreambuf_iterator at GU?$char_traits at G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator at GU?$char_traits at G@std@@@2 at 1HAEBVlocale@2@@Z */
-int __cdecl num_get_short__Getifld(num_get *this, char *dest, istreambuf_iterator_wchar *first,
+int __cdecl num_get_short__Getifld(const num_get *this, char *dest, istreambuf_iterator_wchar *first,
     istreambuf_iterator_wchar *last, int fmtflags, const locale *loc)
 {
-    FIXME("(%p %p %p %04x %p) stub\n", dest, first, last, fmtflags, loc);
-    return -1;
+    return num_get__Getifld(this, dest, first, last,
+            fmtflags, loc, numpunct_short_use_facet(loc));
 }
 
 /* ?_Hexdig@?$num_get at _WV?$istreambuf_iterator at _WU?$char_traits at _W@std@@@std@@@std@@ABEH_W000 at Z */




More information about the wine-cvs mailing list