Commit b08d0bc7 authored by Iván Matellanes's avatar Iván Matellanes Committed by Alexandre Julliard

msvcirt: Add implementation of streambuf::sgetc.

parent 4cef7ad8
...@@ -36,7 +36,7 @@ typedef struct { ...@@ -36,7 +36,7 @@ typedef struct {
const vtable_ptr *vtable; const vtable_ptr *vtable;
int allocated; int allocated;
int unbuffered; int unbuffered;
int unknown; int stored_char;
char *base; char *base;
char *ebuf; char *ebuf;
char *pbase; char *pbase;
...@@ -98,7 +98,7 @@ streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int ...@@ -98,7 +98,7 @@ streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int
TRACE("(%p %p %d)\n", this, buffer, length); TRACE("(%p %p %d)\n", this, buffer, length);
this->vtable = &MSVCP_streambuf_vtable; this->vtable = &MSVCP_streambuf_vtable;
this->allocated = 0; this->allocated = 0;
this->unknown = -1; this->stored_char = EOF;
this->do_lock = -1; this->do_lock = -1;
this->base = NULL; this->base = NULL;
streambuf_setbuf(this, buffer, length); streambuf_setbuf(this, buffer, length);
...@@ -480,6 +480,7 @@ int __thiscall streambuf_unbuffered_get(const streambuf *this) ...@@ -480,6 +480,7 @@ int __thiscall streambuf_unbuffered_get(const streambuf *this)
/* Unexported */ /* Unexported */
DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4) 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) int __thiscall streambuf_underflow(streambuf *this)
{ {
return EOF; return EOF;
...@@ -513,6 +514,20 @@ int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length) ...@@ -513,6 +514,20 @@ int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
return 0; return 0;
} }
/* ?sgetc@streambuf@@QAEHXZ */
/* ?sgetc@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@XZ (MSVCRTI.@) * ??1ios@@UAE@XZ (MSVCRTI.@)
* class ios & __thiscall ios::-ios<<(void) * class ios & __thiscall ios::-ios<<(void)
......
...@@ -693,8 +693,8 @@ ...@@ -693,8 +693,8 @@
@ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) streambuf_setp @ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) streambuf_setp
@ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z # int __thiscall stdiobuf::setrwbuf(int,int) @ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z # int __thiscall stdiobuf::setrwbuf(int,int)
@ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z
@ stub -arch=win32 ?sgetc@streambuf@@QAEHXZ # int __thiscall streambuf::sgetc(void) @ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) streambuf_sgetc
@ stub -arch=win64 ?sgetc@streambuf@@QEAAHXZ @ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) streambuf_sgetc
@ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z # int __thiscall streambuf::sgetn(char *,int) @ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z # int __thiscall streambuf::sgetn(char *,int)
@ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z @ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z
# @ extern ?sh_none@filebuf@@2HB # static int const filebuf::sh_none # @ extern ?sh_none@filebuf@@2HB # static int const filebuf::sh_none
......
...@@ -28,7 +28,7 @@ typedef struct { ...@@ -28,7 +28,7 @@ typedef struct {
const vtable_ptr *vtable; const vtable_ptr *vtable;
int allocated; int allocated;
int unbuffered; int unbuffered;
int unknown; int stored_char;
char *base; char *base;
char *ebuf; char *ebuf;
char *pbase; char *pbase;
...@@ -61,6 +61,7 @@ static void (*__thiscall p_streambuf_pbump)(streambuf*, int); ...@@ -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_setb)(streambuf*, char*, char*, int);
static void (*__thiscall p_streambuf_setlock)(streambuf*); static void (*__thiscall p_streambuf_setlock)(streambuf*);
static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int); static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int);
static int (*__thiscall p_streambuf_sgetc)(streambuf*);
static int (*__thiscall p_streambuf_sync)(streambuf*); static int (*__thiscall p_streambuf_sync)(streambuf*);
static void (*__thiscall p_streambuf_unlock)(streambuf*); static void (*__thiscall p_streambuf_unlock)(streambuf*);
...@@ -145,6 +146,7 @@ static BOOL init(void) ...@@ -145,6 +146,7 @@ static BOOL init(void)
SET(p_streambuf_setb, "?setb@streambuf@@IEAAXPEAD0H@Z"); SET(p_streambuf_setb, "?setb@streambuf@@IEAAXPEAD0H@Z");
SET(p_streambuf_setbuf, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z"); SET(p_streambuf_setbuf, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z");
SET(p_streambuf_setlock, "?setlock@streambuf@@QEAAXXZ"); SET(p_streambuf_setlock, "?setlock@streambuf@@QEAAXXZ");
SET(p_streambuf_sgetc, "?sgetc@streambuf@@QEAAHXZ");
SET(p_streambuf_sync, "?sync@streambuf@@UEAAHXZ"); SET(p_streambuf_sync, "?sync@streambuf@@UEAAHXZ");
SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ");
} else { } else {
...@@ -160,6 +162,7 @@ static BOOL init(void) ...@@ -160,6 +162,7 @@ static BOOL init(void)
SET(p_streambuf_setb, "?setb@streambuf@@IAEXPAD0H@Z"); SET(p_streambuf_setb, "?setb@streambuf@@IAEXPAD0H@Z");
SET(p_streambuf_setbuf, "?setbuf@streambuf@@UAEPAV1@PADH@Z"); SET(p_streambuf_setbuf, "?setbuf@streambuf@@UAEPAV1@PADH@Z");
SET(p_streambuf_setlock, "?setlock@streambuf@@QAEXXZ"); SET(p_streambuf_setlock, "?setlock@streambuf@@QAEXXZ");
SET(p_streambuf_sgetc, "?sgetc@streambuf@@QAEHXZ");
SET(p_streambuf_sync, "?sync@streambuf@@UAEHXZ"); SET(p_streambuf_sync, "?sync@streambuf@@UAEHXZ");
SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ");
} }
...@@ -168,6 +171,18 @@ static BOOL init(void) ...@@ -168,6 +171,18 @@ static BOOL init(void)
return TRUE; 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 struct streambuf_lock_arg
{ {
streambuf *sb; streambuf *sb;
...@@ -197,6 +212,7 @@ static DWORD WINAPI lock_streambuf(void *arg) ...@@ -197,6 +212,7 @@ static DWORD WINAPI lock_streambuf(void *arg)
static void test_streambuf(void) static void test_streambuf(void)
{ {
streambuf sb, sb2, sb3, *psb; streambuf sb, sb2, sb3, *psb;
vtable_ptr test_streambuf_vtbl[11];
struct streambuf_lock_arg lock_arg; struct streambuf_lock_arg lock_arg;
HANDLE thread; HANDLE thread;
char reserve[16]; char reserve[16];
...@@ -226,6 +242,12 @@ static void test_streambuf(void) ...@@ -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.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); 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 */ /* setlock */
ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock); ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock);
call_func1(p_streambuf_setlock, &sb); call_func1(p_streambuf_setlock, &sb);
...@@ -386,6 +408,28 @@ static void test_streambuf(void) ...@@ -386,6 +408,28 @@ static void test_streambuf(void)
ret = (int) call_func1(p_streambuf_sync, &sb3); ret = (int) call_func1(p_streambuf_sync, &sb3);
ok(ret == 0, "sync failed, expected 0 got %d\n", ret); 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]); SetEvent(lock_arg.test[3]);
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
......
...@@ -681,8 +681,8 @@ ...@@ -681,8 +681,8 @@
@ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IEAAXPEAD0@Z @ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IEAAXPEAD0@Z
@ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z @ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z
@ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z
@ stub -arch=win32 ?sgetc@streambuf@@QAEHXZ @ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) msvcirt.?sgetc@streambuf@@QAEHXZ
@ stub -arch=win64 ?sgetc@streambuf@@QEAAHXZ @ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc@streambuf@@QEAAHXZ
@ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z @ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z
@ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z @ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z
# @ extern ?sh_none@filebuf@@2HB # @ extern ?sh_none@filebuf@@2HB
......
...@@ -753,8 +753,8 @@ ...@@ -753,8 +753,8 @@
@ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IEAAXPEAD0@Z @ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IEAAXPEAD0@Z
@ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z @ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z
@ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z
@ stub -arch=win32 ?sgetc@streambuf@@QAEHXZ @ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) msvcirt.?sgetc@streambuf@@QAEHXZ
@ stub -arch=win64 ?sgetc@streambuf@@QEAAHXZ @ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc@streambuf@@QEAAHXZ
@ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z @ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z
@ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z @ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z
# @ extern ?sh_none@filebuf@@2HB # @ extern ?sh_none@filebuf@@2HB
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment