=?UTF-8?Q?Iv=C3=A1n=20Matellanes=20?=: msvcirt: Add implementation of streambuf::sgetc.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jun 17 10:18:10 CDT 2015


Module: wine
Branch: master
Commit: b08d0bc75de8224b95d299b83290fcbc0b00c18f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b08d0bc75de8224b95d299b83290fcbc0b00c18f

Author: Iván Matellanes <matellanesivan at gmail.com>
Date:   Tue Jun 16 11:32:19 2015 +0200

msvcirt: Add implementation of streambuf::sgetc.

---

 dlls/msvcirt/msvcirt.c       | 19 ++++++++++++++++--
 dlls/msvcirt/msvcirt.spec    |  4 ++--
 dlls/msvcirt/tests/msvcirt.c | 46 +++++++++++++++++++++++++++++++++++++++++++-
 dlls/msvcrt20/msvcrt20.spec  |  4 ++--
 dlls/msvcrt40/msvcrt40.spec  |  4 ++--
 5 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 8c05fe3..03db71c 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -36,7 +36,7 @@ typedef struct {
     const vtable_ptr *vtable;
     int allocated;
     int unbuffered;
-    int unknown;
+    int stored_char;
     char *base;
     char *ebuf;
     char *pbase;
@@ -98,7 +98,7 @@ streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int
     TRACE("(%p %p %d)\n", this, buffer, length);
     this->vtable = &MSVCP_streambuf_vtable;
     this->allocated = 0;
-    this->unknown = -1;
+    this->stored_char = EOF;
     this->do_lock = -1;
     this->base = NULL;
     streambuf_setbuf(this, buffer, length);
@@ -480,6 +480,7 @@ int __thiscall streambuf_unbuffered_get(const streambuf *this)
 
 /* Unexported */
 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
+#define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
 int __thiscall streambuf_underflow(streambuf *this)
 {
     return EOF;
@@ -513,6 +514,20 @@ int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
     return 0;
 }
 
+/* ?sgetc at streambuf@@QAEHXZ */
+/* ?sgetc at streambuf@@QEAAHXZ */
+DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
+int __thiscall streambuf_sgetc(streambuf *this)
+{
+    TRACE("(%p)\n", this);
+    if (this->unbuffered) {
+        if (this->stored_char == EOF)
+            this->stored_char = call_streambuf_underflow(this);
+        return this->stored_char;
+    } else
+        return call_streambuf_underflow(this);
+}
+
 /******************************************************************
  *		 ??1ios@@UAE at XZ (MSVCRTI.@)
  *        class ios & __thiscall ios::-ios<<(void)
diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec
index c9f5c06..e879a7f 100644
--- a/dlls/msvcirt/msvcirt.spec
+++ b/dlls/msvcirt/msvcirt.spec
@@ -693,8 +693,8 @@
 @ cdecl -arch=win64 ?setp at streambuf@@IEAAXPEAD0 at Z(ptr ptr ptr) streambuf_setp
 @ stub -arch=win32 ?setrwbuf at stdiobuf@@QAEHHH at Z  # int __thiscall stdiobuf::setrwbuf(int,int)
 @ stub -arch=win64 ?setrwbuf at stdiobuf@@QEAAHHH at Z
-@ stub -arch=win32 ?sgetc at streambuf@@QAEHXZ  # int __thiscall streambuf::sgetc(void)
-@ stub -arch=win64 ?sgetc at streambuf@@QEAAHXZ
+@ thiscall -arch=win32 ?sgetc at streambuf@@QAEHXZ(ptr) streambuf_sgetc
+@ cdecl -arch=win64 ?sgetc at streambuf@@QEAAHXZ(ptr) streambuf_sgetc
 @ stub -arch=win32 ?sgetn at streambuf@@QAEHPADH at Z  # int __thiscall streambuf::sgetn(char *,int)
 @ stub -arch=win64 ?sgetn at streambuf@@QEAAHPEADH at Z
 # @ extern ?sh_none at filebuf@@2HB  # static int const filebuf::sh_none
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 1a6ce5d..7155740 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -28,7 +28,7 @@ typedef struct {
     const vtable_ptr *vtable;
     int allocated;
     int unbuffered;
-    int unknown;
+    int stored_char;
     char *base;
     char *ebuf;
     char *pbase;
@@ -61,6 +61,7 @@ static void (*__thiscall p_streambuf_pbump)(streambuf*, int);
 static void (*__thiscall p_streambuf_setb)(streambuf*, char*, char*, int);
 static void (*__thiscall p_streambuf_setlock)(streambuf*);
 static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int);
+static int (*__thiscall p_streambuf_sgetc)(streambuf*);
 static int (*__thiscall p_streambuf_sync)(streambuf*);
 static void (*__thiscall p_streambuf_unlock)(streambuf*);
 
@@ -145,6 +146,7 @@ static BOOL init(void)
         SET(p_streambuf_setb, "?setb at streambuf@@IEAAXPEAD0H at Z");
         SET(p_streambuf_setbuf, "?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z");
         SET(p_streambuf_setlock, "?setlock at streambuf@@QEAAXXZ");
+        SET(p_streambuf_sgetc, "?sgetc at streambuf@@QEAAHXZ");
         SET(p_streambuf_sync, "?sync at streambuf@@UEAAHXZ");
         SET(p_streambuf_unlock, "?unlock at streambuf@@QEAAXXZ");
     } else {
@@ -160,6 +162,7 @@ static BOOL init(void)
         SET(p_streambuf_setb, "?setb at streambuf@@IAEXPAD0H at Z");
         SET(p_streambuf_setbuf, "?setbuf at streambuf@@UAEPAV1 at PADH@Z");
         SET(p_streambuf_setlock, "?setlock at streambuf@@QAEXXZ");
+        SET(p_streambuf_sgetc, "?sgetc at streambuf@@QAEHXZ");
         SET(p_streambuf_sync, "?sync at streambuf@@UAEHXZ");
         SET(p_streambuf_unlock, "?unlock at streambuf@@QAEXXZ");
     }
@@ -168,6 +171,18 @@ static BOOL init(void)
     return TRUE;
 }
 
+static int underflow_count;
+
+#ifdef __i386__
+static int __thiscall test_streambuf_underflow(void)
+#else
+static int __thiscall test_streambuf_underflow(streambuf *this)
+#endif
+{
+    underflow_count++;
+    return 'u';
+}
+
 struct streambuf_lock_arg
 {
     streambuf *sb;
@@ -197,6 +212,7 @@ static DWORD WINAPI lock_streambuf(void *arg)
 static void test_streambuf(void)
 {
     streambuf sb, sb2, sb3, *psb;
+    vtable_ptr test_streambuf_vtbl[11];
     struct streambuf_lock_arg lock_arg;
     HANDLE thread;
     char reserve[16];
@@ -226,6 +242,12 @@ static void test_streambuf(void)
     ok(sb3.base == NULL, "wrong base pointer, expected %p got %p\n", NULL, sb3.base);
     ok(sb3.ebuf == NULL, "wrong ebuf pointer, expected %p got %p\n", NULL, sb3.ebuf);
 
+    memcpy(test_streambuf_vtbl, sb.vtable, sizeof(test_streambuf_vtbl));
+    test_streambuf_vtbl[8] = (vtable_ptr)&test_streambuf_underflow;
+    sb2.vtable = test_streambuf_vtbl;
+    sb3.vtable = test_streambuf_vtbl;
+    underflow_count = 0;
+
     /* setlock */
     ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock);
     call_func1(p_streambuf_setlock, &sb);
@@ -386,6 +408,28 @@ static void test_streambuf(void)
     ret = (int) call_func1(p_streambuf_sync, &sb3);
     ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
 
+    /* sgetc */
+    ret = (int) call_func1(p_streambuf_sgetc, &sb2);
+    ok(ret == 'u', "expected 'u' got '%c'\n", ret);
+    ok(underflow_count == 1, "expected call to underflow\n");
+    ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char);
+    sb2.gptr = sb2.eback;
+    *sb2.gptr = 'a';
+    ret = (int) call_func1(p_streambuf_sgetc, &sb2);
+    ok(ret == 'u', "expected 'u' got '%c'\n", ret);
+    ok(underflow_count == 2, "expected call to underflow\n");
+    ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char);
+    sb2.gptr = sb2.egptr;
+    ret = (int) call_func1(p_streambuf_sgetc, &sb3);
+    ok(ret == 'u', "expected 'u' got '%c'\n", ret);
+    ok(underflow_count == 3, "expected call to underflow\n");
+    ok(sb3.stored_char == 'u', "wrong stored character, expected 'u' got %c\n", sb3.stored_char);
+    sb3.stored_char = 'b';
+    ret = (int) call_func1(p_streambuf_sgetc, &sb3);
+    ok(ret == 'b', "expected 'b' got '%c'\n", ret);
+    ok(underflow_count == 3, "no call to underflow expected\n");
+    ok(sb3.stored_char == 'b', "wrong stored character, expected 'b' got %c\n", sb3.stored_char);
+
     SetEvent(lock_arg.test[3]);
     WaitForSingleObject(thread, INFINITE);
 
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec
index 9d212fe..14846f3 100644
--- a/dlls/msvcrt20/msvcrt20.spec
+++ b/dlls/msvcrt20/msvcrt20.spec
@@ -681,8 +681,8 @@
 @ cdecl -arch=win64 ?setp at streambuf@@IEAAXPEAD0 at Z(ptr ptr ptr) msvcirt.?setp at streambuf@@IEAAXPEAD0 at Z
 @ stub -arch=win32 ?setrwbuf at stdiobuf@@QAEHHH at Z
 @ stub -arch=win64 ?setrwbuf at stdiobuf@@QEAAHHH at Z
-@ stub -arch=win32 ?sgetc at streambuf@@QAEHXZ
-@ stub -arch=win64 ?sgetc at streambuf@@QEAAHXZ
+@ thiscall -arch=win32 ?sgetc at streambuf@@QAEHXZ(ptr) msvcirt.?sgetc at streambuf@@QAEHXZ
+@ cdecl -arch=win64 ?sgetc at streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc at streambuf@@QEAAHXZ
 @ stub -arch=win32 ?sgetn at streambuf@@QAEHPADH at Z
 @ stub -arch=win64 ?sgetn at streambuf@@QEAAHPEADH at Z
 # @ extern ?sh_none at filebuf@@2HB
diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec
index a1cabf9..c794b6e 100644
--- a/dlls/msvcrt40/msvcrt40.spec
+++ b/dlls/msvcrt40/msvcrt40.spec
@@ -753,8 +753,8 @@
 @ cdecl -arch=win64 ?setp at streambuf@@IEAAXPEAD0 at Z(ptr ptr ptr) msvcirt.?setp at streambuf@@IEAAXPEAD0 at Z
 @ stub -arch=win32 ?setrwbuf at stdiobuf@@QAEHHH at Z
 @ stub -arch=win64 ?setrwbuf at stdiobuf@@QEAAHHH at Z
-@ stub -arch=win32 ?sgetc at streambuf@@QAEHXZ
-@ stub -arch=win64 ?sgetc at streambuf@@QEAAHXZ
+@ thiscall -arch=win32 ?sgetc at streambuf@@QAEHXZ(ptr) msvcirt.?sgetc at streambuf@@QAEHXZ
+@ cdecl -arch=win64 ?sgetc at streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc at streambuf@@QEAAHXZ
 @ stub -arch=win32 ?sgetn at streambuf@@QAEHPADH at Z
 @ stub -arch=win64 ?sgetn at streambuf@@QEAAHPEADH at Z
 # @ extern ?sh_none at filebuf@@2HB




More information about the wine-cvs mailing list