Piotr Caban : msvcp90: Implement remaining functions in basic_stringbuf< char> class.
Alexandre Julliard
julliard at winehq.org
Fri Jun 29 14:24:28 CDT 2012
Module: wine
Branch: master
Commit: d538c1eebec99d28f79988a710702069f9a914e3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d538c1eebec99d28f79988a710702069f9a914e3
Author: Piotr Caban <piotr at codeweavers.com>
Date: Fri Jun 29 12:02:49 2012 +0200
msvcp90: Implement remaining functions in basic_stringbuf<char> class.
---
dlls/msvcp90/ios.c | 182 ++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 157 insertions(+), 25 deletions(-)
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 27694bf..9802f7d 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -2611,17 +2611,80 @@ basic_stringbuf_char* __thiscall MSVCP_basic_stringbuf_char_vector_dtor(basic_st
DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_overflow, 8)
int __thiscall basic_stringbuf_char_overflow(basic_stringbuf_char *this, int meta)
{
- FIXME("(%p %x) stub\n", this, meta);
- return 0;
+ MSVCP_size_t oldsize, size;
+ char *ptr, *buf;
+
+ TRACE("(%p %x)\n", this, meta);
+
+ if(meta == EOF)
+ return !EOF;
+ if(this->state & STRINGBUF_no_write)
+ return EOF;
+
+ ptr = basic_streambuf_char_pptr(&this->base);
+ if((this->state&STRINGBUF_append) && ptr<this->seekhigh)
+ basic_streambuf_char_setp_next(&this->base, basic_streambuf_char_pbase(&this->base),
+ this->seekhigh, basic_streambuf_char_epptr(&this->base));
+
+ if(ptr && ptr<basic_streambuf_char_epptr(&this->base))
+ return (*basic_streambuf_char__Pninc(&this->base) = meta);
+
+ oldsize = (ptr ? basic_streambuf_char_epptr(&this->base)-basic_streambuf_char_eback(&this->base): 0);
+ size = oldsize|0xf;
+ size += size/2;
+ buf = MSVCRT_operator_new(size);
+ if(!buf) {
+ ERR("Out of memory\n");
+ throw_exception(EXCEPTION_BAD_ALLOC, NULL);
+ }
+
+ if(!oldsize) {
+ this->seekhigh = buf;
+ basic_streambuf_char_setp(&this->base, buf, buf+size);
+ if(this->state & STRINGBUF_no_read)
+ basic_streambuf_char_setg(&this->base, buf, NULL, buf);
+ else
+ basic_streambuf_char_setg(&this->base, buf, buf, buf+1);
+
+ this->state |= STRINGBUF_allocated;
+ }else {
+ ptr = basic_streambuf_char_eback(&this->base);
+ memcpy(buf, ptr, oldsize);
+
+ this->seekhigh = buf+(this->seekhigh-ptr);
+ basic_streambuf_char_setp_next(&this->base, buf,
+ buf+(basic_streambuf_char_pptr(&this->base)-ptr), buf+size);
+ if(this->state & STRINGBUF_no_read)
+ basic_streambuf_char_setg(&this->base, buf, NULL, buf);
+ else
+ basic_streambuf_char_setg(&this->base, buf,
+ buf+(basic_streambuf_char_gptr(&this->base)-ptr),
+ basic_streambuf_char_pptr(&this->base)+1);
+
+ MSVCRT_operator_delete(ptr);
+ }
+
+ return (*basic_streambuf_char__Pninc(&this->base) = meta);
}
/* ?pbackfail@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MAEHH at Z */
/* ?pbackfail@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MEAAHH at Z */
DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_pbackfail, 8)
-int __thiscall basic_stringbuf_char_pbackfail(basic_stringbuf_char *this, int type)
+int __thiscall basic_stringbuf_char_pbackfail(basic_stringbuf_char *this, int c)
{
- FIXME("(%p %x) stub\n", this, type);
- return 0;
+ char *cur;
+
+ TRACE("(%p %x)\n", this, c);
+
+ cur = basic_streambuf_char_gptr(&this->base);
+ if(!cur || cur==basic_streambuf_char_eback(&this->base)
+ || (c!=EOF && c!=cur[-1] && this->state&STRINGBUF_no_write))
+ return EOF;
+
+ if(c != EOF)
+ cur[-1] = c;
+ basic_streambuf_char_gbump(&this->base, -1);
+ return c==EOF ? !EOF : c;
}
/* ?underflow@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MAEHXZ */
@@ -2629,26 +2692,98 @@ int __thiscall basic_stringbuf_char_pbackfail(basic_stringbuf_char *this, int ty
DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_underflow, 4)
int __thiscall basic_stringbuf_char_underflow(basic_stringbuf_char *this)
{
- FIXME("(%p) stub\n", this);
- return 0;
+ char *ptr, *cur;
+
+ TRACE("(%p)\n", this);
+
+ cur = basic_streambuf_char_gptr(&this->base);
+ if(!cur || this->state&STRINGBUF_no_read)
+ return EOF;
+
+ ptr = basic_streambuf_char_pptr(&this->base);
+ if(this->seekhigh < ptr)
+ this->seekhigh = ptr;
+
+ ptr = basic_streambuf_char_egptr(&this->base);
+ if(this->seekhigh > ptr)
+ basic_streambuf_char_setg(&this->base, basic_streambuf_char_eback(&this->base), cur, this->seekhigh);
+
+ if(cur < this->seekhigh)
+ return *cur;
+ return EOF;
}
/* ?seekoff@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MAE?AV?$fpos at H@2 at JHH@Z */
/* ?seekoff@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MEAA?AV?$fpos at H@2 at _JHH@Z */
-DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_seekoff, 16)
-int __thiscall basic_stringbuf_char_seekoff(basic_stringbuf_char *this, int off, int way, int which)
+DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_seekoff, 20)
+fpos_int* __thiscall basic_stringbuf_char_seekoff(basic_stringbuf_char *this,
+ fpos_int *ret, streamoff off, int way, int mode)
{
- FIXME("(%p %d %d %d) stub\n", this, off, way, which);
- return 0;
+ char *beg, *cur_r, *cur_w;
+
+ TRACE("(%p %p %ld %d %d)\n", this, ret, off, way, mode);
+
+ cur_w = basic_streambuf_char_pptr(&this->base);
+ if(cur_w > this->seekhigh)
+ this->seekhigh = cur_w;
+
+ ret->off = 0;
+ ret->state = 0;
+
+ beg = basic_streambuf_char_eback(&this->base);
+ cur_r = basic_streambuf_char_gptr(&this->base);
+ if((mode & OPENMODE_in) && cur_r) {
+ if(way==SEEKDIR_cur && !(mode & OPENMODE_out))
+ off += cur_r-beg;
+ else if(way == SEEKDIR_end)
+ off += this->seekhigh-beg;
+ else if(way != SEEKDIR_beg)
+ off = -1;
+
+ if(off<0 || off>this->seekhigh-beg) {
+ off = -1;
+ }else {
+ basic_streambuf_char_gbump(&this->base, beg-cur_r+off);
+ if((mode & OPENMODE_out) && cur_w) {
+ basic_streambuf_char_setp_next(&this->base, beg,
+ basic_streambuf_char_gptr(&this->base),
+ basic_streambuf_char_epptr(&this->base));
+ }
+ }
+ }else if((mode & OPENMODE_out) && cur_w) {
+ if(way == SEEKDIR_cur)
+ off += cur_w-beg;
+ else if(way == SEEKDIR_end)
+ off += this->seekhigh-beg;
+ else if(way != SEEKDIR_beg)
+ off = -1;
+
+ if(off<0 || off>this->seekhigh-beg)
+ off = -1;
+ else
+ basic_streambuf_char_pbump(&this->base, beg-cur_w+off);
+ }else {
+ off = -1;
+ }
+
+ ret->pos = off;
+ return ret;
}
/* ?seekpos@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MAE?AV?$fpos at H@2 at V32@H at Z */
/* ?seekpos@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@MEAA?AV?$fpos at H@2 at V32@H at Z */
-DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_seekpos, 12)
-int __thiscall basic_stringbuf_char_seekpos(basic_stringbuf_char *this, int pos_type, int openmode)
+DEFINE_THISCALL_WRAPPER(basic_stringbuf_char_seekpos, 36)
+fpos_int* __thiscall basic_stringbuf_char_seekpos(basic_stringbuf_char *this,
+ fpos_int *ret, fpos_int pos, int mode)
{
- FIXME("(%p %d %d) stub\n", this, pos_type, openmode);
- return 0;
+ TRACE("(%p %p %s %d)\n", this, ret, debugstr_fpos_int(&pos), mode);
+
+ if(pos.off==0 && pos.pos==-1 && pos.state==0) {
+ *ret = pos;
+ return ret;
+ }
+
+ return basic_stringbuf_char_seekoff(this, ret, pos.off, SEEKDIR_beg, mode);
}
/* ?str@?$basic_stringbuf at DU?$char_traits at D@std@@V?$allocator at D@2@@std@@QAEXABV?$basic_string at DU?$char_traits at D@std@@V?$allocator at D@2@@2@@Z */
@@ -2672,24 +2807,21 @@ basic_string_char* __thiscall basic_stringbuf_char_str_get(basic_stringbuf_char
TRACE("(%p)\n", this);
- if(!(this->state & STRINGBUF_no_read) && basic_streambuf_char_gptr(&this->base)) {
- ptr = basic_streambuf_char_eback(&this->base);
- MSVCP_basic_string_char_ctor_cstr_len(ret, ptr, basic_streambuf_char_egptr(&this->base) - ptr);
- return ret;
- }
-
if(!(this->state & STRINGBUF_no_write) && basic_streambuf_char_pptr(&this->base)) {
char *pptr;
ptr = basic_streambuf_char_pbase(&this->base);
pptr = basic_streambuf_char_pptr(&this->base);
- MSVCP_basic_string_char_ctor_cstr_len(ret, ptr, (this->seekhigh < pptr ? pptr : this->seekhigh) - ptr);
- return ret;
+ return MSVCP_basic_string_char_ctor_cstr_len(ret, ptr, (this->seekhigh < pptr ? pptr : this->seekhigh) - ptr);
}
- MSVCP_basic_string_char_ctor(ret);
- return ret;
+ if(!(this->state & STRINGBUF_no_read) && basic_streambuf_char_gptr(&this->base)) {
+ ptr = basic_streambuf_char_eback(&this->base);
+ return MSVCP_basic_string_char_ctor_cstr_len(ret, ptr, basic_streambuf_char_egptr(&this->base) - ptr);
+ }
+
+ return MSVCP_basic_string_char_ctor(ret);
}
/* ??0ios_base at std@@IAE at XZ */
More information about the wine-cvs
mailing list