msvcirt: Implement stdiobuf::overflow.
Signed-off-by: Iván Matellanes <matellanesivan@gmail.com> Signed-off-by: Piotr Caban <piotr@codeweavers.com>
This commit is contained in:
parent
a9ad6e88d7
commit
608aa13672
|
@ -1532,8 +1532,29 @@ stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
|
||||||
DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
|
DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
|
||||||
int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
|
int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
|
||||||
{
|
{
|
||||||
FIXME("(%p %d) stub\n", this, c);
|
TRACE("(%p %d)\n", this, c);
|
||||||
return EOF;
|
if (this->base.unbuffered)
|
||||||
|
return (c == EOF) ? 1 : fputc(c, this->file);
|
||||||
|
if (streambuf_allocate(&this->base) == EOF)
|
||||||
|
return EOF;
|
||||||
|
|
||||||
|
if (!this->base.epptr) {
|
||||||
|
/* set the put area to the second half of the buffer */
|
||||||
|
streambuf_setp(&this->base,
|
||||||
|
this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
|
||||||
|
} else if (this->base.pptr > this->base.pbase) {
|
||||||
|
/* flush the put area */
|
||||||
|
int count = this->base.pptr - this->base.pbase;
|
||||||
|
if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
|
||||||
|
return EOF;
|
||||||
|
this->base.pptr = this->base.pbase;
|
||||||
|
}
|
||||||
|
if (c != EOF) {
|
||||||
|
if (this->base.pbase >= this->base.epptr)
|
||||||
|
return fputc(c, this->file);
|
||||||
|
*this->base.pptr++ = c;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?pbackfail@stdiobuf@@UAEHH@Z */
|
/* ?pbackfail@stdiobuf@@UAEHH@Z */
|
||||||
|
|
|
@ -209,6 +209,7 @@ static int (*__thiscall p_strstreambuf_underflow)(strstreambuf*);
|
||||||
/* stdiobuf */
|
/* stdiobuf */
|
||||||
static stdiobuf* (*__thiscall p_stdiobuf_file_ctor)(stdiobuf*, FILE*);
|
static stdiobuf* (*__thiscall p_stdiobuf_file_ctor)(stdiobuf*, FILE*);
|
||||||
static void (*__thiscall p_stdiobuf_dtor)(stdiobuf*);
|
static void (*__thiscall p_stdiobuf_dtor)(stdiobuf*);
|
||||||
|
static int (*__thiscall p_stdiobuf_overflow)(stdiobuf*, int);
|
||||||
|
|
||||||
/* ios */
|
/* ios */
|
||||||
static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
|
static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
|
||||||
|
@ -370,6 +371,7 @@ static BOOL init(void)
|
||||||
|
|
||||||
SET(p_stdiobuf_file_ctor, "??0stdiobuf@@QEAA@PEAU_iobuf@@@Z");
|
SET(p_stdiobuf_file_ctor, "??0stdiobuf@@QEAA@PEAU_iobuf@@@Z");
|
||||||
SET(p_stdiobuf_dtor, "??1stdiobuf@@UEAA@XZ");
|
SET(p_stdiobuf_dtor, "??1stdiobuf@@UEAA@XZ");
|
||||||
|
SET(p_stdiobuf_overflow, "?overflow@stdiobuf@@UEAAHH@Z");
|
||||||
|
|
||||||
SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z");
|
SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z");
|
||||||
SET(p_ios_ctor, "??0ios@@IEAA@XZ");
|
SET(p_ios_ctor, "??0ios@@IEAA@XZ");
|
||||||
|
@ -451,6 +453,7 @@ static BOOL init(void)
|
||||||
|
|
||||||
SET(p_stdiobuf_file_ctor, "??0stdiobuf@@QAE@PAU_iobuf@@@Z");
|
SET(p_stdiobuf_file_ctor, "??0stdiobuf@@QAE@PAU_iobuf@@@Z");
|
||||||
SET(p_stdiobuf_dtor, "??1stdiobuf@@UAE@XZ");
|
SET(p_stdiobuf_dtor, "??1stdiobuf@@UAE@XZ");
|
||||||
|
SET(p_stdiobuf_overflow, "?overflow@stdiobuf@@UAEHH@Z");
|
||||||
|
|
||||||
SET(p_ios_copy_ctor, "??0ios@@IAE@ABV0@@Z");
|
SET(p_ios_copy_ctor, "??0ios@@IAE@ABV0@@Z");
|
||||||
SET(p_ios_ctor, "??0ios@@IAE@XZ");
|
SET(p_ios_ctor, "??0ios@@IAE@XZ");
|
||||||
|
@ -1828,6 +1831,8 @@ static void test_stdiobuf(void)
|
||||||
FILE *file1, *file2;
|
FILE *file1, *file2;
|
||||||
const char filename1[] = "stdiobuf_test1";
|
const char filename1[] = "stdiobuf_test1";
|
||||||
const char filename2[] = "stdiobuf_test2";
|
const char filename2[] = "stdiobuf_test2";
|
||||||
|
int ret;
|
||||||
|
char buffer[64];
|
||||||
|
|
||||||
memset(&stb1, 0xab, sizeof(stdiobuf));
|
memset(&stb1, 0xab, sizeof(stdiobuf));
|
||||||
memset(&stb2, 0xab, sizeof(stdiobuf));
|
memset(&stb2, 0xab, sizeof(stdiobuf));
|
||||||
|
@ -1855,6 +1860,59 @@ static void test_stdiobuf(void)
|
||||||
ok(stb2.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", stb2.base.unbuffered);
|
ok(stb2.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", stb2.base.unbuffered);
|
||||||
ok(stb2.file == file2, "wrong file pointer, expected %p got %p\n", file2, stb2.file);
|
ok(stb2.file == file2, "wrong file pointer, expected %p got %p\n", file2, stb2.file);
|
||||||
|
|
||||||
|
/* overflow */
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb1, EOF);
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb1, 'a');
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
stb1.base.unbuffered = 0;
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb1, 'a');
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ok(stb1.base.allocated == 1, "wrong allocate value, expected 1 got %d\n", stb1.base.allocated);
|
||||||
|
ok(stb1.base.ebuf == stb1.base.base + 512, "expected %p got %p\n", stb1.base.base + 512, stb1.base.ebuf);
|
||||||
|
ok(stb1.base.pbase == stb1.base.base + 256, "wrong put base, expected %p got %p\n", stb1.base.base + 256, stb1.base.pbase);
|
||||||
|
ok(stb1.base.pptr == stb1.base.pbase + 1, "wrong put pointer, expected %p got %p\n", stb1.base.pbase + 1, stb1.base.pptr);
|
||||||
|
ok(stb1.base.epptr == stb1.base.ebuf, "wrong put end, expected %p got %p\n", stb1.base.ebuf, stb1.base.epptr);
|
||||||
|
ok(*(stb1.base.pptr-1) == 'a', "expected 'a', got '%c'\n", *(stb1.base.pptr-1));
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb1, EOF);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(stb1.base.pptr == stb1.base.pbase + 1, "wrong put pointer, expected %p got %p\n", stb1.base.pbase + 1, stb1.base.pptr);
|
||||||
|
stb1.base.pptr = stb1.base.pbase;
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb1, EOF);
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ok(stb1.base.pptr == stb1.base.pbase, "wrong put pointer, expected %p got %p\n", stb1.base.pbase, stb1.base.pptr);
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb1, 'b');
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ok(stb1.base.pptr == stb1.base.pbase + 1, "wrong put pointer, expected %p got %p\n", stb1.base.pbase + 1, stb1.base.pptr);
|
||||||
|
ok(*(stb1.base.pptr-1) == 'b', "expected 'b', got '%c'\n", *(stb1.base.pptr-1));
|
||||||
|
stb1.base.unbuffered = 1;
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb2, EOF);
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb2, 'a');
|
||||||
|
ok(ret == 'a', "expected 'a' got %d\n", ret);
|
||||||
|
stb2.base.unbuffered = 0;
|
||||||
|
stb2.base.base = buffer;
|
||||||
|
stb2.base.pbase = stb2.base.pptr = buffer + 32;
|
||||||
|
stb2.base.ebuf = stb2.base.epptr = buffer + 64;
|
||||||
|
ret = (int) call_func3(p_streambuf_xsputn, &stb2.base, "Never gonna run around", 22);
|
||||||
|
ok(ret == 22, "expected 22 got %d\n", ret);
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb2, 'c');
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ok(stb2.base.pptr == stb2.base.pbase + 1, "wrong put pointer, expected %p got %p\n", stb2.base.pbase + 1, stb2.base.pptr);
|
||||||
|
ok(*(stb2.base.pptr-1) == 'c', "expected 'c', got '%c'\n", *(stb2.base.pptr-1));
|
||||||
|
stb2.base.pbase = stb2.base.pptr + 3;
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb2, 'd');
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ok(stb2.base.pptr == stb2.base.pbase - 2, "wrong put pointer, expected %p got %p\n", stb2.base.pbase - 2, stb2.base.pptr);
|
||||||
|
ok(*(stb2.base.pptr-1) == 'd', "expected 'd', got '%c'\n", *(stb2.base.pptr-1));
|
||||||
|
stb2.base.pbase = stb2.base.pptr = buffer + 32;
|
||||||
|
stb2.base.epptr = buffer + 30;
|
||||||
|
ret = (int) call_func2(p_stdiobuf_overflow, &stb2, 'd');
|
||||||
|
ok(ret == 'd', "expected 'd' got %d\n", ret);
|
||||||
|
ok(stb2.base.pptr == stb2.base.pbase, "wrong put pointer, expected %p got %p\n", stb2.base.pbase, stb2.base.pptr);
|
||||||
|
stb2.base.epptr = buffer + 64;
|
||||||
|
stb2.base.unbuffered = 1;
|
||||||
|
|
||||||
call_func1(p_stdiobuf_dtor, &stb1);
|
call_func1(p_stdiobuf_dtor, &stb1);
|
||||||
call_func1(p_stdiobuf_dtor, &stb2);
|
call_func1(p_stdiobuf_dtor, &stb2);
|
||||||
fclose(file1);
|
fclose(file1);
|
||||||
|
|
Loading…
Reference in New Issue