From 6040c8f89752b8d8dd3c62231f510dd25f6d176f Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Thu, 19 Aug 2010 12:17:42 +0200 Subject: [PATCH] msvcp90: Added some basic_string::assign implementations. --- dlls/msvcp90/msvcp90.h | 1 + dlls/msvcp90/msvcp90.spec | 16 ++--- dlls/msvcp90/string.c | 125 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 8 deletions(-) diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 89d549be542..3470d1b0e48 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -123,4 +123,5 @@ typedef struct _basic_string_char size_t res; } basic_string_char; +char* __stdcall MSVCP_allocator_char_allocate(void*, size_t); void __stdcall MSVCP_allocator_char_deallocate(void*, char*, size_t); diff --git a/dlls/msvcp90/msvcp90.spec b/dlls/msvcp90/msvcp90.spec index 1f60fb6bf36..9a0a17a77cf 100644 --- a/dlls/msvcp90/msvcp90.spec +++ b/dlls/msvcp90/msvcp90.spec @@ -2958,17 +2958,17 @@ @ stub -arch=win64 ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@0@Z @ stub -arch=win32 ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@V?$_String_const_iterator@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@2@0@Z @ stub -arch=win64 ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K_W@Z -@ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@@Z -@ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@@Z -@ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z -@ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z +@ cdecl -arch=win32 -i386 -norelay ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@@Z(ptr) __thiscall_MSVCP_basic_string_char_assign +@ cdecl -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@@Z(ptr ptr) MSVCP_basic_string_char_assign +@ cdecl -arch=win32 -i386 -norelay ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z(ptr long long) __thiscall_MSVCP_basic_string_char_assign_substr +@ cdecl -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z(ptr ptr long long) MSVCP_basic_string_char_assign_substr @ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ID@Z @ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD0@Z @ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD0@Z -@ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD@Z -@ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD@Z -@ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z -@ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z +@ cdecl -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD@Z(ptr str) MSVCP_basic_string_char_assign_cstr +@ cdecl -arch=win32 -i386 -norelay ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD@Z(str) __thiscall_MSVCP_basic_string_char_assign_cstr +@ cdecl -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z(ptr ptr long) MSVCP_basic_string_char_assign_cstr_len +@ cdecl -arch=win32 -i386 -norelay ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z(ptr long) __thiscall_MSVCP_basic_string_char_assign_cstr_len @ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@0@Z @ stub -arch=win32 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@V?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@0@Z @ stub -arch=win64 ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_KD@Z diff --git a/dlls/msvcp90/string.c b/dlls/msvcp90/string.c index 82397e27874..93cef1b5e45 100644 --- a/dlls/msvcp90/string.c +++ b/dlls/msvcp90/string.c @@ -478,6 +478,14 @@ static char* basic_string_char_ptr(basic_string_char *this) return this->data.ptr; } +/* Internal: basic_string_char_const_ptr - returns const pointer to stored string */ +static const char* basic_string_char_const_ptr(const basic_string_char *this) +{ + if(this->res == BUF_SIZE_CHAR-1) + return this->data.buf; + return this->data.ptr; +} + /* Internal: basic_string_char_eos - sets string length, puts '\0' on the end */ static void basic_string_char_eos(basic_string_char *this, size_t len) { @@ -487,6 +495,15 @@ static void basic_string_char_eos(basic_string_char *this, size_t len) MSVCP_char_traits_char_assign(basic_string_char_ptr(this)+len, &nullbyte); } +/* Internal: basic_string_char_inside - checks if given pointer points inside stored string */ +static MSVCP_BOOL basic_string_char_inside( + basic_string_char *this, const char *ptr) +{ + char *cstr = basic_string_char_ptr(this); + + return (ptr=cstr+this->size) ? FALSE : TRUE; +} + /* Internal: basic_string_char_tidy - initialize basic_string buffer, deallocates data */ /* Caution: new_size have to be smaller than BUF_SIZE_CHAR */ static void basic_string_char_tidy(basic_string_char *this, @@ -504,6 +521,45 @@ static void basic_string_char_tidy(basic_string_char *this, basic_string_char_eos(this, new_size); } +/* Internal: basic_string_char_grow - changes size of internal buffer */ +static MSVCP_BOOL basic_string_char_grow( + basic_string_char *this, size_t new_size, MSVCP_BOOL trim) +{ + if(this->res < new_size) { + size_t new_res = new_size; + char *ptr; + + new_res |= 0xf; + + if(new_res/3 < this->res/2) + new_res = this->res + this->res/2; + + ptr = MSVCP_allocator_char_allocate(this->allocator, new_res); + if(!ptr) + ptr = MSVCP_allocator_char_allocate(this->allocator, new_size+1); + else + new_size = new_res; + if(!ptr) { + ERR("Out of memory\n"); + basic_string_char_tidy(this, TRUE, 0); + return FALSE; + } + + MSVCP_char_traits_char__Copy_s(ptr, new_size, + basic_string_char_ptr(this), this->size); + basic_string_char_tidy(this, TRUE, 0); + this->data.ptr = ptr; + this->res = new_size; + basic_string_char_eos(this, this->size); + } else if(trim && new_size < BUF_SIZE_CHAR) + basic_string_char_tidy(this, TRUE, + new_sizesize ? new_size : this->size); + else if(new_size == 0) + basic_string_char_eos(this, 0); + + return (new_size>0); +} + /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z */ /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z */ DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_erase, 12) @@ -530,6 +586,75 @@ basic_string_char* __stdcall MSVCP_basic_string_char_erase( return this; } +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z */ +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */ +DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_substr, 16) +basic_string_char* __stdcall MSVCP_basic_string_char_assign_substr( + basic_string_char *this, const basic_string_char *assign, + size_t pos, size_t len) +{ + TRACE("%p %p %d %d\n", this, assign, pos, len); + + if(assign->size < pos) { + FIXME("Throw exception (_Xran)\n"); + return NULL; + } + + if(len > assign->size-pos) + len = assign->size-pos; + + if(this == assign) { + MSVCP_basic_string_char_erase(this, pos+len, MSVCP_basic_string_char_npos); + MSVCP_basic_string_char_erase(this, 0, pos); + } else if(basic_string_char_grow(this, len, FALSE)) { + MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this), + this->res, basic_string_char_const_ptr(assign)+pos, len); + basic_string_char_eos(this, len); + } + + return this; +} + +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@@Z */ +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@@Z */ +DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign, 8) +basic_string_char* __stdcall MSVCP_basic_string_char_assign( + basic_string_char *this, const basic_string_char *assign) +{ + return MSVCP_basic_string_char_assign_substr(this, assign, + 0, MSVCP_basic_string_char_npos); +} + +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z */ +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z */ +DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_cstr_len, 12) +basic_string_char* __stdcall MSVCP_basic_string_char_assign_cstr_len( + basic_string_char *this, const char *str, size_t len) +{ + TRACE("%p %s %d\n", this, debugstr_a(str), len); + + if(basic_string_char_inside(this, str)) + return MSVCP_basic_string_char_assign_substr(this, this, + str-basic_string_char_ptr(this), len); + else if(basic_string_char_grow(this, len, FALSE)) { + MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this), + this->res, str, len); + basic_string_char_eos(this, len); + } + + return this; +} + +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD@Z */ +/* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_assign_cstr, 8) +basic_string_char* __stdcall MSVCP_basic_string_char_assign_cstr( + basic_string_char *this, const char *str) +{ + return MSVCP_basic_string_char_assign_cstr_len(this, str, + MSVCP_char_traits_char_length(str)); +} + /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */ /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */ DEFINE_THISCALL_WRAPPER(MSVCP_basic_string_char_ctor, 4)