Module: wine Branch: master Commit: 60d1d6f5952e8b5d6fb0327a28c047058851fa70 URL: http://source.winehq.org/git/wine.git/?a=commit;h=60d1d6f5952e8b5d6fb0327a28...
Author: Iván Matellanes matellanesivan@gmail.com Date: Thu Sep 17 11:06:54 2015 +0200
msvcirt: Implement strstreambuf::overflow.
---
dlls/msvcirt/msvcirt.c | 14 +++++++-- dlls/msvcirt/tests/msvcirt.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index a320879..0a34ac0 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -1332,8 +1332,18 @@ void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen) DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8) int __thiscall strstreambuf_overflow(strstreambuf *this, int c) { - FIXME("(%p %d) stub\n", this, c); - return EOF; + TRACE("(%p %d)\n", this, c); + if (this->base.pptr >= this->base.epptr) { + /* increase the buffer size if it's dynamic */ + if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF) + return EOF; + if (!this->base.epptr) + this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base; + this->base.epptr = this->base.ebuf; + } + if (c != EOF) + *this->base.pptr++ = c; + return 1; }
/* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 5e29e9a..9bf93af 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -195,6 +195,7 @@ static strstreambuf* (*__thiscall p_strstreambuf_ctor)(strstreambuf*); static void (*__thiscall p_strstreambuf_dtor)(strstreambuf*); static int (*__thiscall p_strstreambuf_doallocate)(strstreambuf*); static void (*__thiscall p_strstreambuf_freeze)(strstreambuf*, int); +static int (*__thiscall p_strstreambuf_overflow)(strstreambuf*, int); static streambuf* (*__thiscall p_strstreambuf_setbuf)(strstreambuf*, char*, int); static int (*__thiscall p_strstreambuf_underflow)(strstreambuf*);
@@ -351,6 +352,7 @@ static BOOL init(void) SET(p_strstreambuf_dtor, "??1strstreambuf@@UEAA@XZ"); SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MEAAHXZ"); SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QEAAXH@Z"); + SET(p_strstreambuf_overflow, "?overflow@strstreambuf@@UEAAHH@Z"); SET(p_strstreambuf_setbuf, "?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z"); SET(p_strstreambuf_underflow, "?underflow@strstreambuf@@UEAAHXZ");
@@ -427,6 +429,7 @@ static BOOL init(void) SET(p_strstreambuf_dtor, "??1strstreambuf@@UAE@XZ"); SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MAEHXZ"); SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QAEXH@Z"); + SET(p_strstreambuf_overflow, "?overflow@strstreambuf@@UAEHH@Z"); SET(p_strstreambuf_setbuf, "?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z"); SET(p_strstreambuf_underflow, "?underflow@strstreambuf@@UAEHXZ");
@@ -1624,6 +1627,71 @@ static void test_strstreambuf(void) ret = (int) call_func1(p_strstreambuf_underflow, &ssb2); ok(ret == EOF, "expected EOF got %d\n", ret);
+ /* overflow */ + ssb1.base.pptr = ssb1.base.epptr - 1; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb1, EOF); + ok(ret == 1, "expected 1 got %d\n", ret); + ret = (int) call_func2(p_strstreambuf_overflow, &ssb1, 'A'); + ok(ret == 1, "expected 1 got %d\n", ret); + ok(ssb1.base.pptr == ssb1.base.epptr, "wrong put pointer, expected %p got %p\n", ssb1.base.epptr, ssb1.base.pptr); + ok(*(ssb1.base.pptr - 1) == 'A', "expected 'A' got %d\n", *(ssb1.base.pptr - 1)); + ret = (int) call_func2(p_strstreambuf_overflow, &ssb1, 'B'); + ok(ret == EOF, "expected EOF got %d\n", ret); + ret = (int) call_func2(p_strstreambuf_overflow, &ssb1, EOF); + ok(ret == EOF, "expected EOF got %d\n", ret); + ssb2.dynamic = 0; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb2, 'C'); + ok(ret == EOF, "expected EOF got %d\n", ret); + ssb2.dynamic = 1; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb2, 'C'); + ok(ret == 1, "expected 1 got %d\n", ret); + ok(ssb2.base.ebuf == ssb2.base.base + 12, "expected %p got %p\n", ssb2.base.base + 12, ssb2.base.ebuf); + ok(ssb2.base.gptr == ssb2.base.base + 11, "wrong get pointer, expected %p got %p\n", ssb2.base.base + 11, ssb2.base.gptr); + ok(ssb2.base.pbase == ssb2.base.base + 11, "wrong put base, expected %p got %p\n", ssb2.base.base + 11, ssb2.base.pbase); + ok(ssb2.base.pptr == ssb2.base.base + 12, "wrong put pointer, expected %p got %p\n", ssb2.base.base + 12, ssb2.base.pptr); + ok(ssb2.base.epptr == ssb2.base.base + 12, "wrong put end, expected %p got %p\n", ssb2.base.base + 12, ssb2.base.epptr); + ok(*(ssb2.base.pptr - 1) == 'C', "expected 'C' got %d\n", *(ssb2.base.pptr - 1)); + ssb2.increase = 4; + ssb2.base.eback = ssb2.base.gptr = ssb2.base.egptr = NULL; + ssb2.base.pbase = ssb2.base.pptr = ssb2.base.epptr = NULL; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb2, 'D'); + ok(ret == 1, "expected 1 got %d\n", ret); + ok(ssb2.base.ebuf == ssb2.base.base + 16, "expected %p got %p\n", ssb2.base.base + 16, ssb2.base.ebuf); + ok(ssb2.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, ssb2.base.gptr); + ok(ssb2.base.pbase == ssb2.base.base, "wrong put base, expected %p got %p\n", ssb2.base.base, ssb2.base.pbase); + ok(ssb2.base.pptr == ssb2.base.base + 1, "wrong put pointer, expected %p got %p\n", ssb2.base.base + 1, ssb2.base.pptr); + ok(ssb2.base.epptr == ssb2.base.base + 16, "wrong put end, expected %p got %p\n", ssb2.base.base + 16, ssb2.base.epptr); + ok(*(ssb2.base.pptr - 1) == 'D', "expected 'D' got %d\n", *(ssb2.base.pptr - 1)); + ssb2.base.pbase = ssb2.base.base + 3; + ssb2.base.pptr = ssb2.base.epptr + 5; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb2, 'E'); + ok(ret == 1, "expected 1 got %d\n", ret); + ok(ssb2.base.ebuf == ssb2.base.base + 20, "expected %p got %p\n", ssb2.base.base + 20, ssb2.base.ebuf); + ok(ssb2.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, ssb2.base.gptr); + ok(ssb2.base.pbase == ssb2.base.base + 3, "wrong put base, expected %p got %p\n", ssb2.base.base + 3, ssb2.base.pbase); + ok(ssb2.base.pptr == ssb2.base.base + 22, "wrong put pointer, expected %p got %p\n", ssb2.base.base + 22, ssb2.base.pptr); + ok(ssb2.base.epptr == ssb2.base.base + 20, "wrong put end, expected %p got %p\n", ssb2.base.base + 20, ssb2.base.epptr); + ok(*(ssb2.base.pptr - 1) == 'E', "expected 'E' got %d\n", *(ssb2.base.pptr - 1)); + ssb2.base.egptr = ssb2.base.base + 2; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb2, 'F'); + ok(ret == 1, "expected 1 got %d\n", ret); + ok(ssb2.base.ebuf == ssb2.base.base + 24, "expected %p got %p\n", ssb2.base.base + 24, ssb2.base.ebuf); + ok(ssb2.base.gptr != NULL, "wrong get pointer, expected != NULL\n"); + ok(ssb2.base.pbase == ssb2.base.base + 3, "wrong put base, expected %p got %p\n", ssb2.base.base + 3, ssb2.base.pbase); + ok(ssb2.base.pptr == ssb2.base.base + 23, "wrong put pointer, expected %p got %p\n", ssb2.base.base + 23, ssb2.base.pptr); + ok(ssb2.base.epptr == ssb2.base.base + 24, "wrong put end, expected %p got %p\n", ssb2.base.base + 24, ssb2.base.epptr); + ok(*(ssb2.base.pptr - 1) == 'F', "expected 'F' got %d\n", *(ssb2.base.pptr - 1)); + ssb2.base.eback = ssb2.base.gptr = ssb2.base.base; + ssb2.base.epptr = NULL; + ret = (int) call_func2(p_strstreambuf_overflow, &ssb2, 'G'); + ok(ret == 1, "expected 1 got %d\n", ret); + ok(ssb2.base.ebuf == ssb2.base.base + 28, "expected %p got %p\n", ssb2.base.base + 28, ssb2.base.ebuf); + ok(ssb2.base.gptr == ssb2.base.base, "wrong get pointer, expected %p got %p\n", ssb2.base.base, ssb2.base.gptr); + ok(ssb2.base.pbase == ssb2.base.base + 2, "wrong put base, expected %p got %p\n", ssb2.base.base + 2, ssb2.base.pbase); + ok(ssb2.base.pptr == ssb2.base.base + 3, "wrong put pointer, expected %p got %p\n", ssb2.base.base + 3, ssb2.base.pptr); + ok(ssb2.base.epptr == ssb2.base.base + 28, "wrong put end, expected %p got %p\n", ssb2.base.base + 28, ssb2.base.epptr); + ok(*(ssb2.base.pptr - 1) == 'G', "expected 'G' got %d\n", *(ssb2.base.pptr - 1)); + call_func1(p_strstreambuf_dtor, &ssb1); call_func1(p_strstreambuf_dtor, &ssb2); }