mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
msvcirt: Correct the behavior of filebuf::setbuf().
While implementing ifstream::setbuf() it turned out that filebuf::setbuf(), behaves a bit different on Windows than our implementation. It seems to reimplement streambuf::setbuf() with a very minor difference - it doesn't ever set unbuffered to 0 and allows to change the underlying buffer as long as the file is not opened. Signed-off-by: Arkadiusz Hiler <ahiler@codeweavers.com> Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
314368e6c4
commit
f4bb6abebc
2 changed files with 77 additions and 5 deletions
|
@ -1175,16 +1175,28 @@ streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_d
|
|||
DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
|
||||
streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
|
||||
{
|
||||
streambuf *ret;
|
||||
|
||||
TRACE("(%p %p %d)\n", this, buffer, length);
|
||||
if (this->base.base != NULL)
|
||||
|
||||
if (filebuf_is_open(this) && this->base.base != NULL)
|
||||
return NULL;
|
||||
|
||||
streambuf_lock(&this->base);
|
||||
ret = streambuf_setbuf(&this->base, buffer, length);
|
||||
|
||||
if (buffer == NULL || !length) {
|
||||
this->base.unbuffered = 1;
|
||||
} else {
|
||||
if (this->base.allocated) {
|
||||
MSVCRT_operator_delete(this->base.base);
|
||||
this->base.allocated = 0;
|
||||
}
|
||||
|
||||
this->base.base = buffer;
|
||||
this->base.ebuf = buffer + length;
|
||||
}
|
||||
|
||||
streambuf_unlock(&this->base);
|
||||
return ret;
|
||||
|
||||
return &this->base;
|
||||
}
|
||||
|
||||
/* ?setmode@filebuf@@QAEHH@Z */
|
||||
|
|
|
@ -1168,16 +1168,22 @@ static void test_streambuf(void)
|
|||
sb.do_lock = -1;
|
||||
|
||||
/* setb */
|
||||
sb.unbuffered = 1;
|
||||
call_func4(p_streambuf_setb, &sb, reserve, reserve+16, 0);
|
||||
ok(sb.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", sb.unbuffered);
|
||||
ok(sb.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb.base);
|
||||
ok(sb.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb.ebuf);
|
||||
call_func4(p_streambuf_setb, &sb, reserve, reserve+16, 4);
|
||||
ok(sb.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", sb.unbuffered);
|
||||
ok(sb.allocated == 4, "wrong allocate value, expected 4 got %d\n", sb.allocated);
|
||||
sb.allocated = 0;
|
||||
sb.unbuffered = 0;
|
||||
call_func4(p_streambuf_setb, &sb, NULL, NULL, 3);
|
||||
ok(sb.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", sb.unbuffered);
|
||||
ok(sb.allocated == 3, "wrong allocate value, expected 3 got %d\n", sb.allocated);
|
||||
|
||||
/* setbuf */
|
||||
sb.unbuffered = 0;
|
||||
psb = call_func3(p_streambuf_setbuf, &sb, NULL, 5);
|
||||
ok(psb == &sb, "wrong return value, expected %p got %p\n", &sb, psb);
|
||||
ok(sb.allocated == 3, "wrong allocate value, expected 3 got %d\n", sb.allocated);
|
||||
|
@ -1659,21 +1665,75 @@ static void test_filebuf(void)
|
|||
|
||||
/* setbuf */
|
||||
fb1.base.do_lock = 0;
|
||||
fb1.fd = -1; /* closed */
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.fd == -1, "wrong fd, expected -1 got %d\n", fb1.fd);
|
||||
fb1.base.unbuffered = 1;
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 16);
|
||||
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer + 8, 8);
|
||||
ok(pret == &fb1, "wrong return, expected %p got %p\n", NULL, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer + 8, "wrong buffer, expected %p got %p\n", read_buffer + 8, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
fb1.base.unbuffered = 0;
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, NULL, 0);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer + 8, "wrong buffer, expected %p got %p\n", read_buffer + 8, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
ok((int) call_func1(p_streambuf_doallocate, &fb1.base) == 1, "failed to allocate buffer\n");
|
||||
ok(fb1.base.allocated == 1, "wrong allocate value, expected 1 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base != NULL, "wrong buffer, expected not NULL got %p\n", fb1.base.base);
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer + 2, 14);
|
||||
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer + 2, "wrong buffer, expected %p got %p\n", read_buffer + 2, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
fb1.fd = 1; /* opened */
|
||||
fb1.base.unbuffered = 1;
|
||||
fb1.base.base = fb1.base.ebuf = NULL;
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 16);
|
||||
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer + 8, 8);
|
||||
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
fb1.base.unbuffered = 0;
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, NULL, 0);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
|
||||
ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
|
||||
fb1.base.unbuffered = 1;
|
||||
fb1.base.pbase = fb1.base.pptr = fb1.base.base;
|
||||
fb1.base.epptr = fb1.base.ebuf;
|
||||
fb1.base.do_lock = -1;
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 16);
|
||||
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
|
||||
ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
|
||||
ok(fb1.base.pbase == read_buffer, "wrong put area, expected %p got %p\n", read_buffer, fb1.base.pbase);
|
||||
fb1.base.base = fb1.base.ebuf = NULL;
|
||||
fb1.base.do_lock = 0;
|
||||
fb1.base.unbuffered = 0;
|
||||
pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 0);
|
||||
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||
|
|
Loading…
Reference in a new issue