[v2 2/6] msvcirt: Implement istream::operator>> for characters.
Iván Matellanes
matellanesivan at gmail.com
Tue Aug 2 06:37:47 CDT 2016
From: Iván Matellanes <matellanes.ivan at gmail.com>
Signed-off-by: Iván Matellanes <matellanesivan at gmail.com>
---
dlls/msvcirt/msvcirt.c | 13 +++++++-
dlls/msvcirt/tests/msvcirt.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 5d55b58..361285a 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -3490,7 +3490,18 @@ int __thiscall istream_getdouble(istream *this, char *str, int count)
DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
istream* __thiscall istream_read_char(istream *this, char *ch)
{
- FIXME("(%p %p) stub\n", this, ch);
+ ios *base = istream_get_ios(this);
+ int ret;
+
+ TRACE("(%p %p)\n", this, ch);
+
+ if (istream_ipfx(this, 0)) {
+ if ((ret = streambuf_sbumpc(base->sb)) == EOF)
+ base->state |= IOSTATE_eofbit | IOSTATE_failbit;
+ else
+ *ch = ret;
+ istream_isfx(this);
+ }
return this;
}
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index a921b27..a706703 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -327,6 +327,7 @@ static int (*__thiscall p_istream_sync)(istream*);
static streampos (*__thiscall p_istream_tellg)(istream*);
static int (*__thiscall p_istream_getint)(istream*, char*);
static int (*__thiscall p_istream_getdouble)(istream*, char*, int);
+static istream* (*__thiscall p_istream_read_char)(istream*, char*);
/* Emulate a __thiscall */
#ifdef __i386__
@@ -542,6 +543,7 @@ static BOOL init(void)
SET(p_istream_tellg, "?tellg at istream@@QEAAJXZ");
SET(p_istream_getint, "?getint at istream@@AEAAHPEAD at Z");
SET(p_istream_getdouble, "?getdouble at istream@@AEAAHPEADH at Z");
+ SET(p_istream_read_char, "??5istream@@QEAAAEAV0 at AEAD@Z");
} else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z");
p_operator_delete = (void*)GetProcAddress(msvcrt, "??3 at YAXPAX@Z");
@@ -679,6 +681,7 @@ static BOOL init(void)
SET(p_istream_tellg, "?tellg at istream@@QAEJXZ");
SET(p_istream_getint, "?getint at istream@@AAEHPAD at Z");
SET(p_istream_getdouble, "?getdouble at istream@@AAEHPADH at Z");
+ SET(p_istream_read_char, "??5istream@@QAEAAV0 at AAD@Z");
}
SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A");
SET(p_ios_lockc, "?lockc at ios@@KAXXZ");
@@ -4851,6 +4854,75 @@ static void test_istream_getdouble(void)
call_func1(p_strstreambuf_dtor, &ssb);
}
+static void test_istream_read(void)
+{
+ istream is, *pis;
+ strstreambuf ssb, *pssb;
+ int len, ret, i;
+
+ /* makes tables narrower */
+ const ios_io_state IOSTATE_faileof = IOSTATE_failbit|IOSTATE_eofbit;
+
+ char c, char_out[] = {-85, ' ', 'a', -50};
+ struct istream_read_test {
+ enum { type_chr } type;
+ const char *stream_content;
+ ios_flags flags;
+ int width;
+ int expected_val;
+ ios_io_state expected_state;
+ int expected_width;
+ int expected_offset;
+ BOOL broken;
+ } tests[] = {
+ /* char */
+ {type_chr, "", FLAGS_skipws, 6, /* -85 */ 0, IOSTATE_faileof, 6, 0, FALSE},
+ {type_chr, " ", FLAGS_skipws, 6, /* -85 */ 0, IOSTATE_faileof, 6, 2, FALSE},
+ {type_chr, " abc ", 0, 6, /* ' ' */ 1, IOSTATE_goodbit, 6, 1, FALSE},
+ {type_chr, " abc ", FLAGS_skipws, 6, /* 'a' */ 2, IOSTATE_goodbit, 6, 2, FALSE},
+ {type_chr, " a", FLAGS_skipws, 0, /* 'a' */ 2, IOSTATE_goodbit, 0, 2, FALSE},
+ {type_chr, "\xce", 0, 6, /* -50 */ 3, IOSTATE_goodbit, 6, 1, FALSE},
+ };
+
+ 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);
+ ok(ret == 1, "expected 1 got %d\n", ret);
+ pis = call_func3(p_istream_sb_ctor, &is, &ssb.base, TRUE);
+ ok(pis == &is, "wrong return, expected %p got %p\n", &is, pis);
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ len = strlen(tests[i].stream_content);
+ is.base_ios.state = IOSTATE_goodbit;
+ is.base_ios.flags = tests[i].flags;
+ is.base_ios.width = tests[i].width;
+ ssb.base.eback = ssb.base.gptr = ssb.base.base;
+ ssb.base.egptr = ssb.base.base + len;
+ memcpy(ssb.base.base, tests[i].stream_content, len);
+
+ switch (tests[i].type) {
+ case type_chr:
+ c = -85;
+ pis = call_func2(p_istream_read_char, &is, &c);
+ ok(c == char_out[tests[i].expected_val], "Test %d: expected %d got %d\n", i,
+ char_out[tests[i].expected_val], c);
+ break;
+ }
+
+ ok(pis == &is, "Test %d: wrong return, expected %p got %p\n", i, &is, pis);
+ ok(is.base_ios.state == tests[i].expected_state || /* xp, 2k3 */ broken(tests[i].broken),
+ "Test %d: expected %d got %d\n", i, tests[i].expected_state, is.base_ios.state);
+ ok(is.base_ios.width == tests[i].expected_width, "Test %d: expected %d got %d\n", i,
+ tests[i].expected_width, is.base_ios.width);
+ ok(ssb.base.gptr == ssb.base.base + tests[i].expected_offset ||
+ /* xp, 2k3 */ broken(tests[i].broken), "Test %d: expected %p got %p\n", i,
+ ssb.base.base + tests[i].expected_offset, ssb.base.gptr);
+ }
+
+ call_func1(p_istream_vbase_dtor, &is);
+ call_func1(p_strstreambuf_dtor, &ssb);
+}
+
START_TEST(msvcirt)
{
if(!init())
@@ -4866,6 +4938,7 @@ START_TEST(msvcirt)
test_istream();
test_istream_getint();
test_istream_getdouble();
+ test_istream_read();
FreeLibrary(msvcrt);
FreeLibrary(msvcirt);
--
2.7.4
More information about the wine-patches
mailing list