[2/6] msvcirt: Implement istream constructors/destructors
Iván Matellanes
matellanesivan at gmail.com
Fri Jul 15 04:26:52 CDT 2016
Signed-off-by: Iván Matellanes <matellanes.ivan at gmail.com>
---
dlls/msvcirt/msvcirt.c | 63 ++++++++++++--
dlls/msvcirt/tests/msvcirt.c | 194 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 248 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index bf0967d..33d1b14 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -2898,7 +2898,22 @@ static inline istream* ios_to_istream(const ios *base)
DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
{
- FIXME("(%p %p %d) stub\n", this, sb, virt_init);
+ ios *base;
+
+ TRACE("(%p %p %d)\n", this, sb, virt_init);
+
+ if (virt_init) {
+ this->vbtable = istream_vbtable;
+ base = istream_get_ios(this);
+ ios_sb_ctor(base, sb);
+ } else {
+ base = istream_get_ios(this);
+ ios_init(base, sb);
+ }
+ base->vtable = &MSVCP_istream_vtable;
+ base->flags |= FLAGS_skipws;
+ this->extract_delim = 0;
+ this->count = 0;
return this;
}
@@ -2907,8 +2922,7 @@ istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init
DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
{
- FIXME("(%p %p %d) stub\n", this, copy, virt_init);
- return this;
+ return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
}
/* ??0istream@@IAE at XZ */
@@ -2916,7 +2930,20 @@ istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL v
DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
{
- FIXME("(%p %d) stub\n", this, virt_init);
+ ios *base;
+
+ TRACE("(%p %d)\n", this, virt_init);
+
+ if (virt_init) {
+ this->vbtable = istream_vbtable;
+ base = istream_get_ios(this);
+ ios_ctor(base);
+ } else
+ base = istream_get_ios(this);
+ base->vtable = &MSVCP_istream_vtable;
+ base->flags |= FLAGS_skipws;
+ this->extract_delim = 0;
+ this->count = 0;
return this;
}
@@ -2925,7 +2952,9 @@ istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
void __thiscall istream_dtor(ios *base)
{
- FIXME("(%p) stub\n", base);
+ istream *this = ios_to_istream(base);
+
+ TRACE("(%p)\n", this);
}
/* ??4istream@@IAEAAV0 at PAVstreambuf@@@Z */
@@ -2933,7 +2962,19 @@ void __thiscall istream_dtor(ios *base)
DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
{
- FIXME("(%p %p) stub\n", this, sb);
+ ios *base = istream_get_ios(this);
+
+ TRACE("(%p %p)\n", this, sb);
+
+ ios_init(base, sb);
+ base->state &= IOSTATE_badbit;
+ base->delbuf = 0;
+ base->tie = NULL;
+ base->flags = FLAGS_skipws;
+ base->precision = 6;
+ base->fill = ' ';
+ base->width = 0;
+ this->count = 0;
return this;
}
@@ -2942,8 +2983,7 @@ istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
DEFINE_THISCALL_WRAPPER(istream_assign, 8)
istream* __thiscall istream_assign(istream *this, const istream *rhs)
{
- FIXME("(%p %p) stub\n", this, rhs);
- return this;
+ return istream_assign_sb(this, istream_get_ios(rhs)->sb);
}
/* ??_Distream@@QAEXXZ */
@@ -2951,7 +2991,12 @@ istream* __thiscall istream_assign(istream *this, const istream *rhs)
DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
void __thiscall istream_vbase_dtor(istream *this)
{
- FIXME("(%p) stub\n", this);
+ ios *base = istream_to_ios(this);
+
+ TRACE("(%p)\n", this);
+
+ istream_dtor(base);
+ ios_dtor(base);
}
/* ??_Eistream@@UAEPAXI at Z */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 13b8397..bdbdbf0 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -146,6 +146,14 @@ typedef struct _ostream {
ios base_ios; /* virtually inherited */
} ostream;
+/* class istream */
+typedef struct {
+ const int *vbtable;
+ int extract_delim;
+ int count;
+ ios base_ios; /* virtually inherited */
+} istream;
+
static inline float __port_infinity(void)
{
static const unsigned __inf_bytes = 0x7f800000;
@@ -293,6 +301,15 @@ static ostream* (*__thiscall p_ostream_print_double)(ostream*, double);
static ostream* (*__thiscall p_ostream_print_ptr)(ostream*, const void*);
static ostream* (*__thiscall p_ostream_print_streambuf)(ostream*, streambuf*);
+/* istream */
+static istream* (*__thiscall p_istream_copy_ctor)(istream*, const istream*, BOOL);
+static istream* (*__thiscall p_istream_ctor)(istream*, BOOL);
+static istream* (*__thiscall p_istream_sb_ctor)(istream*, streambuf*, BOOL);
+static void (*__thiscall p_istream_dtor)(ios*);
+static istream* (*__thiscall p_istream_assign_sb)(istream*, streambuf*);
+static istream* (*__thiscall p_istream_assign)(istream*, const istream*);
+static void (*__thiscall p_istream_vbase_dtor)(istream*);
+
/* Emulate a __thiscall */
#ifdef __i386__
@@ -481,6 +498,14 @@ static BOOL init(void)
SET(p_ostream_print_double, "??6ostream@@QEAAAEAV0 at N@Z");
SET(p_ostream_print_ptr, "??6ostream@@QEAAAEAV0 at PEBX@Z");
SET(p_ostream_print_streambuf, "??6ostream@@QEAAAEAV0 at PEAVstreambuf@@@Z");
+
+ SET(p_istream_copy_ctor, "??0istream@@IEAA at AEBV0@@Z");
+ SET(p_istream_ctor, "??0istream@@IEAA at XZ");
+ SET(p_istream_sb_ctor, "??0istream@@QEAA at PEAVstreambuf@@@Z");
+ SET(p_istream_dtor, "??1istream@@UEAA at XZ");
+ SET(p_istream_assign_sb, "??4istream@@IEAAAEAV0 at PEAVstreambuf@@@Z");
+ SET(p_istream_assign, "??4istream@@IEAAAEAV0 at AEBV0@@Z");
+ SET(p_istream_vbase_dtor, "??_Distream@@QEAAXXZ");
} else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z");
p_operator_delete = (void*)GetProcAddress(msvcrt, "??3 at YAXPAX@Z");
@@ -592,6 +617,14 @@ static BOOL init(void)
SET(p_ostream_print_double, "??6ostream@@QAEAAV0 at N@Z");
SET(p_ostream_print_ptr, "??6ostream@@QAEAAV0 at PBX@Z");
SET(p_ostream_print_streambuf, "??6ostream@@QAEAAV0 at PAVstreambuf@@@Z");
+
+ SET(p_istream_copy_ctor, "??0istream@@IAE at ABV0@@Z");
+ SET(p_istream_ctor, "??0istream@@IAE at XZ");
+ SET(p_istream_sb_ctor, "??0istream@@QAE at PAVstreambuf@@@Z");
+ SET(p_istream_dtor, "??1istream@@UAE at XZ");
+ SET(p_istream_assign_sb, "??4istream@@IAEAAV0 at PAVstreambuf@@@Z");
+ SET(p_istream_assign, "??4istream@@IAEAAV0 at ABV0@@Z");
+ SET(p_istream_vbase_dtor, "??_Distream@@QAEXXZ");
}
SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A");
SET(p_ios_lockc, "?lockc at ios@@KAXXZ");
@@ -3371,6 +3404,166 @@ static void test_ostream_print(void)
call_func1(p_strstreambuf_dtor, &ssb_test3);
}
+static void test_istream(void)
+{
+ istream is1, is2, *pis;
+ filebuf fb1, fb2, *pfb;
+ const char filename1[] = "test1";
+ const char filename2[] = "test2";
+
+ memset(&is1, 0xab, sizeof(istream));
+ memset(&is2, 0xab, sizeof(istream));
+ memset(&fb1, 0xab, sizeof(filebuf));
+ memset(&fb2, 0xab, sizeof(filebuf));
+
+ /* constructors/destructors */
+ pis = call_func3(p_istream_sb_ctor, &is1, NULL, TRUE);
+ ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis);
+ ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim);
+ ok(is1.count == 0, "expected 0 got %d\n", is1.count);
+ ok(is1.base_ios.sb == NULL, "expected %p got %p\n", NULL, is1.base_ios.sb);
+ ok(is1.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is1.base_ios.state);
+ ok(is1.base_ios.flags == FLAGS_skipws, "expected %d got %d\n", FLAGS_skipws, is1.base_ios.flags);
+ call_func1(p_istream_vbase_dtor, &is1);
+ is1.extract_delim = is1.count = 0xabababab;
+ memset(&is1.base_ios, 0xab, sizeof(ios));
+ is1.base_ios.delbuf = 0;
+ pis = call_func3(p_istream_sb_ctor, &is1, NULL, FALSE);
+ ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis);
+ ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim);
+ ok(is1.count == 0, "expected 0 got %d\n", is1.count);
+ ok(is1.base_ios.sb == NULL, "expected %p got %p\n", NULL, is1.base_ios.sb);
+ ok(is1.base_ios.state == (0xabababab|IOSTATE_badbit), "expected %d got %d\n",
+ 0xabababab|IOSTATE_badbit, is1.base_ios.state);
+ ok(is1.base_ios.flags == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.flags);
+ call_func1(p_istream_dtor, &is1.base_ios);
+ pis = call_func3(p_istream_sb_ctor, &is1, &fb1.base, FALSE);
+ ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis);
+ ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim);
+ ok(is1.count == 0, "expected 0 got %d\n", is1.count);
+ ok(is1.base_ios.sb == &fb1.base, "expected %p got %p\n", &fb1.base, is1.base_ios.sb);
+ ok(is1.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.state);
+ ok(is1.base_ios.flags == 0xabababab, "expected %d got %d\n", 0xabababab, is1.base_ios.flags);
+ call_func1(p_istream_dtor, &is1.base_ios);
+ call_func1(p_filebuf_ctor, &fb1);
+ pfb = call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in|OPENMODE_out, filebuf_openprot);
+ ok(pfb == &fb1, "wrong return, expected %p got %p\n", &fb1, pfb);
+ ok(fb1.base.allocated == 1, "expected %d got %d\n", 1, fb1.base.allocated);
+ pis = call_func3(p_istream_sb_ctor, &is1, &fb1.base, TRUE);
+ ok(pis == &is1, "wrong return, expected %p got %p\n", &is1, pis);
+ ok(is1.extract_delim == 0, "expected 0 got %d\n", is1.extract_delim);
+ ok(is1.count == 0, "expected 0 got %d\n", is1.count);
+ ok(is1.base_ios.sb == &fb1.base, "expected %p got %p\n", &fb1.base, is1.base_ios.sb);
+ ok(is1.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is1.base_ios.state);
+ ok(is1.base_ios.flags == FLAGS_skipws, "expected %d got %d\n", FLAGS_skipws, is1.base_ios.flags);
+ pis = call_func2(p_istream_ctor, &is2, TRUE);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0, "expected 0 got %d\n", is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb == NULL, "expected %p got %p\n", NULL, is2.base_ios.sb);
+ ok(is2.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is2.base_ios.state);
+ ok(is2.base_ios.flags == FLAGS_skipws, "expected %d got %d\n", FLAGS_skipws, is2.base_ios.flags);
+ call_func1(p_istream_vbase_dtor, &is2);
+ is2.extract_delim = is2.count = 0xabababab;
+ memset(&is2.base_ios, 0xab, sizeof(ios));
+ is2.base_ios.flags &= ~FLAGS_skipws;
+ pis = call_func2(p_istream_ctor, &is2, FALSE);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0, "expected 0 got %d\n", is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb != NULL, "expected not %p got %p\n", NULL, is2.base_ios.sb);
+ ok(is2.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.state);
+ ok(is2.base_ios.flags == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.flags);
+ call_func1(p_istream_dtor, &is2.base_ios);
+ is1.extract_delim = is1.count = 0xcdcdcdcd;
+ is1.base_ios.state = 0xcdcdcdcd;
+ is1.base_ios.flags &= ~FLAGS_skipws;
+ is2.extract_delim = is2.count = 0xabababab;
+ memset(&is2.base_ios, 0xab, sizeof(ios));
+ is2.base_ios.flags &= ~FLAGS_skipws;
+ is2.base_ios.delbuf = 0;
+ pis = call_func3(p_istream_copy_ctor, &is2, &is1, FALSE);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0, "expected 0 got %d\n", is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb == is1.base_ios.sb, "expected %p got %p\n", is1.base_ios.sb, is2.base_ios.sb);
+ ok(is2.base_ios.state == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.state);
+ ok(is2.base_ios.flags == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.flags);
+ call_func1(p_istream_dtor, &is2.base_ios);
+ is2.extract_delim = is2.count = 0xabababab;
+ memset(&is2.base_ios, 0xab, sizeof(ios));
+ pis = call_func3(p_istream_copy_ctor, &is2, &is1, TRUE);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0, "expected 0 got %d\n", is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb == is1.base_ios.sb, "expected %p got %p\n", is1.base_ios.sb, is2.base_ios.sb);
+ ok(is2.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is2.base_ios.state);
+ ok(is2.base_ios.flags == FLAGS_skipws, "expected %d got %d\n", FLAGS_skipws, is2.base_ios.flags);
+
+ /* assignment */
+ is2.extract_delim = is2.count = 0xabababab;
+ is2.base_ios.sb = (streambuf*) 0xabababab;
+ is2.base_ios.state = 0xabababab;
+ is2.base_ios.special[0] = 0xabababab;
+ is2.base_ios.delbuf = 0;
+ is2.base_ios.tie = (ostream*) 0xabababab;
+ is2.base_ios.flags = 0xabababab;
+ is2.base_ios.precision = 0xabababab;
+ is2.base_ios.width = 0xabababab;
+ pis = call_func2(p_istream_assign, &is2, &is1);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0xabababab, "expected %d got %d\n", 0xabababab, is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb == is1.base_ios.sb, "expected %p got %p\n", is1.base_ios.sb, is2.base_ios.sb);
+ ok(is2.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is2.base_ios.state);
+ ok(is2.base_ios.special[0] == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.fill);
+ ok(is2.base_ios.delbuf == 0, "expected 0 got %d\n", is2.base_ios.delbuf);
+ ok(is2.base_ios.tie == NULL, "expected %p got %p\n", NULL, is2.base_ios.tie);
+ ok(is2.base_ios.flags == FLAGS_skipws, "expected %d got %d\n", FLAGS_skipws, is2.base_ios.flags);
+ ok(is2.base_ios.precision == 6, "expected 6 got %d\n", is2.base_ios.precision);
+ ok(is2.base_ios.width == 0, "expected 0 got %d\n", is2.base_ios.width);
+if (0) /* crashes on native */
+ pis = call_func2(p_istream_assign, &is2, NULL);
+ is2.extract_delim = is2.count = 0xabababab;
+ is2.base_ios.sb = (streambuf*) 0xabababab;
+ is2.base_ios.state = 0xabababab;
+ is2.base_ios.special[0] = 0xabababab;
+ is2.base_ios.delbuf = 0;
+ is2.base_ios.tie = (ostream*) 0xabababab;
+ is2.base_ios.flags = 0xabababab;
+ is2.base_ios.precision = 0xabababab;
+ is2.base_ios.width = 0xabababab;
+ pis = call_func2(p_istream_assign_sb, &is2, NULL);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0xabababab, "expected %d got %d\n", 0xabababab, is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb == NULL, "expected %p got %p\n", NULL, is2.base_ios.sb);
+ ok(is2.base_ios.state == IOSTATE_badbit, "expected %d got %d\n", IOSTATE_badbit, is2.base_ios.state);
+ ok(is2.base_ios.special[0] == 0xabababab, "expected %d got %d\n", 0xabababab, is2.base_ios.fill);
+ ok(is2.base_ios.delbuf == 0, "expected 0 got %d\n", is2.base_ios.delbuf);
+ ok(is2.base_ios.tie == NULL, "expected %p got %p\n", NULL, is2.base_ios.tie);
+ ok(is2.base_ios.flags == FLAGS_skipws, "expected %d got %d\n", FLAGS_skipws, is2.base_ios.flags);
+ ok(is2.base_ios.precision == 6, "expected 6 got %d\n", is2.base_ios.precision);
+ ok(is2.base_ios.width == 0, "expected 0 got %d\n", is2.base_ios.width);
+ call_func1(p_filebuf_ctor, &fb2);
+ pfb = call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in|OPENMODE_out, filebuf_openprot);
+ ok(pfb == &fb2, "wrong return, expected %p got %p\n", &fb2, pfb);
+ ok(fb2.base.allocated == 1, "expected %d got %d\n", 1, fb2.base.allocated);
+ pis = call_func2(p_istream_assign_sb, &is2, &fb2.base);
+ ok(pis == &is2, "wrong return, expected %p got %p\n", &is2, pis);
+ ok(is2.extract_delim == 0xabababab, "expected %d got %d\n", 0xabababab, is2.extract_delim);
+ ok(is2.count == 0, "expected 0 got %d\n", is2.count);
+ ok(is2.base_ios.sb == &fb2.base, "expected %p got %p\n", &fb2.base, is2.base_ios.sb);
+ ok(is2.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, is2.base_ios.state);
+
+ call_func1(p_istream_vbase_dtor, &is1);
+ call_func1(p_istream_vbase_dtor, &is2);
+ call_func1(p_filebuf_dtor, &fb1);
+ call_func1(p_filebuf_dtor, &fb2);
+ ok(_unlink(filename1) == 0, "Couldn't unlink file named '%s'\n", filename1);
+ ok(_unlink(filename2) == 0, "Couldn't unlink file named '%s'\n", filename2);
+}
+
START_TEST(msvcirt)
{
if(!init())
@@ -3383,6 +3576,7 @@ START_TEST(msvcirt)
test_ios();
test_ostream();
test_ostream_print();
+ test_istream();
FreeLibrary(msvcrt);
FreeLibrary(msvcirt);
--
2.7.4
More information about the wine-patches
mailing list