Module: wine Branch: master Commit: 0dd32496b40a6ca467b8f7c733c61acb9177fab2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0dd32496b40a6ca467b8f7c733...
Author: Piotr Caban piotr@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@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@1HABVlocale@2@@Z */ /* ?_Getifld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@2@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@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@1HABVlocale@2@@Z */ /* ?_Getifld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@2@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@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABEH_W000@Z */