msvcirt: Implement strstreambuf::seekoff.
This commit is contained in:
parent
9754cda53b
commit
24d57405ac
|
@ -1351,8 +1351,43 @@ int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
|
||||||
DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
|
DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
|
||||||
streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
|
streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
|
||||||
{
|
{
|
||||||
FIXME("(%p %d %d %d) stub\n", this, offset, dir, mode);
|
char *base[3];
|
||||||
|
|
||||||
|
TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
|
||||||
|
|
||||||
|
if (dir < SEEKDIR_beg || dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
|
||||||
return EOF;
|
return EOF;
|
||||||
|
/* read buffer */
|
||||||
|
if (mode & OPENMODE_in) {
|
||||||
|
call_streambuf_underflow(&this->base);
|
||||||
|
base[SEEKDIR_beg] = this->base.eback;
|
||||||
|
base[SEEKDIR_cur] = this->base.gptr;
|
||||||
|
base[SEEKDIR_end] = this->base.egptr;
|
||||||
|
if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
|
||||||
|
return EOF;
|
||||||
|
this->base.gptr = base[dir] + offset;
|
||||||
|
}
|
||||||
|
/* write buffer */
|
||||||
|
if (mode & OPENMODE_out) {
|
||||||
|
if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
|
||||||
|
return EOF;
|
||||||
|
base[SEEKDIR_beg] = this->base.pbase;
|
||||||
|
base[SEEKDIR_cur] = this->base.pptr;
|
||||||
|
base[SEEKDIR_end] = this->base.epptr;
|
||||||
|
if (base[dir] + offset < this->base.pbase)
|
||||||
|
return EOF;
|
||||||
|
if (base[dir] + offset > this->base.epptr) {
|
||||||
|
/* make room if the buffer is dynamic */
|
||||||
|
if (!this->dynamic)
|
||||||
|
return EOF;
|
||||||
|
this->increase = offset;
|
||||||
|
if (call_streambuf_doallocate(&this->base) == EOF)
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
this->base.pptr = base[dir] + offset;
|
||||||
|
return this->base.pptr - base[SEEKDIR_beg];
|
||||||
|
}
|
||||||
|
return this->base.gptr - base[SEEKDIR_beg];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
|
/* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
|
||||||
|
|
|
@ -196,6 +196,7 @@ static void (*__thiscall p_strstreambuf_dtor)(strstreambuf*);
|
||||||
static int (*__thiscall p_strstreambuf_doallocate)(strstreambuf*);
|
static int (*__thiscall p_strstreambuf_doallocate)(strstreambuf*);
|
||||||
static void (*__thiscall p_strstreambuf_freeze)(strstreambuf*, int);
|
static void (*__thiscall p_strstreambuf_freeze)(strstreambuf*, int);
|
||||||
static int (*__thiscall p_strstreambuf_overflow)(strstreambuf*, int);
|
static int (*__thiscall p_strstreambuf_overflow)(strstreambuf*, int);
|
||||||
|
static streampos (*__thiscall p_strstreambuf_seekoff)(strstreambuf*, streamoff, ios_seek_dir, int);
|
||||||
static streambuf* (*__thiscall p_strstreambuf_setbuf)(strstreambuf*, char*, int);
|
static streambuf* (*__thiscall p_strstreambuf_setbuf)(strstreambuf*, char*, int);
|
||||||
static int (*__thiscall p_strstreambuf_underflow)(strstreambuf*);
|
static int (*__thiscall p_strstreambuf_underflow)(strstreambuf*);
|
||||||
|
|
||||||
|
@ -353,6 +354,7 @@ static BOOL init(void)
|
||||||
SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MEAAHXZ");
|
SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MEAAHXZ");
|
||||||
SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QEAAXH@Z");
|
SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QEAAXH@Z");
|
||||||
SET(p_strstreambuf_overflow, "?overflow@strstreambuf@@UEAAHH@Z");
|
SET(p_strstreambuf_overflow, "?overflow@strstreambuf@@UEAAHH@Z");
|
||||||
|
SET(p_strstreambuf_seekoff, "?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z");
|
||||||
SET(p_strstreambuf_setbuf, "?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z");
|
SET(p_strstreambuf_setbuf, "?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z");
|
||||||
SET(p_strstreambuf_underflow, "?underflow@strstreambuf@@UEAAHXZ");
|
SET(p_strstreambuf_underflow, "?underflow@strstreambuf@@UEAAHXZ");
|
||||||
|
|
||||||
|
@ -430,6 +432,7 @@ static BOOL init(void)
|
||||||
SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MAEHXZ");
|
SET(p_strstreambuf_doallocate, "?doallocate@strstreambuf@@MAEHXZ");
|
||||||
SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QAEXH@Z");
|
SET(p_strstreambuf_freeze, "?freeze@strstreambuf@@QAEXH@Z");
|
||||||
SET(p_strstreambuf_overflow, "?overflow@strstreambuf@@UAEHH@Z");
|
SET(p_strstreambuf_overflow, "?overflow@strstreambuf@@UAEHH@Z");
|
||||||
|
SET(p_strstreambuf_seekoff, "?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z");
|
||||||
SET(p_strstreambuf_setbuf, "?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z");
|
SET(p_strstreambuf_setbuf, "?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z");
|
||||||
SET(p_strstreambuf_underflow, "?underflow@strstreambuf@@UAEHXZ");
|
SET(p_strstreambuf_underflow, "?underflow@strstreambuf@@UAEHXZ");
|
||||||
|
|
||||||
|
@ -1432,7 +1435,7 @@ static void test_strstreambuf(void)
|
||||||
{
|
{
|
||||||
strstreambuf ssb1, ssb2;
|
strstreambuf ssb1, ssb2;
|
||||||
streambuf *pret;
|
streambuf *pret;
|
||||||
char buffer[64];
|
char buffer[64], *pbuffer;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(&ssb1, 0xab, sizeof(strstreambuf));
|
memset(&ssb1, 0xab, sizeof(strstreambuf));
|
||||||
|
@ -1692,6 +1695,113 @@ static void test_strstreambuf(void)
|
||||||
ok(ssb2.base.epptr == ssb2.base.base + 28, "wrong put end, expected %p got %p\n", ssb2.base.base + 28, ssb2.base.epptr);
|
ok(ssb2.base.epptr == ssb2.base.base + 28, "wrong put end, expected %p got %p\n", ssb2.base.base + 28, ssb2.base.epptr);
|
||||||
ok(*(ssb2.base.pptr - 1) == 'G', "expected 'G' got %d\n", *(ssb2.base.pptr - 1));
|
ok(*(ssb2.base.pptr - 1) == 'G', "expected 'G' got %d\n", *(ssb2.base.pptr - 1));
|
||||||
|
|
||||||
|
/* seekoff */
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 0, SEEKDIR_beg, OPENMODE_in);
|
||||||
|
ok(ret == 0, "expected 0 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback, "wrong get pointer, expected %p got %p\n", ssb1.base.eback, ssb1.base.gptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 3, SEEKDIR_beg, OPENMODE_in);
|
||||||
|
ok(ret == 3, "expected 3 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 3, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 3, ssb1.base.gptr);
|
||||||
|
ssb1.base.egptr = ssb1.base.pbase;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 25, SEEKDIR_beg, OPENMODE_in);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 3, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 3, ssb1.base.gptr);
|
||||||
|
ssb1.base.gptr = ssb1.base.egptr;
|
||||||
|
ssb1.base.pptr = ssb1.base.pbase + 10;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 25, SEEKDIR_beg, OPENMODE_in);
|
||||||
|
ok(ret == 25, "expected 25 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 25, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 25, ssb1.base.gptr);
|
||||||
|
ok(ssb1.base.egptr == ssb1.base.pptr, "wrong get end, expected %p got %p\n", ssb1.base.pptr, ssb1.base.egptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, -24, SEEKDIR_cur, OPENMODE_in);
|
||||||
|
ok(ret == 1, "expected 1 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 1, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 1, ssb1.base.gptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, -5, SEEKDIR_cur, OPENMODE_in);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 1, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 1, ssb1.base.gptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 0, SEEKDIR_end, OPENMODE_in);
|
||||||
|
ok(ret == 30, "expected 30 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.egptr, "wrong get pointer, expected %p got %p\n", ssb1.base.egptr, ssb1.base.gptr);
|
||||||
|
ssb1.base.gptr = ssb1.base.eback;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, -2, SEEKDIR_end, OPENMODE_in);
|
||||||
|
ok(ret == 28, "expected 28 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.egptr - 2, "wrong get pointer, expected %p got %p\n", ssb1.base.egptr - 2, ssb1.base.gptr);
|
||||||
|
ssb1.base.gptr = ssb1.base.egptr;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, -5, SEEKDIR_end, OPENMODE_in);
|
||||||
|
ok(ret == 25, "expected 25 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.egptr - 5, "wrong get pointer, expected %p got %p\n", ssb1.base.egptr - 5, ssb1.base.gptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 1, SEEKDIR_end, OPENMODE_in);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.egptr - 5, "wrong get pointer, expected %p got %p\n", ssb1.base.egptr - 5, ssb1.base.gptr);
|
||||||
|
ssb1.base.gptr = ssb1.base.egptr;
|
||||||
|
ssb1.base.pptr = ssb1.base.egptr + 5;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 1, SEEKDIR_end, OPENMODE_in);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.egptr - 5, "wrong get pointer, expected %p got %p\n", ssb1.base.egptr - 5, ssb1.base.gptr);
|
||||||
|
ok(ssb1.base.egptr == ssb1.base.pptr, "wrong get end, expected %p got %p\n", ssb1.base.pptr, ssb1.base.egptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 3, SEEKDIR_beg, OPENMODE_out);
|
||||||
|
ok(ret == 3, "expected 3 got %d\n", ret);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 3, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 3, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, -2, SEEKDIR_beg, OPENMODE_out);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 3, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 3, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 50, SEEKDIR_beg, OPENMODE_out);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 3, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 3, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 5, SEEKDIR_cur, OPENMODE_out);
|
||||||
|
ok(ret == 8, "expected 8 got %d\n", ret);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 8, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 8, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, -2, SEEKDIR_end, OPENMODE_out);
|
||||||
|
ok(ret == 42, "expected 42 got %d\n", ret);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.epptr - 2, "wrong put pointer, expected %p got %p\n", ssb1.base.epptr - 2, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 0, SEEKDIR_end, OPENMODE_out);
|
||||||
|
ok(ret == 44, "expected 44 got %d\n", ret);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.epptr, "wrong put pointer, expected %p got %p\n", ssb1.base.epptr, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 5, SEEKDIR_beg, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == 5, "expected 5 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 5, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 5, ssb1.base.gptr);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 5, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 5, ssb1.base.pptr);
|
||||||
|
ssb1.base.egptr = ssb1.base.pbase;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 21, SEEKDIR_beg, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 5, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 5, ssb1.base.gptr);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 5, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 5, ssb1.base.pptr);
|
||||||
|
ssb1.base.egptr = ssb1.base.epptr;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 50, SEEKDIR_beg, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == EOF, "expected EOF got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 50, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 50, ssb1.base.gptr);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 5, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 5, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb1, 2, SEEKDIR_cur, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == 7, "expected 7 got %d\n", ret);
|
||||||
|
ok(ssb1.base.gptr == ssb1.base.eback + 52, "wrong get pointer, expected %p got %p\n", ssb1.base.eback + 52, ssb1.base.gptr);
|
||||||
|
ok(ssb1.base.pptr == ssb1.base.pbase + 7, "wrong put pointer, expected %p got %p\n", ssb1.base.pbase + 7, ssb1.base.pptr);
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb2, 0, SEEKDIR_beg, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == 0, "expected 0 got %d\n", ret);
|
||||||
|
ok(ssb2.base.gptr == ssb2.base.eback, "wrong get pointer, expected %p got %p\n", ssb2.base.eback, ssb2.base.gptr);
|
||||||
|
ok(ssb2.base.pptr == ssb2.base.pbase, "wrong put pointer, expected %p got %p\n", ssb2.base.pbase, ssb2.base.pptr);
|
||||||
|
ssb2.base.gptr = ssb2.base.egptr;
|
||||||
|
ssb2.base.pptr += 10;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb2, 5, SEEKDIR_cur, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == 15, "expected 15 got %d\n", ret);
|
||||||
|
ok(ssb2.base.gptr == ssb2.base.eback + 7, "wrong get pointer, expected %p got %p\n", ssb2.base.eback + 7, ssb2.base.gptr);
|
||||||
|
ok(ssb2.base.egptr == ssb2.base.eback + 12, "wrong get end, expected %p got %p\n", ssb2.base.eback + 12, ssb2.base.egptr);
|
||||||
|
ok(ssb2.base.pptr == ssb2.base.pbase + 15, "wrong put pointer, expected %p got %p\n", ssb2.base.pbase + 15, ssb2.base.pptr);
|
||||||
|
ssb2.base.pptr = ssb2.base.epptr;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb2, -1, SEEKDIR_cur, OPENMODE_in|OPENMODE_out);
|
||||||
|
ok(ret == 25, "expected 25 got %d\n", ret);
|
||||||
|
ok(ssb2.base.gptr == ssb2.base.eback + 6, "wrong get pointer, expected %p got %p\n", ssb2.base.eback + 6, ssb2.base.gptr);
|
||||||
|
ok(ssb2.base.pptr == ssb2.base.pbase + 25, "wrong put pointer, expected %p got %p\n", ssb2.base.pbase + 25, ssb2.base.pptr);
|
||||||
|
pbuffer = ssb2.base.pbase;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb2, 50, SEEKDIR_beg, OPENMODE_out);
|
||||||
|
ok(ret == 50, "expected 50 got %d\n", ret);
|
||||||
|
ok(ssb2.base.gptr == ssb2.base.eback + 6, "wrong get pointer, expected %p got %p\n", ssb2.base.eback + 6, ssb2.base.gptr);
|
||||||
|
ok(ssb2.base.pptr == pbuffer + 50, "wrong put pointer, expected %p got %p\n", pbuffer + 50, ssb2.base.pptr);
|
||||||
|
ok(ssb2.increase == 50, "expected 50 got %d\n", ssb2.increase);
|
||||||
|
ssb2.base.epptr = NULL;
|
||||||
|
ssb2.increase = 8;
|
||||||
|
ret = (int) call_func4(p_strstreambuf_seekoff, &ssb2, 0, SEEKDIR_end, OPENMODE_out);
|
||||||
|
ok(ret == 74, "expected 74 got %d\n", ret);
|
||||||
|
ok(ssb2.base.pptr == ssb2.base.epptr, "wrong put pointer, expected %p got %p\n", ssb2.base.epptr, ssb2.base.pptr);
|
||||||
|
|
||||||
call_func1(p_strstreambuf_dtor, &ssb1);
|
call_func1(p_strstreambuf_dtor, &ssb1);
|
||||||
call_func1(p_strstreambuf_dtor, &ssb2);
|
call_func1(p_strstreambuf_dtor, &ssb2);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue