msvcirt: Implement istream constructors/destructors.

Signed-off-by: Iván Matellanes <matellanes.ivan@gmail.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Iván Matellanes 2016-07-15 10:26:52 +01:00 committed by Alexandre Julliard
parent db90b19a62
commit a035f67cf5
2 changed files with 248 additions and 9 deletions

View File

@ -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@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@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@Z */

View File

@ -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@N@Z");
SET(p_ostream_print_ptr, "??6ostream@@QEAAAEAV0@PEBX@Z");
SET(p_ostream_print_streambuf, "??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z");
SET(p_istream_copy_ctor, "??0istream@@IEAA@AEBV0@@Z");
SET(p_istream_ctor, "??0istream@@IEAA@XZ");
SET(p_istream_sb_ctor, "??0istream@@QEAA@PEAVstreambuf@@@Z");
SET(p_istream_dtor, "??1istream@@UEAA@XZ");
SET(p_istream_assign_sb, "??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z");
SET(p_istream_assign, "??4istream@@IEAAAEAV0@AEBV0@@Z");
SET(p_istream_vbase_dtor, "??_Distream@@QEAAXXZ");
} else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPAXI@Z");
p_operator_delete = (void*)GetProcAddress(msvcrt, "??3@YAXPAX@Z");
@ -592,6 +617,14 @@ static BOOL init(void)
SET(p_ostream_print_double, "??6ostream@@QAEAAV0@N@Z");
SET(p_ostream_print_ptr, "??6ostream@@QAEAAV0@PBX@Z");
SET(p_ostream_print_streambuf, "??6ostream@@QAEAAV0@PAVstreambuf@@@Z");
SET(p_istream_copy_ctor, "??0istream@@IAE@ABV0@@Z");
SET(p_istream_ctor, "??0istream@@IAE@XZ");
SET(p_istream_sb_ctor, "??0istream@@QAE@PAVstreambuf@@@Z");
SET(p_istream_dtor, "??1istream@@UAE@XZ");
SET(p_istream_assign_sb, "??4istream@@IAEAAV0@PAVstreambuf@@@Z");
SET(p_istream_assign, "??4istream@@IAEAAV0@ABV0@@Z");
SET(p_istream_vbase_dtor, "??_Distream@@QAEXXZ");
}
SET(p_ios_static_lock, "?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A");
SET(p_ios_lockc, "?lockc@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);