=?UTF-8?Q?Iv=C3=A1n=20Matellanes=20?=: msvcirt: Implement filebuf:: seekoff.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Aug 17 09:01:13 CDT 2015


Module: wine
Branch: master
Commit: d5229aeec52ca0d00f0ba96d267a7384b7510204
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d5229aeec52ca0d00f0ba96d267a7384b7510204

Author: Iván Matellanes <matellanesivan at gmail.com>
Date:   Mon Aug 10 20:09:30 2015 +0200

msvcirt: Implement filebuf::seekoff.

---

 dlls/msvcirt/msvcirt.c       | 11 +++++++----
 dlls/msvcirt/tests/msvcirt.c | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 580af82..ff31e8c 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -968,11 +968,12 @@ filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode
 
     streambuf_lock(&this->base);
     this->close = 1;
+    this->fd = fd;
     if ((mode & OPENMODE_ate) &&
             call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
         _close(fd);
-    } else
-        this->fd = fd;
+        this->fd = -1;
+    }
     streambuf_allocate(&this->base);
     streambuf_unlock(&this->base);
     return (this->fd == -1) ? NULL : this;
@@ -1003,8 +1004,10 @@ int __thiscall filebuf_overflow(filebuf *this, int c)
 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
 {
-    FIXME("(%p %d %d %d) stub\n", this, offset, dir, mode);
-    return 0;
+    TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
+    if (call_streambuf_sync(&this->base) == EOF)
+        return EOF;
+    return _lseek(this->fd, offset, dir);
 }
 
 /* ?setbuf at filebuf@@UAEPAVstreambuf@@PADH at Z */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index de53889..b381b30 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -24,6 +24,8 @@
 #include "wine/test.h"
 
 typedef void (*vtable_ptr)(void);
+typedef LONG streamoff;
+typedef LONG streampos;
 typedef int filedesc;
 
 typedef enum {
@@ -45,6 +47,12 @@ typedef enum {
 } ios_open_mode;
 
 typedef enum {
+    SEEKDIR_beg = 0,
+    SEEKDIR_cur = 1,
+    SEEKDIR_end = 2
+} ios_seek_dir;
+
+typedef enum {
     FLAGS_skipws     = 0x1,
     FLAGS_left       = 0x2,
     FLAGS_right      = 0x4,
@@ -162,6 +170,7 @@ static streambuf* (*__thiscall p_filebuf_setbuf)(filebuf*, char*, int);
 static int (*__thiscall p_filebuf_sync)(filebuf*);
 static int (*__thiscall p_filebuf_overflow)(filebuf*, int);
 static int (*__thiscall p_filebuf_underflow)(filebuf*);
+static streampos (*__thiscall p_filebuf_seekoff)(filebuf*, streamoff, ios_seek_dir, int);
 
 /* ios */
 static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
@@ -305,6 +314,7 @@ static BOOL init(void)
         SET(p_filebuf_sync, "?sync at filebuf@@UEAAHXZ");
         SET(p_filebuf_overflow, "?overflow at filebuf@@UEAAHH at Z");
         SET(p_filebuf_underflow, "?underflow at filebuf@@UEAAHXZ");
+        SET(p_filebuf_seekoff, "?seekoff at filebuf@@UEAAJJW4seek_dir at ios@@H at Z");
 
         SET(p_ios_copy_ctor, "??0ios@@IEAA at AEBV0@@Z");
         SET(p_ios_ctor, "??0ios@@IEAA at XZ");
@@ -368,6 +378,7 @@ static BOOL init(void)
         SET(p_filebuf_sync, "?sync at filebuf@@UAEHXZ");
         SET(p_filebuf_overflow, "?overflow at filebuf@@UAEHH at Z");
         SET(p_filebuf_underflow, "?underflow at filebuf@@UAEHXZ");
+        SET(p_filebuf_seekoff, "?seekoff at filebuf@@UAEJJW4seek_dir at ios@@H at Z");
 
         SET(p_ios_copy_ctor, "??0ios@@IAE at ABV0@@Z");
         SET(p_ios_ctor, "??0ios@@IAE at XZ");
@@ -1305,6 +1316,35 @@ static void test_filebuf(void)
     ret = (int) call_func1(p_filebuf_underflow, &fb2);
     ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
 
+    /* seekoff */
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 5, SEEKDIR_beg, 0);
+    ok(ret == 5, "wrong return, expected 5 got %d\n", ret);
+    ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
+    ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
+    fb1.base.eback = fb1.base.gptr = fb1.base.base;
+    fb1.base.egptr = fb1.base.ebuf;
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 0, SEEKDIR_beg, 0);
+    ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
+    fb1.base.eback = fb1.base.gptr = fb1.base.egptr = NULL;
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 10, SEEKDIR_beg, OPENMODE_in|OPENMODE_out);
+    ok(ret == 10, "wrong return, expected 10 got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 0, SEEKDIR_cur, 0);
+    ok(ret == 10, "wrong return, expected 10 got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 200, SEEKDIR_cur, OPENMODE_in);
+    ok(ret == 210, "wrong return, expected 210 got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, -60, SEEKDIR_cur, 0);
+    ok(ret == 150, "wrong return, expected 150 got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 0, SEEKDIR_end, 0);
+    ok(ret == 106, "wrong return, expected 106 got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 20, SEEKDIR_end, OPENMODE_out);
+    ok(ret == 126, "wrong return, expected 126 got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, -150, SEEKDIR_end, -1);
+    ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 10, 3, 0);
+    ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
+    ret = (int) call_func4(p_filebuf_seekoff, &fb1, 16, SEEKDIR_beg, 0);
+    ok(ret == 16, "wrong return, expected 16 got %d\n", ret);
+
     /* close */
     pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
     ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);




More information about the wine-cvs mailing list