wbemprox: Don't fail if there are less objects than asked for in IEnumWbemClassObject...
[wine.git] / dlls / msvcp100 / string.c
blob9771ace8478fe2c1c61ebc453118b5c8d7f87792
1 /*
2 * Copyright 2010 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "config.h"
21 #include <stdarg.h>
23 #include "msvcp.h"
24 #include "stdio.h"
25 #include "assert.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
32 /* _String_iterator<char> and _String_const_iterator<char> class */
33 /* char_traits<char> */
34 /* ?assign@?$char_traits@D@std@@SAXAADABD@Z */
35 /* ?assign@?$char_traits@D@std@@SAXAEADAEBD@Z */
36 static void MSVCP_char_traits_char_assign(char *ch, const char *assign)
38 *ch = *assign;
41 /* ?assign@?$char_traits@D@std@@SAPADPADID@Z */
42 /* ?assign@?$char_traits@D@std@@SAPEADPEAD_KD@Z */
43 static char* MSVCP_char_traits_char_assignn(char *str, MSVCP_size_t num, char c)
45 return memset(str, c, num);
48 /* ?length@?$char_traits@D@std@@SAIPBD@Z */
49 /* ?length@?$char_traits@D@std@@SA_KPEBD@Z */
50 static MSVCP_size_t MSVCP_char_traits_char_length(const char *str)
52 return strlen(str);
55 /* ?_Copy_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
56 /* ?_Copy_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
57 static char* MSVCP_char_traits_char__Copy_s(char *dest,
58 MSVCP_size_t size, const char *src, MSVCP_size_t count)
60 if(!dest || !src || size<count) {
61 if(dest && size)
62 dest[0] = '\0';
63 _invalid_parameter(NULL, NULL, NULL, 0, 0);
64 return dest;
67 return memcpy(dest, src, count);
70 /* ?_Move_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
71 /* ?_Move_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
72 static char* MSVCP_char_traits_char__Move_s(char *dest,
73 MSVCP_size_t size, const char *src, MSVCP_size_t count)
75 if(!dest || !src || size<count) {
76 if(dest && size)
77 dest[0] = '\0';
78 _invalid_parameter(NULL, NULL, NULL, 0, 0);
79 return dest;
82 return memmove(dest, src, count);
85 /* char_traits<wchar_t> */
86 /* ?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z */
87 /* ?assign@?$char_traits@_W@std@@SAXAEA_WAEB_W@Z */
88 static void MSVCP_char_traits_wchar_assign(wchar_t *ch,
89 const wchar_t *assign)
91 *ch = *assign;
94 /* ?length@?$char_traits@_W@std@@SAIPB_W@Z */
95 /* ?length@?$char_traits@_W@std@@SA_KPEB_W@Z */
96 static MSVCP_size_t MSVCP_char_traits_wchar_length(const wchar_t *str)
98 return wcslen((WCHAR*)str);
101 /* ?_Copy_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
102 /* ?_Copy_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
103 static wchar_t* MSVCP_char_traits_wchar__Copy_s(wchar_t *dest,
104 MSVCP_size_t size, const wchar_t *src, MSVCP_size_t count)
106 if(!dest || !src || size<count) {
107 if(dest && size)
108 dest[0] = '\0';
109 _invalid_parameter(NULL, NULL, NULL, 0, 0);
110 return dest;
113 return memcpy(dest, src, count * sizeof(wchar_t));
116 /* ?_Move_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
117 /* ?_Move_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
118 static wchar_t* MSVCP_char_traits_wchar__Move_s(wchar_t *dest,
119 MSVCP_size_t size, const wchar_t *src, MSVCP_size_t count)
121 if(!dest || !src || size<count) {
122 if(dest && size)
123 dest[0] = '\0';
124 _invalid_parameter(NULL, NULL, NULL, 0, 0);
125 return dest;
128 return memmove(dest, src, count * sizeof(WCHAR));
131 /* _String_base */
132 /* ?_Xlen@_String_base@std@@SAXXZ */
133 static void MSVCP__String_base_Xlen(void)
135 static const char msg[] = "string too long";
137 TRACE("\n");
138 throw_exception(EXCEPTION_LENGTH_ERROR, msg);
141 /* _String_base */
142 /* ?_Xran@_String_base@std@@SAXXZ */
143 static void MSVCP__String_base_Xran(void)
145 static const char msg[] = "invalid string position";
147 TRACE("\n");
148 throw_exception(EXCEPTION_OUT_OF_RANGE, msg);
152 /* basic_string<char, char_traits<char>, allocator<char>> */
153 /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB */
154 /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2_KB */
155 static const MSVCP_size_t MSVCP_basic_string_char_npos = -1;
157 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEPADXZ */
158 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAPEADXZ */
159 static char* basic_string_char_ptr(basic_string_char *this)
161 if(this->res < BUF_SIZE_CHAR)
162 return this->data.buf;
163 return this->data.ptr;
166 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IBEPBDXZ */
167 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEBAPEBDXZ */
168 static const char* basic_string_char_const_ptr(const basic_string_char *this)
170 if(this->res < BUF_SIZE_CHAR)
171 return this->data.buf;
172 return this->data.ptr;
175 /* ?_Eos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEXI@Z */
176 /* ?_Eos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_K@Z */
177 static void basic_string_char_eos(basic_string_char *this, MSVCP_size_t len)
179 static const char nullbyte = '\0';
181 this->size = len;
182 MSVCP_char_traits_char_assign(basic_string_char_ptr(this)+len, &nullbyte);
185 /* ?_Inside@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAE_NPBD@Z */
186 /* ?_Inside@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAA_NPEBD@Z */
187 static MSVCP_bool basic_string_char_inside(
188 basic_string_char *this, const char *ptr)
190 char *cstr = basic_string_char_ptr(this);
192 return ptr>=cstr && ptr<cstr+this->size;
195 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEX_NI@Z */
196 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_N_K@Z */
197 static void basic_string_char_tidy(basic_string_char *this,
198 MSVCP_bool built, MSVCP_size_t new_size)
200 if(built && BUF_SIZE_CHAR<=this->res) {
201 char *ptr = this->data.ptr;
203 if(new_size > 0)
204 MSVCP_char_traits_char__Copy_s(this->data.buf, BUF_SIZE_CHAR, ptr, new_size);
205 MSVCP_allocator_char_deallocate(this->allocator, ptr, this->res+1);
208 this->res = BUF_SIZE_CHAR-1;
209 basic_string_char_eos(this, new_size);
212 /* ?_Grow@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAE_NI_N@Z */
213 /* ?_Grow@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAA_N_K_N@Z */
214 static MSVCP_bool basic_string_char_grow(
215 basic_string_char *this, MSVCP_size_t new_size, MSVCP_bool trim)
217 if(this->res < new_size) {
218 MSVCP_size_t new_res = new_size, len = this->size;
219 char *ptr;
221 new_res |= 0xf;
223 if(new_res/3 < this->res/2)
224 new_res = this->res + this->res/2;
226 ptr = MSVCP_allocator_char_allocate(this->allocator, new_res+1);
227 if(!ptr)
228 ptr = MSVCP_allocator_char_allocate(this->allocator, new_size+1);
229 else
230 new_size = new_res;
231 if(!ptr) {
232 ERR("Out of memory\n");
233 basic_string_char_tidy(this, TRUE, 0);
234 return FALSE;
237 MSVCP_char_traits_char__Copy_s(ptr, new_size,
238 basic_string_char_ptr(this), this->size);
239 basic_string_char_tidy(this, TRUE, 0);
240 this->data.ptr = ptr;
241 this->res = new_size;
242 basic_string_char_eos(this, len);
243 } else if(trim && new_size < BUF_SIZE_CHAR)
244 basic_string_char_tidy(this, TRUE,
245 new_size<this->size ? new_size : this->size);
246 else if(new_size == 0)
247 basic_string_char_eos(this, 0);
249 return (new_size>0);
252 /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z */
253 /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z */
254 static basic_string_char* MSVCP_basic_string_char_erase(
255 basic_string_char *this, MSVCP_size_t pos, MSVCP_size_t len)
257 TRACE("%p %lu %lu\n", this, pos, len);
259 if(pos > this->size)
260 MSVCP__String_base_Xran();
262 if(len > this->size-pos)
263 len = this->size-pos;
265 if(len) {
266 MSVCP_char_traits_char__Move_s(basic_string_char_ptr(this)+pos,
267 this->res-pos, basic_string_char_ptr(this)+pos+len,
268 this->size-pos-len);
269 basic_string_char_eos(this, this->size-len);
272 return this;
275 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z */
276 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
277 static basic_string_char* MSVCP_basic_string_char_assign_substr(
278 basic_string_char *this, const basic_string_char *assign,
279 MSVCP_size_t pos, MSVCP_size_t len)
281 TRACE("%p %p %lu %lu\n", this, assign, pos, len);
283 if(assign->size < pos)
284 MSVCP__String_base_Xran();
286 if(len > assign->size-pos)
287 len = assign->size-pos;
289 if(this == assign) {
290 MSVCP_basic_string_char_erase(this, pos+len, MSVCP_basic_string_char_npos);
291 MSVCP_basic_string_char_erase(this, 0, pos);
292 } else if(basic_string_char_grow(this, len, FALSE)) {
293 MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this),
294 this->res, basic_string_char_const_ptr(assign)+pos, len);
295 basic_string_char_eos(this, len);
298 return this;
301 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z */
302 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@AEBV01@@Z */
303 static basic_string_char* MSVCP_basic_string_char_assign(
304 basic_string_char *this, const basic_string_char *assign)
306 return MSVCP_basic_string_char_assign_substr(this, assign,
307 0, MSVCP_basic_string_char_npos);
310 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z */
311 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z */
312 static basic_string_char* MSVCP_basic_string_char_assign_cstr_len(
313 basic_string_char *this, const char *str, MSVCP_size_t len)
315 TRACE("%p %s %lu\n", this, debugstr_an(str, len), len);
317 if(basic_string_char_inside(this, str))
318 return MSVCP_basic_string_char_assign_substr(this, this,
319 str-basic_string_char_ptr(this), len);
320 else if(basic_string_char_grow(this, len, FALSE)) {
321 MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this),
322 this->res, str, len);
323 basic_string_char_eos(this, len);
326 return this;
329 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z */
330 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@PEBD@Z */
331 static basic_string_char* MSVCP_basic_string_char_assign_cstr(
332 basic_string_char *this, const char *str)
334 return MSVCP_basic_string_char_assign_cstr_len(this, str,
335 MSVCP_char_traits_char_length(str));
338 /* ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ */
339 /* ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ */
340 /* ?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ */
341 /* ?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ */
342 const char* MSVCP_basic_string_char_c_str(const basic_string_char *this)
344 TRACE("%p\n", this);
345 return basic_string_char_const_ptr(this);
348 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z */
349 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV01@@Z */
350 basic_string_char* MSVCP_basic_string_char_copy_ctor(
351 basic_string_char *this, const basic_string_char *copy)
353 TRACE("%p %p\n", this, copy);
355 basic_string_char_tidy(this, FALSE, 0);
356 MSVCP_basic_string_char_assign(this, copy);
357 return this;
360 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */
361 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */
362 basic_string_char* MSVCP_basic_string_char_ctor(basic_string_char *this)
364 TRACE("%p\n", this);
366 basic_string_char_tidy(this, FALSE, 0);
367 return this;
370 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z */
371 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z */
372 basic_string_char* MSVCP_basic_string_char_ctor_cstr(
373 basic_string_char *this, const char *str)
375 TRACE("%p %s\n", this, debugstr_a(str));
377 basic_string_char_tidy(this, FALSE, 0);
378 MSVCP_basic_string_char_assign_cstr(this, str);
379 return this;
382 /* ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */
383 /* ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */
384 void MSVCP_basic_string_char_dtor(basic_string_char *this)
386 TRACE("%p\n", this);
387 basic_string_char_tidy(this, TRUE, 0);
390 /* ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
391 /* ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
392 /* ?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
393 /* ?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
394 MSVCP_size_t MSVCP_basic_string_char_length(const basic_string_char *this)
396 TRACE("%p\n", this);
397 return this->size;
400 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ID@Z */
401 /* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_KD@Z */
402 static basic_string_char* MSVCP_basic_string_char_append_len_ch(basic_string_char *this, MSVCP_size_t count, char ch)
404 TRACE("%p %lu %c\n", this, count, ch);
406 if(MSVCP_basic_string_char_npos-this->size <= count)
407 MSVCP__String_base_Xlen();
409 if(basic_string_char_grow(this, this->size+count, FALSE)) {
410 MSVCP_char_traits_char_assignn(basic_string_char_ptr(this)+this->size, count, ch);
411 basic_string_char_eos(this, this->size+count);
414 return this;
417 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@D@Z */
418 /* ??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@D@Z */
419 /* ?push_back@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXD@Z */
420 /* ?push_back@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXD@Z */
421 basic_string_char* MSVCP_basic_string_char_append_ch(basic_string_char *this, char ch)
423 return MSVCP_basic_string_char_append_len_ch(this, 1, ch);
426 /* basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> */
427 /* basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short>> */
428 /* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2IB */
429 /* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2_KB */
430 /* ?npos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@2IB */
431 /* ?npos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@2_KB */
432 const MSVCP_size_t MSVCP_basic_string_wchar_npos = -1;
434 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEPA_WXZ */
435 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAPEA_WXZ */
436 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAEPAGXZ */
437 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAAPEAGXZ */
438 static wchar_t* basic_string_wchar_ptr(basic_string_wchar *this)
440 if(this->res < BUF_SIZE_WCHAR)
441 return this->data.buf;
442 return this->data.ptr;
445 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IBEPB_WXZ */
446 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEBAPEB_WXZ */
447 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IBEPBGXZ */
448 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEBAPEBGXZ */
449 static const wchar_t* basic_string_wchar_const_ptr(const basic_string_wchar *this)
451 if(this->res < BUF_SIZE_WCHAR)
452 return this->data.buf;
453 return this->data.ptr;
456 /* ?_Eos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEXI@Z */
457 /* ?_Eos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_K@Z */
458 /* ?_Eos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAEXI@Z */
459 /* ?_Eos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAAX_K@Z */
460 static void basic_string_wchar_eos(basic_string_wchar *this, MSVCP_size_t len)
462 static const wchar_t nullbyte_w = '\0';
464 this->size = len;
465 MSVCP_char_traits_wchar_assign(basic_string_wchar_ptr(this)+len, &nullbyte_w);
468 /* ?_Inside@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAE_NPB_W@Z */
469 /* ?_Inside@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAA_NPEB_W@Z */
470 /* ?_Inside@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAE_NPBG@Z */
471 /* ?_Inside@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAA_NPEBG@Z */
472 static MSVCP_bool basic_string_wchar_inside(
473 basic_string_wchar *this, const wchar_t *ptr)
475 wchar_t *cstr = basic_string_wchar_ptr(this);
477 return ptr>=cstr && ptr<cstr+this->size;
480 /* ?_Tidy@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEX_NI@Z */
481 /* ?_Tidy@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_N_K@Z */
482 /* ?_Tidy@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAEX_NI@Z */
483 /* ?_Tidy@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAAX_N_K@Z */
484 static void basic_string_wchar_tidy(basic_string_wchar *this,
485 MSVCP_bool built, MSVCP_size_t new_size)
487 if(built && BUF_SIZE_WCHAR<=this->res) {
488 wchar_t *ptr = this->data.ptr;
490 if(new_size > 0)
491 MSVCP_char_traits_wchar__Copy_s(this->data.buf, BUF_SIZE_WCHAR, ptr, new_size);
492 MSVCP_allocator_wchar_deallocate(this->allocator, ptr, this->res+1);
495 this->res = BUF_SIZE_WCHAR-1;
496 basic_string_wchar_eos(this, new_size);
499 /* ?_Grow@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAE_NI_N@Z */
500 /* ?_Grow@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAA_N_K_N@Z */
501 /* ?_Grow@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAE_NI_N@Z */
502 /* ?_Grow@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAA_N_K_N@Z */
503 static MSVCP_bool basic_string_wchar_grow(
504 basic_string_wchar *this, MSVCP_size_t new_size, MSVCP_bool trim)
506 if(this->res < new_size) {
507 MSVCP_size_t new_res = new_size, len = this->size;
508 wchar_t *ptr;
510 new_res |= 0xf;
512 if(new_res/3 < this->res/2)
513 new_res = this->res + this->res/2;
515 ptr = MSVCP_allocator_wchar_allocate(this->allocator, new_res+1);
516 if(!ptr)
517 ptr = MSVCP_allocator_wchar_allocate(this->allocator, new_size+1);
518 else
519 new_size = new_res;
520 if(!ptr) {
521 ERR("Out of memory\n");
522 basic_string_wchar_tidy(this, TRUE, 0);
523 return FALSE;
526 MSVCP_char_traits_wchar__Copy_s(ptr, new_size,
527 basic_string_wchar_ptr(this), this->size);
528 basic_string_wchar_tidy(this, TRUE, 0);
529 this->data.ptr = ptr;
530 this->res = new_size;
531 basic_string_wchar_eos(this, len);
532 } else if(trim && new_size < BUF_SIZE_WCHAR)
533 basic_string_wchar_tidy(this, TRUE,
534 new_size<this->size ? new_size : this->size);
535 else if(new_size == 0)
536 basic_string_wchar_eos(this, 0);
538 return (new_size>0);
541 /* ?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@II@Z */
542 /* ?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K0@Z */
543 /* ?erase@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@II@Z */
544 /* ?erase@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@_K0@Z */
545 static basic_string_wchar* MSVCP_basic_string_wchar_erase(
546 basic_string_wchar *this, MSVCP_size_t pos, MSVCP_size_t len)
548 TRACE("%p %lu %lu\n", this, pos, len);
550 if(pos > this->size)
551 MSVCP__String_base_Xran();
553 if(len > this->size-pos)
554 len = this->size-pos;
556 if(len) {
557 MSVCP_char_traits_wchar__Move_s(basic_string_wchar_ptr(this)+pos,
558 this->res-pos, basic_string_wchar_ptr(this)+pos+len,
559 this->size-pos-len);
560 basic_string_wchar_eos(this, this->size-len);
563 return this;
566 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@ABV12@II@Z */
567 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
568 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@ABV12@II@Z */
569 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
570 static basic_string_wchar* MSVCP_basic_string_wchar_assign_substr(
571 basic_string_wchar *this, const basic_string_wchar *assign,
572 MSVCP_size_t pos, MSVCP_size_t len)
574 TRACE("%p %p %lu %lu\n", this, assign, pos, len);
576 if(assign->size < pos)
577 MSVCP__String_base_Xran();
579 if(len > assign->size-pos)
580 len = assign->size-pos;
582 if(this == assign) {
583 MSVCP_basic_string_wchar_erase(this, pos+len, MSVCP_basic_string_wchar_npos);
584 MSVCP_basic_string_wchar_erase(this, 0, pos);
585 } else if(basic_string_wchar_grow(this, len, FALSE)) {
586 MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this),
587 this->res, basic_string_wchar_const_ptr(assign)+pos, len);
588 basic_string_wchar_eos(this, len);
591 return this;
594 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z */
595 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z */
596 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@PBGI@Z */
597 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@PEBG_K@Z */
598 static basic_string_wchar* MSVCP_basic_string_wchar_assign_cstr_len(
599 basic_string_wchar *this, const wchar_t *str, MSVCP_size_t len)
601 TRACE("%p %s %lu\n", this, debugstr_wn(str, len), len);
603 if(basic_string_wchar_inside(this, str))
604 return MSVCP_basic_string_wchar_assign_substr(this, this,
605 str-basic_string_wchar_ptr(this), len);
606 else if(basic_string_wchar_grow(this, len, FALSE)) {
607 MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this),
608 this->res, str, len);
609 basic_string_wchar_eos(this, len);
612 return this;
615 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_W@Z */
616 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W@Z */
617 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@PB_W@Z */
618 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@PEB_W@Z */
619 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@PBG@Z */
620 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@PEBG@Z */
621 /* ??4?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV01@PBG@Z */
622 /* ??4?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV01@PEBG@Z */
623 static basic_string_wchar* MSVCP_basic_string_wchar_assign_cstr(
624 basic_string_wchar *this, const wchar_t *str)
626 return MSVCP_basic_string_wchar_assign_cstr_len(this, str,
627 MSVCP_char_traits_wchar_length(str));
630 /* ?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ */
631 /* ?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ */
632 /* ?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ */
633 /* ?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ */
634 /* ?c_str@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEPBGXZ */
635 /* ?c_str@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBAPEBGXZ */
636 /* ?data@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEPBGXZ */
637 /* ?data@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBAPEBGXZ */
638 const wchar_t* MSVCP_basic_string_wchar_c_str(const basic_string_wchar *this)
640 TRACE("%p\n", this);
641 return basic_string_wchar_const_ptr(this);
644 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@PB_W@Z */
645 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W@Z */
646 /* ??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@PBG@Z */
647 /* ??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@PEBG@Z */
648 basic_string_wchar* MSVCP_basic_string_wchar_ctor_cstr(
649 basic_string_wchar *this, const wchar_t *str)
651 TRACE("%p %s\n", this, debugstr_w(str));
653 basic_string_wchar_tidy(this, FALSE, 0);
654 MSVCP_basic_string_wchar_assign_cstr(this, str);
655 return this;
658 /* ??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ */
659 /* ??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ */
660 /* ??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@XZ */
661 /* ??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@XZ */
662 void MSVCP_basic_string_wchar_dtor(basic_string_wchar *this)
664 TRACE("%p\n", this);
665 basic_string_wchar_tidy(this, TRUE, 0);
668 /* ?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
669 /* ?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
670 /* ?length@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
671 /* ?length@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
672 /* ?size@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEIXZ */
673 /* ?size@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBA_KXZ */
674 /* ?length@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEIXZ */
675 /* ?length@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBA_KXZ */
676 MSVCP_size_t MSVCP_basic_string_wchar_length(const basic_string_wchar *this)
678 TRACE("%p\n", this);
679 return this->size;
682 /* ??0?$_Yarn@D@std@@QAE@XZ */
683 /* ??0?$_Yarn@D@std@@QEAA@XZ */
684 DEFINE_THISCALL_WRAPPER(_Yarn_char_ctor, 4)
685 _Yarn_char* __thiscall _Yarn_char_ctor(_Yarn_char *this)
687 TRACE("(%p)\n", this);
689 this->str = NULL;
690 this->null_str = '\0';
691 return this;
694 /* ?_Tidy@?$_Yarn@D@std@@AAEXXZ */
695 /* ?_Tidy@?$_Yarn@D@std@@AEAAXXZ */
696 DEFINE_THISCALL_WRAPPER(_Yarn_char__Tidy, 4)
697 void __thiscall _Yarn_char__Tidy(_Yarn_char *this)
699 TRACE("(%p)\n", this);
701 if(this->str)
702 MSVCRT_operator_delete(this->str);
703 this->str = NULL;
706 /* ??4?$_Yarn@D@std@@QAEAAV01@PBD@Z */
707 /* ??4?$_Yarn@D@std@@QEAAAEAV01@PEBD@Z */
708 DEFINE_THISCALL_WRAPPER(_Yarn_char_op_assign_cstr, 8)
709 _Yarn_char* __thiscall _Yarn_char_op_assign_cstr(_Yarn_char *this, const char *str)
711 TRACE("(%p %p)\n", this, str);
713 _Yarn_char__Tidy(this);
715 if(str) {
716 MSVCP_size_t len = strlen(str);
718 this->str = MSVCRT_operator_new((len+1)*sizeof(char));
719 if(!this->str) {
720 ERR("out of memory\n");
721 return NULL;
723 memcpy(this->str, str, (len+1)*sizeof(char));
725 return this;
728 /* ??0?$_Yarn@D@std@@QAE@PBD@Z */
729 /* ??0?$_Yarn@D@std@@QEAA@PEBD@Z */
730 DEFINE_THISCALL_WRAPPER(_Yarn_char_ctor_cstr, 8)
731 _Yarn_char* __thiscall _Yarn_char_ctor_cstr(_Yarn_char *this, const char *str)
733 TRACE("(%p %p)\n", this, str);
735 _Yarn_char_ctor(this);
736 return _Yarn_char_op_assign_cstr(this, str);
739 /* ??4?$_Yarn@D@std@@QAEAAV01@ABV01@@Z */
740 /* ??4?$_Yarn@D@std@@QEAAAEAV01@AEBV01@@Z */
741 DEFINE_THISCALL_WRAPPER(_Yarn_char_op_assign, 8)
742 _Yarn_char* __thiscall _Yarn_char_op_assign(_Yarn_char *this, const _Yarn_char *rhs)
744 TRACE("(%p %p)\n", this, rhs);
746 return _Yarn_char_op_assign_cstr(this, rhs->str);
749 /* ??0?$_Yarn@D@std@@QAE@ABV01@@Z */
750 /* ??0?$_Yarn@D@std@@QEAA@AEBV01@@Z */
751 DEFINE_THISCALL_WRAPPER(_Yarn_char_copy_ctor, 8)
752 _Yarn_char* __thiscall _Yarn_char_copy_ctor(_Yarn_char *this, const _Yarn_char *copy)
754 TRACE("(%p %p)\n", this, copy);
756 _Yarn_char_ctor(this);
757 return _Yarn_char_op_assign(this, copy);
760 /* ??1?$_Yarn@D@std@@QAE@XZ */
761 /* ??1?$_Yarn@D@std@@QEAA@XZ */
762 DEFINE_THISCALL_WRAPPER(_Yarn_char_dtor, 4)
763 void __thiscall _Yarn_char_dtor(_Yarn_char *this)
765 TRACE("(%p)\n", this);
766 _Yarn_char__Tidy(this);
769 /* ?_C_str@?$_Yarn@D@std@@QBEPBDXZ */
770 /* ?_C_str@?$_Yarn@D@std@@QEBAPEBDXZ */
771 /* ?c_str@?$_Yarn@D@std@@QBEPBDXZ */
772 /* ?c_str@?$_Yarn@D@std@@QEBAPEBDXZ */
773 DEFINE_THISCALL_WRAPPER(_Yarn_char_c_str, 4)
774 const char* __thiscall _Yarn_char_c_str(const _Yarn_char *this)
776 TRACE("(%p)\n", this);
777 return this->str ? this->str : &this->null_str;
780 /* ?_Empty@?$_Yarn@D@std@@QBE_NXZ */
781 /* ?_Empty@?$_Yarn@D@std@@QEBA_NXZ */
782 /* ?empty@?$_Yarn@D@std@@QBE_NXZ */
783 /* ?empty@?$_Yarn@D@std@@QEBA_NXZ */
784 DEFINE_THISCALL_WRAPPER(_Yarn_char_empty, 4)
785 MSVCP_bool __thiscall _Yarn_char_empty(const _Yarn_char *this)
787 TRACE("(%p)\n", this);
788 return !this->str;