From f0a547595c3094f5ba2c0595eb02439db34b5bb5 Mon Sep 17 00:00:00 2001
From: Piotr Caban <piotr@codeweavers.com>
Date: Wed, 17 Oct 2012 09:56:09 +0200
Subject: [PATCH] msvcp100: Added _Yarn<char> class implementation.

---
 dlls/msvcp100/msvcp.h       |   6 ++
 dlls/msvcp100/msvcp100.spec |  44 +++++++--------
 dlls/msvcp100/string.c      | 109 ++++++++++++++++++++++++++++++++++++
 3 files changed, 137 insertions(+), 22 deletions(-)

diff --git a/dlls/msvcp100/msvcp.h b/dlls/msvcp100/msvcp.h
index 571c2d06640..dd9675366d2 100644
--- a/dlls/msvcp100/msvcp.h
+++ b/dlls/msvcp100/msvcp.h
@@ -78,6 +78,12 @@ void MSVCP_allocator_char_deallocate(void*, char*, MSVCP_size_t);
 wchar_t* MSVCP_allocator_wchar_allocate(void*, MSVCP_size_t);
 void MSVCP_allocator_wchar_deallocate(void*, wchar_t*, MSVCP_size_t);
 
+typedef struct
+{
+    char *str;
+    char null_str;
+} _Yarn_char;
+
 /* class locale::facet */
 typedef struct {
     const vtable_ptr *vtable;
diff --git a/dlls/msvcp100/msvcp100.spec b/dlls/msvcp100/msvcp100.spec
index 0f485b5d28b..093c9bf9c47 100644
--- a/dlls/msvcp100/msvcp100.spec
+++ b/dlls/msvcp100/msvcp100.spec
@@ -1,9 +1,9 @@
-@ stub -arch=win32 ??0?$_Yarn@D@std@@QAE@ABV01@@Z
-@ stub -arch=win64 ??0?$_Yarn@D@std@@QEAA@AEBV01@@Z
-@ stub -arch=win32 ??0?$_Yarn@D@std@@QAE@PBD@Z
-@ stub -arch=win64 ??0?$_Yarn@D@std@@QEAA@PEBD@Z
-@ stub -arch=win32 ??0?$_Yarn@D@std@@QAE@XZ
-@ stub -arch=win64 ??0?$_Yarn@D@std@@QEAA@XZ
+@ thiscall -arch=win32 ??0?$_Yarn@D@std@@QAE@ABV01@@Z(ptr ptr) _Yarn_char_copy_ctor
+@ cdecl -arch=win64 ??0?$_Yarn@D@std@@QEAA@AEBV01@@Z(ptr ptr) _Yarn_char_copy_ctor
+@ thiscall -arch=win32 ??0?$_Yarn@D@std@@QAE@PBD@Z(ptr str) _Yarn_char_ctor_cstr
+@ cdecl -arch=win64 ??0?$_Yarn@D@std@@QEAA@PEBD@Z(ptr str) _Yarn_char_ctor_cstr
+@ thiscall -arch=win32 ??0?$_Yarn@D@std@@QAE@XZ(ptr) _Yarn_char_ctor
+@ cdecl -arch=win64 ??0?$_Yarn@D@std@@QEAA@XZ(ptr) _Yarn_char_ctor
 @ thiscall -arch=win32 ??0?$basic_ios@DU?$char_traits@D@std@@@std@@IAE@XZ(ptr) basic_ios_char_ctor
 @ cdecl -arch=win64 ??0?$basic_ios@DU?$char_traits@D@std@@@std@@IEAA@XZ(ptr) basic_ios_char_ctor
 @ thiscall -arch=win32 ??0?$basic_ios@DU?$char_traits@D@std@@@std@@QAE@PAV?$basic_streambuf@DU?$char_traits@D@std@@@1@@Z(ptr ptr) basic_ios_char_ctor_streambuf
@@ -230,8 +230,8 @@
 @ cdecl -arch=win64 ??0ios_base@std@@QEAA@AEBV01@@Z(ptr ptr) ios_base_copy_ctor
 @ stub -arch=win32 ??0time_base@std@@QAE@I@Z
 @ stub -arch=win64 ??0time_base@std@@QEAA@_K@Z
-@ stub -arch=win32 ??1?$_Yarn@D@std@@QAE@XZ
-@ stub -arch=win64 ??1?$_Yarn@D@std@@QEAA@XZ
+@ thiscall -arch=win32 ??1?$_Yarn@D@std@@QAE@XZ(ptr) _Yarn_char_dtor
+@ cdecl -arch=win64 ??1?$_Yarn@D@std@@QEAA@XZ(ptr) _Yarn_char_dtor
 @ thiscall -arch=win32 ??1?$basic_ios@DU?$char_traits@D@std@@@std@@UAE@XZ(ptr) basic_ios_char_dtor
 @ cdecl -arch=win64 ??1?$basic_ios@DU?$char_traits@D@std@@@std@@UEAA@XZ(ptr) basic_ios_char_dtor
 @ thiscall -arch=win32 ??1?$basic_ios@GU?$char_traits@G@std@@@std@@UAE@XZ(ptr) basic_ios_wchar_dtor
@@ -338,10 +338,10 @@
 @ stub -arch=win64 ??1time_base@std@@UEAA@XZ
 @ stub -arch=win32 ??4?$_Iosb@H@std@@QAEAAV01@ABV01@@Z
 @ stub -arch=win64 ??4?$_Iosb@H@std@@QEAAAEAV01@AEBV01@@Z
-@ stub -arch=win32 ??4?$_Yarn@D@std@@QAEAAV01@ABV01@@Z
-@ stub -arch=win64 ??4?$_Yarn@D@std@@QEAAAEAV01@AEBV01@@Z
-@ stub -arch=win32 ??4?$_Yarn@D@std@@QAEAAV01@PBD@Z
-@ stub -arch=win64 ??4?$_Yarn@D@std@@QEAAAEAV01@PEBD@Z
+@ thiscall -arch=win32 ??4?$_Yarn@D@std@@QAEAAV01@ABV01@@Z(ptr ptr) _Yarn_char_op_assign
+@ cdecl -arch=win64 ??4?$_Yarn@D@std@@QEAAAEAV01@AEBV01@@Z(ptr ptr) _Yarn_char_op_assign
+@ thiscall -arch=win32 ??4?$_Yarn@D@std@@QAEAAV01@PBD@Z(ptr str) _Yarn_char_op_assign_cstr
+@ cdecl -arch=win64 ??4?$_Yarn@D@std@@QEAAAEAV01@PEBD@Z(ptr str) _Yarn_char_op_assign_cstr
 @ stub -arch=win32 ??4?$basic_iostream@DU?$char_traits@D@std@@@std@@QAEAAV01@$$QAV01@@Z
 @ stub -arch=win64 ??4?$basic_iostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@$$QEAV01@@Z
 @ stub -arch=win32 ??4?$basic_iostream@GU?$char_traits@G@std@@@std@@QAEAAV01@$$QAV01@@Z
@@ -768,8 +768,8 @@
 @ stub -arch=win64 ?_Assign@_Concurrent_queue_iterator_base_v4@details@Concurrency@@IEAAXAEBV123@@Z
 @ stub ?_Atexit@@YAXP6AXXZ@Z
 @ extern ?_BADOFF@std@@3_JB std_BADOFF
-@ stub -arch=win32 ?_C_str@?$_Yarn@D@std@@QBEPBDXZ
-@ stub -arch=win64 ?_C_str@?$_Yarn@D@std@@QEBAPEBDXZ
+@ thiscall -arch=win32 ?_C_str@?$_Yarn@D@std@@QBEPBDXZ(ptr) _Yarn_char_c_str
+@ cdecl -arch=win64 ?_C_str@?$_Yarn@D@std@@QEBAPEBDXZ(ptr) _Yarn_char_c_str
 @ thiscall -arch=win32 ?_Callfns@ios_base@std@@AAEXW4event@12@@Z(ptr long) ios_base_Callfns
 @ cdecl -arch=win64 ?_Callfns@ios_base@std@@AEAAXW4event@12@@Z(ptr long) ios_base_Callfns
 @ extern -arch=win32 ?_Clocptr@_Locimp@locale@std@@0PAV123@A locale__Locimp__Clocptr
@@ -784,8 +784,8 @@
 @ cdecl -arch=win64 ?_Dowiden@?$ctype@G@std@@IEBAGD@Z(ptr long) ctype_wchar__Dowiden
 @ thiscall -arch=win32 ?_Dowiden@?$ctype@_W@std@@IBE_WD@Z(ptr long) ctype_wchar__Dowiden
 @ cdecl -arch=win64 ?_Dowiden@?$ctype@_W@std@@IEBA_WD@Z(ptr long) ctype_wchar__Dowiden
-@ stub -arch=win32 ?_Empty@?$_Yarn@D@std@@QBE_NXZ
-@ stub -arch=win64 ?_Empty@?$_Yarn@D@std@@QEBA_NXZ
+@ thiscall -arch=win32 ?_Empty@?$_Yarn@D@std@@QBE_NXZ(ptr) _Yarn_char_empty
+@ cdecl -arch=win64 ?_Empty@?$_Yarn@D@std@@QEBA_NXZ(ptr) _Yarn_char_empty
 @ cdecl -arch=win32 ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@ABAPADPADDH@Z(ptr ptr long long) num_put_char__Ffmt
 @ cdecl -arch=win64 ?_Ffmt@?$num_put@DV?$ostreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AEBAPEADPEADDH@Z(ptr ptr long long) num_put_char__Ffmt
 @ cdecl -arch=win32 ?_Ffmt@?$num_put@GV?$ostreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@ABAPADPADDH@Z(ptr ptr long long) num_put_wchar__Ffmt
@@ -1207,8 +1207,8 @@
 @ stub -arch=win32 ?_Swap_all@_Container_base12@std@@QAEXAAU12@@Z
 @ stub -arch=win64 ?_Swap_all@_Container_base12@std@@QEAAXAEAU12@@Z
 @ extern ?_Sync@ios_base@std@@0_NA ios_base_Sync
-@ stub -arch=win32 ?_Tidy@?$_Yarn@D@std@@AAEXXZ
-@ stub -arch=win64 ?_Tidy@?$_Yarn@D@std@@AEAAXXZ
+@ thiscall -arch=win32 ?_Tidy@?$_Yarn@D@std@@AAEXXZ(ptr) _Yarn_char__Tidy
+@ cdecl -arch=win64 ?_Tidy@?$_Yarn@D@std@@AEAAXXZ(ptr) _Yarn_char__Tidy
 @ thiscall -arch=win32 ?_Tidy@?$ctype@D@std@@IAEXXZ(ptr) ctype_char__Tidy
 @ cdecl -arch=win64 ?_Tidy@?$ctype@D@std@@IEAAXXZ(ptr) ctype_char__Tidy
 @ stub -arch=win32 ?_Tidy@?$time_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@AAEXXZ
@@ -1247,8 +1247,8 @@
 @ cdecl -arch=win64 ?always_noconv@codecvt_base@std@@QEBA_NXZ(ptr) codecvt_base_always_noconv
 @ thiscall -arch=win32 ?bad@ios_base@std@@QBE_NXZ(ptr) ios_base_bad
 @ cdecl -arch=win64 ?bad@ios_base@std@@QEBA_NXZ(ptr) ios_base_bad
-@ stub -arch=win32 ?c_str@?$_Yarn@D@std@@QBEPBDXZ
-@ stub -arch=win64 ?c_str@?$_Yarn@D@std@@QEBAPEBDXZ
+@ thiscall -arch=win32 ?c_str@?$_Yarn@D@std@@QBEPBDXZ(ptr) _Yarn_char_c_str
+@ cdecl -arch=win64 ?c_str@?$_Yarn@D@std@@QEBAPEBDXZ(ptr) _Yarn_char_c_str
 @ stub -arch=win32 ?cancel@agent@Concurrency@@QAE_NXZ
 @ stub -arch=win64 ?cancel@agent@Concurrency@@QEAA_NXZ
 @ extern ?cerr@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A cerr
@@ -1619,8 +1619,8 @@
 @ cdecl -arch=win64 ?egptr@?$basic_streambuf@GU?$char_traits@G@std@@@std@@IEBAPEAGXZ(ptr) basic_streambuf_wchar_egptr
 @ thiscall -arch=win32 ?egptr@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@IBEPA_WXZ(ptr) basic_streambuf_wchar_egptr
 @ cdecl -arch=win64 ?egptr@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@IEBAPEA_WXZ(ptr) basic_streambuf_wchar_egptr
-@ stub -arch=win32 ?empty@?$_Yarn@D@std@@QBE_NXZ
-@ stub -arch=win64 ?empty@?$_Yarn@D@std@@QEBA_NXZ
+@ thiscall -arch=win32 ?empty@?$_Yarn@D@std@@QBE_NXZ(ptr) _Yarn_char_empty
+@ cdecl -arch=win64 ?empty@?$_Yarn@D@std@@QEBA_NXZ(ptr) _Yarn_char_empty
 @ cdecl ?empty@locale@std@@SA?AV12@XZ(ptr) locale_empty
 @ thiscall -arch=win32 ?encoding@codecvt_base@std@@QBEHXZ(ptr) codecvt_base_encoding
 @ cdecl -arch=win64 ?encoding@codecvt_base@std@@QEBAHXZ(ptr) codecvt_base_encoding
diff --git a/dlls/msvcp100/string.c b/dlls/msvcp100/string.c
index b1b6b891031..39adbd46b8c 100644
--- a/dlls/msvcp100/string.c
+++ b/dlls/msvcp100/string.c
@@ -678,3 +678,112 @@ MSVCP_size_t MSVCP_basic_string_wchar_length(const basic_string_wchar *this)
     TRACE("%p\n", this);
     return this->size;
 }
+
+/* ??0?$_Yarn@D@std@@QAE@XZ */
+/* ??0?$_Yarn@D@std@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_ctor, 4)
+_Yarn_char* __thiscall _Yarn_char_ctor(_Yarn_char *this)
+{
+    TRACE("(%p)\n", this);
+
+    this->str = NULL;
+    this->null_str = '\0';
+    return this;
+}
+
+/* ?_Tidy@?$_Yarn@D@std@@AAEXXZ */
+/* ?_Tidy@?$_Yarn@D@std@@AEAAXXZ */
+DEFINE_THISCALL_WRAPPER(_Yarn_char__Tidy, 4)
+void __thiscall _Yarn_char__Tidy(_Yarn_char *this)
+{
+    TRACE("(%p)\n", this);
+
+    if(this->str)
+        MSVCRT_operator_delete(this->str);
+    this->str = NULL;
+}
+
+/* ??4?$_Yarn@D@std@@QAEAAV01@PBD@Z */
+/* ??4?$_Yarn@D@std@@QEAAAEAV01@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_op_assign_cstr, 8)
+_Yarn_char* __thiscall _Yarn_char_op_assign_cstr(_Yarn_char *this, const char *str)
+{
+    TRACE("(%p %p)\n", this, str);
+
+    _Yarn_char__Tidy(this);
+
+    if(str) {
+        MSVCP_size_t len = strlen(str);
+
+        this->str = MSVCRT_operator_new((len+1)*sizeof(char));
+        if(!this->str) {
+            ERR("out of memory\n");
+            return NULL;
+        }
+        memcpy(this->str, str, (len+1)*sizeof(char));
+    }
+    return this;
+}
+
+/* ??0?$_Yarn@D@std@@QAE@PBD@Z */
+/* ??0?$_Yarn@D@std@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_ctor_cstr, 8)
+_Yarn_char* __thiscall _Yarn_char_ctor_cstr(_Yarn_char *this, const char *str)
+{
+    TRACE("(%p %p)\n", this, str);
+
+    _Yarn_char_ctor(this);
+    return _Yarn_char_op_assign_cstr(this, str);
+}
+
+/* ??4?$_Yarn@D@std@@QAEAAV01@ABV01@@Z */
+/* ??4?$_Yarn@D@std@@QEAAAEAV01@AEBV01@@Z */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_op_assign, 8)
+_Yarn_char* __thiscall _Yarn_char_op_assign(_Yarn_char *this, const _Yarn_char *rhs)
+{
+    TRACE("(%p %p)\n", this, rhs);
+
+    return _Yarn_char_op_assign_cstr(this, rhs->str);
+}
+
+/* ??0?$_Yarn@D@std@@QAE@ABV01@@Z */
+/* ??0?$_Yarn@D@std@@QEAA@AEBV01@@Z */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_copy_ctor, 8)
+_Yarn_char* __thiscall _Yarn_char_copy_ctor(_Yarn_char *this, const _Yarn_char *copy)
+{
+    TRACE("(%p %p)\n", this, copy);
+
+    _Yarn_char_ctor(this);
+    return _Yarn_char_op_assign(this, copy);
+}
+
+/* ??1?$_Yarn@D@std@@QAE@XZ */
+/* ??1?$_Yarn@D@std@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_dtor, 4)
+void __thiscall _Yarn_char_dtor(_Yarn_char *this)
+{
+    TRACE("(%p)\n", this);
+    _Yarn_char__Tidy(this);
+}
+
+/* ?_C_str@?$_Yarn@D@std@@QBEPBDXZ */
+/* ?_C_str@?$_Yarn@D@std@@QEBAPEBDXZ */
+/* ?c_str@?$_Yarn@D@std@@QBEPBDXZ */
+/* ?c_str@?$_Yarn@D@std@@QEBAPEBDXZ */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_c_str, 4)
+const char* __thiscall _Yarn_char_c_str(const _Yarn_char *this)
+{
+    TRACE("(%p)\n", this);
+    return this->str ? this->str : &this->null_str;
+}
+
+/* ?_Empty@?$_Yarn@D@std@@QBE_NXZ */
+/* ?_Empty@?$_Yarn@D@std@@QEBA_NXZ */
+/* ?empty@?$_Yarn@D@std@@QBE_NXZ */
+/* ?empty@?$_Yarn@D@std@@QEBA_NXZ */
+DEFINE_THISCALL_WRAPPER(_Yarn_char_empty, 4)
+MSVCP_bool __thiscall _Yarn_char_empty(const _Yarn_char *this)
+{
+    TRACE("(%p)\n", this);
+    return !this->str;
+}
-- 
GitLab