=?UTF-8?Q?Iv=C3=A1n=20Matellanes=20?=: msvcirt: Implement strstreambuf:: doallocate.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Sep 18 14:31:17 CDT 2015
Module: wine
Branch: master
Commit: 0257ebc838395dd9934e4ab682483eba72963c5e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0257ebc838395dd9934e4ab682483eba72963c5e
Author: Iván Matellanes <matellanesivan at gmail.com>
Date: Thu Sep 17 11:06:50 2015 +0200
msvcirt: Implement strstreambuf::doallocate.
---
dlls/msvcirt/msvcirt.c | 37 +++++++++++++++++++++++++++++++++++--
dlls/msvcirt/tests/msvcirt.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 4b826db..d2c39eb 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -1280,8 +1280,41 @@ strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned i
DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
int __thiscall strstreambuf_doallocate(strstreambuf *this)
{
- FIXME("(%p) stub\n", this);
- return EOF;
+ char *prev_buffer = this->base.base, *new_buffer;
+ LONG prev_size = this->base.ebuf - this->base.base, new_size;
+
+ TRACE("(%p)\n", this);
+
+ /* calculate the size of the new buffer */
+ new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
+ /* get a new buffer */
+ if (this->f_alloc)
+ new_buffer = this->f_alloc(new_size);
+ else
+ new_buffer = MSVCRT_operator_new(new_size);
+ if (!new_buffer)
+ return EOF;
+ if (this->base.ebuf) {
+ /* copy the contents and adjust the pointers */
+ memcpy(new_buffer, this->base.base, prev_size);
+ if (this->base.egptr) {
+ this->base.eback += new_buffer - prev_buffer;
+ this->base.gptr += new_buffer - prev_buffer;
+ this->base.egptr += new_buffer - prev_buffer;
+ }
+ if (this->base.epptr) {
+ this->base.pbase += new_buffer - prev_buffer;
+ this->base.pptr += new_buffer - prev_buffer;
+ this->base.epptr += new_buffer - prev_buffer;
+ }
+ /* free the old buffer */
+ if (this->f_free)
+ this->f_free(this->base.base);
+ else
+ MSVCRT_operator_delete(this->base.base);
+ }
+ streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
+ return 1;
}
/* ?freeze at strstreambuf@@QAEXH at Z */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index aaa9f1c..c7398d6 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -193,6 +193,7 @@ static strstreambuf* (*__thiscall p_strstreambuf_buffer_ctor)(strstreambuf*, cha
static strstreambuf* (*__thiscall p_strstreambuf_ubuffer_ctor)(strstreambuf*, unsigned char*, int, unsigned char*);
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);
/* ios */
@@ -346,6 +347,7 @@ static BOOL init(void)
SET(p_strstreambuf_ubuffer_ctor, "??0strstreambuf@@QEAA at PEAEH0@Z");
SET(p_strstreambuf_ctor, "??0strstreambuf@@QEAA at XZ");
SET(p_strstreambuf_dtor, "??1strstreambuf@@UEAA at XZ");
+ SET(p_strstreambuf_doallocate, "?doallocate at strstreambuf@@MEAAHXZ");
SET(p_strstreambuf_freeze, "?freeze at strstreambuf@@QEAAXH at Z");
SET(p_ios_copy_ctor, "??0ios@@IEAA at AEBV0@@Z");
@@ -419,6 +421,7 @@ static BOOL init(void)
SET(p_strstreambuf_ubuffer_ctor, "??0strstreambuf@@QAE at PAEH0@Z");
SET(p_strstreambuf_ctor, "??0strstreambuf@@QAE at XZ");
SET(p_strstreambuf_dtor, "??1strstreambuf@@UAE at XZ");
+ SET(p_strstreambuf_doallocate, "?doallocate at strstreambuf@@MAEHXZ");
SET(p_strstreambuf_freeze, "?freeze at strstreambuf@@QAEXH at Z");
SET(p_ios_copy_ctor, "??0ios@@IAE at ABV0@@Z");
@@ -1420,6 +1423,7 @@ static void test_strstreambuf(void)
{
strstreambuf ssb1, ssb2;
char buffer[64];
+ int ret;
memset(&ssb1, 0xab, sizeof(strstreambuf));
memset(&ssb2, 0xab, sizeof(strstreambuf));
@@ -1544,6 +1548,35 @@ static void test_strstreambuf(void)
call_func2(p_strstreambuf_freeze, &ssb2, 0);
ok(ssb2.dynamic == 1, "expected 1, got %d\n", ssb2.dynamic);
+ /* doallocate */
+ ssb2.dynamic = 0;
+ ssb2.increase = 5;
+ ret = (int) call_func1(p_strstreambuf_doallocate, &ssb2);
+ ok(ret == 1, "return value %d\n", ret);
+ ok(ssb2.base.ebuf == ssb2.base.base + 5, "expected %p, got %p\n", ssb2.base.base + 5, ssb2.base.ebuf);
+ ssb2.base.eback = ssb2.base.base;
+ ssb2.base.gptr = ssb2.base.base + 2;
+ ssb2.base.egptr = ssb2.base.base + 4;
+ strcpy(ssb2.base.base, "Check");
+ ret = (int) call_func1(p_strstreambuf_doallocate, &ssb2);
+ ok(ret == 1, "return value %d\n", ret);
+ ok(ssb2.base.ebuf == ssb2.base.base + 10, "expected %p, got %p\n", ssb2.base.base + 10, ssb2.base.ebuf);
+ ok(ssb2.base.eback == ssb2.base.base, "wrong get base, expected %p got %p\n", ssb2.base.base, ssb2.base.eback);
+ ok(ssb2.base.gptr == ssb2.base.base + 2, "wrong get pointer, expected %p got %p\n", ssb2.base.base + 2, ssb2.base.gptr);
+ ok(ssb2.base.egptr == ssb2.base.base + 4, "wrong get end, expected %p got %p\n", ssb2.base.base + 4, ssb2.base.egptr);
+ ok(!strncmp(ssb2.base.base, "Check", 5), "strings are not equal\n");
+ ssb2.base.pbase = ssb2.base.pptr = ssb2.base.base + 4;
+ ssb2.base.epptr = ssb2.base.ebuf;
+ ssb2.increase = -3;
+ ret = (int) call_func1(p_strstreambuf_doallocate, &ssb2);
+ ok(ret == 1, "return value %d\n", ret);
+ ok(ssb2.base.ebuf == ssb2.base.base + 11, "expected %p, got %p\n", ssb2.base.base + 11, ssb2.base.ebuf);
+ ok(ssb2.base.pbase == ssb2.base.base + 4, "wrong put base, expected %p got %p\n", ssb2.base.base + 4, ssb2.base.pbase);
+ ok(ssb2.base.pptr == ssb2.base.base + 4, "wrong put pointer, expected %p got %p\n", ssb2.base.base + 4, ssb2.base.pptr);
+ ok(ssb2.base.epptr == ssb2.base.base + 10, "wrong put end, expected %p got %p\n", ssb2.base.base + 10, ssb2.base.epptr);
+ ok(!strncmp(ssb2.base.base, "Check", 5), "strings are not equal\n");
+ ssb2.dynamic = 1;
+
call_func1(p_strstreambuf_dtor, &ssb1);
call_func1(p_strstreambuf_dtor, &ssb2);
}
More information about the wine-cvs
mailing list