regedit: Output an error message and exit with error code zero instead of calling...
[wine.git] / dlls / msvcirt / msvcirt.c
blob7f48346d051b051c83359ac13962a0c16bf7e928
1 /*
2 * Copyright (C) 2007 Alexandre Julliard
3 * Copyright (C) 2015-2016 Iván Matellanes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <float.h>
25 #include <io.h>
26 #include <limits.h>
27 #include <share.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <sys/stat.h>
32 #include "msvcirt.h"
33 #include "windef.h"
34 #include "winbase.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
39 #define RESERVE_SIZE 512
40 #define STATEBUF_SIZE 8
42 /* ?sh_none@filebuf@@2HB */
43 const int filebuf_sh_none = 0x800;
44 /* ?sh_read@filebuf@@2HB */
45 const int filebuf_sh_read = 0xa00;
46 /* ?sh_write@filebuf@@2HB */
47 const int filebuf_sh_write = 0xc00;
48 /* ?openprot@filebuf@@2HB */
49 const int filebuf_openprot = 420;
50 /* ?binary@filebuf@@2HB */
51 const int filebuf_binary = _O_BINARY;
52 /* ?text@filebuf@@2HB */
53 const int filebuf_text = _O_TEXT;
55 /* ?adjustfield@ios@@2JB */
56 const LONG ios_adjustfield = FLAGS_left | FLAGS_right | FLAGS_internal;
57 /* ?basefield@ios@@2JB */
58 const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
59 /* ?floatfield@ios@@2JB */
60 const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
61 /* ?fLockcInit@ios@@0HA */
62 int ios_fLockcInit = 0;
63 /* ?sunk_with_stdio@ios@@0HA */
64 int ios_sunk_with_stdio = 0;
65 /* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
66 extern CRITICAL_SECTION ios_static_lock;
67 CRITICAL_SECTION_DEBUG ios_static_lock_debug =
69 0, 0, &ios_static_lock,
70 { &ios_static_lock_debug.ProcessLocksList, &ios_static_lock_debug.ProcessLocksList },
71 0, 0, { (DWORD_PTR)(__FILE__ ": ios_static_lock") }
73 CRITICAL_SECTION ios_static_lock = { &ios_static_lock_debug, -1, 0, 0, 0, 0 };
74 /* ?x_maxbit@ios@@0JA */
75 LONG ios_maxbit = 0x8000;
76 /* ?x_curindex@ios@@0HA */
77 int ios_curindex = -1;
78 /* ?x_statebuf@ios@@0PAJA */
79 LONG ios_statebuf[STATEBUF_SIZE] = {0};
81 /* class streambuf */
82 typedef struct {
83 const vtable_ptr *vtable;
84 int allocated;
85 int unbuffered;
86 int stored_char;
87 char *base;
88 char *ebuf;
89 char *pbase;
90 char *pptr;
91 char *epptr;
92 char *eback;
93 char *gptr;
94 char *egptr;
95 int do_lock;
96 CRITICAL_SECTION lock;
97 } streambuf;
99 void __thiscall streambuf_setb(streambuf*, char*, char*, int);
100 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
101 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
102 void __thiscall streambuf_setp(streambuf*, char*, char*);
104 /* class filebuf */
105 typedef struct {
106 streambuf base;
107 filedesc fd;
108 int close;
109 } filebuf;
111 filebuf* __thiscall filebuf_close(filebuf*);
113 /* class strstreambuf */
114 typedef struct {
115 streambuf base;
116 int dynamic;
117 int increase;
118 int unknown;
119 int constant;
120 allocFunction f_alloc;
121 freeFunction f_free;
122 } strstreambuf;
124 /* class stdiobuf */
125 typedef struct {
126 streambuf base;
127 FILE *file;
128 } stdiobuf;
130 /* class ios */
131 struct _ostream;
132 typedef struct {
133 const vtable_ptr *vtable;
134 streambuf *sb;
135 ios_io_state state;
136 int special[4];
137 int delbuf;
138 struct _ostream *tie;
139 ios_flags flags;
140 int precision;
141 char fill;
142 int width;
143 int do_lock;
144 CRITICAL_SECTION lock;
145 } ios;
147 ios* __thiscall ios_assign(ios*, const ios*);
148 int __thiscall ios_fail(const ios*);
149 void __cdecl ios_lock(ios*);
150 void __cdecl ios_lockc(void);
151 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
152 void __cdecl ios_unlock(ios*);
153 void __cdecl ios_unlockc(void);
155 /* class ostream */
156 typedef struct _ostream {
157 const int *vbtable;
158 int unknown;
159 } ostream;
161 /* class istream */
162 typedef struct {
163 const int *vbtable;
164 int extract_delim;
165 int count;
166 } istream;
168 /* class iostream */
169 typedef struct {
170 istream base1;
171 ostream base2;
172 } iostream;
174 /* ??_7streambuf@@6B@ */
175 extern const vtable_ptr MSVCP_streambuf_vtable;
176 /* ??_7filebuf@@6B@ */
177 extern const vtable_ptr MSVCP_filebuf_vtable;
178 /* ??_7strstreambuf@@6B@ */
179 extern const vtable_ptr MSVCP_strstreambuf_vtable;
180 /* ??_7stdiobuf@@6B@ */
181 extern const vtable_ptr MSVCP_stdiobuf_vtable;
182 /* ??_7ios@@6B@ */
183 extern const vtable_ptr MSVCP_ios_vtable;
184 /* ??_7ostream@@6B@ */
185 extern const vtable_ptr MSVCP_ostream_vtable;
186 /* ??_7ostream_withassign@@6B@ */
187 extern const vtable_ptr MSVCP_ostream_withassign_vtable;
188 /* ??_7ostrstream@@6B@ */
189 extern const vtable_ptr MSVCP_ostrstream_vtable;
190 /* ??_7istream@@6B@ */
191 extern const vtable_ptr MSVCP_istream_vtable;
192 /* ??_7istream_withassign@@6B@ */
193 extern const vtable_ptr MSVCP_istream_withassign_vtable;
194 /* ??_7istrstream@@6B@ */
195 extern const vtable_ptr MSVCP_istrstream_vtable;
196 /* ??_7iostream@@6B@ */
197 extern const vtable_ptr MSVCP_iostream_vtable;
198 /* ??_7strstream@@6B@ */
199 extern const vtable_ptr MSVCP_strstream_vtable;
200 /* ??_7stdiostream@@6B@ */
201 extern const vtable_ptr MSVCP_stdiostream_vtable;
203 #ifndef __GNUC__
204 void __asm_dummy_vtables(void) {
205 #endif
206 __ASM_VTABLE(streambuf,
207 VTABLE_ADD_FUNC(streambuf_vector_dtor)
208 VTABLE_ADD_FUNC(streambuf_sync)
209 VTABLE_ADD_FUNC(streambuf_setbuf)
210 VTABLE_ADD_FUNC(streambuf_seekoff)
211 VTABLE_ADD_FUNC(streambuf_seekpos)
212 VTABLE_ADD_FUNC(streambuf_xsputn)
213 VTABLE_ADD_FUNC(streambuf_xsgetn)
214 VTABLE_ADD_FUNC(streambuf_overflow)
215 VTABLE_ADD_FUNC(streambuf_underflow)
216 VTABLE_ADD_FUNC(streambuf_pbackfail)
217 VTABLE_ADD_FUNC(streambuf_doallocate));
218 __ASM_VTABLE(filebuf,
219 VTABLE_ADD_FUNC(filebuf_vector_dtor)
220 VTABLE_ADD_FUNC(filebuf_sync)
221 VTABLE_ADD_FUNC(filebuf_setbuf)
222 VTABLE_ADD_FUNC(filebuf_seekoff)
223 VTABLE_ADD_FUNC(streambuf_seekpos)
224 VTABLE_ADD_FUNC(streambuf_xsputn)
225 VTABLE_ADD_FUNC(streambuf_xsgetn)
226 VTABLE_ADD_FUNC(filebuf_overflow)
227 VTABLE_ADD_FUNC(filebuf_underflow)
228 VTABLE_ADD_FUNC(streambuf_pbackfail)
229 VTABLE_ADD_FUNC(streambuf_doallocate));
230 __ASM_VTABLE(strstreambuf,
231 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
232 VTABLE_ADD_FUNC(strstreambuf_sync)
233 VTABLE_ADD_FUNC(strstreambuf_setbuf)
234 VTABLE_ADD_FUNC(strstreambuf_seekoff)
235 VTABLE_ADD_FUNC(streambuf_seekpos)
236 VTABLE_ADD_FUNC(streambuf_xsputn)
237 VTABLE_ADD_FUNC(streambuf_xsgetn)
238 VTABLE_ADD_FUNC(strstreambuf_overflow)
239 VTABLE_ADD_FUNC(strstreambuf_underflow)
240 VTABLE_ADD_FUNC(streambuf_pbackfail)
241 VTABLE_ADD_FUNC(strstreambuf_doallocate));
242 __ASM_VTABLE(stdiobuf,
243 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
244 VTABLE_ADD_FUNC(stdiobuf_sync)
245 VTABLE_ADD_FUNC(streambuf_setbuf)
246 VTABLE_ADD_FUNC(stdiobuf_seekoff)
247 VTABLE_ADD_FUNC(streambuf_seekpos)
248 VTABLE_ADD_FUNC(streambuf_xsputn)
249 VTABLE_ADD_FUNC(streambuf_xsgetn)
250 VTABLE_ADD_FUNC(stdiobuf_overflow)
251 VTABLE_ADD_FUNC(stdiobuf_underflow)
252 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
253 VTABLE_ADD_FUNC(streambuf_doallocate));
254 __ASM_VTABLE(ios,
255 VTABLE_ADD_FUNC(ios_vector_dtor));
256 __ASM_VTABLE(ostream,
257 VTABLE_ADD_FUNC(ostream_vector_dtor));
258 __ASM_VTABLE(ostream_withassign,
259 VTABLE_ADD_FUNC(ostream_vector_dtor));
260 __ASM_VTABLE(ostrstream,
261 VTABLE_ADD_FUNC(ostream_vector_dtor));
262 __ASM_VTABLE(istream,
263 VTABLE_ADD_FUNC(istream_vector_dtor));
264 __ASM_VTABLE(istream_withassign,
265 VTABLE_ADD_FUNC(istream_vector_dtor));
266 __ASM_VTABLE(istrstream,
267 VTABLE_ADD_FUNC(istream_vector_dtor));
268 __ASM_VTABLE(iostream,
269 VTABLE_ADD_FUNC(iostream_vector_dtor));
270 __ASM_VTABLE(strstream,
271 VTABLE_ADD_FUNC(iostream_vector_dtor));
272 __ASM_VTABLE(stdiostream,
273 VTABLE_ADD_FUNC(iostream_vector_dtor));
274 #ifndef __GNUC__
276 #endif
278 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
279 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
281 /* ??_8ostream@@7B@ */
282 /* ??_8ostream_withassign@@7B@ */
283 /* ??_8ostrstream@@7B@ */
284 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
285 /* ??_8istream@@7B@ */
286 /* ??_8istream_withassign@@7B@ */
287 /* ??_8istrstream@@7B@ */
288 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
289 /* ??_8iostream@@7Bistream@@@ */
290 /* ??_8stdiostream@@7Bistream@@@ */
291 /* ??_8strstream@@7Bistream@@@ */
292 const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)};
293 /* ??_8iostream@@7Bostream@@@ */
294 /* ??_8stdiostream@@7Bostream@@@ */
295 /* ??_8strstream@@7Bostream@@@ */
296 const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)};
298 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
299 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
300 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
301 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
302 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
303 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
304 DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream),
305 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@")
306 DEFINE_RTTI_DATA2(ostrstream, sizeof(ostream),
307 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostrstream@@")
308 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
309 DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
310 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
311 DEFINE_RTTI_DATA2(istrstream, sizeof(istream),
312 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistrstream@@")
313 DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
314 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
315 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
316 DEFINE_RTTI_DATA4(strstream, sizeof(iostream),
317 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
318 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstrstream@@")
319 DEFINE_RTTI_DATA4(stdiostream, sizeof(iostream),
320 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
321 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstdiostream@@")
323 /* ?cin@@3Vistream_withassign@@A */
324 struct {
325 istream is;
326 ios vbase;
327 } cin = { { 0 } };
329 /* ?cout@@3Vostream_withassign@@A */
330 /* ?cerr@@3Vostream_withassign@@A */
331 /* ?clog@@3Vostream_withassign@@A */
332 struct {
333 ostream os;
334 ios vbase;
335 } cout = { { 0 } }, cerr = { { 0 } }, clog = { { 0 } };
338 /* ??0streambuf@@IAE@PADH@Z */
339 /* ??0streambuf@@IEAA@PEADH@Z */
340 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
341 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
343 TRACE("(%p %p %d)\n", this, buffer, length);
344 this->vtable = &MSVCP_streambuf_vtable;
345 this->allocated = 0;
346 this->stored_char = EOF;
347 this->do_lock = -1;
348 this->base = NULL;
349 streambuf_setbuf(this, buffer, length);
350 streambuf_setg(this, NULL, NULL, NULL);
351 streambuf_setp(this, NULL, NULL);
352 InitializeCriticalSection(&this->lock);
353 return this;
356 /* ??0streambuf@@IAE@XZ */
357 /* ??0streambuf@@IEAA@XZ */
358 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
359 streambuf* __thiscall streambuf_ctor(streambuf *this)
361 streambuf_reserve_ctor(this, NULL, 0);
362 this->unbuffered = 0;
363 return this;
366 /* ??0streambuf@@QAE@ABV0@@Z */
367 /* ??0streambuf@@QEAA@AEBV0@@Z */
368 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
369 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
371 TRACE("(%p %p)\n", this, copy);
372 *this = *copy;
373 this->vtable = &MSVCP_streambuf_vtable;
374 return this;
377 /* ??1streambuf@@UAE@XZ */
378 /* ??1streambuf@@UEAA@XZ */
379 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
380 void __thiscall streambuf_dtor(streambuf *this)
382 TRACE("(%p)\n", this);
383 if (this->allocated)
384 MSVCRT_operator_delete(this->base);
385 DeleteCriticalSection(&this->lock);
388 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
389 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
390 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
391 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
393 streambuf_dtor(this);
394 return streambuf_copy_ctor(this, rhs);
397 /* ??_Estreambuf@@UAEPAXI@Z */
398 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
399 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
400 streambuf*, (streambuf*, unsigned int), (this, flags))
401 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
403 TRACE("(%p %x)\n", this, flags);
404 if (flags & 2) {
405 /* we have an array, with the number of elements stored before the first object */
406 INT_PTR i, *ptr = (INT_PTR *)this-1;
408 for (i = *ptr-1; i >= 0; i--)
409 streambuf_dtor(this+i);
410 MSVCRT_operator_delete(ptr);
411 } else {
412 streambuf_dtor(this);
413 if (flags & 1)
414 MSVCRT_operator_delete(this);
416 return this;
419 /* ??_Gstreambuf@@UAEPAXI@Z */
420 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
421 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
423 TRACE("(%p %x)\n", this, flags);
424 streambuf_dtor(this);
425 if (flags & 1) MSVCRT_operator_delete(this);
426 return this;
429 /* ?doallocate@streambuf@@MAEHXZ */
430 /* ?doallocate@streambuf@@MEAAHXZ */
431 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
432 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
433 int __thiscall streambuf_doallocate(streambuf *this)
435 char *reserve;
437 TRACE("(%p)\n", this);
438 reserve = MSVCRT_operator_new(RESERVE_SIZE);
439 if (!reserve)
440 return EOF;
442 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
443 return 1;
446 /* ?allocate@streambuf@@IAEHXZ */
447 /* ?allocate@streambuf@@IEAAHXZ */
448 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
449 int __thiscall streambuf_allocate(streambuf *this)
451 TRACE("(%p)\n", this);
452 if (this->base != NULL || this->unbuffered)
453 return 0;
454 return call_streambuf_doallocate(this);
457 /* ?base@streambuf@@IBEPADXZ */
458 /* ?base@streambuf@@IEBAPEADXZ */
459 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
460 char* __thiscall streambuf_base(const streambuf *this)
462 TRACE("(%p)\n", this);
463 return this->base;
466 /* ?blen@streambuf@@IBEHXZ */
467 /* ?blen@streambuf@@IEBAHXZ */
468 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
469 int __thiscall streambuf_blen(const streambuf *this)
471 TRACE("(%p)\n", this);
472 return this->ebuf - this->base;
475 /* ?eback@streambuf@@IBEPADXZ */
476 /* ?eback@streambuf@@IEBAPEADXZ */
477 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
478 char* __thiscall streambuf_eback(const streambuf *this)
480 TRACE("(%p)\n", this);
481 return this->eback;
484 /* ?ebuf@streambuf@@IBEPADXZ */
485 /* ?ebuf@streambuf@@IEBAPEADXZ */
486 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
487 char* __thiscall streambuf_ebuf(const streambuf *this)
489 TRACE("(%p)\n", this);
490 return this->ebuf;
493 /* ?egptr@streambuf@@IBEPADXZ */
494 /* ?egptr@streambuf@@IEBAPEADXZ */
495 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
496 char* __thiscall streambuf_egptr(const streambuf *this)
498 TRACE("(%p)\n", this);
499 return this->egptr;
502 /* ?epptr@streambuf@@IBEPADXZ */
503 /* ?epptr@streambuf@@IEBAPEADXZ */
504 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
505 char* __thiscall streambuf_epptr(const streambuf *this)
507 TRACE("(%p)\n", this);
508 return this->epptr;
511 /* ?gptr@streambuf@@IBEPADXZ */
512 /* ?gptr@streambuf@@IEBAPEADXZ */
513 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
514 char* __thiscall streambuf_gptr(const streambuf *this)
516 TRACE("(%p)\n", this);
517 return this->gptr;
520 /* ?pbase@streambuf@@IBEPADXZ */
521 /* ?pbase@streambuf@@IEBAPEADXZ */
522 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
523 char* __thiscall streambuf_pbase(const streambuf *this)
525 TRACE("(%p)\n", this);
526 return this->pbase;
529 /* ?pptr@streambuf@@IBEPADXZ */
530 /* ?pptr@streambuf@@IEBAPEADXZ */
531 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
532 char* __thiscall streambuf_pptr(const streambuf *this)
534 TRACE("(%p)\n", this);
535 return this->pptr;
538 /* ?clrlock@streambuf@@QAEXXZ */
539 /* ?clrlock@streambuf@@QEAAXXZ */
540 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
541 void __thiscall streambuf_clrlock(streambuf *this)
543 TRACE("(%p)\n", this);
544 if (this->do_lock <= 0)
545 this->do_lock++;
548 /* ?lock@streambuf@@QAEXXZ */
549 /* ?lock@streambuf@@QEAAXXZ */
550 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
551 void __thiscall streambuf_lock(streambuf *this)
553 TRACE("(%p)\n", this);
554 if (this->do_lock < 0)
555 EnterCriticalSection(&this->lock);
558 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
559 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
560 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
561 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
563 TRACE("(%p)\n", this);
564 return &this->lock;
567 /* ?gbump@streambuf@@IAEXH@Z */
568 /* ?gbump@streambuf@@IEAAXH@Z */
569 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
570 void __thiscall streambuf_gbump(streambuf *this, int count)
572 TRACE("(%p %d)\n", this, count);
573 this->gptr += count;
576 /* ?pbump@streambuf@@IAEXH@Z */
577 /* ?pbump@streambuf@@IEAAXH@Z */
578 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
579 void __thiscall streambuf_pbump(streambuf *this, int count)
581 TRACE("(%p %d)\n", this, count);
582 this->pptr += count;
585 /* ?in_avail@streambuf@@QBEHXZ */
586 /* ?in_avail@streambuf@@QEBAHXZ */
587 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
588 int __thiscall streambuf_in_avail(const streambuf *this)
590 TRACE("(%p)\n", this);
591 return (this->egptr - this->gptr > 0) ? this->egptr - this->gptr : 0;
594 /* ?out_waiting@streambuf@@QBEHXZ */
595 /* ?out_waiting@streambuf@@QEBAHXZ */
596 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
597 int __thiscall streambuf_out_waiting(const streambuf *this)
599 TRACE("(%p)\n", this);
600 return (this->pptr - this->pbase > 0) ? this->pptr - this->pbase : 0;
603 /* Unexported */
604 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
605 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
606 int __thiscall streambuf_overflow(streambuf *this, int c)
608 ERR("overflow is not implemented in streambuf\n");
609 return EOF;
612 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
613 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
614 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
615 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
616 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
618 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
619 return EOF;
622 /* ?seekpos@streambuf@@UAEJJH@Z */
623 /* ?seekpos@streambuf@@UEAAJJH@Z */
624 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
625 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
627 TRACE("(%p %d %d)\n", this, pos, mode);
628 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
631 /* ?pbackfail@streambuf@@UAEHH@Z */
632 /* ?pbackfail@streambuf@@UEAAHH@Z */
633 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
634 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
635 int __thiscall streambuf_pbackfail(streambuf *this, int c)
637 TRACE("(%p %d)\n", this, c);
638 if (this->gptr > this->eback)
639 return *--this->gptr = c;
640 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
641 return EOF;
642 if (!this->unbuffered && this->egptr) {
643 /* 'c' should be the next character read */
644 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
645 *this->gptr = c;
647 return c;
650 /* ?setb@streambuf@@IAEXPAD0H@Z */
651 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
652 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
653 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
655 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
656 if (this->allocated)
657 MSVCRT_operator_delete(this->base);
658 this->allocated = delete;
659 this->base = ba;
660 this->ebuf = eb;
663 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
664 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
665 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
666 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
668 TRACE("(%p %p %d)\n", this, buffer, length);
669 if (this->base != NULL)
670 return NULL;
672 if (buffer == NULL || !length) {
673 this->unbuffered = 1;
674 this->base = this->ebuf = NULL;
675 } else {
676 this->unbuffered = 0;
677 this->base = buffer;
678 this->ebuf = buffer + length;
680 return this;
683 /* ?setg@streambuf@@IAEXPAD00@Z */
684 /* ?setg@streambuf@@IEAAXPEAD00@Z */
685 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
686 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
688 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
689 this->eback = ek;
690 this->gptr = gp;
691 this->egptr = eg;
694 /* ?setlock@streambuf@@QAEXXZ */
695 /* ?setlock@streambuf@@QEAAXXZ */
696 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
697 void __thiscall streambuf_setlock(streambuf *this)
699 TRACE("(%p)\n", this);
700 this->do_lock--;
703 /* ?setp@streambuf@@IAEXPAD0@Z */
704 /* ?setp@streambuf@@IEAAXPEAD0@Z */
705 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
706 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
708 TRACE("(%p %p %p)\n", this, pb, ep);
709 this->pbase = this->pptr = pb;
710 this->epptr = ep;
713 /* ?sync@streambuf@@UAEHXZ */
714 /* ?sync@streambuf@@UEAAHXZ */
715 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
716 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
717 int __thiscall streambuf_sync(streambuf *this)
719 TRACE("(%p)\n", this);
720 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
723 /* ?unbuffered@streambuf@@IAEXH@Z */
724 /* ?unbuffered@streambuf@@IEAAXH@Z */
725 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
726 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
728 TRACE("(%p %d)\n", this, buf);
729 this->unbuffered = buf;
732 /* ?unbuffered@streambuf@@IBEHXZ */
733 /* ?unbuffered@streambuf@@IEBAHXZ */
734 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
735 int __thiscall streambuf_unbuffered_get(const streambuf *this)
737 TRACE("(%p)\n", this);
738 return this->unbuffered;
741 /* Unexported */
742 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
743 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
744 int __thiscall streambuf_underflow(streambuf *this)
746 ERR("underflow is not implemented in streambuf\n");
747 return EOF;
750 /* ?unlock@streambuf@@QAEXXZ */
751 /* ?unlock@streambuf@@QEAAXXZ */
752 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
753 void __thiscall streambuf_unlock(streambuf *this)
755 TRACE("(%p)\n", this);
756 if (this->do_lock < 0)
757 LeaveCriticalSection(&this->lock);
760 /* ?xsgetn@streambuf@@UAEHPADH@Z */
761 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
762 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
763 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
764 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
766 int copied = 0, chunk;
768 TRACE("(%p %p %d)\n", this, buffer, count);
770 if (this->unbuffered) {
771 if (this->stored_char == EOF)
772 this->stored_char = call_streambuf_underflow(this);
773 while (copied < count && this->stored_char != EOF) {
774 buffer[copied++] = this->stored_char;
775 this->stored_char = call_streambuf_underflow(this);
777 } else {
778 while (copied < count) {
779 if (call_streambuf_underflow(this) == EOF)
780 break;
781 chunk = this->egptr - this->gptr;
782 if (chunk > count - copied)
783 chunk = count - copied;
784 memcpy(buffer+copied, this->gptr, chunk);
785 this->gptr += chunk;
786 copied += chunk;
789 return copied;
792 /* ?xsputn@streambuf@@UAEHPBDH@Z */
793 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
794 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
795 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
796 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
798 int copied = 0, chunk;
800 TRACE("(%p %p %d)\n", this, data, length);
802 while (copied < length) {
803 if (this->unbuffered || this->pptr == this->epptr) {
804 if (call_streambuf_overflow(this, data[copied]) == EOF)
805 break;
806 copied++;
807 } else {
808 chunk = this->epptr - this->pptr;
809 if (chunk > length - copied)
810 chunk = length - copied;
811 memcpy(this->pptr, data+copied, chunk);
812 this->pptr += chunk;
813 copied += chunk;
816 return copied;
819 /* ?sgetc@streambuf@@QAEHXZ */
820 /* ?sgetc@streambuf@@QEAAHXZ */
821 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
822 int __thiscall streambuf_sgetc(streambuf *this)
824 TRACE("(%p)\n", this);
825 if (this->unbuffered) {
826 if (this->stored_char == EOF)
827 this->stored_char = call_streambuf_underflow(this);
828 return this->stored_char;
829 } else
830 return call_streambuf_underflow(this);
833 /* ?sputc@streambuf@@QAEHH@Z */
834 /* ?sputc@streambuf@@QEAAHH@Z */
835 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
836 int __thiscall streambuf_sputc(streambuf *this, int ch)
838 TRACE("(%p %d)\n", this, ch);
839 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
842 /* ?sgetn@streambuf@@QAEHPADH@Z */
843 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
844 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
845 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
847 return call_streambuf_xsgetn(this, buffer, count);
850 /* ?sputn@streambuf@@QAEHPBDH@Z */
851 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
852 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
853 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
855 return call_streambuf_xsputn(this, data, length);
858 /* ?snextc@streambuf@@QAEHXZ */
859 /* ?snextc@streambuf@@QEAAHXZ */
860 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
861 int __thiscall streambuf_snextc(streambuf *this)
863 TRACE("(%p)\n", this);
864 if (this->unbuffered) {
865 if (this->stored_char == EOF)
866 call_streambuf_underflow(this);
867 return this->stored_char = call_streambuf_underflow(this);
868 } else {
869 if (this->gptr >= this->egptr)
870 call_streambuf_underflow(this);
871 this->gptr++;
872 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
876 /* ?sbumpc@streambuf@@QAEHXZ */
877 /* ?sbumpc@streambuf@@QEAAHXZ */
878 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
879 int __thiscall streambuf_sbumpc(streambuf *this)
881 int ret;
883 TRACE("(%p)\n", this);
885 if (this->unbuffered) {
886 ret = this->stored_char;
887 this->stored_char = EOF;
888 if (ret == EOF)
889 ret = call_streambuf_underflow(this);
890 } else {
891 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
892 this->gptr++;
894 return ret;
897 /* ?stossc@streambuf@@QAEXXZ */
898 /* ?stossc@streambuf@@QEAAXXZ */
899 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
900 void __thiscall streambuf_stossc(streambuf *this)
902 TRACE("(%p)\n", this);
903 if (this->unbuffered) {
904 if (this->stored_char == EOF)
905 call_streambuf_underflow(this);
906 else
907 this->stored_char = EOF;
908 } else {
909 if (this->gptr >= this->egptr)
910 call_streambuf_underflow(this);
911 if (this->gptr < this->egptr)
912 this->gptr++;
916 /* ?sputbackc@streambuf@@QAEHD@Z */
917 /* ?sputbackc@streambuf@@QEAAHD@Z */
918 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
919 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
921 TRACE("(%p %d)\n", this, ch);
922 return call_streambuf_pbackfail(this, ch);
925 /* ?dbp@streambuf@@QAEXXZ */
926 /* ?dbp@streambuf@@QEAAXXZ */
927 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
928 void __thiscall streambuf_dbp(streambuf *this)
930 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
931 if (this->unbuffered) {
932 printf("unbuffered\n");
933 } else {
934 printf("_fAlloc=%d\n", this->allocated);
935 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
936 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
937 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
941 /* ??0filebuf@@QAE@ABV0@@Z */
942 /* ??0filebuf@@QEAA@AEBV0@@Z */
943 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
944 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
946 TRACE("(%p %p)\n", this, copy);
947 *this = *copy;
948 this->base.vtable = &MSVCP_filebuf_vtable;
949 return this;
952 /* ??0filebuf@@QAE@HPADH@Z */
953 /* ??0filebuf@@QEAA@HPEADH@Z */
954 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
955 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
957 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
958 streambuf_reserve_ctor(&this->base, buffer, length);
959 this->base.vtable = &MSVCP_filebuf_vtable;
960 this->fd = fd;
961 this->close = 0;
962 return this;
965 /* ??0filebuf@@QAE@H@Z */
966 /* ??0filebuf@@QEAA@H@Z */
967 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
968 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
970 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
971 this->base.unbuffered = 0;
972 return this;
975 /* ??0filebuf@@QAE@XZ */
976 /* ??0filebuf@@QEAA@XZ */
977 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
978 filebuf* __thiscall filebuf_ctor(filebuf* this)
980 return filebuf_fd_ctor(this, -1);
983 /* ??1filebuf@@UAE@XZ */
984 /* ??1filebuf@@UEAA@XZ */
985 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
986 void __thiscall filebuf_dtor(filebuf* this)
988 TRACE("(%p)\n", this);
989 if (this->close)
990 filebuf_close(this);
991 streambuf_dtor(&this->base);
994 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
995 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
996 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
997 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
999 filebuf_dtor(this);
1000 return filebuf_copy_ctor(this, rhs);
1003 /* ??_Efilebuf@@UAEPAXI@Z */
1004 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
1005 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
1007 TRACE("(%p %x)\n", this, flags);
1008 if (flags & 2) {
1009 /* we have an array, with the number of elements stored before the first object */
1010 INT_PTR i, *ptr = (INT_PTR *)this-1;
1012 for (i = *ptr-1; i >= 0; i--)
1013 filebuf_dtor(this+i);
1014 MSVCRT_operator_delete(ptr);
1015 } else {
1016 filebuf_dtor(this);
1017 if (flags & 1)
1018 MSVCRT_operator_delete(this);
1020 return this;
1023 /* ??_Gfilebuf@@UAEPAXI@Z */
1024 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
1025 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
1027 TRACE("(%p %x)\n", this, flags);
1028 filebuf_dtor(this);
1029 if (flags & 1) MSVCRT_operator_delete(this);
1030 return this;
1033 /* ?attach@filebuf@@QAEPAV1@H@Z */
1034 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
1035 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
1036 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
1038 TRACE("(%p %d)\n", this, fd);
1039 if (this->fd != -1)
1040 return NULL;
1042 streambuf_lock(&this->base);
1043 this->fd = fd;
1044 streambuf_allocate(&this->base);
1045 streambuf_unlock(&this->base);
1046 return this;
1049 /* ?close@filebuf@@QAEPAV1@XZ */
1050 /* ?close@filebuf@@QEAAPEAV1@XZ */
1051 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
1052 filebuf* __thiscall filebuf_close(filebuf *this)
1054 filebuf *ret;
1056 TRACE("(%p)\n", this);
1057 if (this->fd == -1)
1058 return NULL;
1060 streambuf_lock(&this->base);
1061 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
1062 ret = NULL;
1063 } else {
1064 this->fd = -1;
1065 ret = this;
1067 streambuf_unlock(&this->base);
1068 return ret;
1071 /* ?fd@filebuf@@QBEHXZ */
1072 /* ?fd@filebuf@@QEBAHXZ */
1073 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
1074 filedesc __thiscall filebuf_fd(const filebuf *this)
1076 TRACE("(%p)\n", this);
1077 return this->fd;
1080 /* ?is_open@filebuf@@QBEHXZ */
1081 /* ?is_open@filebuf@@QEBAHXZ */
1082 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1083 int __thiscall filebuf_is_open(const filebuf *this)
1085 TRACE("(%p)\n", this);
1086 return this->fd != -1;
1089 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1090 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1091 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1092 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1094 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1095 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1096 int op_flags, sh_flags, fd;
1098 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1099 if (this->fd != -1)
1100 return NULL;
1102 /* mode */
1103 if (mode & (OPENMODE_app|OPENMODE_trunc))
1104 mode |= OPENMODE_out;
1105 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1106 if (op_flags < 0)
1107 return NULL;
1108 if (mode & OPENMODE_app)
1109 op_flags |= _O_APPEND;
1110 if ((mode & OPENMODE_trunc) ||
1111 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1112 op_flags |= _O_TRUNC;
1113 if (!(mode & OPENMODE_nocreate))
1114 op_flags |= _O_CREAT;
1115 if (mode & OPENMODE_noreplace)
1116 op_flags |= _O_EXCL;
1117 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1119 /* share protection */
1120 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1122 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1123 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1124 if (fd < 0)
1125 return NULL;
1127 streambuf_lock(&this->base);
1128 this->close = 1;
1129 this->fd = fd;
1130 if ((mode & OPENMODE_ate) &&
1131 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1132 _close(fd);
1133 this->fd = -1;
1135 streambuf_allocate(&this->base);
1136 streambuf_unlock(&this->base);
1137 return (this->fd == -1) ? NULL : this;
1140 /* ?overflow@filebuf@@UAEHH@Z */
1141 /* ?overflow@filebuf@@UEAAHH@Z */
1142 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1143 int __thiscall filebuf_overflow(filebuf *this, int c)
1145 TRACE("(%p %d)\n", this, c);
1146 if (call_streambuf_sync(&this->base) == EOF)
1147 return EOF;
1148 if (this->base.unbuffered)
1149 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1150 if (streambuf_allocate(&this->base) == EOF)
1151 return EOF;
1153 this->base.pbase = this->base.pptr = this->base.base;
1154 this->base.epptr = this->base.ebuf;
1155 if (c != EOF)
1156 *this->base.pptr++ = c;
1157 return 1;
1160 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1161 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1162 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1163 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1165 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1166 if (call_streambuf_sync(&this->base) == EOF)
1167 return EOF;
1168 return _lseek(this->fd, offset, dir);
1171 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1172 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1173 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1174 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1176 streambuf *ret;
1178 TRACE("(%p %p %d)\n", this, buffer, length);
1179 if (this->base.base != NULL)
1180 return NULL;
1182 streambuf_lock(&this->base);
1183 ret = streambuf_setbuf(&this->base, buffer, length);
1184 streambuf_unlock(&this->base);
1185 return ret;
1188 /* ?setmode@filebuf@@QAEHH@Z */
1189 /* ?setmode@filebuf@@QEAAHH@Z */
1190 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1191 int __thiscall filebuf_setmode(filebuf *this, int mode)
1193 int ret;
1195 TRACE("(%p %d)\n", this, mode);
1196 if (mode != filebuf_text && mode != filebuf_binary)
1197 return -1;
1199 streambuf_lock(&this->base);
1200 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1201 streambuf_unlock(&this->base);
1202 return ret;
1205 /* ?sync@filebuf@@UAEHXZ */
1206 /* ?sync@filebuf@@UEAAHXZ */
1207 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1208 int __thiscall filebuf_sync(filebuf *this)
1210 int count, mode;
1211 char *ptr;
1212 LONG offset;
1214 TRACE("(%p)\n", this);
1215 if (this->fd == -1)
1216 return EOF;
1217 if (this->base.unbuffered)
1218 return 0;
1220 /* flush output buffer */
1221 if (this->base.pptr != NULL) {
1222 count = this->base.pptr - this->base.pbase;
1223 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1224 return EOF;
1226 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1227 /* flush input buffer */
1228 if (this->base.egptr != NULL) {
1229 offset = this->base.egptr - this->base.gptr;
1230 if (offset > 0) {
1231 mode = _setmode(this->fd, _O_TEXT);
1232 _setmode(this->fd, mode);
1233 if (mode & _O_TEXT) {
1234 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1235 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1236 if (*ptr == '\n')
1237 offset++;
1239 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1240 return EOF;
1243 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1244 return 0;
1247 /* ?underflow@filebuf@@UAEHXZ */
1248 /* ?underflow@filebuf@@UEAAHXZ */
1249 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1250 int __thiscall filebuf_underflow(filebuf *this)
1252 int buffer_size, read_bytes;
1253 char c;
1255 TRACE("(%p)\n", this);
1257 if (this->base.unbuffered)
1258 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1260 if (this->base.gptr >= this->base.egptr) {
1261 if (call_streambuf_sync(&this->base) == EOF)
1262 return EOF;
1263 buffer_size = this->base.ebuf - this->base.base;
1264 read_bytes = _read(this->fd, this->base.base, buffer_size);
1265 if (read_bytes <= 0)
1266 return EOF;
1267 this->base.eback = this->base.gptr = this->base.base;
1268 this->base.egptr = this->base.base + read_bytes;
1270 return (unsigned char) *this->base.gptr;
1273 /* ??0strstreambuf@@QAE@ABV0@@Z */
1274 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1275 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1276 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1278 TRACE("(%p %p)\n", this, copy);
1279 *this = *copy;
1280 this->base.vtable = &MSVCP_strstreambuf_vtable;
1281 return this;
1284 /* ??0strstreambuf@@QAE@H@Z */
1285 /* ??0strstreambuf@@QEAA@H@Z */
1286 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1287 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1289 TRACE("(%p %d)\n", this, length);
1290 streambuf_ctor(&this->base);
1291 this->base.vtable = &MSVCP_strstreambuf_vtable;
1292 this->dynamic = 1;
1293 this->increase = length;
1294 this->constant = 0;
1295 this->f_alloc = NULL;
1296 this->f_free = NULL;
1297 return this;
1300 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1301 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1302 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1303 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1305 TRACE("(%p %p %p)\n", this, falloc, ffree);
1306 strstreambuf_dynamic_ctor(this, 1);
1307 this->f_alloc = falloc;
1308 this->f_free = ffree;
1309 return this;
1312 /* ??0strstreambuf@@QAE@PADH0@Z */
1313 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1314 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1315 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1317 char *end_buffer;
1319 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1321 if (length > 0)
1322 end_buffer = buffer + length;
1323 else if (length == 0)
1324 end_buffer = buffer + strlen(buffer);
1325 else
1326 end_buffer = (char*) -1;
1328 streambuf_ctor(&this->base);
1329 streambuf_setb(&this->base, buffer, end_buffer, 0);
1330 if (put == NULL) {
1331 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1332 } else {
1333 streambuf_setg(&this->base, buffer, buffer, put);
1334 streambuf_setp(&this->base, put, end_buffer);
1336 this->base.vtable = &MSVCP_strstreambuf_vtable;
1337 this->dynamic = 0;
1338 this->constant = 1;
1339 return this;
1342 /* ??0strstreambuf@@QAE@PAEH0@Z */
1343 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1344 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1345 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1347 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1348 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1351 /* ??0strstreambuf@@QAE@XZ */
1352 /* ??0strstreambuf@@QEAA@XZ */
1353 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1354 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1356 TRACE("(%p)\n", this);
1357 return strstreambuf_dynamic_ctor(this, 1);
1360 /* ??1strstreambuf@@UAE@XZ */
1361 /* ??1strstreambuf@@UEAA@XZ */
1362 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1363 void __thiscall strstreambuf_dtor(strstreambuf *this)
1365 TRACE("(%p)\n", this);
1366 if (this->dynamic && this->base.base) {
1367 if (this->f_free)
1368 this->f_free(this->base.base);
1369 else
1370 MSVCRT_operator_delete(this->base.base);
1372 streambuf_dtor(&this->base);
1375 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1376 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1377 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1378 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1380 strstreambuf_dtor(this);
1381 return strstreambuf_copy_ctor(this, rhs);
1384 /* ??_Estrstreambuf@@UAEPAXI@Z */
1385 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1386 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1388 TRACE("(%p %x)\n", this, flags);
1389 if (flags & 2) {
1390 /* we have an array, with the number of elements stored before the first object */
1391 INT_PTR i, *ptr = (INT_PTR *)this-1;
1393 for (i = *ptr-1; i >= 0; i--)
1394 strstreambuf_dtor(this+i);
1395 MSVCRT_operator_delete(ptr);
1396 } else {
1397 strstreambuf_dtor(this);
1398 if (flags & 1)
1399 MSVCRT_operator_delete(this);
1401 return this;
1404 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1405 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1406 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1408 TRACE("(%p %x)\n", this, flags);
1409 strstreambuf_dtor(this);
1410 if (flags & 1) MSVCRT_operator_delete(this);
1411 return this;
1414 /* ?doallocate@strstreambuf@@MAEHXZ */
1415 /* ?doallocate@strstreambuf@@MEAAHXZ */
1416 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1417 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1419 char *prev_buffer = this->base.base, *new_buffer;
1420 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1422 TRACE("(%p)\n", this);
1424 /* calculate the size of the new buffer */
1425 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1426 /* get a new buffer */
1427 if (this->f_alloc)
1428 new_buffer = this->f_alloc(new_size);
1429 else
1430 new_buffer = MSVCRT_operator_new(new_size);
1431 if (!new_buffer)
1432 return EOF;
1433 if (this->base.ebuf) {
1434 /* copy the contents and adjust the pointers */
1435 memcpy(new_buffer, this->base.base, prev_size);
1436 if (this->base.egptr) {
1437 this->base.eback += new_buffer - prev_buffer;
1438 this->base.gptr += new_buffer - prev_buffer;
1439 this->base.egptr += new_buffer - prev_buffer;
1441 if (this->base.epptr) {
1442 this->base.pbase += new_buffer - prev_buffer;
1443 this->base.pptr += new_buffer - prev_buffer;
1444 this->base.epptr += new_buffer - prev_buffer;
1446 /* free the old buffer */
1447 if (this->f_free)
1448 this->f_free(this->base.base);
1449 else
1450 MSVCRT_operator_delete(this->base.base);
1452 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1453 return 1;
1456 /* ?freeze@strstreambuf@@QAEXH@Z */
1457 /* ?freeze@strstreambuf@@QEAAXH@Z */
1458 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1459 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1461 TRACE("(%p %d)\n", this, frozen);
1462 if (!this->constant)
1463 this->dynamic = !frozen;
1466 /* ?overflow@strstreambuf@@UAEHH@Z */
1467 /* ?overflow@strstreambuf@@UEAAHH@Z */
1468 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1469 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1471 TRACE("(%p %d)\n", this, c);
1472 if (this->base.pptr >= this->base.epptr) {
1473 /* increase the buffer size if it's dynamic */
1474 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1475 return EOF;
1476 if (!this->base.epptr)
1477 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1478 this->base.epptr = this->base.ebuf;
1480 if (c != EOF)
1481 *this->base.pptr++ = c;
1482 return 1;
1485 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1486 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1487 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1488 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1490 char *base[3];
1492 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1494 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1495 return EOF;
1496 /* read buffer */
1497 if (mode & OPENMODE_in) {
1498 call_streambuf_underflow(&this->base);
1499 base[SEEKDIR_beg] = this->base.eback;
1500 base[SEEKDIR_cur] = this->base.gptr;
1501 base[SEEKDIR_end] = this->base.egptr;
1502 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1503 return EOF;
1504 this->base.gptr = base[dir] + offset;
1506 /* write buffer */
1507 if (mode & OPENMODE_out) {
1508 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1509 return EOF;
1510 base[SEEKDIR_beg] = this->base.pbase;
1511 base[SEEKDIR_cur] = this->base.pptr;
1512 base[SEEKDIR_end] = this->base.epptr;
1513 if (base[dir] + offset < this->base.pbase)
1514 return EOF;
1515 if (base[dir] + offset > this->base.epptr) {
1516 /* make room if the buffer is dynamic */
1517 if (!this->dynamic)
1518 return EOF;
1519 this->increase = offset;
1520 if (call_streambuf_doallocate(&this->base) == EOF)
1521 return EOF;
1523 this->base.pptr = base[dir] + offset;
1524 return this->base.pptr - base[SEEKDIR_beg];
1526 return this->base.gptr - base[SEEKDIR_beg];
1529 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1530 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1531 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1532 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1534 TRACE("(%p %p %d)\n", this, buffer, length);
1535 if (length)
1536 this->increase = length;
1537 return &this->base;
1540 /* ?str@strstreambuf@@QAEPADXZ */
1541 /* ?str@strstreambuf@@QEAAPEADXZ */
1542 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1543 char* __thiscall strstreambuf_str(strstreambuf *this)
1545 TRACE("(%p)\n", this);
1546 strstreambuf_freeze(this, 1);
1547 return this->base.base;
1550 /* ?sync@strstreambuf@@UAEHXZ */
1551 /* ?sync@strstreambuf@@UEAAHXZ */
1552 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1553 int __thiscall strstreambuf_sync(strstreambuf *this)
1555 TRACE("(%p)\n", this);
1556 return 0;
1559 /* ?underflow@strstreambuf@@UAEHXZ */
1560 /* ?underflow@strstreambuf@@UEAAHXZ */
1561 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1562 int __thiscall strstreambuf_underflow(strstreambuf *this)
1564 TRACE("(%p)\n", this);
1565 if (this->base.gptr < this->base.egptr)
1566 return (unsigned char) *this->base.gptr;
1567 /* extend the get area to include the characters written */
1568 if (this->base.egptr < this->base.pptr) {
1569 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1570 this->base.eback = this->base.base;
1571 this->base.egptr = this->base.pptr;
1573 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1576 /* ??0stdiobuf@@QAE@ABV0@@Z */
1577 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1578 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1579 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1581 TRACE("(%p %p)\n", this, copy);
1582 *this = *copy;
1583 this->base.vtable = &MSVCP_stdiobuf_vtable;
1584 return this;
1587 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1588 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1589 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1590 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1592 TRACE("(%p %p)\n", this, file);
1593 streambuf_reserve_ctor(&this->base, NULL, 0);
1594 this->base.vtable = &MSVCP_stdiobuf_vtable;
1595 this->file = file;
1596 return this;
1599 /* ??1stdiobuf@@UAE@XZ */
1600 /* ??1stdiobuf@@UEAA@XZ */
1601 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1602 void __thiscall stdiobuf_dtor(stdiobuf *this)
1604 TRACE("(%p)\n", this);
1605 call_streambuf_sync(&this->base);
1606 streambuf_dtor(&this->base);
1609 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1610 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1611 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1612 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1614 stdiobuf_dtor(this);
1615 return stdiobuf_copy_ctor(this, rhs);
1618 /* ??_Estdiobuf@@UAEPAXI@Z */
1619 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1620 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1622 TRACE("(%p %x)\n", this, flags);
1623 if (flags & 2) {
1624 /* we have an array, with the number of elements stored before the first object */
1625 INT_PTR i, *ptr = (INT_PTR *)this-1;
1627 for (i = *ptr-1; i >= 0; i--)
1628 stdiobuf_dtor(this+i);
1629 MSVCRT_operator_delete(ptr);
1630 } else {
1631 stdiobuf_dtor(this);
1632 if (flags & 1)
1633 MSVCRT_operator_delete(this);
1635 return this;
1638 /* ??_Gstdiobuf@@UAEPAXI@Z */
1639 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1640 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1642 TRACE("(%p %x)\n", this, flags);
1643 stdiobuf_dtor(this);
1644 if (flags & 1) MSVCRT_operator_delete(this);
1645 return this;
1648 /* ?overflow@stdiobuf@@UAEHH@Z */
1649 /* ?overflow@stdiobuf@@UEAAHH@Z */
1650 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1651 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1653 TRACE("(%p %d)\n", this, c);
1654 if (this->base.unbuffered)
1655 return (c == EOF) ? 1 : fputc(c, this->file);
1656 if (streambuf_allocate(&this->base) == EOF)
1657 return EOF;
1659 if (!this->base.epptr) {
1660 /* set the put area to the second half of the buffer */
1661 streambuf_setp(&this->base,
1662 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1663 } else if (this->base.pptr > this->base.pbase) {
1664 /* flush the put area */
1665 int count = this->base.pptr - this->base.pbase;
1666 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1667 return EOF;
1668 this->base.pptr = this->base.pbase;
1670 if (c != EOF) {
1671 if (this->base.pbase >= this->base.epptr)
1672 return fputc(c, this->file);
1673 *this->base.pptr++ = c;
1675 return 1;
1678 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1679 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1680 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1681 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1683 TRACE("(%p %d)\n", this, c);
1684 return streambuf_pbackfail(&this->base, c);
1687 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1688 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1689 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1690 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1692 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1693 call_streambuf_overflow(&this->base, EOF);
1694 if (fseek(this->file, offset, dir))
1695 return EOF;
1696 return ftell(this->file);
1699 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1700 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1701 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1702 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1704 char *reserve;
1705 int buffer_size = read_size + write_size;
1707 TRACE("(%p %d %d)\n", this, read_size, write_size);
1708 if (read_size < 0 || write_size < 0)
1709 return 0;
1710 if (!buffer_size) {
1711 this->base.unbuffered = 1;
1712 return 0;
1714 /* get a new buffer */
1715 reserve = MSVCRT_operator_new(buffer_size);
1716 if (!reserve)
1717 return 0;
1718 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1719 this->base.unbuffered = 0;
1720 /* set the get/put areas */
1721 if (read_size > 0)
1722 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1723 else
1724 streambuf_setg(&this->base, NULL, NULL, NULL);
1725 if (write_size > 0)
1726 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1727 else
1728 streambuf_setp(&this->base, NULL, NULL);
1729 return 1;
1732 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1733 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1734 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1735 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1737 TRACE("(%p)\n", this);
1738 return this->file;
1741 /* ?sync@stdiobuf@@UAEHXZ */
1742 /* ?sync@stdiobuf@@UEAAHXZ */
1743 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1744 int __thiscall stdiobuf_sync(stdiobuf *this)
1746 TRACE("(%p)\n", this);
1747 if (this->base.unbuffered)
1748 return 0;
1749 /* flush the put area */
1750 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1751 return EOF;
1752 /* flush the get area */
1753 if (this->base.gptr < this->base.egptr) {
1754 char *ptr;
1755 int fd, mode, offset = this->base.egptr - this->base.gptr;
1756 if ((fd = fileno(this->file)) < 0)
1757 return EOF;
1758 mode = _setmode(fd, _O_TEXT);
1759 _setmode(fd, mode);
1760 if (mode & _O_TEXT) {
1761 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1762 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1763 if (*ptr == '\n')
1764 offset++;
1766 if (fseek(this->file, -offset, SEEK_CUR))
1767 return EOF;
1768 this->base.gptr = this->base.egptr;
1770 return 0;
1773 /* ?underflow@stdiobuf@@UAEHXZ */
1774 /* ?underflow@stdiobuf@@UEAAHXZ */
1775 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1776 int __thiscall stdiobuf_underflow(stdiobuf *this)
1778 TRACE("(%p)\n", this);
1779 if (!this->file)
1780 return EOF;
1781 if (this->base.unbuffered)
1782 return fgetc(this->file);
1783 if (streambuf_allocate(&this->base) == EOF)
1784 return EOF;
1786 if (!this->base.egptr) {
1787 /* set the get area to the first half of the buffer */
1788 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1789 streambuf_setg(&this->base, this->base.base, middle, middle);
1791 if (this->base.gptr >= this->base.egptr) {
1792 /* read characters from the file */
1793 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1794 if (!this->base.eback ||
1795 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1796 return EOF;
1797 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1798 this->base.gptr = this->base.egptr - read_bytes;
1800 return (unsigned char) *this->base.gptr++;
1803 /* ??0ios@@IAE@ABV0@@Z */
1804 /* ??0ios@@IEAA@AEBV0@@Z */
1805 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1806 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1808 TRACE("(%p %p)\n", this, copy);
1809 ios_fLockcInit++;
1810 this->vtable = &MSVCP_ios_vtable;
1811 this->sb = NULL;
1812 this->delbuf = 0;
1813 this->do_lock = -1;
1814 InitializeCriticalSection(&this->lock);
1815 return ios_assign(this, copy);
1818 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1819 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1820 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1821 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1823 TRACE("(%p %p)\n", this, sb);
1824 ios_fLockcInit++;
1825 this->vtable = &MSVCP_ios_vtable;
1826 this->sb = sb;
1827 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1828 this->special[0] = this->special[1] = 0;
1829 this->delbuf = 0;
1830 this->tie = NULL;
1831 this->flags = 0;
1832 this->precision = 6;
1833 this->fill = ' ';
1834 this->width = 0;
1835 this->do_lock = -1;
1836 InitializeCriticalSection(&this->lock);
1837 return this;
1840 /* ??0ios@@IAE@XZ */
1841 /* ??0ios@@IEAA@XZ */
1842 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1843 ios* __thiscall ios_ctor(ios *this)
1845 return ios_sb_ctor(this, NULL);
1848 /* ??1ios@@UAE@XZ */
1849 /* ??1ios@@UEAA@XZ */
1850 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1851 void __thiscall ios_dtor(ios *this)
1853 TRACE("(%p)\n", this);
1854 ios_fLockcInit--;
1855 if (this->delbuf && this->sb)
1856 call_streambuf_vector_dtor(this->sb, 1);
1857 this->sb = NULL;
1858 this->state = IOSTATE_badbit;
1859 DeleteCriticalSection(&this->lock);
1862 /* ??4ios@@IAEAAV0@ABV0@@Z */
1863 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1864 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1865 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1867 TRACE("(%p %p)\n", this, rhs);
1868 this->state = rhs->state;
1869 if (!this->sb)
1870 this->state |= IOSTATE_badbit;
1871 this->tie = rhs->tie;
1872 this->flags = rhs->flags;
1873 this->precision = (char) rhs->precision;
1874 this->fill = rhs->fill;
1875 this->width = (char) rhs->width;
1876 return this;
1879 /* ??7ios@@QBEHXZ */
1880 /* ??7ios@@QEBAHXZ */
1881 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1882 int __thiscall ios_op_not(const ios *this)
1884 TRACE("(%p)\n", this);
1885 return ios_fail(this);
1888 /* ??Bios@@QBEPAXXZ */
1889 /* ??Bios@@QEBAPEAXXZ */
1890 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1891 void* __thiscall ios_op_void(const ios *this)
1893 TRACE("(%p)\n", this);
1894 return ios_fail(this) ? NULL : (void*)this;
1897 /* ??_Eios@@UAEPAXI@Z */
1898 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1899 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1901 TRACE("(%p %x)\n", this, flags);
1902 if (flags & 2) {
1903 /* we have an array, with the number of elements stored before the first object */
1904 INT_PTR i, *ptr = (INT_PTR *)this-1;
1906 for (i = *ptr-1; i >= 0; i--)
1907 ios_dtor(this+i);
1908 MSVCRT_operator_delete(ptr);
1909 } else {
1910 ios_dtor(this);
1911 if (flags & 1)
1912 MSVCRT_operator_delete(this);
1914 return this;
1917 /* ??_Gios@@UAEPAXI@Z */
1918 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1919 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1921 TRACE("(%p %x)\n", this, flags);
1922 ios_dtor(this);
1923 if (flags & 1) MSVCRT_operator_delete(this);
1924 return this;
1927 /* ?bad@ios@@QBEHXZ */
1928 /* ?bad@ios@@QEBAHXZ */
1929 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1930 int __thiscall ios_bad(const ios *this)
1932 TRACE("(%p)\n", this);
1933 return (this->state & IOSTATE_badbit);
1936 /* ?bitalloc@ios@@SAJXZ */
1937 LONG __cdecl ios_bitalloc(void)
1939 TRACE("()\n");
1940 ios_lockc();
1941 ios_maxbit <<= 1;
1942 ios_unlockc();
1943 return ios_maxbit;
1946 /* ?clear@ios@@QAEXH@Z */
1947 /* ?clear@ios@@QEAAXH@Z */
1948 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1949 void __thiscall ios_clear(ios *this, int state)
1951 TRACE("(%p %d)\n", this, state);
1952 ios_lock(this);
1953 this->state = state;
1954 ios_unlock(this);
1957 /* ?clrlock@ios@@QAAXXZ */
1958 /* ?clrlock@ios@@QEAAXXZ */
1959 void __cdecl ios_clrlock(ios *this)
1961 TRACE("(%p)\n", this);
1962 if (this->do_lock <= 0)
1963 this->do_lock++;
1964 if (this->sb)
1965 streambuf_clrlock(this->sb);
1968 /* ?delbuf@ios@@QAEXH@Z */
1969 /* ?delbuf@ios@@QEAAXH@Z */
1970 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1971 void __thiscall ios_delbuf_set(ios *this, int delete)
1973 TRACE("(%p %d)\n", this, delete);
1974 this->delbuf = delete;
1977 /* ?delbuf@ios@@QBEHXZ */
1978 /* ?delbuf@ios@@QEBAHXZ */
1979 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1980 int __thiscall ios_delbuf_get(const ios *this)
1982 TRACE("(%p)\n", this);
1983 return this->delbuf;
1986 /* ?dec@@YAAAVios@@AAV1@@Z */
1987 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1988 ios* __cdecl ios_dec(ios *this)
1990 TRACE("(%p)\n", this);
1991 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1992 return this;
1995 /* ?eof@ios@@QBEHXZ */
1996 /* ?eof@ios@@QEBAHXZ */
1997 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1998 int __thiscall ios_eof(const ios *this)
2000 TRACE("(%p)\n", this);
2001 return (this->state & IOSTATE_eofbit);
2004 /* ?fail@ios@@QBEHXZ */
2005 /* ?fail@ios@@QEBAHXZ */
2006 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
2007 int __thiscall ios_fail(const ios *this)
2009 TRACE("(%p)\n", this);
2010 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
2013 /* ?fill@ios@@QAEDD@Z */
2014 /* ?fill@ios@@QEAADD@Z */
2015 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
2016 char __thiscall ios_fill_set(ios *this, char fill)
2018 char prev = this->fill;
2020 TRACE("(%p %d)\n", this, fill);
2022 this->fill = fill;
2023 return prev;
2026 /* ?fill@ios@@QBEDXZ */
2027 /* ?fill@ios@@QEBADXZ */
2028 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
2029 char __thiscall ios_fill_get(const ios *this)
2031 TRACE("(%p)\n", this);
2032 return this->fill;
2035 /* ?flags@ios@@QAEJJ@Z */
2036 /* ?flags@ios@@QEAAJJ@Z */
2037 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
2038 LONG __thiscall ios_flags_set(ios *this, LONG flags)
2040 LONG prev = this->flags;
2042 TRACE("(%p %x)\n", this, flags);
2044 this->flags = flags;
2045 return prev;
2048 /* ?flags@ios@@QBEJXZ */
2049 /* ?flags@ios@@QEBAJXZ */
2050 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
2051 LONG __thiscall ios_flags_get(const ios *this)
2053 TRACE("(%p)\n", this);
2054 return this->flags;
2057 /* ?good@ios@@QBEHXZ */
2058 /* ?good@ios@@QEBAHXZ */
2059 DEFINE_THISCALL_WRAPPER(ios_good, 4)
2060 int __thiscall ios_good(const ios *this)
2062 TRACE("(%p)\n", this);
2063 return this->state == IOSTATE_goodbit;
2066 /* ?hex@@YAAAVios@@AAV1@@Z */
2067 /* ?hex@@YAAEAVios@@AEAV1@@Z */
2068 ios* __cdecl ios_hex(ios *this)
2070 TRACE("(%p)\n", this);
2071 ios_setf_mask(this, FLAGS_hex, ios_basefield);
2072 return this;
2075 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
2076 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
2077 DEFINE_THISCALL_WRAPPER(ios_init, 8)
2078 void __thiscall ios_init(ios *this, streambuf *sb)
2080 TRACE("(%p %p)\n", this, sb);
2081 if (this->delbuf && this->sb)
2082 call_streambuf_vector_dtor(this->sb, 1);
2083 this->sb = sb;
2084 if (sb == NULL)
2085 this->state |= IOSTATE_badbit;
2086 else
2087 this->state &= ~IOSTATE_badbit;
2090 /* ?iword@ios@@QBEAAJH@Z */
2091 /* ?iword@ios@@QEBAAEAJH@Z */
2092 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2093 LONG* __thiscall ios_iword(const ios *this, int index)
2095 TRACE("(%p %d)\n", this, index);
2096 return &ios_statebuf[index];
2099 /* ?lock@ios@@QAAXXZ */
2100 /* ?lock@ios@@QEAAXXZ */
2101 void __cdecl ios_lock(ios *this)
2103 TRACE("(%p)\n", this);
2104 if (this->do_lock < 0)
2105 EnterCriticalSection(&this->lock);
2108 /* ?lockbuf@ios@@QAAXXZ */
2109 /* ?lockbuf@ios@@QEAAXXZ */
2110 void __cdecl ios_lockbuf(ios *this)
2112 TRACE("(%p)\n", this);
2113 streambuf_lock(this->sb);
2116 /* ?lockc@ios@@KAXXZ */
2117 void __cdecl ios_lockc(void)
2119 TRACE("()\n");
2120 EnterCriticalSection(&ios_static_lock);
2123 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2124 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2125 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2126 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2128 TRACE("(%p)\n", this);
2129 return &this->lock;
2132 /* ?oct@@YAAAVios@@AAV1@@Z */
2133 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2134 ios* __cdecl ios_oct(ios *this)
2136 TRACE("(%p)\n", this);
2137 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2138 return this;
2141 /* ?precision@ios@@QAEHH@Z */
2142 /* ?precision@ios@@QEAAHH@Z */
2143 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2144 int __thiscall ios_precision_set(ios *this, int prec)
2146 int prev = this->precision;
2148 TRACE("(%p %d)\n", this, prec);
2150 this->precision = prec;
2151 return prev;
2154 /* ?precision@ios@@QBEHXZ */
2155 /* ?precision@ios@@QEBAHXZ */
2156 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2157 int __thiscall ios_precision_get(const ios *this)
2159 TRACE("(%p)\n", this);
2160 return this->precision;
2163 /* ?pword@ios@@QBEAAPAXH@Z */
2164 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2165 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2166 void** __thiscall ios_pword(const ios *this, int index)
2168 TRACE("(%p %d)\n", this, index);
2169 return (void**)&ios_statebuf[index];
2172 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2173 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2174 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2175 streambuf* __thiscall ios_rdbuf(const ios *this)
2177 TRACE("(%p)\n", this);
2178 return this->sb;
2181 /* ?rdstate@ios@@QBEHXZ */
2182 /* ?rdstate@ios@@QEBAHXZ */
2183 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2184 int __thiscall ios_rdstate(const ios *this)
2186 TRACE("(%p)\n", this);
2187 return this->state;
2190 /* ?setf@ios@@QAEJJ@Z */
2191 /* ?setf@ios@@QEAAJJ@Z */
2192 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2193 LONG __thiscall ios_setf(ios *this, LONG flags)
2195 LONG prev = this->flags;
2197 TRACE("(%p %x)\n", this, flags);
2199 ios_lock(this);
2200 this->flags |= flags;
2201 ios_unlock(this);
2202 return prev;
2205 /* ?setf@ios@@QAEJJJ@Z */
2206 /* ?setf@ios@@QEAAJJJ@Z */
2207 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2208 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2210 LONG prev = this->flags;
2212 TRACE("(%p %x %x)\n", this, flags, mask);
2214 ios_lock(this);
2215 this->flags = (this->flags & (~mask)) | (flags & mask);
2216 ios_unlock(this);
2217 return prev;
2220 /* ?setlock@ios@@QAAXXZ */
2221 /* ?setlock@ios@@QEAAXXZ */
2222 void __cdecl ios_setlock(ios *this)
2224 TRACE("(%p)\n", this);
2225 this->do_lock--;
2226 if (this->sb)
2227 streambuf_setlock(this->sb);
2230 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2231 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2232 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2233 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2235 ostream *prev = this->tie;
2237 TRACE("(%p %p)\n", this, ostr);
2239 this->tie = ostr;
2240 return prev;
2243 /* ?tie@ios@@QBEPAVostream@@XZ */
2244 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2245 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2246 ostream* __thiscall ios_tie_get(const ios *this)
2248 TRACE("(%p)\n", this);
2249 return this->tie;
2252 /* ?unlock@ios@@QAAXXZ */
2253 /* ?unlock@ios@@QEAAXXZ */
2254 void __cdecl ios_unlock(ios *this)
2256 TRACE("(%p)\n", this);
2257 if (this->do_lock < 0)
2258 LeaveCriticalSection(&this->lock);
2261 /* ?unlockbuf@ios@@QAAXXZ */
2262 /* ?unlockbuf@ios@@QEAAXXZ */
2263 void __cdecl ios_unlockbuf(ios *this)
2265 TRACE("(%p)\n", this);
2266 streambuf_unlock(this->sb);
2269 /* ?unlockc@ios@@KAXXZ */
2270 void __cdecl ios_unlockc(void)
2272 TRACE("()\n");
2273 LeaveCriticalSection(&ios_static_lock);
2276 /* ?unsetf@ios@@QAEJJ@Z */
2277 /* ?unsetf@ios@@QEAAJJ@Z */
2278 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2279 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2281 LONG prev = this->flags;
2283 TRACE("(%p %x)\n", this, flags);
2285 ios_lock(this);
2286 this->flags &= ~flags;
2287 ios_unlock(this);
2288 return prev;
2291 /* ?width@ios@@QAEHH@Z */
2292 /* ?width@ios@@QEAAHH@Z */
2293 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2294 int __thiscall ios_width_set(ios *this, int width)
2296 int prev = this->width;
2298 TRACE("(%p %d)\n", this, width);
2300 this->width = width;
2301 return prev;
2304 /* ?width@ios@@QBEHXZ */
2305 /* ?width@ios@@QEBAHXZ */
2306 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2307 int __thiscall ios_width_get(const ios *this)
2309 TRACE("(%p)\n", this);
2310 return this->width;
2313 /* ?xalloc@ios@@SAHXZ */
2314 int __cdecl ios_xalloc(void)
2316 int ret;
2318 TRACE("()\n");
2320 ios_lockc();
2321 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2322 ios_unlockc();
2323 return ret;
2326 static inline ios* ostream_get_ios(const ostream *this)
2328 return (ios*)((char*)this + this->vbtable[1]);
2331 static inline ios* ostream_to_ios(const ostream *this)
2333 return (ios*)((char*)this + ostream_vbtable[1]);
2336 static inline ostream* ios_to_ostream(const ios *base)
2338 return (ostream*)((char*)base - ostream_vbtable[1]);
2341 /* ??0ostream@@IAE@XZ */
2342 /* ??0ostream@@IEAA@XZ */
2343 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2344 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2346 ios *base;
2348 TRACE("(%p %d)\n", this, virt_init);
2350 if (virt_init) {
2351 this->vbtable = ostream_vbtable;
2352 base = ostream_get_ios(this);
2353 ios_ctor(base);
2354 } else
2355 base = ostream_get_ios(this);
2356 base->vtable = &MSVCP_ostream_vtable;
2357 this->unknown = 0;
2358 return this;
2361 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2362 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2363 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2364 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2366 TRACE("(%p %p %d)\n", this, sb, virt_init);
2367 ostream_ctor(this, virt_init);
2368 ios_init(ostream_get_ios(this), sb);
2369 return this;
2372 /* ??0ostream@@IAE@ABV0@@Z */
2373 /* ??0ostream@@IEAA@AEBV0@@Z */
2374 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2375 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2377 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2380 /* ??1ostream@@UAE@XZ */
2381 /* ??1ostream@@UEAA@XZ */
2382 /* ??1ostream_withassign@@UAE@XZ */
2383 /* ??1ostream_withassign@@UEAA@XZ */
2384 /* ??1ostrstream@@UAE@XZ */
2385 /* ??1ostrstream@@UEAA@XZ */
2386 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2387 void __thiscall ostream_dtor(ios *base)
2389 ostream *this = ios_to_ostream(base);
2391 TRACE("(%p)\n", this);
2394 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2395 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2396 /* ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z */
2397 /* ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z */
2398 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2399 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2401 ios *base = ostream_get_ios(this);
2403 TRACE("(%p %p)\n", this, sb);
2405 ios_init(base, sb);
2406 base->state &= IOSTATE_badbit;
2407 base->delbuf = 0;
2408 base->tie = NULL;
2409 base->flags = 0;
2410 base->precision = 6;
2411 base->fill = ' ';
2412 base->width = 0;
2413 return this;
2416 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2417 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2418 /* ??4ostream_withassign@@QAEAAV0@ABV0@@Z */
2419 /* ??4ostream_withassign@@QEAAAEAV0@AEBV0@@Z */
2420 /* ??4ostream_withassign@@QAEAAVostream@@ABV1@@Z */
2421 /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */
2422 /* ??4ostrstream@@QAEAAV0@ABV0@@Z */
2423 /* ??4ostrstream@@QEAAAEAV0@AEBV0@@Z */
2424 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2425 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2427 return ostream_assign_sb(this, ostream_get_ios(rhs)->sb);
2430 /* ??_Dostream@@QAEXXZ */
2431 /* ??_Dostream@@QEAAXXZ */
2432 /* ??_Dostream_withassign@@QAEXXZ */
2433 /* ??_Dostream_withassign@@QEAAXXZ */
2434 /* ??_Dostrstream@@QAEXXZ */
2435 /* ??_Dostrstream@@QEAAXXZ */
2436 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2437 void __thiscall ostream_vbase_dtor(ostream *this)
2439 ios *base = ostream_to_ios(this);
2441 TRACE("(%p)\n", this);
2443 ostream_dtor(base);
2444 ios_dtor(base);
2447 /* ??_Eostream@@UAEPAXI@Z */
2448 /* ??_Eostream_withassign@@UAEPAXI@Z */
2449 /* ??_Eostrstream@@UAEPAXI@Z */
2450 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2451 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2453 ostream *this = ios_to_ostream(base);
2455 TRACE("(%p %x)\n", this, flags);
2457 if (flags & 2) {
2458 /* we have an array, with the number of elements stored before the first object */
2459 INT_PTR i, *ptr = (INT_PTR *)this-1;
2461 for (i = *ptr-1; i >= 0; i--)
2462 ostream_vbase_dtor(this+i);
2463 MSVCRT_operator_delete(ptr);
2464 } else {
2465 ostream_vbase_dtor(this);
2466 if (flags & 1)
2467 MSVCRT_operator_delete(this);
2469 return this;
2472 /* ??_Gostream@@UAEPAXI@Z */
2473 /* ??_Gostream_withassign@@UAEPAXI@Z */
2474 /* ??_Gostrstream@@UAEPAXI@Z */
2475 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2476 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2478 ostream *this = ios_to_ostream(base);
2480 TRACE("(%p %x)\n", this, flags);
2482 ostream_vbase_dtor(this);
2483 if (flags & 1) MSVCRT_operator_delete(this);
2484 return this;
2487 /* ?flush@ostream@@QAEAAV1@XZ */
2488 /* ?flush@ostream@@QEAAAEAV1@XZ */
2489 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2490 ostream* __thiscall ostream_flush(ostream *this)
2492 ios *base = ostream_get_ios(this);
2494 TRACE("(%p)\n", this);
2496 ios_lockbuf(base);
2497 if (call_streambuf_sync(base->sb) == EOF)
2498 ios_clear(base, base->state | IOSTATE_failbit);
2499 ios_unlockbuf(base);
2500 return this;
2503 /* ?opfx@ostream@@QAEHXZ */
2504 /* ?opfx@ostream@@QEAAHXZ */
2505 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2506 int __thiscall ostream_opfx(ostream *this)
2508 ios *base = ostream_get_ios(this);
2510 TRACE("(%p)\n", this);
2512 if (!ios_good(base)) {
2513 ios_clear(base, base->state | IOSTATE_failbit);
2514 return 0;
2516 ios_lock(base);
2517 ios_lockbuf(base);
2518 if (base->tie)
2519 ostream_flush(base->tie);
2520 return 1;
2523 /* ?osfx@ostream@@QAEXXZ */
2524 /* ?osfx@ostream@@QEAAXXZ */
2525 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2526 void __thiscall ostream_osfx(ostream *this)
2528 ios *base = ostream_get_ios(this);
2530 TRACE("(%p)\n", this);
2532 ios_unlockbuf(base);
2533 ios_width_set(base, 0);
2534 if (base->flags & FLAGS_unitbuf)
2535 ostream_flush(this);
2536 if (base->flags & FLAGS_stdio) {
2537 fflush(stdout);
2538 fflush(stderr);
2540 ios_unlock(base);
2543 /* ?put@ostream@@QAEAAV1@C@Z */
2544 /* ?put@ostream@@QEAAAEAV1@C@Z */
2545 /* ?put@ostream@@QAEAAV1@D@Z */
2546 /* ?put@ostream@@QEAAAEAV1@D@Z */
2547 /* ?put@ostream@@QAEAAV1@E@Z */
2548 /* ?put@ostream@@QEAAAEAV1@E@Z */
2549 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2550 ostream* __thiscall ostream_put(ostream *this, char c)
2552 ios *base = ostream_get_ios(this);
2554 TRACE("(%p %c)\n", this, c);
2556 if (ostream_opfx(this)) {
2557 if (streambuf_sputc(base->sb, c) == EOF)
2558 base->state = IOSTATE_badbit | IOSTATE_failbit;
2559 ostream_osfx(this);
2561 return this;
2564 /* ?seekp@ostream@@QAEAAV1@J@Z */
2565 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2566 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2567 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2569 ios *base = ostream_get_ios(this);
2571 TRACE("(%p %d)\n", this, pos);
2573 ios_lockbuf(base);
2574 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2575 ios_clear(base, base->state | IOSTATE_failbit);
2576 ios_unlockbuf(base);
2577 return this;
2580 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2581 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2582 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2583 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2585 ios *base = ostream_get_ios(this);
2587 TRACE("(%p %d %d)\n", this, off, dir);
2589 ios_lockbuf(base);
2590 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2591 ios_clear(base, base->state | IOSTATE_failbit);
2592 ios_unlockbuf(base);
2593 return this;
2596 /* ?tellp@ostream@@QAEJXZ */
2597 /* ?tellp@ostream@@QEAAJXZ */
2598 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2599 streampos __thiscall ostream_tellp(ostream *this)
2601 ios *base = ostream_get_ios(this);
2602 streampos pos;
2604 TRACE("(%p)\n", this);
2606 ios_lockbuf(base);
2607 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2608 ios_clear(base, base->state | IOSTATE_failbit);
2609 ios_unlockbuf(base);
2610 return pos;
2613 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2614 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2615 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2616 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2617 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2618 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2619 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2620 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2622 ios *base = ostream_get_ios(this);
2624 TRACE("(%p %p %d)\n", this, str, count);
2626 if (ostream_opfx(this)) {
2627 if (streambuf_sputn(base->sb, str, count) != count)
2628 base->state = IOSTATE_badbit | IOSTATE_failbit;
2629 ostream_osfx(this);
2631 return this;
2634 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2635 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2636 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2637 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2639 ios *base = ostream_get_ios(this);
2640 int len1 = strlen(str1), len2 = strlen(str2), i;
2642 TRACE("(%p %p %p)\n", this, str1, str2);
2644 /* left of the padding */
2645 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2646 if (streambuf_sputn(base->sb, str1, len1) != len1)
2647 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2648 if (!(base->flags & FLAGS_internal))
2649 if (streambuf_sputn(base->sb, str2, len2) != len2)
2650 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2652 /* add padding to fill the width */
2653 for (i = len1 + len2; i < base->width; i++)
2654 if (streambuf_sputc(base->sb, base->fill) == EOF)
2655 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2656 /* right of the padding */
2657 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2658 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2659 if (streambuf_sputn(base->sb, str1, len1) != len1)
2660 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2661 if (streambuf_sputn(base->sb, str2, len2) != len2)
2662 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2664 return this;
2667 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2669 ios *base = ostream_get_ios(ostr);
2670 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2672 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2674 if (ostream_opfx(ostr)) {
2675 if (base->flags & FLAGS_hex) {
2676 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2677 if (base->flags & FLAGS_showbase) {
2678 prefix_str[0] = '0';
2679 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2681 } else if (base->flags & FLAGS_oct) {
2682 sprintf_fmt[1] = 'o';
2683 if (base->flags & FLAGS_showbase)
2684 prefix_str[0] = '0';
2685 } else { /* FLAGS_dec */
2686 if (unsig)
2687 sprintf_fmt[1] = 'u';
2688 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2689 prefix_str[0] = '+';
2692 if (shrt) {
2693 sprintf_fmt[2] = sprintf_fmt[1];
2694 sprintf_fmt[1] = 'h';
2697 if (sprintf(number_str, sprintf_fmt, n) > 0)
2698 ostream_writepad(ostr, prefix_str, number_str);
2699 else
2700 base->state |= IOSTATE_failbit;
2701 ostream_osfx(ostr);
2703 return ostr;
2706 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2708 ios *base = ostream_get_ios(ostr);
2709 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2710 int prec, max_prec = dbl ? 15 : 6;
2711 int str_length = 1; /* null end char */
2713 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2715 if (ostream_opfx(ostr)) {
2716 if ((base->flags & FLAGS_showpos) && d > 0) {
2717 prefix_str[0] = '+';
2718 str_length++; /* plus sign */
2720 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2721 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2722 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2723 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2724 if (base->flags & FLAGS_showpoint) {
2725 sprintf_fmt[4] = sprintf_fmt[3];
2726 sprintf_fmt[3] = sprintf_fmt[2];
2727 sprintf_fmt[2] = sprintf_fmt[1];
2728 sprintf_fmt[1] = '#';
2731 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2732 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2733 if (str_length > 24) {
2734 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2735 ostream_writepad(ostr, "", "");
2736 } else {
2737 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2738 ostream_writepad(ostr, prefix_str, number_str);
2739 else
2740 base->state |= IOSTATE_failbit;
2742 ostream_osfx(ostr);
2744 return ostr;
2747 /* ??6ostream@@QAEAAV0@C@Z */
2748 /* ??6ostream@@QEAAAEAV0@C@Z */
2749 /* ??6ostream@@QAEAAV0@D@Z */
2750 /* ??6ostream@@QEAAAEAV0@D@Z */
2751 /* ??6ostream@@QAEAAV0@E@Z */
2752 /* ??6ostream@@QEAAAEAV0@E@Z */
2753 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2754 ostream* __thiscall ostream_print_char(ostream *this, char c)
2756 const char c_str[2] = {c, 0};
2758 TRACE("(%p %c)\n", this, c);
2760 if (ostream_opfx(this)) {
2761 ostream_writepad(this, "", c_str);
2762 ostream_osfx(this);
2764 return this;
2767 /* ??6ostream@@QAEAAV0@PBC@Z */
2768 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2769 /* ??6ostream@@QAEAAV0@PBD@Z */
2770 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2771 /* ??6ostream@@QAEAAV0@PBE@Z */
2772 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2773 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2774 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2776 TRACE("(%p %s)\n", this, str);
2777 if (ostream_opfx(this)) {
2778 ostream_writepad(this, "", str);
2779 ostream_osfx(this);
2781 return this;
2784 /* ??6ostream@@QAEAAV0@F@Z */
2785 /* ??6ostream@@QEAAAEAV0@F@Z */
2786 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2787 ostream* __thiscall ostream_print_short(ostream *this, short n)
2789 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2792 /* ??6ostream@@QAEAAV0@G@Z */
2793 /* ??6ostream@@QEAAAEAV0@G@Z */
2794 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2795 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2797 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2800 /* ??6ostream@@QAEAAV0@H@Z */
2801 /* ??6ostream@@QEAAAEAV0@H@Z */
2802 /* ??6ostream@@QAEAAV0@J@Z */
2803 /* ??6ostream@@QEAAAEAV0@J@Z */
2804 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2805 ostream* __thiscall ostream_print_int(ostream *this, int n)
2807 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2810 /* ??6ostream@@QAEAAV0@I@Z */
2811 /* ??6ostream@@QEAAAEAV0@I@Z */
2812 /* ??6ostream@@QAEAAV0@K@Z */
2813 /* ??6ostream@@QEAAAEAV0@K@Z */
2814 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2815 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2817 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2820 /* ??6ostream@@QAEAAV0@M@Z */
2821 /* ??6ostream@@QEAAAEAV0@M@Z */
2822 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2823 ostream* __thiscall ostream_print_float(ostream *this, float f)
2825 return ostream_internal_print_float(this, f, FALSE);
2828 /* ??6ostream@@QAEAAV0@N@Z */
2829 /* ??6ostream@@QEAAAEAV0@N@Z */
2830 /* ??6ostream@@QAEAAV0@O@Z */
2831 /* ??6ostream@@QEAAAEAV0@O@Z */
2832 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2833 ostream* __thiscall ostream_print_double(ostream *this, double d)
2835 return ostream_internal_print_float(this, d, TRUE);
2838 /* ??6ostream@@QAEAAV0@PBX@Z */
2839 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2840 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2841 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2843 ios *base = ostream_get_ios(this);
2844 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2846 TRACE("(%p %p)\n", this, ptr);
2848 if (ostream_opfx(this)) {
2849 if (ptr && base->flags & FLAGS_uppercase)
2850 prefix_str[1] = 'X';
2852 if (sprintf(pointer_str, "%p", ptr) > 0)
2853 ostream_writepad(this, prefix_str, pointer_str);
2854 else
2855 base->state |= IOSTATE_failbit;
2856 ostream_osfx(this);
2858 return this;
2861 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2862 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2863 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2864 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2866 ios *base = ostream_get_ios(this);
2867 int c;
2869 TRACE("(%p %p)\n", this, sb);
2871 if (ostream_opfx(this)) {
2872 while ((c = streambuf_sbumpc(sb)) != EOF) {
2873 if (streambuf_sputc(base->sb, c) == EOF) {
2874 base->state |= IOSTATE_failbit;
2875 break;
2878 ostream_osfx(this);
2880 return this;
2883 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2884 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2885 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2886 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2888 TRACE("(%p %p)\n", this, func);
2889 return func(this);
2892 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2893 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2894 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2895 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2897 TRACE("(%p %p)\n", this, func);
2898 func(ostream_get_ios(this));
2899 return this;
2902 /* ?endl@@YAAAVostream@@AAV1@@Z */
2903 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2904 ostream* __cdecl ostream_endl(ostream *this)
2906 TRACE("(%p)\n", this);
2907 ostream_put(this, '\n');
2908 return ostream_flush(this);
2911 /* ?ends@@YAAAVostream@@AAV1@@Z */
2912 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2913 ostream* __cdecl ostream_ends(ostream *this)
2915 TRACE("(%p)\n", this);
2916 return ostream_put(this, 0);
2919 /* ?flush@@YAAAVostream@@AAV1@@Z */
2920 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2921 ostream* __cdecl ostream_flush_manip(ostream *this)
2923 TRACE("(%p)\n", this);
2924 return ostream_flush(this);
2927 /* ??0ostream_withassign@@QAE@ABV0@@Z */
2928 /* ??0ostream_withassign@@QEAA@AEBV0@@Z */
2929 DEFINE_THISCALL_WRAPPER(ostream_withassign_copy_ctor, 12)
2930 ostream* __thiscall ostream_withassign_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2932 ios *base, *base_copy;
2934 TRACE("(%p %p %d)\n", this, copy, virt_init);
2936 base_copy = ostream_get_ios(copy);
2937 if (virt_init) {
2938 this->vbtable = ostream_vbtable;
2939 base = ostream_get_ios(this);
2940 ios_copy_ctor(base, base_copy);
2941 } else
2942 base = ostream_get_ios(this);
2943 ios_init(base, base_copy->sb);
2944 base->vtable = &MSVCP_ostream_withassign_vtable;
2945 this->unknown = 0;
2946 return this;
2949 /* ??0ostream_withassign@@QAE@PAVstreambuf@@@Z */
2950 /* ??0ostream_withassign@@QEAA@PEAVstreambuf@@@Z */
2951 DEFINE_THISCALL_WRAPPER(ostream_withassign_sb_ctor, 12)
2952 ostream* __thiscall ostream_withassign_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2954 ios *base;
2956 TRACE("(%p %p %d)\n", this, sb, virt_init);
2958 ostream_sb_ctor(this, sb, virt_init);
2959 base = ostream_get_ios(this);
2960 base->vtable = &MSVCP_ostream_withassign_vtable;
2961 return this;
2964 /* ??0ostream_withassign@@QAE@XZ */
2965 /* ??0ostream_withassign@@QEAA@XZ */
2966 DEFINE_THISCALL_WRAPPER(ostream_withassign_ctor, 8)
2967 ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init)
2969 ios *base;
2971 TRACE("(%p %d)\n", this, virt_init);
2973 ostream_ctor(this, virt_init);
2974 base = ostream_get_ios(this);
2975 base->vtable = &MSVCP_ostream_withassign_vtable;
2976 return this;
2979 static ostream* ostrstream_internal_sb_ctor(ostream *this, strstreambuf *ssb, BOOL virt_init)
2981 ios *base;
2983 if (ssb)
2984 ostream_sb_ctor(this, &ssb->base, virt_init);
2985 else
2986 ostream_ctor(this, virt_init);
2987 base = ostream_get_ios(this);
2988 base->vtable = &MSVCP_ostrstream_vtable;
2989 base->delbuf = 1;
2990 return this;
2993 /* ??0ostrstream@@QAE@ABV0@@Z */
2994 /* ??0ostrstream@@QEAA@AEBV0@@Z */
2995 DEFINE_THISCALL_WRAPPER(ostrstream_copy_ctor, 12)
2996 ostream* __thiscall ostrstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2998 TRACE("(%p %p %d)\n", this, copy, virt_init);
2999 ostream_withassign_copy_ctor(this, copy, virt_init);
3000 ostream_get_ios(this)->vtable = &MSVCP_ostrstream_vtable;
3001 return this;
3004 /* ??0ostrstream@@QAE@PADHH@Z */
3005 /* ??0ostrstream@@QEAA@PEADHH@Z */
3006 DEFINE_THISCALL_WRAPPER(ostrstream_buffer_ctor, 20)
3007 ostream* __thiscall ostrstream_buffer_ctor(ostream *this, char *buffer, int length, int mode, BOOL virt_init)
3009 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
3011 TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init);
3013 if (ssb) {
3014 strstreambuf_buffer_ctor(ssb, buffer, length, buffer);
3015 if (mode & (OPENMODE_app|OPENMODE_ate))
3016 ssb->base.pptr = buffer + strlen(buffer);
3018 return ostrstream_internal_sb_ctor(this, ssb, virt_init);
3021 /* ??0ostrstream@@QAE@XZ */
3022 /* ??0ostrstream@@QEAA@XZ */
3023 DEFINE_THISCALL_WRAPPER(ostrstream_ctor, 8)
3024 ostream* __thiscall ostrstream_ctor(ostream *this, BOOL virt_init)
3026 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
3028 TRACE("(%p %d)\n", this, virt_init);
3030 if (ssb)
3031 strstreambuf_ctor(ssb);
3032 return ostrstream_internal_sb_ctor(this, ssb, virt_init);
3035 /* ?pcount@ostrstream@@QBEHXZ */
3036 /* ?pcount@ostrstream@@QEBAHXZ */
3037 DEFINE_THISCALL_WRAPPER(ostrstream_pcount, 4)
3038 int __thiscall ostrstream_pcount(const ostream *this)
3040 return streambuf_out_waiting(ostream_get_ios(this)->sb);
3043 /* ?rdbuf@ostrstream@@QBEPAVstrstreambuf@@XZ */
3044 /* ?rdbuf@ostrstream@@QEBAPEAVstrstreambuf@@XZ */
3045 DEFINE_THISCALL_WRAPPER(ostrstream_rdbuf, 4)
3046 strstreambuf* __thiscall ostrstream_rdbuf(const ostream *this)
3048 return (strstreambuf*) ostream_get_ios(this)->sb;
3051 /* ?str@ostrstream@@QAEPADXZ */
3052 /* ?str@ostrstream@@QEAAPEADXZ */
3053 DEFINE_THISCALL_WRAPPER(ostrstream_str, 4)
3054 char* __thiscall ostrstream_str(ostream *this)
3056 return strstreambuf_str(ostrstream_rdbuf(this));
3059 static inline ios* istream_get_ios(const istream *this)
3061 return (ios*)((char*)this + this->vbtable[1]);
3064 static inline ios* istream_to_ios(const istream *this)
3066 return (ios*)((char*)this + istream_vbtable[1]);
3069 static inline istream* ios_to_istream(const ios *base)
3071 return (istream*)((char*)base - istream_vbtable[1]);
3074 /* ??0istream@@IAE@XZ */
3075 /* ??0istream@@IEAA@XZ */
3076 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
3077 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
3079 ios *base;
3081 TRACE("(%p %d)\n", this, virt_init);
3083 if (virt_init) {
3084 this->vbtable = istream_vbtable;
3085 base = istream_get_ios(this);
3086 ios_ctor(base);
3087 } else
3088 base = istream_get_ios(this);
3089 base->vtable = &MSVCP_istream_vtable;
3090 base->flags |= FLAGS_skipws;
3091 this->extract_delim = 0;
3092 this->count = 0;
3093 return this;
3096 /* ??0istream@@QAE@PAVstreambuf@@@Z */
3097 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
3098 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
3099 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
3101 TRACE("(%p %p %d)\n", this, sb, virt_init);
3102 istream_ctor(this, virt_init);
3103 ios_init(istream_get_ios(this), sb);
3104 return this;
3107 /* ??0istream@@IAE@ABV0@@Z */
3108 /* ??0istream@@IEAA@AEBV0@@Z */
3109 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
3110 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3112 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
3115 /* ??1istream@@UAE@XZ */
3116 /* ??1istream@@UEAA@XZ */
3117 /* ??1istream_withassign@@UAE@XZ */
3118 /* ??1istream_withassign@@UEAA@XZ */
3119 /* ??1istrstream@@UAE@XZ */
3120 /* ??1istrstream@@UEAA@XZ */
3121 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
3122 void __thiscall istream_dtor(ios *base)
3124 istream *this = ios_to_istream(base);
3126 TRACE("(%p)\n", this);
3129 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
3130 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3131 /* ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z */
3132 /* ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z */
3133 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
3134 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
3136 ios *base = istream_get_ios(this);
3138 TRACE("(%p %p)\n", this, sb);
3140 ios_init(base, sb);
3141 base->state &= IOSTATE_badbit;
3142 base->delbuf = 0;
3143 base->tie = NULL;
3144 base->flags = FLAGS_skipws;
3145 base->precision = 6;
3146 base->fill = ' ';
3147 base->width = 0;
3148 this->count = 0;
3149 return this;
3152 /* ??4istream@@IAEAAV0@ABV0@@Z */
3153 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
3154 /* ??4istream_withassign@@QAEAAV0@ABV0@@Z */
3155 /* ??4istream_withassign@@QEAAAEAV0@AEBV0@@Z */
3156 /* ??4istream_withassign@@QAEAAVistream@@ABV1@@Z */
3157 /* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */
3158 /* ??4istrstream@@QAEAAV0@ABV0@@Z */
3159 /* ??4istrstream@@QEAAAEAV0@AEBV0@@Z */
3160 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
3161 istream* __thiscall istream_assign(istream *this, const istream *rhs)
3163 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
3166 /* ??_Distream@@QAEXXZ */
3167 /* ??_Distream@@QEAAXXZ */
3168 /* ??_Distream_withassign@@QAEXXZ */
3169 /* ??_Distream_withassign@@QEAAXXZ */
3170 /* ??_Distrstream@@QAEXXZ */
3171 /* ??_Distrstream@@QEAAXXZ */
3172 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
3173 void __thiscall istream_vbase_dtor(istream *this)
3175 ios *base = istream_to_ios(this);
3177 TRACE("(%p)\n", this);
3179 istream_dtor(base);
3180 ios_dtor(base);
3183 /* ??_Eistream@@UAEPAXI@Z */
3184 /* ??_Eistream_withassign@@UAEPAXI@Z */
3185 /* ??_Eistrstream@@UAEPAXI@Z */
3186 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
3187 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
3189 istream *this = ios_to_istream(base);
3191 TRACE("(%p %x)\n", this, flags);
3193 if (flags & 2) {
3194 /* we have an array, with the number of elements stored before the first object */
3195 INT_PTR i, *ptr = (INT_PTR *)this-1;
3197 for (i = *ptr-1; i >= 0; i--)
3198 istream_vbase_dtor(this+i);
3199 MSVCRT_operator_delete(ptr);
3200 } else {
3201 istream_vbase_dtor(this);
3202 if (flags & 1)
3203 MSVCRT_operator_delete(this);
3205 return this;
3208 /* ??_Gistream@@UAEPAXI@Z */
3209 /* ??_Gistream_withassign@@UAEPAXI@Z */
3210 /* ??_Gistrstream@@UAEPAXI@Z */
3211 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
3212 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
3214 istream *this = ios_to_istream(base);
3216 TRACE("(%p %x)\n", this, flags);
3218 istream_vbase_dtor(this);
3219 if (flags & 1) MSVCRT_operator_delete(this);
3220 return this;
3223 /* ?eatwhite@istream@@QAEXXZ */
3224 /* ?eatwhite@istream@@QEAAXXZ */
3225 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3226 void __thiscall istream_eatwhite(istream *this)
3228 ios *base = istream_get_ios(this);
3229 int c;
3231 TRACE("(%p)\n", this);
3233 ios_lockbuf(base);
3234 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3235 ios_unlockbuf(base);
3236 if (c == EOF)
3237 ios_clear(base, base->state | IOSTATE_eofbit);
3240 /* ?gcount@istream@@QBEHXZ */
3241 /* ?gcount@istream@@QEBAHXZ */
3242 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3243 int __thiscall istream_gcount(const istream *this)
3245 TRACE("(%p)\n", this);
3246 return this->count;
3249 /* ?ipfx@istream@@QAEHH@Z */
3250 /* ?ipfx@istream@@QEAAHH@Z */
3251 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3252 int __thiscall istream_ipfx(istream *this, int need)
3254 ios *base = istream_get_ios(this);
3256 TRACE("(%p %d)\n", this, need);
3258 if (need)
3259 this->count = 0;
3260 if (!ios_good(base)) {
3261 ios_clear(base, base->state | IOSTATE_failbit);
3262 return 0;
3264 ios_lock(base);
3265 ios_lockbuf(base);
3266 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3267 ostream_flush(base->tie);
3268 if ((base->flags & FLAGS_skipws) && !need) {
3269 istream_eatwhite(this);
3270 if (base->state & IOSTATE_eofbit) {
3271 base->state |= IOSTATE_failbit;
3272 ios_unlockbuf(base);
3273 ios_unlock(base);
3274 return 0;
3277 return 1;
3280 /* ?isfx@istream@@QAEXXZ */
3281 /* ?isfx@istream@@QEAAXXZ */
3282 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3283 void __thiscall istream_isfx(istream *this)
3285 ios *base = istream_get_ios(this);
3287 TRACE("(%p)\n", this);
3289 ios_unlockbuf(base);
3290 ios_unlock(base);
3293 /* ?get@istream@@IAEAAV1@PADHH@Z */
3294 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3295 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3296 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3298 ios *base = istream_get_ios(this);
3299 int ch, i = 0;
3301 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3303 if (istream_ipfx(this, 1)) {
3304 while (i < count - 1) {
3305 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3306 base->state |= IOSTATE_eofbit;
3307 if (!i) /* tried to read, but not a single character was obtained */
3308 base->state |= IOSTATE_failbit;
3309 break;
3311 if (ch == delim) {
3312 if (this->extract_delim) { /* discard the delimiter */
3313 streambuf_stossc(base->sb);
3314 this->count++;
3316 break;
3318 if (str)
3319 str[i] = ch;
3320 streambuf_stossc(base->sb);
3321 i++;
3323 this->count += i;
3324 istream_isfx(this);
3326 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3327 str[i] = 0;
3328 this->extract_delim = 0;
3329 return this;
3332 /* ?get@istream@@QAEAAV1@PACHD@Z */
3333 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3334 /* ?get@istream@@QAEAAV1@PADHD@Z */
3335 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3336 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3337 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3338 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3339 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3341 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3344 static int istream_internal_get_char(istream *this, char *ch)
3346 ios *base = istream_get_ios(this);
3347 int ret = EOF;
3349 TRACE("(%p %p)\n", this, ch);
3351 if (istream_ipfx(this, 1)) {
3352 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3353 this->count = 1;
3354 } else {
3355 base->state |= IOSTATE_eofbit;
3356 if (ch)
3357 base->state |= IOSTATE_failbit;
3359 if (ch)
3360 *ch = ret;
3361 istream_isfx(this);
3363 return ret;
3366 /* ?get@istream@@QAEAAV1@AAC@Z */
3367 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3368 /* ?get@istream@@QAEAAV1@AAD@Z */
3369 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3370 /* ?get@istream@@QAEAAV1@AAE@Z */
3371 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3372 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3373 istream* __thiscall istream_get_char(istream *this, char *ch)
3375 istream_internal_get_char(this, ch);
3376 return this;
3379 /* ?get@istream@@QAEHXZ */
3380 /* ?get@istream@@QEAAHXZ */
3381 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3382 int __thiscall istream_get(istream *this)
3384 return istream_internal_get_char(this, NULL);
3387 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3388 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3389 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3390 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3392 ios *base = istream_get_ios(this);
3393 int ch;
3395 TRACE("(%p %p %c)\n", this, sb, delim);
3397 if (istream_ipfx(this, 1)) {
3398 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3399 if (ch == EOF) {
3400 base->state |= IOSTATE_eofbit;
3401 break;
3403 if (streambuf_sputc(sb, ch) == EOF)
3404 base->state |= IOSTATE_failbit;
3405 this->count++;
3407 istream_isfx(this);
3409 return this;
3412 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3413 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3414 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3415 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3416 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3417 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3418 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3419 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3421 ios *base = istream_get_ios(this);
3423 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3425 ios_lock(base);
3426 this->extract_delim++;
3427 istream_get_str_delim(this, str, count, (unsigned char) delim);
3428 ios_unlock(base);
3429 return this;
3432 /* ?ignore@istream@@QAEAAV1@HH@Z */
3433 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3434 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3435 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3437 ios *base = istream_get_ios(this);
3439 TRACE("(%p %d %d)\n", this, count, delim);
3441 ios_lock(base);
3442 this->extract_delim++;
3443 istream_get_str_delim(this, NULL, count + 1, delim);
3444 ios_unlock(base);
3445 return this;
3448 /* ?peek@istream@@QAEHXZ */
3449 /* ?peek@istream@@QEAAHXZ */
3450 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3451 int __thiscall istream_peek(istream *this)
3453 ios *base = istream_get_ios(this);
3454 int ret = EOF;
3456 TRACE("(%p)\n", this);
3458 if (istream_ipfx(this, 1)) {
3459 ret = streambuf_sgetc(base->sb);
3460 istream_isfx(this);
3462 return ret;
3465 /* ?putback@istream@@QAEAAV1@D@Z */
3466 /* ?putback@istream@@QEAAAEAV1@D@Z */
3467 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3468 istream* __thiscall istream_putback(istream *this, char ch)
3470 ios *base = istream_get_ios(this);
3472 TRACE("(%p %c)\n", this, ch);
3474 if (ios_good(base)) {
3475 ios_lockbuf(base);
3476 if (streambuf_sputbackc(base->sb, ch) == EOF)
3477 ios_clear(base, base->state | IOSTATE_failbit);
3478 ios_unlockbuf(base);
3480 return this;
3483 /* ?read@istream@@QAEAAV1@PACH@Z */
3484 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3485 /* ?read@istream@@QAEAAV1@PADH@Z */
3486 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3487 /* ?read@istream@@QAEAAV1@PAEH@Z */
3488 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3489 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3490 istream* __thiscall istream_read(istream *this, char *str, int count)
3492 ios *base = istream_get_ios(this);
3494 TRACE("(%p %p %d)\n", this, str, count);
3496 if (istream_ipfx(this, 1)) {
3497 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3498 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3499 istream_isfx(this);
3501 return this;
3504 /* ?seekg@istream@@QAEAAV1@J@Z */
3505 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3506 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3507 istream* __thiscall istream_seekg(istream *this, streampos pos)
3509 ios *base = istream_get_ios(this);
3511 TRACE("(%p %d)\n", this, pos);
3513 ios_lockbuf(base);
3514 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3515 ios_clear(base, base->state | IOSTATE_failbit);
3516 ios_unlockbuf(base);
3517 return this;
3520 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3521 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3522 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3523 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3525 ios *base = istream_get_ios(this);
3527 TRACE("(%p %d %d)\n", this, off, dir);
3529 ios_lockbuf(base);
3530 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3531 ios_clear(base, base->state | IOSTATE_failbit);
3532 ios_unlockbuf(base);
3533 return this;
3536 /* ?sync@istream@@QAEHXZ */
3537 /* ?sync@istream@@QEAAHXZ */
3538 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3539 int __thiscall istream_sync(istream *this)
3541 ios *base = istream_get_ios(this);
3542 int ret;
3544 TRACE("(%p)\n", this);
3546 ios_lockbuf(base);
3547 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3548 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3549 ios_unlockbuf(base);
3550 return ret;
3553 /* ?tellg@istream@@QAEJXZ */
3554 /* ?tellg@istream@@QEAAJXZ */
3555 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3556 streampos __thiscall istream_tellg(istream *this)
3558 ios *base = istream_get_ios(this);
3559 streampos pos;
3561 TRACE("(%p)\n", this);
3563 ios_lockbuf(base);
3564 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3565 ios_clear(base, base->state | IOSTATE_failbit);
3566 ios_unlockbuf(base);
3567 return pos;
3570 static int getint_is_valid_digit(char ch, int base)
3572 if (base == 8) return (ch >= '0' && ch <= '7');
3573 if (base == 16) return isxdigit(ch);
3574 return isdigit(ch);
3577 /* ?getint@istream@@AAEHPAD@Z */
3578 /* ?getint@istream@@AEAAHPEAD@Z */
3579 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3580 int __thiscall istream_getint(istream *this, char *str)
3582 ios *base = istream_get_ios(this);
3583 int ch, num_base = 0, i = 0;
3584 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3586 TRACE("(%p %p)\n", this, str);
3588 if (istream_ipfx(this, 0)) {
3589 num_base = (base->flags & FLAGS_dec) ? 10 :
3590 (base->flags & FLAGS_hex) ? 16 :
3591 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3592 /* scan valid characters, up to 15 (hard limit on Windows) */
3593 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3594 if ((ch == '+' || ch == '-') && scan_sign) {
3595 /* no additional sign allowed */
3596 scan_sign = FALSE;
3597 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3598 /* only hex digits can (and must) follow */
3599 scan_x = valid_integer = FALSE;
3600 num_base = 16;
3601 } else if (ch == '0' && scan_prefix) {
3602 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3603 scan_sign = scan_prefix = FALSE;
3604 scan_x = !num_base || num_base == 16;
3605 valid_integer = TRUE;
3606 if (!num_base)
3607 num_base = 8;
3608 } else if (getint_is_valid_digit(ch, num_base)) {
3609 /* only digits in the corresponding base can follow */
3610 scan_sign = scan_prefix = scan_x = FALSE;
3611 valid_integer = TRUE;
3612 } else {
3613 /* unexpected character, stop scanning */
3614 if (!valid_integer) {
3615 /* the result is not a valid integer */
3616 base->state |= IOSTATE_failbit;
3617 /* put any extracted character back into the stream */
3618 while (i > 0)
3619 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3620 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3621 } else if (ch == EOF) {
3622 base->state |= IOSTATE_eofbit;
3623 if (scan_x && !(base->flags & ios_basefield)) {
3624 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3625 num_base = 0;
3628 break;
3630 str[i++] = ch;
3632 /* append a null terminator */
3633 str[i] = 0;
3634 istream_isfx(this);
3636 return num_base;
3639 /* ?getdouble@istream@@AAEHPADH@Z */
3640 /* ?getdouble@istream@@AEAAHPEADH@Z */
3641 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3642 int __thiscall istream_getdouble(istream *this, char *str, int count)
3644 ios *base = istream_get_ios(this);
3645 int ch, i = 0;
3646 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3647 valid_mantissa = FALSE, valid_exponent = FALSE;
3649 TRACE("(%p %p %d)\n", this, str, count);
3651 if (istream_ipfx(this, 0)) {
3652 if (!count) {
3653 /* can't output anything */
3654 base->state |= IOSTATE_failbit;
3655 i = -1;
3656 } else {
3657 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3658 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3659 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3660 if ((ch == '+' || ch == '-') && scan_sign) {
3661 /* no additional sign allowed */
3662 scan_sign = FALSE;
3663 } else if (ch == '.' && scan_dot) {
3664 /* no sign or additional dot allowed */
3665 scan_sign = scan_dot = FALSE;
3666 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3667 /* sign is allowed again but not dots or exponents */
3668 scan_sign = TRUE;
3669 scan_dot = scan_exp = FALSE;
3670 } else if (isdigit(ch)) {
3671 if (scan_exp)
3672 valid_mantissa = TRUE;
3673 else
3674 valid_exponent = TRUE;
3675 /* no sign allowed after a digit */
3676 scan_sign = FALSE;
3677 } else {
3678 /* unexpected character, stop scanning */
3679 /* check whether the result is a valid double */
3680 if (!scan_exp && !valid_exponent) {
3681 /* put the last character back into the stream, usually the 'e' or 'E' */
3682 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3683 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3684 } else if (ch == EOF)
3685 base->state |= IOSTATE_eofbit;
3686 if (!valid_mantissa)
3687 base->state |= IOSTATE_failbit;
3688 break;
3690 str[i++] = ch;
3692 /* check if character limit has been reached */
3693 if (i == count) {
3694 base->state |= IOSTATE_failbit;
3695 i--;
3697 /* append a null terminator */
3698 str[i] = 0;
3700 istream_isfx(this);
3702 return i;
3705 /* ??5istream@@QAEAAV0@AAC@Z */
3706 /* ??5istream@@QEAAAEAV0@AEAC@Z */
3707 /* ??5istream@@QAEAAV0@AAD@Z */
3708 /* ??5istream@@QEAAAEAV0@AEAD@Z */
3709 /* ??5istream@@QAEAAV0@AAE@Z */
3710 /* ??5istream@@QEAAAEAV0@AEAE@Z */
3711 DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
3712 istream* __thiscall istream_read_char(istream *this, char *ch)
3714 ios *base = istream_get_ios(this);
3715 int ret;
3717 TRACE("(%p %p)\n", this, ch);
3719 if (istream_ipfx(this, 0)) {
3720 if ((ret = streambuf_sbumpc(base->sb)) == EOF)
3721 base->state |= IOSTATE_eofbit | IOSTATE_failbit;
3722 else
3723 *ch = ret;
3724 istream_isfx(this);
3726 return this;
3729 /* ??5istream@@QAEAAV0@PAC@Z */
3730 /* ??5istream@@QEAAAEAV0@PEAC@Z */
3731 /* ??5istream@@QAEAAV0@PAD@Z */
3732 /* ??5istream@@QEAAAEAV0@PEAD@Z */
3733 /* ??5istream@@QAEAAV0@PAE@Z */
3734 /* ??5istream@@QEAAAEAV0@PEAE@Z */
3735 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
3736 istream* __thiscall istream_read_str(istream *this, char *str)
3738 ios *base = istream_get_ios(this);
3739 int ch, count = 0;
3741 TRACE("(%p %p)\n", this, str);
3743 if (istream_ipfx(this, 0)) {
3744 if (str) {
3745 for (ch = streambuf_sgetc(base->sb);
3746 count < (unsigned int) base->width - 1 && !isspace(ch);
3747 ch = streambuf_snextc(base->sb)) {
3748 if (ch == EOF) {
3749 base->state |= IOSTATE_eofbit;
3750 break;
3752 str[count++] = ch;
3755 if (!count) /* nothing to output */
3756 base->state |= IOSTATE_failbit;
3757 else /* append a null terminator */
3758 str[count] = 0;
3759 base->width = 0;
3760 istream_isfx(this);
3762 return this;
3765 static LONG istream_internal_read_integer(istream *this, LONG min_value, LONG max_value, BOOL set_flag)
3767 ios *base = istream_get_ios(this);
3768 char buffer[16];
3769 int num_base;
3770 LONG ret;
3772 TRACE("(%p %d %d %d)\n", this, min_value, max_value, set_flag);
3774 num_base = istream_getint(this, buffer);
3775 errno = 0;
3776 ret = strtol(buffer, NULL, num_base);
3777 /* check for overflow and whether the value fits in the output var */
3778 if (set_flag && errno == ERANGE) {
3779 base->state |= IOSTATE_failbit;
3780 } else if (ret > max_value) {
3781 base->state |= IOSTATE_failbit;
3782 ret = max_value;
3783 } else if (ret < min_value) {
3784 base->state |= IOSTATE_failbit;
3785 ret = min_value;
3787 return ret;
3790 static ULONG istream_internal_read_unsigned_integer(istream *this, LONG min_value, ULONG max_value)
3792 ios *base = istream_get_ios(this);
3793 char buffer[16];
3794 int num_base;
3795 ULONG ret;
3797 TRACE("(%p %d %u)\n", this, min_value, max_value);
3799 num_base = istream_getint(this, buffer);
3800 errno = 0;
3801 ret = strtoul(buffer, NULL, num_base);
3802 /* check for overflow and whether the value fits in the output var */
3803 if ((ret == ULONG_MAX && errno == ERANGE) ||
3804 (ret > max_value && ret < (ULONG) min_value)) {
3805 base->state |= IOSTATE_failbit;
3806 ret = max_value;
3808 return ret;
3811 /* ??5istream@@QAEAAV0@AAF@Z */
3812 /* ??5istream@@QEAAAEAV0@AEAF@Z */
3813 DEFINE_THISCALL_WRAPPER(istream_read_short, 8)
3814 istream* __thiscall istream_read_short(istream *this, short *p)
3816 if (istream_ipfx(this, 0)) {
3817 *p = istream_internal_read_integer(this, SHRT_MIN, SHRT_MAX, FALSE);
3818 istream_isfx(this);
3820 return this;
3823 /* ??5istream@@QAEAAV0@AAG@Z */
3824 /* ??5istream@@QEAAAEAV0@AEAG@Z */
3825 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_short, 8)
3826 istream* __thiscall istream_read_unsigned_short(istream *this, unsigned short *p)
3828 if (istream_ipfx(this, 0)) {
3829 *p = istream_internal_read_unsigned_integer(this, SHRT_MIN, USHRT_MAX);
3830 istream_isfx(this);
3832 return this;
3835 /* ??5istream@@QAEAAV0@AAH@Z */
3836 /* ??5istream@@QEAAAEAV0@AEAH@Z */
3837 DEFINE_THISCALL_WRAPPER(istream_read_int, 8)
3838 istream* __thiscall istream_read_int(istream *this, int *p)
3840 if (istream_ipfx(this, 0)) {
3841 *p = istream_internal_read_integer(this, INT_MIN, INT_MAX, FALSE);
3842 istream_isfx(this);
3844 return this;
3847 /* ??5istream@@QAEAAV0@AAI@Z */
3848 /* ??5istream@@QEAAAEAV0@AEAI@Z */
3849 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_int, 8)
3850 istream* __thiscall istream_read_unsigned_int(istream *this, unsigned int *p)
3852 if (istream_ipfx(this, 0)) {
3853 *p = istream_internal_read_unsigned_integer(this, INT_MIN, UINT_MAX);
3854 istream_isfx(this);
3856 return this;
3859 /* ??5istream@@QAEAAV0@AAJ@Z */
3860 /* ??5istream@@QEAAAEAV0@AEAJ@Z */
3861 DEFINE_THISCALL_WRAPPER(istream_read_long, 8)
3862 istream* __thiscall istream_read_long(istream *this, LONG *p)
3864 if (istream_ipfx(this, 0)) {
3865 *p = istream_internal_read_integer(this, LONG_MIN, LONG_MAX, TRUE);
3866 istream_isfx(this);
3868 return this;
3871 /* ??5istream@@QAEAAV0@AAK@Z */
3872 /* ??5istream@@QEAAAEAV0@AEAK@Z */
3873 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_long, 8)
3874 istream* __thiscall istream_read_unsigned_long(istream *this, ULONG *p)
3876 if (istream_ipfx(this, 0)) {
3877 *p = istream_internal_read_unsigned_integer(this, LONG_MIN, ULONG_MAX);
3878 istream_isfx(this);
3880 return this;
3883 static BOOL istream_internal_read_float(istream *this, int max_chars, double *out)
3885 char buffer[32];
3886 BOOL read = FALSE;
3888 TRACE("(%p %d %p)\n", this, max_chars, out);
3890 if (istream_ipfx(this, 0)) {
3891 /* character count is limited on Windows */
3892 if (istream_getdouble(this, buffer, max_chars) > 0) {
3893 *out = strtod(buffer, NULL);
3894 read = TRUE;
3896 istream_isfx(this);
3898 return read;
3901 /* ??5istream@@QAEAAV0@AAM@Z */
3902 /* ??5istream@@QEAAAEAV0@AEAM@Z */
3903 DEFINE_THISCALL_WRAPPER(istream_read_float, 8)
3904 istream* __thiscall istream_read_float(istream *this, float *f)
3906 double tmp;
3907 if (istream_internal_read_float(this, 20, &tmp)) {
3908 /* check whether the value fits in the output var */
3909 if (tmp > FLT_MAX)
3910 tmp = FLT_MAX;
3911 else if (tmp < -FLT_MAX)
3912 tmp = -FLT_MAX;
3913 else if (tmp > 0 && tmp < FLT_MIN)
3914 tmp = FLT_MIN;
3915 else if (tmp < 0 && tmp > -FLT_MIN)
3916 tmp = -FLT_MIN;
3917 *f = tmp;
3919 return this;
3922 /* ??5istream@@QAEAAV0@AAN@Z */
3923 /* ??5istream@@QEAAAEAV0@AEAN@Z */
3924 DEFINE_THISCALL_WRAPPER(istream_read_double, 8)
3925 istream* __thiscall istream_read_double(istream *this, double *d)
3927 istream_internal_read_float(this, 28, d);
3928 return this;
3931 /* ??5istream@@QAEAAV0@AAO@Z */
3932 /* ??5istream@@QEAAAEAV0@AEAO@Z */
3933 DEFINE_THISCALL_WRAPPER(istream_read_long_double, 8)
3934 istream* __thiscall istream_read_long_double(istream *this, double *ld)
3936 istream_internal_read_float(this, 32, ld);
3937 return this;
3940 /* ??5istream@@QAEAAV0@PAVstreambuf@@@Z */
3941 /* ??5istream@@QEAAAEAV0@PEAVstreambuf@@@Z */
3942 DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
3943 istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
3945 ios *base = istream_get_ios(this);
3946 int ch;
3948 TRACE("(%p %p)\n", this, sb);
3950 if (istream_ipfx(this, 0)) {
3951 while ((ch = streambuf_sbumpc(base->sb)) != EOF)
3952 if (streambuf_sputc(sb, ch) == EOF)
3953 base->state |= IOSTATE_failbit;
3954 istream_isfx(this);
3956 return this;
3959 /* ??5istream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
3960 /* ??5istream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
3961 DEFINE_THISCALL_WRAPPER(istream_read_manip, 8)
3962 istream* __thiscall istream_read_manip(istream *this, istream* (__cdecl *func)(istream*))
3964 TRACE("(%p %p)\n", this, func);
3965 return func(this);
3968 /* ??5istream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
3969 /* ??5istream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
3970 DEFINE_THISCALL_WRAPPER(istream_read_ios_manip, 8)
3971 istream* __thiscall istream_read_ios_manip(istream *this, ios* (__cdecl *func)(ios*))
3973 TRACE("(%p %p)\n", this, func);
3974 func(istream_get_ios(this));
3975 return this;
3978 /* ?ws@@YAAAVistream@@AAV1@@Z */
3979 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
3980 istream* __cdecl istream_ws(istream *this)
3982 TRACE("(%p)\n", this);
3983 istream_eatwhite(this);
3984 return this;
3987 /* ??0istream_withassign@@QAE@ABV0@@Z */
3988 /* ??0istream_withassign@@QEAA@AEBV0@@Z */
3989 DEFINE_THISCALL_WRAPPER(istream_withassign_copy_ctor, 12)
3990 istream* __thiscall istream_withassign_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3992 ios *base, *base_copy;
3994 TRACE("(%p %p %d)\n", this, copy, virt_init);
3996 base_copy = istream_get_ios(copy);
3997 if (virt_init) {
3998 this->vbtable = istream_vbtable;
3999 base = istream_get_ios(this);
4000 ios_copy_ctor(base, base_copy);
4001 } else
4002 base = istream_get_ios(this);
4003 ios_init(base, base_copy->sb);
4004 base->vtable = &MSVCP_istream_withassign_vtable;
4005 base->flags |= FLAGS_skipws;
4006 this->extract_delim = 0;
4007 this->count = 0;
4008 return this;
4011 /* ??0istream_withassign@@QAE@PAVstreambuf@@@Z */
4012 /* ??0istream_withassign@@QEAA@PEAVstreambuf@@@Z */
4013 DEFINE_THISCALL_WRAPPER(istream_withassign_sb_ctor, 12)
4014 istream* __thiscall istream_withassign_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
4016 ios *base;
4018 TRACE("(%p %p %d)\n", this, sb, virt_init);
4020 istream_sb_ctor(this, sb, virt_init);
4021 base = istream_get_ios(this);
4022 base->vtable = &MSVCP_istream_withassign_vtable;
4023 return this;
4026 /* ??0istream_withassign@@QAE@XZ */
4027 /* ??0istream_withassign@@QEAA@XZ */
4028 DEFINE_THISCALL_WRAPPER(istream_withassign_ctor, 8)
4029 istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init)
4031 ios *base;
4033 TRACE("(%p %d)\n", this, virt_init);
4035 istream_ctor(this, virt_init);
4036 base = istream_get_ios(this);
4037 base->vtable = &MSVCP_istream_withassign_vtable;
4038 return this;
4041 /* ??0istrstream@@QAE@ABV0@@Z */
4042 /* ??0istrstream@@QEAA@AEBV0@@Z */
4043 DEFINE_THISCALL_WRAPPER(istrstream_copy_ctor, 12)
4044 istream* __thiscall istrstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
4046 TRACE("(%p %p %d)\n", this, copy, virt_init);
4047 istream_withassign_copy_ctor(this, copy, virt_init);
4048 istream_get_ios(this)->vtable = &MSVCP_istrstream_vtable;
4049 return this;
4052 /* ??0istrstream@@QAE@PADH@Z */
4053 /* ??0istrstream@@QEAA@PEADH@Z */
4054 DEFINE_THISCALL_WRAPPER(istrstream_buffer_ctor, 16)
4055 istream* __thiscall istrstream_buffer_ctor(istream *this, char *buffer, int length, BOOL virt_init)
4057 ios *base;
4058 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
4060 TRACE("(%p %p %d %d)\n", this, buffer, length, virt_init);
4062 if (ssb) {
4063 strstreambuf_buffer_ctor(ssb, buffer, length, NULL);
4064 istream_sb_ctor(this, &ssb->base, virt_init);
4065 } else
4066 istream_ctor(this, virt_init);
4067 base = istream_get_ios(this);
4068 base->vtable = &MSVCP_istrstream_vtable;
4069 base->delbuf = 1;
4070 return this;
4073 /* ??0istrstream@@QAE@PAD@Z */
4074 /* ??0istrstream@@QEAA@PEAD@Z */
4075 DEFINE_THISCALL_WRAPPER(istrstream_str_ctor, 12)
4076 istream* __thiscall istrstream_str_ctor(istream *this, char *str, BOOL virt_init)
4078 return istrstream_buffer_ctor(this, str, 0, virt_init);
4081 /* ?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ */
4082 /* ?rdbuf@istrstream@@QEBAPEAVstrstreambuf@@XZ */
4083 DEFINE_THISCALL_WRAPPER(istrstream_rdbuf, 4)
4084 strstreambuf* __thiscall istrstream_rdbuf(const istream *this)
4086 return (strstreambuf*) istream_get_ios(this)->sb;
4089 /* ?str@istrstream@@QAEPADXZ */
4090 /* ?str@istrstream@@QEAAPEADXZ */
4091 DEFINE_THISCALL_WRAPPER(istrstream_str, 4)
4092 char* __thiscall istrstream_str(istream *this)
4094 return strstreambuf_str(istrstream_rdbuf(this));
4097 static inline ios* iostream_to_ios(const iostream *this)
4099 return (ios*)((char*)this + iostream_vbtable_istream[1]);
4102 static inline iostream* ios_to_iostream(const ios *base)
4104 return (iostream*)((char*)base - iostream_vbtable_istream[1]);
4107 /* ??0iostream@@IAE@XZ */
4108 /* ??0iostream@@IEAA@XZ */
4109 DEFINE_THISCALL_WRAPPER(iostream_ctor, 8)
4110 iostream* __thiscall iostream_ctor(iostream *this, BOOL virt_init)
4112 ios *base;
4114 TRACE("(%p %d)\n", this, virt_init);
4116 if (virt_init) {
4117 this->base1.vbtable = iostream_vbtable_istream;
4118 this->base2.vbtable = iostream_vbtable_ostream;
4119 base = istream_get_ios(&this->base1);
4120 ios_ctor(base);
4121 } else
4122 base = istream_get_ios(&this->base1);
4123 istream_ctor(&this->base1, FALSE);
4124 ostream_ctor(&this->base2, FALSE);
4125 base->vtable = &MSVCP_iostream_vtable;
4126 return this;
4129 /* ??0iostream@@QAE@PAVstreambuf@@@Z */
4130 /* ??0iostream@@QEAA@PEAVstreambuf@@@Z */
4131 DEFINE_THISCALL_WRAPPER(iostream_sb_ctor, 12)
4132 iostream* __thiscall iostream_sb_ctor(iostream *this, streambuf *sb, BOOL virt_init)
4134 TRACE("(%p %p %d)\n", this, sb, virt_init);
4135 iostream_ctor(this, virt_init);
4136 ios_init(istream_get_ios(&this->base1), sb);
4137 return this;
4140 /* ??0iostream@@IAE@ABV0@@Z */
4141 /* ??0iostream@@IEAA@AEBV0@@Z */
4142 DEFINE_THISCALL_WRAPPER(iostream_copy_ctor, 12)
4143 iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4145 return iostream_sb_ctor(this, istream_get_ios(&copy->base1)->sb, virt_init);
4148 /* ??1iostream@@UAE@XZ */
4149 /* ??1iostream@@UEAA@XZ */
4150 /* ??1stdiostream@@UAE@XZ */
4151 /* ??1stdiostream@@UEAA@XZ */
4152 /* ??1strstream@@UAE@XZ */
4153 /* ??1strstream@@UEAA@XZ */
4154 DEFINE_THISCALL_WRAPPER(iostream_dtor, 4)
4155 void __thiscall iostream_dtor(ios *base)
4157 iostream *this = ios_to_iostream(base);
4159 TRACE("(%p)\n", this);
4161 ostream_dtor(ostream_to_ios(&this->base2));
4162 istream_dtor(istream_to_ios(&this->base1));
4165 /* ??4iostream@@IAEAAV0@PAVstreambuf@@@Z */
4166 /* ??4iostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
4167 DEFINE_THISCALL_WRAPPER(iostream_assign_sb, 8)
4168 iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb)
4170 TRACE("(%p %p)\n", this, sb);
4171 this->base1.count = 0;
4172 ostream_assign_sb(&this->base2, sb);
4173 return this;
4176 /* ??4iostream@@IAEAAV0@AAV0@@Z */
4177 /* ??4iostream@@IEAAAEAV0@AEAV0@@Z */
4178 /* ??4stdiostream@@QAEAAV0@AAV0@@Z */
4179 /* ??4stdiostream@@QEAAAEAV0@AEAV0@@Z */
4180 /* ??4strstream@@QAEAAV0@ABV0@@Z */
4181 /* ??4strstream@@QEAAAEAV0@AEBV0@@Z */
4182 DEFINE_THISCALL_WRAPPER(iostream_assign, 8)
4183 iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs)
4185 return iostream_assign_sb(this, istream_get_ios(&rhs->base1)->sb);
4188 /* ??_Diostream@@QAEXXZ */
4189 /* ??_Diostream@@QEAAXXZ */
4190 /* ??_Dstdiostream@@QAEXXZ */
4191 /* ??_Dstdiostream@@QEAAXXZ */
4192 /* ??_Dstrstream@@QAEXXZ */
4193 /* ??_Dstrstream@@QEAAXXZ */
4194 DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4)
4195 void __thiscall iostream_vbase_dtor(iostream *this)
4197 ios *base = iostream_to_ios(this);
4199 TRACE("(%p)\n", this);
4201 iostream_dtor(base);
4202 ios_dtor(base);
4205 /* ??_Eiostream@@UAEPAXI@Z */
4206 /* ??_Estdiostream@@UAEPAXI@Z */
4207 /* ??_Estrstream@@UAEPAXI@Z */
4208 DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8)
4209 iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags)
4211 iostream *this = ios_to_iostream(base);
4213 TRACE("(%p %x)\n", this, flags);
4215 if (flags & 2) {
4216 /* we have an array, with the number of elements stored before the first object */
4217 INT_PTR i, *ptr = (INT_PTR *)this-1;
4219 for (i = *ptr-1; i >= 0; i--)
4220 iostream_vbase_dtor(this+i);
4221 MSVCRT_operator_delete(ptr);
4222 } else {
4223 iostream_vbase_dtor(this);
4224 if (flags & 1)
4225 MSVCRT_operator_delete(this);
4227 return this;
4230 /* ??_Giostream@@UAEPAXI@Z */
4231 /* ??_Gstdiostream@@UAEPAXI@Z */
4232 /* ??_Gstrstream@@UAEPAXI@Z */
4233 DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8)
4234 iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags)
4236 iostream *this = ios_to_iostream(base);
4238 TRACE("(%p %x)\n", this, flags);
4240 iostream_vbase_dtor(this);
4241 if (flags & 1) MSVCRT_operator_delete(this);
4242 return this;
4245 static iostream* iostream_internal_copy_ctor(iostream *this, const iostream *copy, const vtable_ptr *vtbl, BOOL virt_init)
4247 ios *base, *base_copy = istream_get_ios(&copy->base1);
4249 if (virt_init) {
4250 this->base1.vbtable = iostream_vbtable_istream;
4251 this->base2.vbtable = iostream_vbtable_ostream;
4252 base = istream_get_ios(&this->base1);
4253 ios_copy_ctor(base, base_copy);
4254 } else
4255 base = istream_get_ios(&this->base1);
4256 ios_init(base, base_copy->sb);
4257 istream_ctor(&this->base1, FALSE);
4258 ostream_ctor(&this->base2, FALSE);
4259 base->vtable = vtbl;
4260 return this;
4263 static iostream* iostream_internal_sb_ctor(iostream *this, streambuf *sb, const vtable_ptr *vtbl, BOOL virt_init)
4265 ios *base;
4267 iostream_ctor(this, virt_init);
4268 base = istream_get_ios(&this->base1);
4269 if (sb)
4270 ios_init(base, sb);
4271 base->vtable = vtbl;
4272 base->delbuf = 1;
4273 return this;
4276 /* ??0strstream@@QAE@ABV0@@Z */
4277 /* ??0strstream@@QEAA@AEBV0@@Z */
4278 DEFINE_THISCALL_WRAPPER(strstream_copy_ctor, 12)
4279 iostream* __thiscall strstream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4281 TRACE("(%p %p %d)\n", this, copy, virt_init);
4282 return iostream_internal_copy_ctor(this, copy, &MSVCP_strstream_vtable, virt_init);
4285 /* ??0strstream@@QAE@PADHH@Z */
4286 /* ??0strstream@@QEAA@PEADHH@Z */
4287 DEFINE_THISCALL_WRAPPER(strstream_buffer_ctor, 20)
4288 iostream* __thiscall strstream_buffer_ctor(iostream *this, char *buffer, int length, int mode, BOOL virt_init)
4290 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
4292 TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init);
4294 if (ssb) {
4295 strstreambuf_buffer_ctor(ssb, buffer, length, buffer);
4296 if ((mode & OPENMODE_out) && (mode & (OPENMODE_app|OPENMODE_ate)))
4297 ssb->base.pptr = buffer + strlen(buffer);
4298 return iostream_internal_sb_ctor(this, &ssb->base, &MSVCP_strstream_vtable, virt_init);
4300 return iostream_internal_sb_ctor(this, NULL, &MSVCP_strstream_vtable, virt_init);
4303 /* ??0strstream@@QAE@XZ */
4304 /* ??0strstream@@QEAA@XZ */
4305 DEFINE_THISCALL_WRAPPER(strstream_ctor, 8)
4306 iostream* __thiscall strstream_ctor(iostream *this, BOOL virt_init)
4308 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
4310 TRACE("(%p %d)\n", this, virt_init);
4312 if (ssb) {
4313 strstreambuf_ctor(ssb);
4314 return iostream_internal_sb_ctor(this, &ssb->base, &MSVCP_strstream_vtable, virt_init);
4316 return iostream_internal_sb_ctor(this, NULL, &MSVCP_strstream_vtable, virt_init);
4319 /* ?pcount@strstream@@QBEHXZ */
4320 /* ?pcount@strstream@@QEBAHXZ */
4321 DEFINE_THISCALL_WRAPPER(strstream_pcount, 4)
4322 int __thiscall strstream_pcount(const iostream *this)
4324 return streambuf_out_waiting(istream_get_ios(&this->base1)->sb);
4327 /* ?rdbuf@strstream@@QBEPAVstrstreambuf@@XZ */
4328 /* ?rdbuf@strstream@@QEBAPEAVstrstreambuf@@XZ */
4329 DEFINE_THISCALL_WRAPPER(strstream_rdbuf, 4)
4330 strstreambuf* __thiscall strstream_rdbuf(const iostream *this)
4332 return (strstreambuf*) istream_get_ios(&this->base1)->sb;
4335 /* ?str@strstream@@QAEPADXZ */
4336 /* ?str@strstream@@QEAAPEADXZ */
4337 DEFINE_THISCALL_WRAPPER(strstream_str, 4)
4338 char* __thiscall strstream_str(iostream *this)
4340 return strstreambuf_str(strstream_rdbuf(this));
4343 /* ??0stdiostream@@QAE@ABV0@@Z */
4344 /* ??0stdiostream@@QEAA@AEBV0@@Z */
4345 DEFINE_THISCALL_WRAPPER(stdiostream_copy_ctor, 12)
4346 iostream* __thiscall stdiostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4348 TRACE("(%p %p %d)\n", this, copy, virt_init);
4349 return iostream_internal_copy_ctor(this, copy, &MSVCP_stdiostream_vtable, virt_init);
4352 /* ??0stdiostream@@QAE@PAU_iobuf@@@Z */
4353 /* ??0stdiostream@@QEAA@PEAU_iobuf@@@Z */
4354 DEFINE_THISCALL_WRAPPER(stdiostream_file_ctor, 12)
4355 iostream* __thiscall stdiostream_file_ctor(iostream *this, FILE *file, BOOL virt_init)
4357 stdiobuf *stb = MSVCRT_operator_new(sizeof(stdiobuf));
4359 TRACE("(%p %p %d)\n", this, file, virt_init);
4361 if (stb) {
4362 stdiobuf_file_ctor(stb, file);
4363 return iostream_internal_sb_ctor(this, &stb->base, &MSVCP_stdiostream_vtable, virt_init);
4365 return iostream_internal_sb_ctor(this, NULL, &MSVCP_stdiostream_vtable, virt_init);
4368 /* ?rdbuf@stdiostream@@QBEPAVstdiobuf@@XZ */
4369 /* ?rdbuf@stdiostream@@QEBAPEAVstdiobuf@@XZ */
4370 DEFINE_THISCALL_WRAPPER(stdiostream_rdbuf, 4)
4371 stdiobuf* __thiscall stdiostream_rdbuf(const iostream *this)
4373 return (stdiobuf*) istream_get_ios(&this->base1)->sb;
4376 /* ??0Iostream_init@@QAE@AAVios@@H@Z */
4377 /* ??0Iostream_init@@QEAA@AEAVios@@H@Z */
4378 DEFINE_THISCALL_WRAPPER(Iostream_init_ios_ctor, 12)
4379 void* __thiscall Iostream_init_ios_ctor(void *this, ios *obj, int n)
4381 TRACE("(%p %p %d)\n", this, obj, n);
4382 obj->delbuf = 1;
4383 if (n >= 0) {
4384 obj->tie = &cout.os;
4385 if (n > 0)
4386 ios_setf(obj, FLAGS_unitbuf);
4388 return this;
4391 /* ??0Iostream_init@@QAE@XZ */
4392 /* ??0Iostream_init@@QEAA@XZ */
4393 DEFINE_THISCALL_WRAPPER(Iostream_init_ctor, 4)
4394 void* __thiscall Iostream_init_ctor(void *this)
4396 TRACE("(%p)\n", this);
4397 return this;
4400 /* ??1Iostream_init@@QAE@XZ */
4401 /* ??1Iostream_init@@QEAA@XZ */
4402 DEFINE_THISCALL_WRAPPER(Iostream_init_dtor, 4)
4403 void __thiscall Iostream_init_dtor(void *this)
4405 TRACE("(%p)\n", this);
4408 /* ??4Iostream_init@@QAEAAV0@ABV0@@Z */
4409 /* ??4Iostream_init@@QEAAAEAV0@AEBV0@@Z */
4410 DEFINE_THISCALL_WRAPPER(Iostream_init_assign, 8)
4411 void* __thiscall Iostream_init_assign(void *this, const void *rhs)
4413 TRACE("(%p %p)\n", this, rhs);
4414 return this;
4417 /* ?sync_with_stdio@ios@@SAXXZ */
4418 void __cdecl ios_sync_with_stdio(void)
4420 if (!ios_sunk_with_stdio) {
4421 stdiobuf *new_buf;
4423 TRACE("()\n");
4425 /* run at most once */
4426 ios_sunk_with_stdio++;
4428 /* calls to [io]stream_assign_sb automatically destroy the old buffers */
4429 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4430 stdiobuf_file_ctor(new_buf, stdin);
4431 istream_assign_sb(&cin.is, &new_buf->base);
4432 } else
4433 istream_assign_sb(&cin.is, NULL);
4434 cin.vbase.delbuf = 1;
4435 ios_setf(&cin.vbase, FLAGS_stdio);
4437 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4438 stdiobuf_file_ctor(new_buf, stdout);
4439 stdiobuf_setrwbuf(new_buf, 0, 80);
4440 ostream_assign_sb(&cout.os, &new_buf->base);
4441 } else
4442 ostream_assign_sb(&cout.os, NULL);
4443 cout.vbase.delbuf = 1;
4444 ios_setf(&cout.vbase, FLAGS_unitbuf | FLAGS_stdio);
4446 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4447 stdiobuf_file_ctor(new_buf, stderr);
4448 stdiobuf_setrwbuf(new_buf, 0, 80);
4449 ostream_assign_sb(&cerr.os, &new_buf->base);
4450 } else
4451 ostream_assign_sb(&cerr.os, NULL);
4452 cerr.vbase.delbuf = 1;
4453 ios_setf(&cerr.vbase, FLAGS_unitbuf | FLAGS_stdio);
4455 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4456 stdiobuf_file_ctor(new_buf, stderr);
4457 stdiobuf_setrwbuf(new_buf, 0, 512);
4458 ostream_assign_sb(&clog.os, &new_buf->base);
4459 } else
4460 ostream_assign_sb(&clog.os, NULL);
4461 clog.vbase.delbuf = 1;
4462 ios_setf(&clog.vbase, FLAGS_stdio);
4467 #ifdef __i386__
4469 #define DEFINE_VTBL_WRAPPER(off) \
4470 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
4471 "popl %eax\n\t" \
4472 "popl %ecx\n\t" \
4473 "pushl %eax\n\t" \
4474 "movl 0(%ecx), %eax\n\t" \
4475 "jmp *" #off "(%eax)\n\t")
4477 DEFINE_VTBL_WRAPPER(0);
4478 DEFINE_VTBL_WRAPPER(4);
4479 DEFINE_VTBL_WRAPPER(8);
4480 DEFINE_VTBL_WRAPPER(12);
4481 DEFINE_VTBL_WRAPPER(16);
4482 DEFINE_VTBL_WRAPPER(20);
4483 DEFINE_VTBL_WRAPPER(24);
4484 DEFINE_VTBL_WRAPPER(28);
4485 DEFINE_VTBL_WRAPPER(32);
4486 DEFINE_VTBL_WRAPPER(36);
4487 DEFINE_VTBL_WRAPPER(40);
4488 DEFINE_VTBL_WRAPPER(44);
4489 DEFINE_VTBL_WRAPPER(48);
4490 DEFINE_VTBL_WRAPPER(52);
4491 DEFINE_VTBL_WRAPPER(56);
4493 #endif
4495 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
4496 void (__cdecl *MSVCRT_operator_delete)(void*);
4498 static void init_cxx_funcs(void)
4500 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
4502 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
4504 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
4505 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
4507 else
4509 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
4510 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
4514 static void init_io(void *base)
4516 filebuf *fb;
4518 #ifdef __x86_64__
4519 init_streambuf_rtti(base);
4520 init_filebuf_rtti(base);
4521 init_strstreambuf_rtti(base);
4522 init_stdiobuf_rtti(base);
4523 init_ios_rtti(base);
4524 init_ostream_rtti(base);
4525 init_ostream_withassign_rtti(base);
4526 init_ostrstream_rtti(base);
4527 init_istream_rtti(base);
4528 init_istream_withassign_rtti(base);
4529 init_istrstream_rtti(base);
4530 init_iostream_rtti(base);
4531 init_strstream_rtti(base);
4532 init_stdiostream_rtti(base);
4533 #endif
4535 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4536 filebuf_fd_ctor(fb, 0);
4537 istream_withassign_sb_ctor(&cin.is, &fb->base, TRUE);
4538 } else
4539 istream_withassign_sb_ctor(&cin.is, NULL, TRUE);
4540 Iostream_init_ios_ctor(NULL, &cin.vbase, 0);
4542 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4543 filebuf_fd_ctor(fb, 1);
4544 ostream_withassign_sb_ctor(&cout.os, &fb->base, TRUE);
4545 } else
4546 ostream_withassign_sb_ctor(&cout.os, NULL, TRUE);
4547 Iostream_init_ios_ctor(NULL, &cout.vbase, -1);
4549 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4550 filebuf_fd_ctor(fb, 2);
4551 ostream_withassign_sb_ctor(&cerr.os, &fb->base, TRUE);
4552 } else
4553 ostream_withassign_sb_ctor(&cerr.os, NULL, TRUE);
4554 Iostream_init_ios_ctor(NULL, &cerr.vbase, 1);
4556 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4557 filebuf_fd_ctor(fb, 2);
4558 ostream_withassign_sb_ctor(&clog.os, &fb->base, TRUE);
4559 } else
4560 ostream_withassign_sb_ctor(&clog.os, NULL, TRUE);
4561 Iostream_init_ios_ctor(NULL, &clog.vbase, 0);
4564 static void free_io(void)
4566 /* destructors take care of deleting the buffers */
4567 istream_vbase_dtor(&cin.is);
4568 ostream_vbase_dtor(&cout.os);
4569 ostream_vbase_dtor(&cerr.os);
4570 ostream_vbase_dtor(&clog.os);
4573 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
4575 switch (reason)
4577 case DLL_WINE_PREATTACH:
4578 return FALSE; /* prefer native version */
4579 case DLL_PROCESS_ATTACH:
4580 init_cxx_funcs();
4581 init_exception(inst);
4582 init_io(inst);
4583 DisableThreadLibraryCalls( inst );
4584 break;
4585 case DLL_PROCESS_DETACH:
4586 if (reserved) break;
4587 free_io();
4588 break;
4590 return TRUE;