wininet: Correctly set headers size in CommitUrlCacheEntryW function.
[wine] / dlls / msvcp100 / string.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "msvcp.h"
24 #include "stdio.h"
25 #include "assert.h"
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
31
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)
37 {
38     *ch = *assign;
39 }
40
41 /* ?length@?$char_traits@D@std@@SAIPBD@Z */
42 /* ?length@?$char_traits@D@std@@SA_KPEBD@Z */
43 static MSVCP_size_t MSVCP_char_traits_char_length(const char *str)
44 {
45     return strlen(str);
46 }
47
48 /* ?_Copy_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
49 /* ?_Copy_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
50 static char* MSVCP_char_traits_char__Copy_s(char *dest,
51         MSVCP_size_t size, const char *src, MSVCP_size_t count)
52 {
53     if(!dest || !src || size<count) {
54         if(dest && size)
55             dest[0] = '\0';
56         _invalid_parameter(NULL, NULL, NULL, 0, 0);
57         return dest;
58     }
59
60     return memcpy(dest, src, count);
61 }
62
63 /* ?_Move_s@?$char_traits@D@std@@SAPADPADIPBDI@Z */
64 /* ?_Move_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z */
65 static char* MSVCP_char_traits_char__Move_s(char *dest,
66         MSVCP_size_t size, const char *src, MSVCP_size_t count)
67 {
68     if(!dest || !src || size<count) {
69         if(dest && size)
70             dest[0] = '\0';
71         _invalid_parameter(NULL, NULL, NULL, 0, 0);
72         return dest;
73     }
74
75     return memmove(dest, src, count);
76 }
77
78 /* char_traits<wchar_t> */
79 /* ?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z */
80 /* ?assign@?$char_traits@_W@std@@SAXAEA_WAEB_W@Z */
81 static void MSVCP_char_traits_wchar_assign(wchar_t *ch,
82         const wchar_t *assign)
83 {
84     *ch = *assign;
85 }
86
87 /* ?length@?$char_traits@_W@std@@SAIPB_W@Z */
88 /* ?length@?$char_traits@_W@std@@SA_KPEB_W@Z */
89 static MSVCP_size_t MSVCP_char_traits_wchar_length(const wchar_t *str)
90 {
91     return wcslen((WCHAR*)str);
92 }
93
94 /* ?_Copy_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
95 /* ?_Copy_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
96 static wchar_t* MSVCP_char_traits_wchar__Copy_s(wchar_t *dest,
97         MSVCP_size_t size, const wchar_t *src, MSVCP_size_t count)
98 {
99     if(!dest || !src || size<count) {
100         if(dest && size)
101             dest[0] = '\0';
102         _invalid_parameter(NULL, NULL, NULL, 0, 0);
103         return dest;
104     }
105
106     return memcpy(dest, src, count * sizeof(wchar_t));
107 }
108
109 /* ?_Move_s@?$char_traits@_W@std@@SAPA_WPA_WIPB_WI@Z */
110 /* ?_Move_s@?$char_traits@_W@std@@SAPEA_WPEA_W_KPEB_W1@Z */
111 static wchar_t* MSVCP_char_traits_wchar__Move_s(wchar_t *dest,
112         MSVCP_size_t size, const wchar_t *src, MSVCP_size_t count)
113 {
114     if(!dest || !src || size<count) {
115         if(dest && size)
116             dest[0] = '\0';
117         _invalid_parameter(NULL, NULL, NULL, 0, 0);
118         return dest;
119     }
120
121     return memmove(dest, src, count * sizeof(WCHAR));
122 }
123
124 /* _String_base */
125 /* ?_Xran@_String_base@std@@SAXXZ */
126 static void MSVCP__String_base_Xran(void)
127 {
128     static const char msg[] = "invalid string position";
129
130     TRACE("\n");
131     throw_exception(EXCEPTION_OUT_OF_RANGE, msg);
132 }
133
134
135 /* basic_string<char, char_traits<char>, allocator<char>> */
136 /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB */
137 /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2_KB */
138 static const MSVCP_size_t MSVCP_basic_string_char_npos = -1;
139
140 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEPADXZ */
141 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAPEADXZ */
142 static char* basic_string_char_ptr(basic_string_char *this)
143 {
144     if(this->res == BUF_SIZE_CHAR-1)
145         return this->data.buf;
146     return this->data.ptr;
147 }
148
149 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IBEPBDXZ */
150 /* ?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEBAPEBDXZ */
151 static const char* basic_string_char_const_ptr(const basic_string_char *this)
152 {
153     if(this->res == BUF_SIZE_CHAR-1)
154         return this->data.buf;
155     return this->data.ptr;
156 }
157
158 /* ?_Eos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEXI@Z */
159 /* ?_Eos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_K@Z */
160 static void basic_string_char_eos(basic_string_char *this, MSVCP_size_t len)
161 {
162     static const char nullbyte = '\0';
163
164     this->size = len;
165     MSVCP_char_traits_char_assign(basic_string_char_ptr(this)+len, &nullbyte);
166 }
167
168 /* ?_Inside@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAE_NPBD@Z */
169 /* ?_Inside@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAA_NPEBD@Z */
170 static MSVCP_bool basic_string_char_inside(
171         basic_string_char *this, const char *ptr)
172 {
173     char *cstr = basic_string_char_ptr(this);
174
175     return (ptr<cstr || ptr>=cstr+this->size) ? FALSE : TRUE;
176 }
177
178 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEX_NI@Z */
179 /* ?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAAX_N_K@Z */
180 static void basic_string_char_tidy(basic_string_char *this,
181         MSVCP_bool built, MSVCP_size_t new_size)
182 {
183     if(built && BUF_SIZE_CHAR<=this->res) {
184         char *ptr = this->data.ptr;
185
186         if(new_size > 0)
187             MSVCP_char_traits_char__Copy_s(this->data.buf, BUF_SIZE_CHAR, ptr, new_size);
188         MSVCP_allocator_char_deallocate(this->allocator, ptr, this->res+1);
189     }
190
191     this->res = BUF_SIZE_CHAR-1;
192     basic_string_char_eos(this, new_size);
193 }
194
195 /* ?_Grow@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAE_NI_N@Z */
196 /* ?_Grow@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IEAA_N_K_N@Z */
197 static MSVCP_bool basic_string_char_grow(
198         basic_string_char *this, MSVCP_size_t new_size, MSVCP_bool trim)
199 {
200     if(this->res < new_size) {
201         MSVCP_size_t new_res = new_size, len = this->size;
202         char *ptr;
203
204         new_res |= 0xf;
205
206         if(new_res/3 < this->res/2)
207             new_res = this->res + this->res/2;
208
209         ptr = MSVCP_allocator_char_allocate(this->allocator, new_res+1);
210         if(!ptr)
211             ptr = MSVCP_allocator_char_allocate(this->allocator, new_size+1);
212         else
213             new_size = new_res;
214         if(!ptr) {
215             ERR("Out of memory\n");
216             basic_string_char_tidy(this, TRUE, 0);
217             return FALSE;
218         }
219
220         MSVCP_char_traits_char__Copy_s(ptr, new_size,
221                 basic_string_char_ptr(this), this->size);
222         basic_string_char_tidy(this, TRUE, 0);
223         this->data.ptr = ptr;
224         this->res = new_size;
225         basic_string_char_eos(this, len);
226     } else if(trim && new_size < BUF_SIZE_CHAR)
227         basic_string_char_tidy(this, TRUE,
228                 new_size<this->size ? new_size : this->size);
229     else if(new_size == 0)
230         basic_string_char_eos(this, 0);
231
232     return (new_size>0);
233 }
234
235 /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z */
236 /* ?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z */
237 static basic_string_char* MSVCP_basic_string_char_erase(
238         basic_string_char *this, MSVCP_size_t pos, MSVCP_size_t len)
239 {
240     TRACE("%p %lu %lu\n", this, pos, len);
241
242     if(pos > this->size)
243         MSVCP__String_base_Xran();
244
245     if(len > this->size-pos)
246         len = this->size-pos;
247
248     if(len) {
249         MSVCP_char_traits_char__Move_s(basic_string_char_ptr(this)+pos,
250                 this->res-pos, basic_string_char_ptr(this)+pos+len,
251                 this->size-pos-len);
252         basic_string_char_eos(this, this->size-len);
253     }
254
255     return this;
256 }
257
258 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z */
259 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
260 static basic_string_char* MSVCP_basic_string_char_assign_substr(
261         basic_string_char *this, const basic_string_char *assign,
262         MSVCP_size_t pos, MSVCP_size_t len)
263 {
264     TRACE("%p %p %lu %lu\n", this, assign, pos, len);
265
266     if(assign->size < pos)
267         MSVCP__String_base_Xran();
268
269     if(len > assign->size-pos)
270         len = assign->size-pos;
271
272     if(this == assign) {
273         MSVCP_basic_string_char_erase(this, pos+len, MSVCP_basic_string_char_npos);
274         MSVCP_basic_string_char_erase(this, 0, pos);
275     } else if(basic_string_char_grow(this, len, FALSE)) {
276         MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this),
277                 this->res, basic_string_char_const_ptr(assign)+pos, len);
278         basic_string_char_eos(this, len);
279     }
280
281     return this;
282 }
283
284 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z */
285 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@AEBV01@@Z */
286 static basic_string_char* MSVCP_basic_string_char_assign(
287         basic_string_char *this, const basic_string_char *assign)
288 {
289     return MSVCP_basic_string_char_assign_substr(this, assign,
290             0, MSVCP_basic_string_char_npos);
291 }
292
293 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z */
294 /* ?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z */
295 static basic_string_char* MSVCP_basic_string_char_assign_cstr_len(
296         basic_string_char *this, const char *str, MSVCP_size_t len)
297 {
298     TRACE("%p %s %lu\n", this, debugstr_an(str, len), len);
299
300     if(basic_string_char_inside(this, str))
301         return MSVCP_basic_string_char_assign_substr(this, this,
302                 str-basic_string_char_ptr(this), len);
303     else if(basic_string_char_grow(this, len, FALSE)) {
304         MSVCP_char_traits_char__Copy_s(basic_string_char_ptr(this),
305                 this->res, str, len);
306         basic_string_char_eos(this, len);
307     }
308
309     return this;
310 }
311
312 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z */
313 /* ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV01@PEBD@Z */
314 static basic_string_char* MSVCP_basic_string_char_assign_cstr(
315         basic_string_char *this, const char *str)
316 {
317     return MSVCP_basic_string_char_assign_cstr_len(this, str,
318             MSVCP_char_traits_char_length(str));
319 }
320
321 /* ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ */
322 /* ?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ */
323 /* ?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ */
324 /* ?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ */
325 const char* MSVCP_basic_string_char_c_str(const basic_string_char *this)
326 {
327     TRACE("%p\n", this);
328     return basic_string_char_const_ptr(this);
329 }
330
331 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z */
332 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV01@@Z */
333 basic_string_char* MSVCP_basic_string_char_copy_ctor(
334     basic_string_char *this, const basic_string_char *copy)
335 {
336     TRACE("%p %p\n", this, copy);
337
338     basic_string_char_tidy(this, FALSE, 0);
339     MSVCP_basic_string_char_assign(this, copy);
340     return this;
341 }
342
343 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z */
344 /* ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z */
345 basic_string_char* MSVCP_basic_string_char_ctor_cstr(
346         basic_string_char *this, const char *str)
347 {
348     TRACE("%p %s\n", this, debugstr_a(str));
349
350     basic_string_char_tidy(this, FALSE, 0);
351     MSVCP_basic_string_char_assign_cstr(this, str);
352     return this;
353 }
354
355 /* ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ */
356 /* ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ */
357 void MSVCP_basic_string_char_dtor(basic_string_char *this)
358 {
359     TRACE("%p\n", this);
360     basic_string_char_tidy(this, TRUE, 0);
361 }
362
363 /* ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
364 /* ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
365 /* ?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ */
366 /* ?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ */
367 MSVCP_size_t MSVCP_basic_string_char_length(const basic_string_char *this)
368 {
369     TRACE("%p\n", this);
370     return this->size;
371 }
372
373 /* basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> */
374 /* basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short>> */
375 /* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2IB */
376 /* ?npos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@2_KB */
377 /* ?npos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@2IB */
378 /* ?npos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@2_KB */
379 const MSVCP_size_t MSVCP_basic_string_wchar_npos = -1;
380
381 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEPA_WXZ */
382 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAPEA_WXZ */
383 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAEPAGXZ */
384 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAAPEAGXZ */
385 static wchar_t* basic_string_wchar_ptr(basic_string_wchar *this)
386 {
387     if(this->res == BUF_SIZE_WCHAR-1)
388         return this->data.buf;
389     return this->data.ptr;
390 }
391
392 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IBEPB_WXZ */
393 /* ?_Myptr@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEBAPEB_WXZ */
394 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IBEPBGXZ */
395 /* ?_Myptr@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEBAPEBGXZ */
396 static const wchar_t* basic_string_wchar_const_ptr(const basic_string_wchar *this)
397 {
398     if(this->res == BUF_SIZE_WCHAR-1)
399         return this->data.buf;
400     return this->data.ptr;
401 }
402
403 /* ?_Eos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEXI@Z */
404 /* ?_Eos@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_K@Z */
405 /* ?_Eos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAEXI@Z */
406 /* ?_Eos@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAAX_K@Z */
407 static void basic_string_wchar_eos(basic_string_wchar *this, MSVCP_size_t len)
408 {
409     static const wchar_t nullbyte_w = '\0';
410
411     this->size = len;
412     MSVCP_char_traits_wchar_assign(basic_string_wchar_ptr(this)+len, &nullbyte_w);
413 }
414
415 /* ?_Inside@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAE_NPB_W@Z */
416 /* ?_Inside@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAA_NPEB_W@Z */
417 /* ?_Inside@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAE_NPBG@Z */
418 /* ?_Inside@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAA_NPEBG@Z */
419 static MSVCP_bool basic_string_wchar_inside(
420         basic_string_wchar *this, const wchar_t *ptr)
421 {
422     wchar_t *cstr = basic_string_wchar_ptr(this);
423
424     return (ptr<cstr || ptr>=cstr+this->size) ? FALSE : TRUE;
425 }
426
427 /* ?_Tidy@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAEX_NI@Z */
428 /* ?_Tidy@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAAX_N_K@Z */
429 /* ?_Tidy@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAEX_NI@Z */
430 /* ?_Tidy@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAAX_N_K@Z */
431 static void basic_string_wchar_tidy(basic_string_wchar *this,
432         MSVCP_bool built, MSVCP_size_t new_size)
433 {
434     if(built && BUF_SIZE_WCHAR<=this->res) {
435         wchar_t *ptr = this->data.ptr;
436
437         if(new_size > 0)
438             MSVCP_char_traits_wchar__Copy_s(this->data.buf, BUF_SIZE_WCHAR, ptr, new_size);
439         MSVCP_allocator_wchar_deallocate(this->allocator, ptr, this->res+1);
440     }
441
442     this->res = BUF_SIZE_WCHAR-1;
443     basic_string_wchar_eos(this, new_size);
444 }
445
446 /* ?_Grow@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IAE_NI_N@Z */
447 /* ?_Grow@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@IEAA_N_K_N@Z */
448 /* ?_Grow@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IAE_NI_N@Z */
449 /* ?_Grow@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@IEAA_N_K_N@Z */
450 static MSVCP_bool basic_string_wchar_grow(
451         basic_string_wchar *this, MSVCP_size_t new_size, MSVCP_bool trim)
452 {
453     if(this->res < new_size) {
454         MSVCP_size_t new_res = new_size, len = this->size;
455         wchar_t *ptr;
456
457         new_res |= 0xf;
458
459         if(new_res/3 < this->res/2)
460             new_res = this->res + this->res/2;
461
462         ptr = MSVCP_allocator_wchar_allocate(this->allocator, new_res+1);
463         if(!ptr)
464             ptr = MSVCP_allocator_wchar_allocate(this->allocator, new_size+1);
465         else
466             new_size = new_res;
467         if(!ptr) {
468             ERR("Out of memory\n");
469             basic_string_wchar_tidy(this, TRUE, 0);
470             return FALSE;
471         }
472
473         MSVCP_char_traits_wchar__Copy_s(ptr, new_size,
474                 basic_string_wchar_ptr(this), this->size);
475         basic_string_wchar_tidy(this, TRUE, 0);
476         this->data.ptr = ptr;
477         this->res = new_size;
478         basic_string_wchar_eos(this, len);
479     } else if(trim && new_size < BUF_SIZE_WCHAR)
480         basic_string_wchar_tidy(this, TRUE,
481                 new_size<this->size ? new_size : this->size);
482     else if(new_size == 0)
483         basic_string_wchar_eos(this, 0);
484
485     return (new_size>0);
486 }
487
488 /* ?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@II@Z */
489 /* ?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K0@Z */
490 /* ?erase@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@II@Z */
491 /* ?erase@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@_K0@Z */
492 static basic_string_wchar* MSVCP_basic_string_wchar_erase(
493             basic_string_wchar *this, MSVCP_size_t pos, MSVCP_size_t len)
494 {
495     TRACE("%p %lu %lu\n", this, pos, len);
496
497     if(pos > this->size)
498         MSVCP__String_base_Xran();
499
500     if(len > this->size-pos)
501         len = this->size-pos;
502
503     if(len) {
504         MSVCP_char_traits_wchar__Move_s(basic_string_wchar_ptr(this)+pos,
505                 this->res-pos, basic_string_wchar_ptr(this)+pos+len,
506                 this->size-pos-len);
507         basic_string_wchar_eos(this, this->size-len);
508     }
509
510     return this;
511 }
512
513 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@ABV12@II@Z */
514 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
515 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@ABV12@II@Z */
516 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@AEBV12@_K1@Z */
517 static basic_string_wchar* MSVCP_basic_string_wchar_assign_substr(
518             basic_string_wchar *this, const basic_string_wchar *assign,
519             MSVCP_size_t pos, MSVCP_size_t len)
520 {
521     TRACE("%p %p %lu %lu\n", this, assign, pos, len);
522
523     if(assign->size < pos)
524         MSVCP__String_base_Xran();
525
526     if(len > assign->size-pos)
527         len = assign->size-pos;
528
529     if(this == assign) {
530         MSVCP_basic_string_wchar_erase(this, pos+len, MSVCP_basic_string_wchar_npos);
531         MSVCP_basic_string_wchar_erase(this, 0, pos);
532     } else if(basic_string_wchar_grow(this, len, FALSE)) {
533         MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this),
534                 this->res, basic_string_wchar_const_ptr(assign)+pos, len);
535         basic_string_wchar_eos(this, len);
536     }
537
538     return this;
539 }
540
541 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z */
542 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z */
543 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@PBGI@Z */
544 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@PEBG_K@Z */
545 static basic_string_wchar* MSVCP_basic_string_wchar_assign_cstr_len(
546             basic_string_wchar *this, const wchar_t *str, MSVCP_size_t len)
547 {
548     TRACE("%p %s %lu\n", this, debugstr_wn(str, len), len);
549
550     if(basic_string_wchar_inside(this, str))
551         return MSVCP_basic_string_wchar_assign_substr(this, this,
552                 str-basic_string_wchar_ptr(this), len);
553     else if(basic_string_wchar_grow(this, len, FALSE)) {
554         MSVCP_char_traits_wchar__Copy_s(basic_string_wchar_ptr(this),
555                 this->res, str, len);
556         basic_string_wchar_eos(this, len);
557     }
558
559     return this;
560 }
561
562 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_W@Z */
563 /* ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W@Z */
564 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV01@PB_W@Z */
565 /* ??4?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@PEB_W@Z */
566 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@PBG@Z */
567 /* ?assign@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV12@PEBG@Z */
568 /* ??4?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV01@PBG@Z */
569 /* ??4?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAAAEAV01@PEBG@Z */
570 static basic_string_wchar* MSVCP_basic_string_wchar_assign_cstr(
571             basic_string_wchar *this, const wchar_t *str)
572 {
573     return MSVCP_basic_string_wchar_assign_cstr_len(this, str,
574             MSVCP_char_traits_wchar_length(str));
575 }
576
577 /* ?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ */
578 /* ?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ */
579 /* ?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ */
580 /* ?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ */
581 /* ?c_str@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEPBGXZ */
582 /* ?c_str@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBAPEBGXZ */
583 /* ?data@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEPBGXZ */
584 /* ?data@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBAPEBGXZ */
585 const wchar_t* MSVCP_basic_string_wchar_c_str(const basic_string_wchar *this)
586 {
587     TRACE("%p\n", this);
588     return basic_string_wchar_const_ptr(this);
589 }
590
591 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@PB_W@Z */
592 /* ??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W@Z */
593 /* ??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@PBG@Z */
594 /* ??0?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@PEBG@Z */
595 basic_string_wchar* MSVCP_basic_string_wchar_ctor_cstr(
596             basic_string_wchar *this, const wchar_t *str)
597 {
598     TRACE("%p %s\n", this, debugstr_w(str));
599
600     basic_string_wchar_tidy(this, FALSE, 0);
601     MSVCP_basic_string_wchar_assign_cstr(this, str);
602     return this;
603 }
604
605 /* ??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ */
606 /* ??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ */
607 /* ??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@XZ */
608 /* ??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@XZ */
609 void MSVCP_basic_string_wchar_dtor(basic_string_wchar *this)
610 {
611     TRACE("%p\n", this);
612     basic_string_wchar_tidy(this, TRUE, 0);
613 }
614
615 /* ?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
616 /* ?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
617 /* ?length@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ */
618 /* ?length@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ */
619 /* ?size@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEIXZ */
620 /* ?size@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBA_KXZ */
621 /* ?length@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEIXZ */
622 /* ?length@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEBA_KXZ */
623 MSVCP_size_t MSVCP_basic_string_wchar_length(const basic_string_wchar *this)
624 {
625     TRACE("%p\n", this);
626     return this->size;
627 }