msvcirt: Add implementation of streambuf::allocate.

This commit is contained in:
Iván Matellanes 2015-06-08 21:26:21 +02:00 committed by Alexandre Julliard
parent 3d7aa246d5
commit 77dbfc8979
6 changed files with 84 additions and 9 deletions

View File

@ -29,6 +29,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
#define RESERVE_SIZE 512
/* class streambuf */
typedef struct {
const vtable_ptr *vtable;
@ -47,6 +49,7 @@ typedef struct {
CRITICAL_SECTION lock;
} streambuf;
void __thiscall streambuf_setb(streambuf*, char*, char*, int);
streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
void __thiscall streambuf_setp(streambuf*, char*, char*);
@ -179,10 +182,29 @@ streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
/* ?doallocate@streambuf@@MAEHXZ */
/* ?doallocate@streambuf@@MEAAHXZ */
DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
#define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
int __thiscall streambuf_doallocate(streambuf *this)
{
FIXME("(%p): stub\n", this);
char *reserve;
TRACE("(%p)\n", this);
reserve = MSVCRT_operator_new(RESERVE_SIZE);
if (!reserve)
return EOF;
streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
return 1;
}
/* ?allocate@streambuf@@IAEHXZ */
/* ?allocate@streambuf@@IEAAHXZ */
DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
int __thiscall streambuf_allocate(streambuf *this)
{
TRACE("(%p)\n", this);
if (this->base != NULL || this->unbuffered)
return 0;
return call_streambuf_doallocate(this);
}
/* Unexported */
@ -404,6 +426,35 @@ char * __thiscall MSVCIRT_str_sl_void(class_strstreambuf * _this)
return 0;
}
#ifdef __i386__
#define DEFINE_VTBL_WRAPPER(off) \
__ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
"popl %eax\n\t" \
"popl %ecx\n\t" \
"pushl %eax\n\t" \
"movl 0(%ecx), %eax\n\t" \
"jmp *" #off "(%eax)\n\t")
DEFINE_VTBL_WRAPPER(0);
DEFINE_VTBL_WRAPPER(4);
DEFINE_VTBL_WRAPPER(8);
DEFINE_VTBL_WRAPPER(12);
DEFINE_VTBL_WRAPPER(16);
DEFINE_VTBL_WRAPPER(20);
DEFINE_VTBL_WRAPPER(24);
DEFINE_VTBL_WRAPPER(28);
DEFINE_VTBL_WRAPPER(32);
DEFINE_VTBL_WRAPPER(36);
DEFINE_VTBL_WRAPPER(40);
DEFINE_VTBL_WRAPPER(44);
DEFINE_VTBL_WRAPPER(48);
DEFINE_VTBL_WRAPPER(52);
DEFINE_VTBL_WRAPPER(56);
#endif
void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
void (__cdecl *MSVCRT_operator_delete)(void*);
static void init_cxx_funcs(void)
@ -412,10 +463,12 @@ static void init_cxx_funcs(void)
if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
{
MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
}
else
{
MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
}
}

View File

@ -23,6 +23,7 @@
typedef LONG streamoff;
typedef LONG streampos;
extern void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
extern void (__cdecl *MSVCRT_operator_delete)(void*);
void init_exception(void*);

View File

@ -400,8 +400,8 @@
@ stub -arch=win32 ??_Gstrstream@@UAEPAXI@Z # virtual void * __thiscall strstream::`scalar deleting destructor'(unsigned int)
@ stub -arch=win32 ??_Gstrstreambuf@@UAEPAXI@Z # virtual void * __thiscall strstreambuf::`scalar deleting destructor'(unsigned int)
# @ extern ?adjustfield@ios@@2JB # static long const ios::adjustfield
@ stub -arch=win32 ?allocate@streambuf@@IAEHXZ # int __thiscall streambuf::allocate(void)
@ stub -arch=win64 ?allocate@streambuf@@IEAAHXZ
@ thiscall -arch=win32 ?allocate@streambuf@@IAEHXZ(ptr) streambuf_allocate
@ cdecl -arch=win64 ?allocate@streambuf@@IEAAHXZ(ptr) streambuf_allocate
@ stub -arch=win32 ?attach@filebuf@@QAEPAV1@H@Z # class filebuf * __thiscall filebuf::attach(int)
@ stub -arch=win64 ?attach@filebuf@@QEAAPEAV1@H@Z
@ stub -arch=win32 ?attach@fstream@@QAEXH@Z # void __thiscall fstream::attach(int)

View File

@ -52,6 +52,8 @@ typedef struct {
static streambuf* (*__thiscall p_streambuf_reserve_ctor)(streambuf*, char*, int);
static streambuf* (*__thiscall p_streambuf_ctor)(streambuf*);
static void (*__thiscall p_streambuf_dtor)(streambuf*);
static int (*__thiscall p_streambuf_allocate)(streambuf*);
static int (*__thiscall p_streambuf_doallocate)(streambuf*);
static void (*__thiscall p_streambuf_setb)(streambuf*, char*, char*, int);
static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int);
@ -127,12 +129,16 @@ static BOOL init(void)
SET(p_streambuf_reserve_ctor, "??0streambuf@@IEAA@PEADH@Z");
SET(p_streambuf_ctor, "??0streambuf@@IEAA@XZ");
SET(p_streambuf_dtor, "??1streambuf@@UEAA@XZ");
SET(p_streambuf_allocate, "?allocate@streambuf@@IEAAHXZ");
SET(p_streambuf_doallocate, "?doallocate@streambuf@@MEAAHXZ");
SET(p_streambuf_setb, "?setb@streambuf@@IEAAXPEAD0H@Z");
SET(p_streambuf_setbuf, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z");
} else {
SET(p_streambuf_reserve_ctor, "??0streambuf@@IAE@PADH@Z");
SET(p_streambuf_ctor, "??0streambuf@@IAE@XZ");
SET(p_streambuf_dtor, "??1streambuf@@UAE@XZ");
SET(p_streambuf_allocate, "?allocate@streambuf@@IAEHXZ");
SET(p_streambuf_doallocate, "?doallocate@streambuf@@MAEHXZ");
SET(p_streambuf_setb, "?setb@streambuf@@IAEXPAD0H@Z");
SET(p_streambuf_setbuf, "?setbuf@streambuf@@UAEPAV1@PADH@Z");
}
@ -145,6 +151,7 @@ static void test_streambuf(void)
{
streambuf sb, sb2, *psb;
char reserve[16];
int ret;
memset(&sb, 0xab, sizeof(streambuf));
memset(&sb2, 0xab, sizeof(streambuf));
@ -197,7 +204,21 @@ static void test_streambuf(void)
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);
sb.allocated = 0;
/* allocate */
ret = (int) call_func1(p_streambuf_allocate, &sb);
ok(ret == 0, "wrong return value, expected 0 got %d\n", ret);
sb.base = NULL;
ret = (int) call_func1(p_streambuf_allocate, &sb);
ok(ret == 1, "wrong return value, expected 1 got %d\n", ret);
ok(sb.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb.allocated);
ok(sb.ebuf - sb.base == 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb.ebuf, sb.base);
/* doallocate */
ret = (int) call_func1(p_streambuf_doallocate, &sb2);
ok(ret == 1, "doallocate failed, got %d\n", ret);
ok(sb2.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb2.allocated);
ok(sb2.ebuf - sb2.base == 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb2.ebuf, sb2.base);
call_func1(p_streambuf_dtor, &sb);
call_func1(p_streambuf_dtor, &sb2);
}

View File

@ -388,8 +388,8 @@
@ cdecl -arch=win32 ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
@ cdecl -arch=win64 ?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
# @ extern ?adjustfield@ios@@2JB
@ stub -arch=win32 ?allocate@streambuf@@IAEHXZ
@ stub -arch=win64 ?allocate@streambuf@@IEAAHXZ
@ thiscall -arch=win32 ?allocate@streambuf@@IAEHXZ(ptr) msvcirt.?allocate@streambuf@@IAEHXZ
@ cdecl -arch=win64 ?allocate@streambuf@@IEAAHXZ(ptr) msvcirt.?allocate@streambuf@@IEAAHXZ
@ stub -arch=win32 ?attach@filebuf@@QAEPAV1@H@Z
@ stub -arch=win64 ?attach@filebuf@@QEAAPEAV1@H@Z
@ stub -arch=win32 ?attach@fstream@@QAEXH@Z

View File

@ -451,8 +451,8 @@
@ cdecl -arch=win32 ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
@ cdecl -arch=win64 ?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) msvcrt.?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
# @ extern ?adjustfield@ios@@2JB
@ stub -arch=win32 ?allocate@streambuf@@IAEHXZ
@ stub -arch=win64 ?allocate@streambuf@@IEAAHXZ
@ thiscall -arch=win32 ?allocate@streambuf@@IAEHXZ(ptr) msvcirt.?allocate@streambuf@@IAEHXZ
@ cdecl -arch=win64 ?allocate@streambuf@@IEAAHXZ(ptr) msvcirt.?allocate@streambuf@@IEAAHXZ
@ stub -arch=win32 ?attach@filebuf@@QAEPAV1@H@Z
@ stub -arch=win64 ?attach@filebuf@@QEAAPEAV1@H@Z
@ stub -arch=win32 ?attach@fstream@@QAEXH@Z