=?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