diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index f860c9550d6..8e9f93ab2db 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -778,16 +778,9 @@ void __thiscall streambuf_dbp(streambuf *this) DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8) filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy) { - FIXME("(%p %p) stub\n", this, copy); - return this; -} - -/* ??0filebuf@@QAE@H@Z */ -/* ??0filebuf@@QEAA@H@Z */ -DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8) -filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd) -{ - FIXME("(%p %d) stub\n", this, fd); + TRACE("(%p %p)\n", this, copy); + *this = *copy; + this->base.vtable = &MSVCP_filebuf_vtable; return this; } @@ -796,7 +789,21 @@ filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd) DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16) filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length) { - FIXME("(%p %d %p %d) stub\n", this, fd, buffer, length); + TRACE("(%p %d %p %d)\n", this, fd, buffer, length); + streambuf_reserve_ctor(&this->base, buffer, length); + this->base.vtable = &MSVCP_filebuf_vtable; + this->fd = fd; + this->close = 0; + return this; +} + +/* ??0filebuf@@QAE@H@Z */ +/* ??0filebuf@@QEAA@H@Z */ +DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8) +filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd) +{ + filebuf_fd_reserve_ctor(this, fd, NULL, 0); + this->base.unbuffered = 0; return this; } @@ -805,8 +812,7 @@ filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *bu DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4) filebuf* __thiscall filebuf_ctor(filebuf* this) { - FIXME("(%p) stub\n", this); - return this; + return filebuf_fd_ctor(this, -1); } /* ??1filebuf@@UAE@XZ */ @@ -814,7 +820,8 @@ filebuf* __thiscall filebuf_ctor(filebuf* this) DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4) void __thiscall filebuf_dtor(filebuf* this) { - FIXME("(%p) stub\n", this); + TRACE("(%p)\n", this); + streambuf_dtor(&this->base); } /* ??4filebuf@@QAEAAV0@ABV0@@Z */ @@ -822,8 +829,8 @@ void __thiscall filebuf_dtor(filebuf* this) DEFINE_THISCALL_WRAPPER(filebuf_assign, 8) filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs) { - FIXME("(%p %p) stub\n", this, rhs); - return this; + filebuf_dtor(this); + return filebuf_copy_ctor(this, rhs); } /* ??_Efilebuf@@UAEPAXI@Z */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 30941d56a0e..8437e9c00a4 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -22,6 +22,7 @@ #include "wine/test.h" typedef void (*vtable_ptr)(void); +typedef int filedesc; typedef enum { IOSTATE_goodbit = 0x0, @@ -66,6 +67,13 @@ typedef struct { CRITICAL_SECTION lock; } streambuf; +/* class filebuf */ +typedef struct { + streambuf base; + filedesc fd; + int close; +} filebuf; + /* class ios */ struct _ostream; typedef struct { @@ -121,6 +129,12 @@ static void (*__thiscall p_streambuf_unlock)(streambuf*); static int (*__thiscall p_streambuf_xsgetn)(streambuf*, char*, int); static int (*__thiscall p_streambuf_xsputn)(streambuf*, const char*, int); +/* filebuf */ +static filebuf* (*__thiscall p_filebuf_fd_ctor)(filebuf*, int); +static filebuf* (*__thiscall p_filebuf_fd_reserve_ctor)(filebuf*, int, char*, int); +static filebuf* (*__thiscall p_filebuf_ctor)(filebuf*); +static void (*__thiscall p_filebuf_dtor)(filebuf*); + /* ios */ static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*); static ios* (*__thiscall p_ios_ctor)(ios*); @@ -251,6 +265,11 @@ static BOOL init(void) SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UEAAHPEADH@Z"); SET(p_streambuf_xsputn, "?xsputn@streambuf@@UEAAHPEBDH@Z"); + SET(p_filebuf_fd_ctor, "??0filebuf@@QEAA@H@Z"); + SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QEAA@HPEADH@Z"); + SET(p_filebuf_ctor, "??0filebuf@@QEAA@XZ"); + SET(p_filebuf_dtor, "??1filebuf@@UEAA@XZ"); + SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z"); SET(p_ios_ctor, "??0ios@@IEAA@XZ"); SET(p_ios_sb_ctor, "??0ios@@QEAA@PEAVstreambuf@@@Z"); @@ -301,6 +320,11 @@ static BOOL init(void) SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UAEHPADH@Z"); SET(p_streambuf_xsputn, "?xsputn@streambuf@@UAEHPBDH@Z"); + SET(p_filebuf_fd_ctor, "??0filebuf@@QAE@H@Z"); + SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QAE@HPADH@Z"); + SET(p_filebuf_ctor, "??0filebuf@@QAE@XZ"); + SET(p_filebuf_dtor, "??1filebuf@@UAE@XZ"); + SET(p_ios_copy_ctor, "??0ios@@IAE@ABV0@@Z"); SET(p_ios_ctor, "??0ios@@IAE@XZ"); SET(p_ios_sb_ctor, "??0ios@@QAE@PAVstreambuf@@@Z"); @@ -877,6 +901,37 @@ static void test_streambuf(void) CloseHandle(thread); } +static void test_filebuf(void) +{ + filebuf fb1, fb2, fb3; + + memset(&fb1, 0xab, sizeof(filebuf)); + memset(&fb2, 0xab, sizeof(filebuf)); + memset(&fb3, 0xab, sizeof(filebuf)); + + /* constructors */ + call_func2(p_filebuf_fd_ctor, &fb1, 1); + ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated); + ok(fb1.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", fb1.base.unbuffered); + ok(fb1.fd == 1, "wrong fd, expected 1 got %d\n", fb1.fd); + ok(fb1.close == 0, "wrong value, expected 0 got %d\n", fb1.close); + call_func4(p_filebuf_fd_reserve_ctor, &fb2, 4, NULL, 0); + ok(fb2.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb2.base.allocated); + ok(fb2.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb2.base.unbuffered); + ok(fb2.fd == 4, "wrong fd, expected 4 got %d\n", fb2.fd); + ok(fb2.close == 0, "wrong value, expected 0 got %d\n", fb2.close); + call_func1(p_filebuf_ctor, &fb3); + ok(fb3.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb3.base.allocated); + ok(fb3.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", fb3.base.unbuffered); + ok(fb3.fd == -1, "wrong fd, expected -1 got %d\n", fb3.fd); + ok(fb3.close == 0, "wrong value, expected 0 got %d\n", fb3.close); + + /* destructor */ + call_func1(p_filebuf_dtor, &fb1); + call_func1(p_filebuf_dtor, &fb2); + call_func1(p_filebuf_dtor, &fb3); +} + struct ios_lock_arg { ios *ios_obj; @@ -1160,6 +1215,7 @@ START_TEST(msvcirt) return; test_streambuf(); + test_filebuf(); test_ios(); FreeLibrary(msvcrt);