[6/6] msvcirt: Implement istream::operator>> for streambufs.
Iván Matellanes
matellanesivan at gmail.com
Mon Aug 1 05:40:43 CDT 2016
Signed-off-by: Iván Matellanes <matellanes.ivan at gmail.com>
---
dlls/msvcirt/msvcirt.c | 12 +++++++++++-
dlls/msvcirt/tests/msvcirt.c | 31 +++++++++++++++++++++++++++++--
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 6964809..bdbf7f7 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -3720,7 +3720,17 @@ istream* __thiscall istream_read_long_double(istream *this, double *ld)
DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
{
- FIXME("(%p %p) stub\n", this, sb);
+ ios *base = istream_get_ios(this);
+ int ch;
+
+ TRACE("(%p %p)\n", this, sb);
+
+ if (istream_ipfx(this, 0)) {
+ while ((ch = streambuf_sbumpc(base->sb)) != EOF)
+ if (streambuf_sputc(sb, ch) == EOF)
+ base->state |= IOSTATE_failbit;
+ istream_isfx(this);
+ }
return this;
}
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 0de96c5..f9fbb26 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -338,6 +338,7 @@ static istream* (*__thiscall p_istream_read_unsigned_long)(istream*, ULONG*);
static istream* (*__thiscall p_istream_read_float)(istream*, float*);
static istream* (*__thiscall p_istream_read_double)(istream*, double*);
static istream* (*__thiscall p_istream_read_long_double)(istream*, double*);
+static istream* (*__thiscall p_istream_read_streambuf)(istream*, streambuf*);
/* Emulate a __thiscall */
#ifdef __i386__
@@ -564,6 +565,7 @@ static BOOL init(void)
SET(p_istream_read_float, "??5istream@@QEAAAEAV0 at AEAM@Z");
SET(p_istream_read_double, "??5istream@@QEAAAEAV0 at AEAN@Z");
SET(p_istream_read_long_double, "??5istream@@QEAAAEAV0 at AEAO@Z");
+ SET(p_istream_read_streambuf, "??5istream@@QEAAAEAV0 at PEAVstreambuf@@@Z");
} else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z");
p_operator_delete = (void*)GetProcAddress(msvcrt, "??3 at YAXPAX@Z");
@@ -712,6 +714,7 @@ static BOOL init(void)
SET(p_istream_read_float, "??5istream@@QAEAAV0 at AAM@Z");
SET(p_istream_read_double, "??5istream@@QAEAAV0 at AAN@Z");
SET(p_istream_read_long_double, "??5istream@@QAEAAV0 at AAO@Z");
+ SET(p_istream_read_streambuf, "??5istream@@QAEAAV0 at PAVstreambuf@@@Z");
}
SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A");
SET(p_ios_lockc, "?lockc at ios@@KAXXZ");
@@ -4887,7 +4890,7 @@ static void test_istream_getdouble(void)
static void test_istream_read(void)
{
istream is, *pis;
- strstreambuf ssb, *pssb;
+ strstreambuf ssb, ssb_test, *pssb;
int len, ret, i;
/* makes tables narrower */
@@ -4903,9 +4906,10 @@ static void test_istream_read(void)
ULONG ul, ulong_out[] = {4294967295ul, 4294967294ul, 2147483648ul, 1ul};
float f, float_out[] = {123.456f, 0.0f, 1.0f, 0.1f, -1.0f, -0.1f, FLT_MIN, -FLT_MIN, FLT_MAX, -FLT_MAX};
double d, double_out[] = {1.0, 0.1, 0.0, INFINITY, -INFINITY};
+ const char *sbf_out[] = {"", "abcd\n", "abcdef"};
struct istream_read_test {
enum { type_chr, type_str, type_shrt, type_ushrt, type_int, type_uint,
- type_long, type_ulong, type_flt, type_dbl, type_ldbl } type;
+ type_long, type_ulong, type_flt, type_dbl, type_ldbl, type_sbf } type;
const char *stream_content;
ios_flags flags;
int width;
@@ -5041,8 +5045,19 @@ static void test_istream_read(void)
{type_ldbl, "-1.69781699841e-1475l", 0, 6, /* 0.0 */ 2, IOSTATE_goodbit, 6, 20, FALSE},
{type_ldbl, "1.69781699841e1475", 0, 6, /* INF */ 3, IOSTATE_eofbit, 6, 18, FALSE},
{type_ldbl, "-1.69781699841e1475", 0, 6, /* -INF */ 4, IOSTATE_eofbit, 6, 19, FALSE},
+ /* streambuf */
+ {type_sbf, "", FLAGS_skipws, 6, /* "" */ 0, IOSTATE_faileof, 6, 0, FALSE},
+ {type_sbf, " ", FLAGS_skipws, 6, /* "" */ 0, IOSTATE_faileof, 6, 2, FALSE},
+ {type_sbf, "\r\nabcd\n", FLAGS_skipws, 6, /* "abc\n" */ 1, IOSTATE_goodbit, 6, 8, FALSE},
+ {type_sbf, "abcdefg\n", 0, 6, /* "abcde" */ 2, IOSTATE_failbit, 6, 9, FALSE},
+ {type_sbf, "abcdefg\n", 0, 0, /* "" */ 0, IOSTATE_failbit, 0, 9, FALSE}
};
+ pssb = call_func2(p_strstreambuf_dynamic_ctor, &ssb_test, 64);
+ ok(pssb == &ssb_test, "wrong return, expected %p got %p\n", &ssb_test, pssb);
+ ret = (int) call_func1(p_streambuf_allocate, &ssb_test.base);
+ ok(ret == 1, "expected 1 got %d\n", ret);
+ ssb_test.dynamic = 0;
pssb = call_func2(p_strstreambuf_dynamic_ctor, &ssb, 64);
ok(pssb == &ssb, "wrong return, expected %p got %p\n", &ssb, pssb);
ret = (int) call_func1(p_streambuf_allocate, &ssb.base);
@@ -5127,6 +5142,16 @@ static void test_istream_read(void)
ok(d == double_out[tests[i].expected_val], "Test %d: expected %f got %f\n", i,
double_out[tests[i].expected_val], d);
break;
+ case type_sbf:
+ ssb_test.base.pbase = ssb_test.base.pptr = ssb_test.base.base;
+ ssb_test.base.epptr = ssb_test.base.base + tests[i].width;
+ pis = call_func2(p_istream_read_streambuf, &is, &ssb_test.base);
+ len = strlen(sbf_out[tests[i].expected_val]);
+ ok(ssb_test.base.pptr == ssb_test.base.pbase + len, "Test %d: wrong put pointer, expected %p got %p\n",
+ i, ssb_test.base.pbase + len, ssb_test.base.pptr);
+ ok(!strncmp(ssb_test.base.pbase, sbf_out[tests[i].expected_val], len),
+ "Test %d: expected %s got %s\n", i, sbf_out[tests[i].expected_val], ssb_test.base.pbase);
+ break;
}
ok(pis == &is, "Test %d: wrong return, expected %p got %p\n", i, &is, pis);
@@ -5139,8 +5164,10 @@ static void test_istream_read(void)
ssb.base.base + tests[i].expected_offset, ssb.base.gptr);
}
+ ssb_test.dynamic = 1;
call_func1(p_istream_vbase_dtor, &is);
call_func1(p_strstreambuf_dtor, &ssb);
+ call_func1(p_strstreambuf_dtor, &ssb_test);
}
START_TEST(msvcirt)
--
2.7.4
More information about the wine-patches
mailing list