msvcirt: Implement strstreambuf::doallocate.

This commit is contained in:
Iván Matellanes 2015-09-17 11:06:50 +02:00 committed by Alexandre Julliard
parent 222cd629a3
commit 0257ebc838
2 changed files with 68 additions and 2 deletions

View File

@ -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@strstreambuf@@QAEXH@Z */

View File

@ -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@PEAEH0@Z");
SET(p_strstreambuf_ctor, "??0strstreambuf@@QEAA@XZ");
SET(p_strstreambuf_dtor, "??1strstreambuf@@UEAA@XZ");
SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MEAAHXZ");
SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QEAAXH@Z");
SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z");
@ -419,6 +421,7 @@ static BOOL init(void)
SET(p_strstreambuf_ubuffer_ctor, "??0strstreambuf@@QAE@PAEH0@Z");
SET(p_strstreambuf_ctor, "??0strstreambuf@@QAE@XZ");
SET(p_strstreambuf_dtor, "??1strstreambuf@@UAE@XZ");
SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MAEHXZ");
SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QAEXH@Z");
SET(p_ios_copy_ctor, "??0ios@@IAE@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);
}