ver: Use the 16-bit resource function in GetFileVersionInfo16().
[wine.git] / dlls / msvcirt / msvcirt.c
blob797b0b1b56a7e45c6da8fb728c0d5a69966923d5
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
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <float.h>
24 #include <io.h>
25 #include <limits.h>
26 #include <share.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <sys/stat.h>
31 #include "msvcirt.h"
32 #include "windef.h"
33 #include "winbase.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
38 #define RESERVE_SIZE 512
39 #define STATEBUF_SIZE 8
41 /* ?sh_none@filebuf@@2HB */
42 const int filebuf_sh_none = 0x800;
43 /* ?sh_read@filebuf@@2HB */
44 const int filebuf_sh_read = 0xa00;
45 /* ?sh_write@filebuf@@2HB */
46 const int filebuf_sh_write = 0xc00;
47 /* ?openprot@filebuf@@2HB */
48 const int filebuf_openprot = 420;
49 /* ?binary@filebuf@@2HB */
50 const int filebuf_binary = _O_BINARY;
51 /* ?text@filebuf@@2HB */
52 const int filebuf_text = _O_TEXT;
54 /* ?adjustfield@ios@@2JB */
55 const LONG ios_adjustfield = FLAGS_left | FLAGS_right | FLAGS_internal;
56 /* ?basefield@ios@@2JB */
57 const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
58 /* ?floatfield@ios@@2JB */
59 const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
60 /* ?fLockcInit@ios@@0HA */
61 int ios_fLockcInit = 0;
62 /* ?sunk_with_stdio@ios@@0HA */
63 int ios_sunk_with_stdio = 0;
64 /* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
65 extern CRITICAL_SECTION ios_static_lock;
66 CRITICAL_SECTION_DEBUG ios_static_lock_debug =
68 0, 0, &ios_static_lock,
69 { &ios_static_lock_debug.ProcessLocksList, &ios_static_lock_debug.ProcessLocksList },
70 0, 0, { (DWORD_PTR)(__FILE__ ": ios_static_lock") }
72 CRITICAL_SECTION ios_static_lock = { &ios_static_lock_debug, -1, 0, 0, 0, 0 };
73 /* ?x_maxbit@ios@@0JA */
74 LONG ios_maxbit = 0x8000;
75 /* ?x_curindex@ios@@0HA */
76 int ios_curindex = -1;
77 /* ?x_statebuf@ios@@0PAJA */
78 LONG ios_statebuf[STATEBUF_SIZE] = {0};
80 /* class streambuf */
81 typedef struct {
82 const vtable_ptr *vtable;
83 int allocated;
84 int unbuffered;
85 int stored_char;
86 char *base;
87 char *ebuf;
88 char *pbase;
89 char *pptr;
90 char *epptr;
91 char *eback;
92 char *gptr;
93 char *egptr;
94 int do_lock;
95 CRITICAL_SECTION lock;
96 } streambuf;
98 void __thiscall streambuf_setb(streambuf*, char*, char*, int);
99 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
100 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
101 void __thiscall streambuf_setp(streambuf*, char*, char*);
103 /* class filebuf */
104 typedef struct {
105 streambuf base;
106 filedesc fd;
107 int close;
108 } filebuf;
110 filebuf* __thiscall filebuf_close(filebuf*);
112 /* class strstreambuf */
113 typedef struct {
114 streambuf base;
115 int dynamic;
116 int increase;
117 int unknown;
118 int constant;
119 allocFunction f_alloc;
120 freeFunction f_free;
121 } strstreambuf;
123 /* class stdiobuf */
124 typedef struct {
125 streambuf base;
126 FILE *file;
127 } stdiobuf;
129 /* class ios */
130 struct _ostream;
131 typedef struct {
132 const vtable_ptr *vtable;
133 streambuf *sb;
134 ios_io_state state;
135 int special[4];
136 int delbuf;
137 struct _ostream *tie;
138 ios_flags flags;
139 int precision;
140 char fill;
141 int width;
142 int do_lock;
143 CRITICAL_SECTION lock;
144 } ios;
146 ios* __thiscall ios_assign(ios*, const ios*);
147 int __thiscall ios_fail(const ios*);
148 void __cdecl ios_lock(ios*);
149 void __cdecl ios_lockc(void);
150 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
151 void __cdecl ios_unlock(ios*);
152 void __cdecl ios_unlockc(void);
154 /* class ostream */
155 typedef struct _ostream {
156 const int *vbtable;
157 int unknown;
158 } ostream;
160 /* class istream */
161 typedef struct {
162 const int *vbtable;
163 int extract_delim;
164 int count;
165 } istream;
167 /* class iostream */
168 typedef struct {
169 istream base1;
170 ostream base2;
171 } iostream;
173 /* ??_7streambuf@@6B@ */
174 extern const vtable_ptr MSVCP_streambuf_vtable;
175 /* ??_7filebuf@@6B@ */
176 extern const vtable_ptr MSVCP_filebuf_vtable;
177 /* ??_7strstreambuf@@6B@ */
178 extern const vtable_ptr MSVCP_strstreambuf_vtable;
179 /* ??_7stdiobuf@@6B@ */
180 extern const vtable_ptr MSVCP_stdiobuf_vtable;
181 /* ??_7ios@@6B@ */
182 extern const vtable_ptr MSVCP_ios_vtable;
183 /* ??_7ostream@@6B@ */
184 extern const vtable_ptr MSVCP_ostream_vtable;
185 /* ??_7ostream_withassign@@6B@ */
186 extern const vtable_ptr MSVCP_ostream_withassign_vtable;
187 /* ??_7ostrstream@@6B@ */
188 extern const vtable_ptr MSVCP_ostrstream_vtable;
189 /* ??_7istream@@6B@ */
190 extern const vtable_ptr MSVCP_istream_vtable;
191 /* ??_7istream_withassign@@6B@ */
192 extern const vtable_ptr MSVCP_istream_withassign_vtable;
193 /* ??_7istrstream@@6B@ */
194 extern const vtable_ptr MSVCP_istrstream_vtable;
195 /* ??_7iostream@@6B@ */
196 extern const vtable_ptr MSVCP_iostream_vtable;
197 /* ??_7strstream@@6B@ */
198 extern const vtable_ptr MSVCP_strstream_vtable;
199 /* ??_7stdiostream@@6B@ */
200 extern const vtable_ptr MSVCP_stdiostream_vtable;
202 #ifndef __GNUC__
203 void __asm_dummy_vtables(void) {
204 #endif
205 __ASM_VTABLE(streambuf,
206 VTABLE_ADD_FUNC(streambuf_vector_dtor)
207 VTABLE_ADD_FUNC(streambuf_sync)
208 VTABLE_ADD_FUNC(streambuf_setbuf)
209 VTABLE_ADD_FUNC(streambuf_seekoff)
210 VTABLE_ADD_FUNC(streambuf_seekpos)
211 VTABLE_ADD_FUNC(streambuf_xsputn)
212 VTABLE_ADD_FUNC(streambuf_xsgetn)
213 VTABLE_ADD_FUNC(streambuf_overflow)
214 VTABLE_ADD_FUNC(streambuf_underflow)
215 VTABLE_ADD_FUNC(streambuf_pbackfail)
216 VTABLE_ADD_FUNC(streambuf_doallocate));
217 __ASM_VTABLE(filebuf,
218 VTABLE_ADD_FUNC(filebuf_vector_dtor)
219 VTABLE_ADD_FUNC(filebuf_sync)
220 VTABLE_ADD_FUNC(filebuf_setbuf)
221 VTABLE_ADD_FUNC(filebuf_seekoff)
222 VTABLE_ADD_FUNC(streambuf_seekpos)
223 VTABLE_ADD_FUNC(streambuf_xsputn)
224 VTABLE_ADD_FUNC(streambuf_xsgetn)
225 VTABLE_ADD_FUNC(filebuf_overflow)
226 VTABLE_ADD_FUNC(filebuf_underflow)
227 VTABLE_ADD_FUNC(streambuf_pbackfail)
228 VTABLE_ADD_FUNC(streambuf_doallocate));
229 __ASM_VTABLE(strstreambuf,
230 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
231 VTABLE_ADD_FUNC(strstreambuf_sync)
232 VTABLE_ADD_FUNC(strstreambuf_setbuf)
233 VTABLE_ADD_FUNC(strstreambuf_seekoff)
234 VTABLE_ADD_FUNC(streambuf_seekpos)
235 VTABLE_ADD_FUNC(streambuf_xsputn)
236 VTABLE_ADD_FUNC(streambuf_xsgetn)
237 VTABLE_ADD_FUNC(strstreambuf_overflow)
238 VTABLE_ADD_FUNC(strstreambuf_underflow)
239 VTABLE_ADD_FUNC(streambuf_pbackfail)
240 VTABLE_ADD_FUNC(strstreambuf_doallocate));
241 __ASM_VTABLE(stdiobuf,
242 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
243 VTABLE_ADD_FUNC(stdiobuf_sync)
244 VTABLE_ADD_FUNC(streambuf_setbuf)
245 VTABLE_ADD_FUNC(stdiobuf_seekoff)
246 VTABLE_ADD_FUNC(streambuf_seekpos)
247 VTABLE_ADD_FUNC(streambuf_xsputn)
248 VTABLE_ADD_FUNC(streambuf_xsgetn)
249 VTABLE_ADD_FUNC(stdiobuf_overflow)
250 VTABLE_ADD_FUNC(stdiobuf_underflow)
251 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
252 VTABLE_ADD_FUNC(streambuf_doallocate));
253 __ASM_VTABLE(ios,
254 VTABLE_ADD_FUNC(ios_vector_dtor));
255 __ASM_VTABLE(ostream,
256 VTABLE_ADD_FUNC(ostream_vector_dtor));
257 __ASM_VTABLE(ostream_withassign,
258 VTABLE_ADD_FUNC(ostream_vector_dtor));
259 __ASM_VTABLE(ostrstream,
260 VTABLE_ADD_FUNC(ostream_vector_dtor));
261 __ASM_VTABLE(istream,
262 VTABLE_ADD_FUNC(istream_vector_dtor));
263 __ASM_VTABLE(istream_withassign,
264 VTABLE_ADD_FUNC(istream_vector_dtor));
265 __ASM_VTABLE(istrstream,
266 VTABLE_ADD_FUNC(istream_vector_dtor));
267 __ASM_VTABLE(iostream,
268 VTABLE_ADD_FUNC(iostream_vector_dtor));
269 __ASM_VTABLE(strstream,
270 VTABLE_ADD_FUNC(iostream_vector_dtor));
271 __ASM_VTABLE(stdiostream,
272 VTABLE_ADD_FUNC(iostream_vector_dtor));
273 #ifndef __GNUC__
275 #endif
277 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
278 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
280 /* ??_8ostream@@7B@ */
281 /* ??_8ostream_withassign@@7B@ */
282 /* ??_8ostrstream@@7B@ */
283 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
284 /* ??_8istream@@7B@ */
285 /* ??_8istream_withassign@@7B@ */
286 /* ??_8istrstream@@7B@ */
287 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
288 /* ??_8iostream@@7Bistream@@@ */
289 /* ??_8stdiostream@@7Bistream@@@ */
290 /* ??_8strstream@@7Bistream@@@ */
291 const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)};
292 /* ??_8iostream@@7Bostream@@@ */
293 /* ??_8stdiostream@@7Bostream@@@ */
294 /* ??_8strstream@@7Bostream@@@ */
295 const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)};
297 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
298 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
299 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
300 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
301 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
302 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
303 DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream),
304 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@")
305 DEFINE_RTTI_DATA2(ostrstream, sizeof(ostream),
306 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostrstream@@")
307 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
308 DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
309 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
310 DEFINE_RTTI_DATA2(istrstream, sizeof(istream),
311 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistrstream@@")
312 DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
313 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
314 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
315 DEFINE_RTTI_DATA4(strstream, sizeof(iostream),
316 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
317 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstrstream@@")
318 DEFINE_RTTI_DATA4(stdiostream, sizeof(iostream),
319 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
320 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstdiostream@@")
322 /* ?cin@@3Vistream_withassign@@A */
323 struct {
324 istream is;
325 ios vbase;
326 } cin = { { 0 } };
328 /* ?cout@@3Vostream_withassign@@A */
329 /* ?cerr@@3Vostream_withassign@@A */
330 /* ?clog@@3Vostream_withassign@@A */
331 struct {
332 ostream os;
333 ios vbase;
334 } cout = { { 0 } }, cerr = { { 0 } }, MSVCP_clog = { { 0 } };
337 /* ??0streambuf@@IAE@PADH@Z */
338 /* ??0streambuf@@IEAA@PEADH@Z */
339 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
340 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
342 TRACE("(%p %p %d)\n", this, buffer, length);
343 this->vtable = &MSVCP_streambuf_vtable;
344 this->allocated = 0;
345 this->stored_char = EOF;
346 this->do_lock = -1;
347 this->base = NULL;
348 streambuf_setbuf(this, buffer, length);
349 streambuf_setg(this, NULL, NULL, NULL);
350 streambuf_setp(this, NULL, NULL);
351 InitializeCriticalSection(&this->lock);
352 return this;
355 /* ??0streambuf@@IAE@XZ */
356 /* ??0streambuf@@IEAA@XZ */
357 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
358 streambuf* __thiscall streambuf_ctor(streambuf *this)
360 streambuf_reserve_ctor(this, NULL, 0);
361 this->unbuffered = 0;
362 return this;
365 /* ??0streambuf@@QAE@ABV0@@Z */
366 /* ??0streambuf@@QEAA@AEBV0@@Z */
367 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
368 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
370 TRACE("(%p %p)\n", this, copy);
371 *this = *copy;
372 this->vtable = &MSVCP_streambuf_vtable;
373 return this;
376 /* ??1streambuf@@UAE@XZ */
377 /* ??1streambuf@@UEAA@XZ */
378 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
379 void __thiscall streambuf_dtor(streambuf *this)
381 TRACE("(%p)\n", this);
382 if (this->allocated)
383 MSVCRT_operator_delete(this->base);
384 DeleteCriticalSection(&this->lock);
387 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
388 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
389 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
390 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
392 streambuf_dtor(this);
393 return streambuf_copy_ctor(this, rhs);
396 /* ??_Estreambuf@@UAEPAXI@Z */
397 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
398 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
399 streambuf*, (streambuf*, unsigned int), (this, flags))
400 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
402 TRACE("(%p %x)\n", this, flags);
403 if (flags & 2) {
404 /* we have an array, with the number of elements stored before the first object */
405 INT_PTR i, *ptr = (INT_PTR *)this-1;
407 for (i = *ptr-1; i >= 0; i--)
408 streambuf_dtor(this+i);
409 MSVCRT_operator_delete(ptr);
410 } else {
411 streambuf_dtor(this);
412 if (flags & 1)
413 MSVCRT_operator_delete(this);
415 return this;
418 /* ??_Gstreambuf@@UAEPAXI@Z */
419 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
420 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
422 TRACE("(%p %x)\n", this, flags);
423 streambuf_dtor(this);
424 if (flags & 1) MSVCRT_operator_delete(this);
425 return this;
428 /* ?doallocate@streambuf@@MAEHXZ */
429 /* ?doallocate@streambuf@@MEAAHXZ */
430 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
431 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
432 int __thiscall streambuf_doallocate(streambuf *this)
434 char *reserve;
436 TRACE("(%p)\n", this);
437 reserve = MSVCRT_operator_new(RESERVE_SIZE);
438 if (!reserve)
439 return EOF;
441 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
442 return 1;
445 /* ?allocate@streambuf@@IAEHXZ */
446 /* ?allocate@streambuf@@IEAAHXZ */
447 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
448 int __thiscall streambuf_allocate(streambuf *this)
450 TRACE("(%p)\n", this);
451 if (this->base != NULL || this->unbuffered)
452 return 0;
453 return call_streambuf_doallocate(this);
456 /* ?base@streambuf@@IBEPADXZ */
457 /* ?base@streambuf@@IEBAPEADXZ */
458 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
459 char* __thiscall streambuf_base(const streambuf *this)
461 TRACE("(%p)\n", this);
462 return this->base;
465 /* ?blen@streambuf@@IBEHXZ */
466 /* ?blen@streambuf@@IEBAHXZ */
467 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
468 int __thiscall streambuf_blen(const streambuf *this)
470 TRACE("(%p)\n", this);
471 return this->ebuf - this->base;
474 /* ?eback@streambuf@@IBEPADXZ */
475 /* ?eback@streambuf@@IEBAPEADXZ */
476 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
477 char* __thiscall streambuf_eback(const streambuf *this)
479 TRACE("(%p)\n", this);
480 return this->eback;
483 /* ?ebuf@streambuf@@IBEPADXZ */
484 /* ?ebuf@streambuf@@IEBAPEADXZ */
485 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
486 char* __thiscall streambuf_ebuf(const streambuf *this)
488 TRACE("(%p)\n", this);
489 return this->ebuf;
492 /* ?egptr@streambuf@@IBEPADXZ */
493 /* ?egptr@streambuf@@IEBAPEADXZ */
494 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
495 char* __thiscall streambuf_egptr(const streambuf *this)
497 TRACE("(%p)\n", this);
498 return this->egptr;
501 /* ?epptr@streambuf@@IBEPADXZ */
502 /* ?epptr@streambuf@@IEBAPEADXZ */
503 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
504 char* __thiscall streambuf_epptr(const streambuf *this)
506 TRACE("(%p)\n", this);
507 return this->epptr;
510 /* ?gptr@streambuf@@IBEPADXZ */
511 /* ?gptr@streambuf@@IEBAPEADXZ */
512 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
513 char* __thiscall streambuf_gptr(const streambuf *this)
515 TRACE("(%p)\n", this);
516 return this->gptr;
519 /* ?pbase@streambuf@@IBEPADXZ */
520 /* ?pbase@streambuf@@IEBAPEADXZ */
521 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
522 char* __thiscall streambuf_pbase(const streambuf *this)
524 TRACE("(%p)\n", this);
525 return this->pbase;
528 /* ?pptr@streambuf@@IBEPADXZ */
529 /* ?pptr@streambuf@@IEBAPEADXZ */
530 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
531 char* __thiscall streambuf_pptr(const streambuf *this)
533 TRACE("(%p)\n", this);
534 return this->pptr;
537 /* ?clrlock@streambuf@@QAEXXZ */
538 /* ?clrlock@streambuf@@QEAAXXZ */
539 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
540 void __thiscall streambuf_clrlock(streambuf *this)
542 TRACE("(%p)\n", this);
543 if (this->do_lock <= 0)
544 this->do_lock++;
547 /* ?lock@streambuf@@QAEXXZ */
548 /* ?lock@streambuf@@QEAAXXZ */
549 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
550 void __thiscall streambuf_lock(streambuf *this)
552 TRACE("(%p)\n", this);
553 if (this->do_lock < 0)
554 EnterCriticalSection(&this->lock);
557 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
558 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
559 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
560 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
562 TRACE("(%p)\n", this);
563 return &this->lock;
566 /* ?gbump@streambuf@@IAEXH@Z */
567 /* ?gbump@streambuf@@IEAAXH@Z */
568 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
569 void __thiscall streambuf_gbump(streambuf *this, int count)
571 TRACE("(%p %d)\n", this, count);
572 this->gptr += count;
575 /* ?pbump@streambuf@@IAEXH@Z */
576 /* ?pbump@streambuf@@IEAAXH@Z */
577 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
578 void __thiscall streambuf_pbump(streambuf *this, int count)
580 TRACE("(%p %d)\n", this, count);
581 this->pptr += count;
584 /* ?in_avail@streambuf@@QBEHXZ */
585 /* ?in_avail@streambuf@@QEBAHXZ */
586 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
587 int __thiscall streambuf_in_avail(const streambuf *this)
589 TRACE("(%p)\n", this);
590 return (this->egptr - this->gptr > 0) ? this->egptr - this->gptr : 0;
593 /* ?out_waiting@streambuf@@QBEHXZ */
594 /* ?out_waiting@streambuf@@QEBAHXZ */
595 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
596 int __thiscall streambuf_out_waiting(const streambuf *this)
598 TRACE("(%p)\n", this);
599 return (this->pptr - this->pbase > 0) ? this->pptr - this->pbase : 0;
602 /* Unexported */
603 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
604 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
605 int __thiscall streambuf_overflow(streambuf *this, int c)
607 ERR("overflow is not implemented in streambuf\n");
608 return EOF;
611 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
612 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
613 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
614 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
615 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
617 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
618 return EOF;
621 /* ?seekpos@streambuf@@UAEJJH@Z */
622 /* ?seekpos@streambuf@@UEAAJJH@Z */
623 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
624 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
626 TRACE("(%p %d %d)\n", this, pos, mode);
627 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
630 /* ?pbackfail@streambuf@@UAEHH@Z */
631 /* ?pbackfail@streambuf@@UEAAHH@Z */
632 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
633 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
634 int __thiscall streambuf_pbackfail(streambuf *this, int c)
636 TRACE("(%p %d)\n", this, c);
637 if (this->gptr > this->eback)
638 return *--this->gptr = c;
639 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
640 return EOF;
641 if (!this->unbuffered && this->egptr) {
642 /* 'c' should be the next character read */
643 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
644 *this->gptr = c;
646 return c;
649 /* ?setb@streambuf@@IAEXPAD0H@Z */
650 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
651 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
652 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
654 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
655 if (this->allocated)
656 MSVCRT_operator_delete(this->base);
657 this->allocated = delete;
658 this->base = ba;
659 this->ebuf = eb;
662 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
663 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
664 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
665 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
667 TRACE("(%p %p %d)\n", this, buffer, length);
668 if (this->base != NULL)
669 return NULL;
671 if (buffer == NULL || !length) {
672 this->unbuffered = 1;
673 this->base = this->ebuf = NULL;
674 } else {
675 this->unbuffered = 0;
676 this->base = buffer;
677 this->ebuf = buffer + length;
679 return this;
682 /* ?setg@streambuf@@IAEXPAD00@Z */
683 /* ?setg@streambuf@@IEAAXPEAD00@Z */
684 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
685 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
687 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
688 this->eback = ek;
689 this->gptr = gp;
690 this->egptr = eg;
693 /* ?setlock@streambuf@@QAEXXZ */
694 /* ?setlock@streambuf@@QEAAXXZ */
695 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
696 void __thiscall streambuf_setlock(streambuf *this)
698 TRACE("(%p)\n", this);
699 this->do_lock--;
702 /* ?setp@streambuf@@IAEXPAD0@Z */
703 /* ?setp@streambuf@@IEAAXPEAD0@Z */
704 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
705 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
707 TRACE("(%p %p %p)\n", this, pb, ep);
708 this->pbase = this->pptr = pb;
709 this->epptr = ep;
712 /* ?sync@streambuf@@UAEHXZ */
713 /* ?sync@streambuf@@UEAAHXZ */
714 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
715 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
716 int __thiscall streambuf_sync(streambuf *this)
718 TRACE("(%p)\n", this);
719 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
722 /* ?unbuffered@streambuf@@IAEXH@Z */
723 /* ?unbuffered@streambuf@@IEAAXH@Z */
724 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
725 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
727 TRACE("(%p %d)\n", this, buf);
728 this->unbuffered = buf;
731 /* ?unbuffered@streambuf@@IBEHXZ */
732 /* ?unbuffered@streambuf@@IEBAHXZ */
733 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
734 int __thiscall streambuf_unbuffered_get(const streambuf *this)
736 TRACE("(%p)\n", this);
737 return this->unbuffered;
740 /* Unexported */
741 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
742 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
743 int __thiscall streambuf_underflow(streambuf *this)
745 ERR("underflow is not implemented in streambuf\n");
746 return EOF;
749 /* ?unlock@streambuf@@QAEXXZ */
750 /* ?unlock@streambuf@@QEAAXXZ */
751 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
752 void __thiscall streambuf_unlock(streambuf *this)
754 TRACE("(%p)\n", this);
755 if (this->do_lock < 0)
756 LeaveCriticalSection(&this->lock);
759 /* ?xsgetn@streambuf@@UAEHPADH@Z */
760 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
761 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
762 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
763 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
765 int copied = 0, chunk;
767 TRACE("(%p %p %d)\n", this, buffer, count);
769 if (this->unbuffered) {
770 if (this->stored_char == EOF)
771 this->stored_char = call_streambuf_underflow(this);
772 while (copied < count && this->stored_char != EOF) {
773 buffer[copied++] = this->stored_char;
774 this->stored_char = call_streambuf_underflow(this);
776 } else {
777 while (copied < count) {
778 if (call_streambuf_underflow(this) == EOF)
779 break;
780 chunk = this->egptr - this->gptr;
781 if (chunk > count - copied)
782 chunk = count - copied;
783 memcpy(buffer+copied, this->gptr, chunk);
784 this->gptr += chunk;
785 copied += chunk;
788 return copied;
791 /* ?xsputn@streambuf@@UAEHPBDH@Z */
792 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
793 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
794 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
795 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
797 int copied = 0, chunk;
799 TRACE("(%p %p %d)\n", this, data, length);
801 while (copied < length) {
802 if (this->unbuffered || this->pptr == this->epptr) {
803 if (call_streambuf_overflow(this, data[copied]) == EOF)
804 break;
805 copied++;
806 } else {
807 chunk = this->epptr - this->pptr;
808 if (chunk > length - copied)
809 chunk = length - copied;
810 memcpy(this->pptr, data+copied, chunk);
811 this->pptr += chunk;
812 copied += chunk;
815 return copied;
818 /* ?sgetc@streambuf@@QAEHXZ */
819 /* ?sgetc@streambuf@@QEAAHXZ */
820 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
821 int __thiscall streambuf_sgetc(streambuf *this)
823 TRACE("(%p)\n", this);
824 if (this->unbuffered) {
825 if (this->stored_char == EOF)
826 this->stored_char = call_streambuf_underflow(this);
827 return this->stored_char;
828 } else
829 return call_streambuf_underflow(this);
832 /* ?sputc@streambuf@@QAEHH@Z */
833 /* ?sputc@streambuf@@QEAAHH@Z */
834 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
835 int __thiscall streambuf_sputc(streambuf *this, int ch)
837 TRACE("(%p %d)\n", this, ch);
838 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
841 /* ?sgetn@streambuf@@QAEHPADH@Z */
842 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
843 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
844 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
846 return call_streambuf_xsgetn(this, buffer, count);
849 /* ?sputn@streambuf@@QAEHPBDH@Z */
850 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
851 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
852 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
854 return call_streambuf_xsputn(this, data, length);
857 /* ?snextc@streambuf@@QAEHXZ */
858 /* ?snextc@streambuf@@QEAAHXZ */
859 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
860 int __thiscall streambuf_snextc(streambuf *this)
862 TRACE("(%p)\n", this);
863 if (this->unbuffered) {
864 if (this->stored_char == EOF)
865 call_streambuf_underflow(this);
866 return this->stored_char = call_streambuf_underflow(this);
867 } else {
868 if (this->gptr >= this->egptr)
869 call_streambuf_underflow(this);
870 this->gptr++;
871 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
875 /* ?sbumpc@streambuf@@QAEHXZ */
876 /* ?sbumpc@streambuf@@QEAAHXZ */
877 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
878 int __thiscall streambuf_sbumpc(streambuf *this)
880 int ret;
882 TRACE("(%p)\n", this);
884 if (this->unbuffered) {
885 ret = this->stored_char;
886 this->stored_char = EOF;
887 if (ret == EOF)
888 ret = call_streambuf_underflow(this);
889 } else {
890 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
891 this->gptr++;
893 return ret;
896 /* ?stossc@streambuf@@QAEXXZ */
897 /* ?stossc@streambuf@@QEAAXXZ */
898 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
899 void __thiscall streambuf_stossc(streambuf *this)
901 TRACE("(%p)\n", this);
902 if (this->unbuffered) {
903 if (this->stored_char == EOF)
904 call_streambuf_underflow(this);
905 else
906 this->stored_char = EOF;
907 } else {
908 if (this->gptr >= this->egptr)
909 call_streambuf_underflow(this);
910 if (this->gptr < this->egptr)
911 this->gptr++;
915 /* ?sputbackc@streambuf@@QAEHD@Z */
916 /* ?sputbackc@streambuf@@QEAAHD@Z */
917 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
918 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
920 TRACE("(%p %d)\n", this, ch);
921 return call_streambuf_pbackfail(this, ch);
924 /* ?dbp@streambuf@@QAEXXZ */
925 /* ?dbp@streambuf@@QEAAXXZ */
926 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
927 void __thiscall streambuf_dbp(streambuf *this)
929 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
930 if (this->unbuffered) {
931 printf("unbuffered\n");
932 } else {
933 printf("_fAlloc=%d\n", this->allocated);
934 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
935 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
936 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
940 /* ??0filebuf@@QAE@ABV0@@Z */
941 /* ??0filebuf@@QEAA@AEBV0@@Z */
942 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
943 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
945 TRACE("(%p %p)\n", this, copy);
946 *this = *copy;
947 this->base.vtable = &MSVCP_filebuf_vtable;
948 return this;
951 /* ??0filebuf@@QAE@HPADH@Z */
952 /* ??0filebuf@@QEAA@HPEADH@Z */
953 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
954 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
956 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
957 streambuf_reserve_ctor(&this->base, buffer, length);
958 this->base.vtable = &MSVCP_filebuf_vtable;
959 this->fd = fd;
960 this->close = 0;
961 return this;
964 /* ??0filebuf@@QAE@H@Z */
965 /* ??0filebuf@@QEAA@H@Z */
966 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
967 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
969 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
970 this->base.unbuffered = 0;
971 return this;
974 /* ??0filebuf@@QAE@XZ */
975 /* ??0filebuf@@QEAA@XZ */
976 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
977 filebuf* __thiscall filebuf_ctor(filebuf* this)
979 return filebuf_fd_ctor(this, -1);
982 /* ??1filebuf@@UAE@XZ */
983 /* ??1filebuf@@UEAA@XZ */
984 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
985 void __thiscall filebuf_dtor(filebuf* this)
987 TRACE("(%p)\n", this);
988 if (this->close)
989 filebuf_close(this);
990 streambuf_dtor(&this->base);
993 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
994 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
995 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
996 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
998 filebuf_dtor(this);
999 return filebuf_copy_ctor(this, rhs);
1002 /* ??_Efilebuf@@UAEPAXI@Z */
1003 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
1004 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
1006 TRACE("(%p %x)\n", this, flags);
1007 if (flags & 2) {
1008 /* we have an array, with the number of elements stored before the first object */
1009 INT_PTR i, *ptr = (INT_PTR *)this-1;
1011 for (i = *ptr-1; i >= 0; i--)
1012 filebuf_dtor(this+i);
1013 MSVCRT_operator_delete(ptr);
1014 } else {
1015 filebuf_dtor(this);
1016 if (flags & 1)
1017 MSVCRT_operator_delete(this);
1019 return this;
1022 /* ??_Gfilebuf@@UAEPAXI@Z */
1023 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
1024 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
1026 TRACE("(%p %x)\n", this, flags);
1027 filebuf_dtor(this);
1028 if (flags & 1) MSVCRT_operator_delete(this);
1029 return this;
1032 /* ?attach@filebuf@@QAEPAV1@H@Z */
1033 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
1034 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
1035 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
1037 TRACE("(%p %d)\n", this, fd);
1038 if (this->fd != -1)
1039 return NULL;
1041 streambuf_lock(&this->base);
1042 this->fd = fd;
1043 streambuf_allocate(&this->base);
1044 streambuf_unlock(&this->base);
1045 return this;
1048 /* ?close@filebuf@@QAEPAV1@XZ */
1049 /* ?close@filebuf@@QEAAPEAV1@XZ */
1050 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
1051 filebuf* __thiscall filebuf_close(filebuf *this)
1053 filebuf *ret;
1055 TRACE("(%p)\n", this);
1056 if (this->fd == -1)
1057 return NULL;
1059 streambuf_lock(&this->base);
1060 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
1061 ret = NULL;
1062 } else {
1063 this->fd = -1;
1064 ret = this;
1066 streambuf_unlock(&this->base);
1067 return ret;
1070 /* ?fd@filebuf@@QBEHXZ */
1071 /* ?fd@filebuf@@QEBAHXZ */
1072 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
1073 filedesc __thiscall filebuf_fd(const filebuf *this)
1075 TRACE("(%p)\n", this);
1076 return this->fd;
1079 /* ?is_open@filebuf@@QBEHXZ */
1080 /* ?is_open@filebuf@@QEBAHXZ */
1081 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1082 int __thiscall filebuf_is_open(const filebuf *this)
1084 TRACE("(%p)\n", this);
1085 return this->fd != -1;
1088 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1089 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1090 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1091 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1093 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1094 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1095 int op_flags, sh_flags, fd;
1097 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1098 if (this->fd != -1)
1099 return NULL;
1101 /* mode */
1102 if (mode & (OPENMODE_app|OPENMODE_trunc))
1103 mode |= OPENMODE_out;
1104 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1105 if (op_flags < 0)
1106 return NULL;
1107 if (mode & OPENMODE_app)
1108 op_flags |= _O_APPEND;
1109 if ((mode & OPENMODE_trunc) ||
1110 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1111 op_flags |= _O_TRUNC;
1112 if (!(mode & OPENMODE_nocreate))
1113 op_flags |= _O_CREAT;
1114 if (mode & OPENMODE_noreplace)
1115 op_flags |= _O_EXCL;
1116 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1118 /* share protection */
1119 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1121 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1122 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1123 if (fd < 0)
1124 return NULL;
1126 streambuf_lock(&this->base);
1127 this->close = 1;
1128 this->fd = fd;
1129 if ((mode & OPENMODE_ate) &&
1130 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1131 _close(fd);
1132 this->fd = -1;
1134 streambuf_allocate(&this->base);
1135 streambuf_unlock(&this->base);
1136 return (this->fd == -1) ? NULL : this;
1139 /* ?overflow@filebuf@@UAEHH@Z */
1140 /* ?overflow@filebuf@@UEAAHH@Z */
1141 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1142 int __thiscall filebuf_overflow(filebuf *this, int c)
1144 TRACE("(%p %d)\n", this, c);
1145 if (call_streambuf_sync(&this->base) == EOF)
1146 return EOF;
1147 if (this->base.unbuffered)
1148 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1149 if (streambuf_allocate(&this->base) == EOF)
1150 return EOF;
1152 this->base.pbase = this->base.pptr = this->base.base;
1153 this->base.epptr = this->base.ebuf;
1154 if (c != EOF)
1155 *this->base.pptr++ = c;
1156 return 1;
1159 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1160 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1161 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1162 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1164 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1165 if (call_streambuf_sync(&this->base) == EOF)
1166 return EOF;
1167 return _lseek(this->fd, offset, dir);
1170 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1171 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1172 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1173 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1175 streambuf *ret;
1177 TRACE("(%p %p %d)\n", this, buffer, length);
1178 if (this->base.base != NULL)
1179 return NULL;
1181 streambuf_lock(&this->base);
1182 ret = streambuf_setbuf(&this->base, buffer, length);
1183 streambuf_unlock(&this->base);
1184 return ret;
1187 /* ?setmode@filebuf@@QAEHH@Z */
1188 /* ?setmode@filebuf@@QEAAHH@Z */
1189 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1190 int __thiscall filebuf_setmode(filebuf *this, int mode)
1192 int ret;
1194 TRACE("(%p %d)\n", this, mode);
1195 if (mode != filebuf_text && mode != filebuf_binary)
1196 return -1;
1198 streambuf_lock(&this->base);
1199 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1200 streambuf_unlock(&this->base);
1201 return ret;
1204 /* ?sync@filebuf@@UAEHXZ */
1205 /* ?sync@filebuf@@UEAAHXZ */
1206 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1207 int __thiscall filebuf_sync(filebuf *this)
1209 int count, mode;
1210 char *ptr;
1211 LONG offset;
1213 TRACE("(%p)\n", this);
1214 if (this->fd == -1)
1215 return EOF;
1216 if (this->base.unbuffered)
1217 return 0;
1219 /* flush output buffer */
1220 if (this->base.pptr != NULL) {
1221 count = this->base.pptr - this->base.pbase;
1222 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1223 return EOF;
1225 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1226 /* flush input buffer */
1227 if (this->base.egptr != NULL) {
1228 offset = this->base.egptr - this->base.gptr;
1229 if (offset > 0) {
1230 mode = _setmode(this->fd, _O_TEXT);
1231 _setmode(this->fd, mode);
1232 if (mode & _O_TEXT) {
1233 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1234 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1235 if (*ptr == '\n')
1236 offset++;
1238 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1239 return EOF;
1242 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1243 return 0;
1246 /* ?underflow@filebuf@@UAEHXZ */
1247 /* ?underflow@filebuf@@UEAAHXZ */
1248 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1249 int __thiscall filebuf_underflow(filebuf *this)
1251 int buffer_size, read_bytes;
1252 char c;
1254 TRACE("(%p)\n", this);
1256 if (this->base.unbuffered)
1257 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1259 if (this->base.gptr >= this->base.egptr) {
1260 if (call_streambuf_sync(&this->base) == EOF)
1261 return EOF;
1262 buffer_size = this->base.ebuf - this->base.base;
1263 read_bytes = _read(this->fd, this->base.base, buffer_size);
1264 if (read_bytes <= 0)
1265 return EOF;
1266 this->base.eback = this->base.gptr = this->base.base;
1267 this->base.egptr = this->base.base + read_bytes;
1269 return (unsigned char) *this->base.gptr;
1272 /* ??0strstreambuf@@QAE@ABV0@@Z */
1273 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1274 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1275 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1277 TRACE("(%p %p)\n", this, copy);
1278 *this = *copy;
1279 this->base.vtable = &MSVCP_strstreambuf_vtable;
1280 return this;
1283 /* ??0strstreambuf@@QAE@H@Z */
1284 /* ??0strstreambuf@@QEAA@H@Z */
1285 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1286 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1288 TRACE("(%p %d)\n", this, length);
1289 streambuf_ctor(&this->base);
1290 this->base.vtable = &MSVCP_strstreambuf_vtable;
1291 this->dynamic = 1;
1292 this->increase = length;
1293 this->constant = 0;
1294 this->f_alloc = NULL;
1295 this->f_free = NULL;
1296 return this;
1299 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1300 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1301 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1302 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1304 TRACE("(%p %p %p)\n", this, falloc, ffree);
1305 strstreambuf_dynamic_ctor(this, 1);
1306 this->f_alloc = falloc;
1307 this->f_free = ffree;
1308 return this;
1311 /* ??0strstreambuf@@QAE@PADH0@Z */
1312 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1313 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1314 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1316 char *end_buffer;
1318 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1320 if (length > 0)
1321 end_buffer = buffer + length;
1322 else if (length == 0)
1323 end_buffer = buffer + strlen(buffer);
1324 else
1325 end_buffer = (char*) -1;
1327 streambuf_ctor(&this->base);
1328 streambuf_setb(&this->base, buffer, end_buffer, 0);
1329 if (put == NULL) {
1330 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1331 } else {
1332 streambuf_setg(&this->base, buffer, buffer, put);
1333 streambuf_setp(&this->base, put, end_buffer);
1335 this->base.vtable = &MSVCP_strstreambuf_vtable;
1336 this->dynamic = 0;
1337 this->constant = 1;
1338 return this;
1341 /* ??0strstreambuf@@QAE@PAEH0@Z */
1342 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1343 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1344 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1346 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1347 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1350 /* ??0strstreambuf@@QAE@XZ */
1351 /* ??0strstreambuf@@QEAA@XZ */
1352 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1353 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1355 TRACE("(%p)\n", this);
1356 return strstreambuf_dynamic_ctor(this, 1);
1359 /* ??1strstreambuf@@UAE@XZ */
1360 /* ??1strstreambuf@@UEAA@XZ */
1361 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1362 void __thiscall strstreambuf_dtor(strstreambuf *this)
1364 TRACE("(%p)\n", this);
1365 if (this->dynamic && this->base.base) {
1366 if (this->f_free)
1367 this->f_free(this->base.base);
1368 else
1369 MSVCRT_operator_delete(this->base.base);
1371 streambuf_dtor(&this->base);
1374 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1375 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1376 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1377 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1379 strstreambuf_dtor(this);
1380 return strstreambuf_copy_ctor(this, rhs);
1383 /* ??_Estrstreambuf@@UAEPAXI@Z */
1384 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1385 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1387 TRACE("(%p %x)\n", this, flags);
1388 if (flags & 2) {
1389 /* we have an array, with the number of elements stored before the first object */
1390 INT_PTR i, *ptr = (INT_PTR *)this-1;
1392 for (i = *ptr-1; i >= 0; i--)
1393 strstreambuf_dtor(this+i);
1394 MSVCRT_operator_delete(ptr);
1395 } else {
1396 strstreambuf_dtor(this);
1397 if (flags & 1)
1398 MSVCRT_operator_delete(this);
1400 return this;
1403 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1404 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1405 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1407 TRACE("(%p %x)\n", this, flags);
1408 strstreambuf_dtor(this);
1409 if (flags & 1) MSVCRT_operator_delete(this);
1410 return this;
1413 /* ?doallocate@strstreambuf@@MAEHXZ */
1414 /* ?doallocate@strstreambuf@@MEAAHXZ */
1415 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1416 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1418 char *prev_buffer = this->base.base, *new_buffer;
1419 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1421 TRACE("(%p)\n", this);
1423 /* calculate the size of the new buffer */
1424 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1425 /* get a new buffer */
1426 if (this->f_alloc)
1427 new_buffer = this->f_alloc(new_size);
1428 else
1429 new_buffer = MSVCRT_operator_new(new_size);
1430 if (!new_buffer)
1431 return EOF;
1432 if (this->base.ebuf) {
1433 /* copy the contents and adjust the pointers */
1434 memcpy(new_buffer, this->base.base, prev_size);
1435 if (this->base.egptr) {
1436 this->base.eback += new_buffer - prev_buffer;
1437 this->base.gptr += new_buffer - prev_buffer;
1438 this->base.egptr += new_buffer - prev_buffer;
1440 if (this->base.epptr) {
1441 this->base.pbase += new_buffer - prev_buffer;
1442 this->base.pptr += new_buffer - prev_buffer;
1443 this->base.epptr += new_buffer - prev_buffer;
1445 /* free the old buffer */
1446 if (this->f_free)
1447 this->f_free(this->base.base);
1448 else
1449 MSVCRT_operator_delete(this->base.base);
1451 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1452 return 1;
1455 /* ?freeze@strstreambuf@@QAEXH@Z */
1456 /* ?freeze@strstreambuf@@QEAAXH@Z */
1457 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1458 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1460 TRACE("(%p %d)\n", this, frozen);
1461 if (!this->constant)
1462 this->dynamic = !frozen;
1465 /* ?overflow@strstreambuf@@UAEHH@Z */
1466 /* ?overflow@strstreambuf@@UEAAHH@Z */
1467 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1468 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1470 TRACE("(%p %d)\n", this, c);
1471 if (this->base.pptr >= this->base.epptr) {
1472 /* increase the buffer size if it's dynamic */
1473 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1474 return EOF;
1475 if (!this->base.epptr)
1476 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1477 this->base.epptr = this->base.ebuf;
1479 if (c != EOF)
1480 *this->base.pptr++ = c;
1481 return 1;
1484 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1485 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1486 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1487 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1489 char *base[3];
1491 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1493 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1494 return EOF;
1495 /* read buffer */
1496 if (mode & OPENMODE_in) {
1497 call_streambuf_underflow(&this->base);
1498 base[SEEKDIR_beg] = this->base.eback;
1499 base[SEEKDIR_cur] = this->base.gptr;
1500 base[SEEKDIR_end] = this->base.egptr;
1501 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1502 return EOF;
1503 this->base.gptr = base[dir] + offset;
1505 /* write buffer */
1506 if (mode & OPENMODE_out) {
1507 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1508 return EOF;
1509 base[SEEKDIR_beg] = this->base.pbase;
1510 base[SEEKDIR_cur] = this->base.pptr;
1511 base[SEEKDIR_end] = this->base.epptr;
1512 if (base[dir] + offset < this->base.pbase)
1513 return EOF;
1514 if (base[dir] + offset > this->base.epptr) {
1515 /* make room if the buffer is dynamic */
1516 if (!this->dynamic)
1517 return EOF;
1518 this->increase = offset;
1519 if (call_streambuf_doallocate(&this->base) == EOF)
1520 return EOF;
1522 this->base.pptr = base[dir] + offset;
1523 return this->base.pptr - base[SEEKDIR_beg];
1525 return this->base.gptr - base[SEEKDIR_beg];
1528 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1529 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1530 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1531 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1533 TRACE("(%p %p %d)\n", this, buffer, length);
1534 if (length)
1535 this->increase = length;
1536 return &this->base;
1539 /* ?str@strstreambuf@@QAEPADXZ */
1540 /* ?str@strstreambuf@@QEAAPEADXZ */
1541 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1542 char* __thiscall strstreambuf_str(strstreambuf *this)
1544 TRACE("(%p)\n", this);
1545 strstreambuf_freeze(this, 1);
1546 return this->base.base;
1549 /* ?sync@strstreambuf@@UAEHXZ */
1550 /* ?sync@strstreambuf@@UEAAHXZ */
1551 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1552 int __thiscall strstreambuf_sync(strstreambuf *this)
1554 TRACE("(%p)\n", this);
1555 return 0;
1558 /* ?underflow@strstreambuf@@UAEHXZ */
1559 /* ?underflow@strstreambuf@@UEAAHXZ */
1560 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1561 int __thiscall strstreambuf_underflow(strstreambuf *this)
1563 TRACE("(%p)\n", this);
1564 if (this->base.gptr < this->base.egptr)
1565 return (unsigned char) *this->base.gptr;
1566 /* extend the get area to include the characters written */
1567 if (this->base.egptr < this->base.pptr) {
1568 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1569 this->base.eback = this->base.base;
1570 this->base.egptr = this->base.pptr;
1572 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1575 /* ??0stdiobuf@@QAE@ABV0@@Z */
1576 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1577 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1578 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1580 TRACE("(%p %p)\n", this, copy);
1581 *this = *copy;
1582 this->base.vtable = &MSVCP_stdiobuf_vtable;
1583 return this;
1586 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1587 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1588 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1589 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1591 TRACE("(%p %p)\n", this, file);
1592 streambuf_reserve_ctor(&this->base, NULL, 0);
1593 this->base.vtable = &MSVCP_stdiobuf_vtable;
1594 this->file = file;
1595 return this;
1598 /* ??1stdiobuf@@UAE@XZ */
1599 /* ??1stdiobuf@@UEAA@XZ */
1600 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1601 void __thiscall stdiobuf_dtor(stdiobuf *this)
1603 TRACE("(%p)\n", this);
1604 call_streambuf_sync(&this->base);
1605 streambuf_dtor(&this->base);
1608 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1609 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1610 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1611 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1613 stdiobuf_dtor(this);
1614 return stdiobuf_copy_ctor(this, rhs);
1617 /* ??_Estdiobuf@@UAEPAXI@Z */
1618 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1619 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1621 TRACE("(%p %x)\n", this, flags);
1622 if (flags & 2) {
1623 /* we have an array, with the number of elements stored before the first object */
1624 INT_PTR i, *ptr = (INT_PTR *)this-1;
1626 for (i = *ptr-1; i >= 0; i--)
1627 stdiobuf_dtor(this+i);
1628 MSVCRT_operator_delete(ptr);
1629 } else {
1630 stdiobuf_dtor(this);
1631 if (flags & 1)
1632 MSVCRT_operator_delete(this);
1634 return this;
1637 /* ??_Gstdiobuf@@UAEPAXI@Z */
1638 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1639 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1641 TRACE("(%p %x)\n", this, flags);
1642 stdiobuf_dtor(this);
1643 if (flags & 1) MSVCRT_operator_delete(this);
1644 return this;
1647 /* ?overflow@stdiobuf@@UAEHH@Z */
1648 /* ?overflow@stdiobuf@@UEAAHH@Z */
1649 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1650 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1652 TRACE("(%p %d)\n", this, c);
1653 if (this->base.unbuffered)
1654 return (c == EOF) ? 1 : fputc(c, this->file);
1655 if (streambuf_allocate(&this->base) == EOF)
1656 return EOF;
1658 if (!this->base.epptr) {
1659 /* set the put area to the second half of the buffer */
1660 streambuf_setp(&this->base,
1661 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1662 } else if (this->base.pptr > this->base.pbase) {
1663 /* flush the put area */
1664 int count = this->base.pptr - this->base.pbase;
1665 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1666 return EOF;
1667 this->base.pptr = this->base.pbase;
1669 if (c != EOF) {
1670 if (this->base.pbase >= this->base.epptr)
1671 return fputc(c, this->file);
1672 *this->base.pptr++ = c;
1674 return 1;
1677 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1678 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1679 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1680 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1682 TRACE("(%p %d)\n", this, c);
1683 return streambuf_pbackfail(&this->base, c);
1686 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1687 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1688 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1689 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1691 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1692 call_streambuf_overflow(&this->base, EOF);
1693 if (fseek(this->file, offset, dir))
1694 return EOF;
1695 return ftell(this->file);
1698 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1699 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1700 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1701 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1703 char *reserve;
1704 int buffer_size = read_size + write_size;
1706 TRACE("(%p %d %d)\n", this, read_size, write_size);
1707 if (read_size < 0 || write_size < 0)
1708 return 0;
1709 if (!buffer_size) {
1710 this->base.unbuffered = 1;
1711 return 0;
1713 /* get a new buffer */
1714 reserve = MSVCRT_operator_new(buffer_size);
1715 if (!reserve)
1716 return 0;
1717 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1718 this->base.unbuffered = 0;
1719 /* set the get/put areas */
1720 if (read_size > 0)
1721 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1722 else
1723 streambuf_setg(&this->base, NULL, NULL, NULL);
1724 if (write_size > 0)
1725 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1726 else
1727 streambuf_setp(&this->base, NULL, NULL);
1728 return 1;
1731 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1732 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1733 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1734 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1736 TRACE("(%p)\n", this);
1737 return this->file;
1740 /* ?sync@stdiobuf@@UAEHXZ */
1741 /* ?sync@stdiobuf@@UEAAHXZ */
1742 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1743 int __thiscall stdiobuf_sync(stdiobuf *this)
1745 TRACE("(%p)\n", this);
1746 if (this->base.unbuffered)
1747 return 0;
1748 /* flush the put area */
1749 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1750 return EOF;
1751 /* flush the get area */
1752 if (this->base.gptr < this->base.egptr) {
1753 char *ptr;
1754 int fd, mode, offset = this->base.egptr - this->base.gptr;
1755 if ((fd = fileno(this->file)) < 0)
1756 return EOF;
1757 mode = _setmode(fd, _O_TEXT);
1758 _setmode(fd, mode);
1759 if (mode & _O_TEXT) {
1760 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1761 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1762 if (*ptr == '\n')
1763 offset++;
1765 if (fseek(this->file, -offset, SEEK_CUR))
1766 return EOF;
1767 this->base.gptr = this->base.egptr;
1769 return 0;
1772 /* ?underflow@stdiobuf@@UAEHXZ */
1773 /* ?underflow@stdiobuf@@UEAAHXZ */
1774 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1775 int __thiscall stdiobuf_underflow(stdiobuf *this)
1777 TRACE("(%p)\n", this);
1778 if (!this->file)
1779 return EOF;
1780 if (this->base.unbuffered)
1781 return fgetc(this->file);
1782 if (streambuf_allocate(&this->base) == EOF)
1783 return EOF;
1785 if (!this->base.egptr) {
1786 /* set the get area to the first half of the buffer */
1787 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1788 streambuf_setg(&this->base, this->base.base, middle, middle);
1790 if (this->base.gptr >= this->base.egptr) {
1791 /* read characters from the file */
1792 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1793 if (!this->base.eback ||
1794 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1795 return EOF;
1796 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1797 this->base.gptr = this->base.egptr - read_bytes;
1799 return (unsigned char) *this->base.gptr++;
1802 /* ??0ios@@IAE@ABV0@@Z */
1803 /* ??0ios@@IEAA@AEBV0@@Z */
1804 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1805 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1807 TRACE("(%p %p)\n", this, copy);
1808 ios_fLockcInit++;
1809 this->vtable = &MSVCP_ios_vtable;
1810 this->sb = NULL;
1811 this->delbuf = 0;
1812 this->do_lock = -1;
1813 InitializeCriticalSection(&this->lock);
1814 return ios_assign(this, copy);
1817 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1818 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1819 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1820 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1822 TRACE("(%p %p)\n", this, sb);
1823 ios_fLockcInit++;
1824 this->vtable = &MSVCP_ios_vtable;
1825 this->sb = sb;
1826 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1827 this->special[0] = this->special[1] = 0;
1828 this->delbuf = 0;
1829 this->tie = NULL;
1830 this->flags = 0;
1831 this->precision = 6;
1832 this->fill = ' ';
1833 this->width = 0;
1834 this->do_lock = -1;
1835 InitializeCriticalSection(&this->lock);
1836 return this;
1839 /* ??0ios@@IAE@XZ */
1840 /* ??0ios@@IEAA@XZ */
1841 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1842 ios* __thiscall ios_ctor(ios *this)
1844 return ios_sb_ctor(this, NULL);
1847 /* ??1ios@@UAE@XZ */
1848 /* ??1ios@@UEAA@XZ */
1849 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1850 void __thiscall ios_dtor(ios *this)
1852 TRACE("(%p)\n", this);
1853 ios_fLockcInit--;
1854 if (this->delbuf && this->sb)
1855 call_streambuf_vector_dtor(this->sb, 1);
1856 this->sb = NULL;
1857 this->state = IOSTATE_badbit;
1858 DeleteCriticalSection(&this->lock);
1861 /* ??4ios@@IAEAAV0@ABV0@@Z */
1862 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1863 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1864 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1866 TRACE("(%p %p)\n", this, rhs);
1867 this->state = rhs->state;
1868 if (!this->sb)
1869 this->state |= IOSTATE_badbit;
1870 this->tie = rhs->tie;
1871 this->flags = rhs->flags;
1872 this->precision = (char) rhs->precision;
1873 this->fill = rhs->fill;
1874 this->width = (char) rhs->width;
1875 return this;
1878 /* ??7ios@@QBEHXZ */
1879 /* ??7ios@@QEBAHXZ */
1880 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1881 int __thiscall ios_op_not(const ios *this)
1883 TRACE("(%p)\n", this);
1884 return ios_fail(this);
1887 /* ??Bios@@QBEPAXXZ */
1888 /* ??Bios@@QEBAPEAXXZ */
1889 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1890 void* __thiscall ios_op_void(const ios *this)
1892 TRACE("(%p)\n", this);
1893 return ios_fail(this) ? NULL : (void*)this;
1896 /* ??_Eios@@UAEPAXI@Z */
1897 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1898 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1900 TRACE("(%p %x)\n", this, flags);
1901 if (flags & 2) {
1902 /* we have an array, with the number of elements stored before the first object */
1903 INT_PTR i, *ptr = (INT_PTR *)this-1;
1905 for (i = *ptr-1; i >= 0; i--)
1906 ios_dtor(this+i);
1907 MSVCRT_operator_delete(ptr);
1908 } else {
1909 ios_dtor(this);
1910 if (flags & 1)
1911 MSVCRT_operator_delete(this);
1913 return this;
1916 /* ??_Gios@@UAEPAXI@Z */
1917 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1918 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1920 TRACE("(%p %x)\n", this, flags);
1921 ios_dtor(this);
1922 if (flags & 1) MSVCRT_operator_delete(this);
1923 return this;
1926 /* ?bad@ios@@QBEHXZ */
1927 /* ?bad@ios@@QEBAHXZ */
1928 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1929 int __thiscall ios_bad(const ios *this)
1931 TRACE("(%p)\n", this);
1932 return (this->state & IOSTATE_badbit);
1935 /* ?bitalloc@ios@@SAJXZ */
1936 LONG __cdecl ios_bitalloc(void)
1938 TRACE("()\n");
1939 ios_lockc();
1940 ios_maxbit <<= 1;
1941 ios_unlockc();
1942 return ios_maxbit;
1945 /* ?clear@ios@@QAEXH@Z */
1946 /* ?clear@ios@@QEAAXH@Z */
1947 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1948 void __thiscall ios_clear(ios *this, int state)
1950 TRACE("(%p %d)\n", this, state);
1951 ios_lock(this);
1952 this->state = state;
1953 ios_unlock(this);
1956 /* ?clrlock@ios@@QAAXXZ */
1957 /* ?clrlock@ios@@QEAAXXZ */
1958 void __cdecl ios_clrlock(ios *this)
1960 TRACE("(%p)\n", this);
1961 if (this->do_lock <= 0)
1962 this->do_lock++;
1963 if (this->sb)
1964 streambuf_clrlock(this->sb);
1967 /* ?delbuf@ios@@QAEXH@Z */
1968 /* ?delbuf@ios@@QEAAXH@Z */
1969 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1970 void __thiscall ios_delbuf_set(ios *this, int delete)
1972 TRACE("(%p %d)\n", this, delete);
1973 this->delbuf = delete;
1976 /* ?delbuf@ios@@QBEHXZ */
1977 /* ?delbuf@ios@@QEBAHXZ */
1978 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1979 int __thiscall ios_delbuf_get(const ios *this)
1981 TRACE("(%p)\n", this);
1982 return this->delbuf;
1985 /* ?dec@@YAAAVios@@AAV1@@Z */
1986 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1987 ios* __cdecl ios_dec(ios *this)
1989 TRACE("(%p)\n", this);
1990 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1991 return this;
1994 /* ?eof@ios@@QBEHXZ */
1995 /* ?eof@ios@@QEBAHXZ */
1996 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1997 int __thiscall ios_eof(const ios *this)
1999 TRACE("(%p)\n", this);
2000 return (this->state & IOSTATE_eofbit);
2003 /* ?fail@ios@@QBEHXZ */
2004 /* ?fail@ios@@QEBAHXZ */
2005 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
2006 int __thiscall ios_fail(const ios *this)
2008 TRACE("(%p)\n", this);
2009 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
2012 /* ?fill@ios@@QAEDD@Z */
2013 /* ?fill@ios@@QEAADD@Z */
2014 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
2015 char __thiscall ios_fill_set(ios *this, char fill)
2017 char prev = this->fill;
2019 TRACE("(%p %d)\n", this, fill);
2021 this->fill = fill;
2022 return prev;
2025 /* ?fill@ios@@QBEDXZ */
2026 /* ?fill@ios@@QEBADXZ */
2027 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
2028 char __thiscall ios_fill_get(const ios *this)
2030 TRACE("(%p)\n", this);
2031 return this->fill;
2034 /* ?flags@ios@@QAEJJ@Z */
2035 /* ?flags@ios@@QEAAJJ@Z */
2036 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
2037 LONG __thiscall ios_flags_set(ios *this, LONG flags)
2039 LONG prev = this->flags;
2041 TRACE("(%p %x)\n", this, flags);
2043 this->flags = flags;
2044 return prev;
2047 /* ?flags@ios@@QBEJXZ */
2048 /* ?flags@ios@@QEBAJXZ */
2049 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
2050 LONG __thiscall ios_flags_get(const ios *this)
2052 TRACE("(%p)\n", this);
2053 return this->flags;
2056 /* ?good@ios@@QBEHXZ */
2057 /* ?good@ios@@QEBAHXZ */
2058 DEFINE_THISCALL_WRAPPER(ios_good, 4)
2059 int __thiscall ios_good(const ios *this)
2061 TRACE("(%p)\n", this);
2062 return this->state == IOSTATE_goodbit;
2065 /* ?hex@@YAAAVios@@AAV1@@Z */
2066 /* ?hex@@YAAEAVios@@AEAV1@@Z */
2067 ios* __cdecl ios_hex(ios *this)
2069 TRACE("(%p)\n", this);
2070 ios_setf_mask(this, FLAGS_hex, ios_basefield);
2071 return this;
2074 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
2075 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
2076 DEFINE_THISCALL_WRAPPER(ios_init, 8)
2077 void __thiscall ios_init(ios *this, streambuf *sb)
2079 TRACE("(%p %p)\n", this, sb);
2080 if (this->delbuf && this->sb)
2081 call_streambuf_vector_dtor(this->sb, 1);
2082 this->sb = sb;
2083 if (sb == NULL)
2084 this->state |= IOSTATE_badbit;
2085 else
2086 this->state &= ~IOSTATE_badbit;
2089 /* ?iword@ios@@QBEAAJH@Z */
2090 /* ?iword@ios@@QEBAAEAJH@Z */
2091 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2092 LONG* __thiscall ios_iword(const ios *this, int index)
2094 TRACE("(%p %d)\n", this, index);
2095 return &ios_statebuf[index];
2098 /* ?lock@ios@@QAAXXZ */
2099 /* ?lock@ios@@QEAAXXZ */
2100 void __cdecl ios_lock(ios *this)
2102 TRACE("(%p)\n", this);
2103 if (this->do_lock < 0)
2104 EnterCriticalSection(&this->lock);
2107 /* ?lockbuf@ios@@QAAXXZ */
2108 /* ?lockbuf@ios@@QEAAXXZ */
2109 void __cdecl ios_lockbuf(ios *this)
2111 TRACE("(%p)\n", this);
2112 streambuf_lock(this->sb);
2115 /* ?lockc@ios@@KAXXZ */
2116 void __cdecl ios_lockc(void)
2118 TRACE("()\n");
2119 EnterCriticalSection(&ios_static_lock);
2122 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2123 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2124 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2125 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2127 TRACE("(%p)\n", this);
2128 return &this->lock;
2131 /* ?oct@@YAAAVios@@AAV1@@Z */
2132 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2133 ios* __cdecl ios_oct(ios *this)
2135 TRACE("(%p)\n", this);
2136 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2137 return this;
2140 /* ?precision@ios@@QAEHH@Z */
2141 /* ?precision@ios@@QEAAHH@Z */
2142 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2143 int __thiscall ios_precision_set(ios *this, int prec)
2145 int prev = this->precision;
2147 TRACE("(%p %d)\n", this, prec);
2149 this->precision = prec;
2150 return prev;
2153 /* ?precision@ios@@QBEHXZ */
2154 /* ?precision@ios@@QEBAHXZ */
2155 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2156 int __thiscall ios_precision_get(const ios *this)
2158 TRACE("(%p)\n", this);
2159 return this->precision;
2162 /* ?pword@ios@@QBEAAPAXH@Z */
2163 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2164 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2165 void** __thiscall ios_pword(const ios *this, int index)
2167 TRACE("(%p %d)\n", this, index);
2168 return (void**)&ios_statebuf[index];
2171 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2172 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2173 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2174 streambuf* __thiscall ios_rdbuf(const ios *this)
2176 TRACE("(%p)\n", this);
2177 return this->sb;
2180 /* ?rdstate@ios@@QBEHXZ */
2181 /* ?rdstate@ios@@QEBAHXZ */
2182 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2183 int __thiscall ios_rdstate(const ios *this)
2185 TRACE("(%p)\n", this);
2186 return this->state;
2189 /* ?setf@ios@@QAEJJ@Z */
2190 /* ?setf@ios@@QEAAJJ@Z */
2191 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2192 LONG __thiscall ios_setf(ios *this, LONG flags)
2194 LONG prev = this->flags;
2196 TRACE("(%p %x)\n", this, flags);
2198 ios_lock(this);
2199 this->flags |= flags;
2200 ios_unlock(this);
2201 return prev;
2204 /* ?setf@ios@@QAEJJJ@Z */
2205 /* ?setf@ios@@QEAAJJJ@Z */
2206 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2207 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2209 LONG prev = this->flags;
2211 TRACE("(%p %x %x)\n", this, flags, mask);
2213 ios_lock(this);
2214 this->flags = (this->flags & (~mask)) | (flags & mask);
2215 ios_unlock(this);
2216 return prev;
2219 /* ?setlock@ios@@QAAXXZ */
2220 /* ?setlock@ios@@QEAAXXZ */
2221 void __cdecl ios_setlock(ios *this)
2223 TRACE("(%p)\n", this);
2224 this->do_lock--;
2225 if (this->sb)
2226 streambuf_setlock(this->sb);
2229 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2230 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2231 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2232 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2234 ostream *prev = this->tie;
2236 TRACE("(%p %p)\n", this, ostr);
2238 this->tie = ostr;
2239 return prev;
2242 /* ?tie@ios@@QBEPAVostream@@XZ */
2243 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2244 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2245 ostream* __thiscall ios_tie_get(const ios *this)
2247 TRACE("(%p)\n", this);
2248 return this->tie;
2251 /* ?unlock@ios@@QAAXXZ */
2252 /* ?unlock@ios@@QEAAXXZ */
2253 void __cdecl ios_unlock(ios *this)
2255 TRACE("(%p)\n", this);
2256 if (this->do_lock < 0)
2257 LeaveCriticalSection(&this->lock);
2260 /* ?unlockbuf@ios@@QAAXXZ */
2261 /* ?unlockbuf@ios@@QEAAXXZ */
2262 void __cdecl ios_unlockbuf(ios *this)
2264 TRACE("(%p)\n", this);
2265 streambuf_unlock(this->sb);
2268 /* ?unlockc@ios@@KAXXZ */
2269 void __cdecl ios_unlockc(void)
2271 TRACE("()\n");
2272 LeaveCriticalSection(&ios_static_lock);
2275 /* ?unsetf@ios@@QAEJJ@Z */
2276 /* ?unsetf@ios@@QEAAJJ@Z */
2277 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2278 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2280 LONG prev = this->flags;
2282 TRACE("(%p %x)\n", this, flags);
2284 ios_lock(this);
2285 this->flags &= ~flags;
2286 ios_unlock(this);
2287 return prev;
2290 /* ?width@ios@@QAEHH@Z */
2291 /* ?width@ios@@QEAAHH@Z */
2292 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2293 int __thiscall ios_width_set(ios *this, int width)
2295 int prev = this->width;
2297 TRACE("(%p %d)\n", this, width);
2299 this->width = width;
2300 return prev;
2303 /* ?width@ios@@QBEHXZ */
2304 /* ?width@ios@@QEBAHXZ */
2305 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2306 int __thiscall ios_width_get(const ios *this)
2308 TRACE("(%p)\n", this);
2309 return this->width;
2312 /* ?xalloc@ios@@SAHXZ */
2313 int __cdecl ios_xalloc(void)
2315 int ret;
2317 TRACE("()\n");
2319 ios_lockc();
2320 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2321 ios_unlockc();
2322 return ret;
2325 static inline ios* ostream_get_ios(const ostream *this)
2327 return (ios*)((char*)this + this->vbtable[1]);
2330 static inline ios* ostream_to_ios(const ostream *this)
2332 return (ios*)((char*)this + ostream_vbtable[1]);
2335 static inline ostream* ios_to_ostream(const ios *base)
2337 return (ostream*)((char*)base - ostream_vbtable[1]);
2340 /* ??0ostream@@IAE@XZ */
2341 /* ??0ostream@@IEAA@XZ */
2342 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2343 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2345 ios *base;
2347 TRACE("(%p %d)\n", this, virt_init);
2349 if (virt_init) {
2350 this->vbtable = ostream_vbtable;
2351 base = ostream_get_ios(this);
2352 ios_ctor(base);
2353 } else
2354 base = ostream_get_ios(this);
2355 base->vtable = &MSVCP_ostream_vtable;
2356 this->unknown = 0;
2357 return this;
2360 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2361 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2362 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2363 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2365 TRACE("(%p %p %d)\n", this, sb, virt_init);
2366 ostream_ctor(this, virt_init);
2367 ios_init(ostream_get_ios(this), sb);
2368 return this;
2371 /* ??0ostream@@IAE@ABV0@@Z */
2372 /* ??0ostream@@IEAA@AEBV0@@Z */
2373 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2374 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2376 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2379 /* ??1ostream@@UAE@XZ */
2380 /* ??1ostream@@UEAA@XZ */
2381 /* ??1ostream_withassign@@UAE@XZ */
2382 /* ??1ostream_withassign@@UEAA@XZ */
2383 /* ??1ostrstream@@UAE@XZ */
2384 /* ??1ostrstream@@UEAA@XZ */
2385 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2386 void __thiscall ostream_dtor(ios *base)
2388 ostream *this = ios_to_ostream(base);
2390 TRACE("(%p)\n", this);
2393 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2394 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2395 /* ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z */
2396 /* ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z */
2397 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2398 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2400 ios *base = ostream_get_ios(this);
2402 TRACE("(%p %p)\n", this, sb);
2404 ios_init(base, sb);
2405 base->state &= IOSTATE_badbit;
2406 base->delbuf = 0;
2407 base->tie = NULL;
2408 base->flags = 0;
2409 base->precision = 6;
2410 base->fill = ' ';
2411 base->width = 0;
2412 return this;
2415 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2416 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2417 /* ??4ostream_withassign@@QAEAAV0@ABV0@@Z */
2418 /* ??4ostream_withassign@@QEAAAEAV0@AEBV0@@Z */
2419 /* ??4ostream_withassign@@QAEAAVostream@@ABV1@@Z */
2420 /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */
2421 /* ??4ostrstream@@QAEAAV0@ABV0@@Z */
2422 /* ??4ostrstream@@QEAAAEAV0@AEBV0@@Z */
2423 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2424 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2426 return ostream_assign_sb(this, ostream_get_ios(rhs)->sb);
2429 /* ??_Dostream@@QAEXXZ */
2430 /* ??_Dostream@@QEAAXXZ */
2431 /* ??_Dostream_withassign@@QAEXXZ */
2432 /* ??_Dostream_withassign@@QEAAXXZ */
2433 /* ??_Dostrstream@@QAEXXZ */
2434 /* ??_Dostrstream@@QEAAXXZ */
2435 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2436 void __thiscall ostream_vbase_dtor(ostream *this)
2438 ios *base = ostream_to_ios(this);
2440 TRACE("(%p)\n", this);
2442 ostream_dtor(base);
2443 ios_dtor(base);
2446 /* ??_Eostream@@UAEPAXI@Z */
2447 /* ??_Eostream_withassign@@UAEPAXI@Z */
2448 /* ??_Eostrstream@@UAEPAXI@Z */
2449 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2450 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2452 ostream *this = ios_to_ostream(base);
2454 TRACE("(%p %x)\n", this, flags);
2456 if (flags & 2) {
2457 /* we have an array, with the number of elements stored before the first object */
2458 INT_PTR i, *ptr = (INT_PTR *)this-1;
2460 for (i = *ptr-1; i >= 0; i--)
2461 ostream_vbase_dtor(this+i);
2462 MSVCRT_operator_delete(ptr);
2463 } else {
2464 ostream_vbase_dtor(this);
2465 if (flags & 1)
2466 MSVCRT_operator_delete(this);
2468 return this;
2471 /* ??_Gostream@@UAEPAXI@Z */
2472 /* ??_Gostream_withassign@@UAEPAXI@Z */
2473 /* ??_Gostrstream@@UAEPAXI@Z */
2474 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2475 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2477 ostream *this = ios_to_ostream(base);
2479 TRACE("(%p %x)\n", this, flags);
2481 ostream_vbase_dtor(this);
2482 if (flags & 1) MSVCRT_operator_delete(this);
2483 return this;
2486 /* ?flush@ostream@@QAEAAV1@XZ */
2487 /* ?flush@ostream@@QEAAAEAV1@XZ */
2488 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2489 ostream* __thiscall ostream_flush(ostream *this)
2491 ios *base = ostream_get_ios(this);
2493 TRACE("(%p)\n", this);
2495 ios_lockbuf(base);
2496 if (call_streambuf_sync(base->sb) == EOF)
2497 ios_clear(base, base->state | IOSTATE_failbit);
2498 ios_unlockbuf(base);
2499 return this;
2502 /* ?opfx@ostream@@QAEHXZ */
2503 /* ?opfx@ostream@@QEAAHXZ */
2504 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2505 int __thiscall ostream_opfx(ostream *this)
2507 ios *base = ostream_get_ios(this);
2509 TRACE("(%p)\n", this);
2511 if (!ios_good(base)) {
2512 ios_clear(base, base->state | IOSTATE_failbit);
2513 return 0;
2515 ios_lock(base);
2516 ios_lockbuf(base);
2517 if (base->tie)
2518 ostream_flush(base->tie);
2519 return 1;
2522 /* ?osfx@ostream@@QAEXXZ */
2523 /* ?osfx@ostream@@QEAAXXZ */
2524 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2525 void __thiscall ostream_osfx(ostream *this)
2527 ios *base = ostream_get_ios(this);
2529 TRACE("(%p)\n", this);
2531 ios_unlockbuf(base);
2532 ios_width_set(base, 0);
2533 if (base->flags & FLAGS_unitbuf)
2534 ostream_flush(this);
2535 if (base->flags & FLAGS_stdio) {
2536 fflush(stdout);
2537 fflush(stderr);
2539 ios_unlock(base);
2542 /* ?put@ostream@@QAEAAV1@C@Z */
2543 /* ?put@ostream@@QEAAAEAV1@C@Z */
2544 /* ?put@ostream@@QAEAAV1@D@Z */
2545 /* ?put@ostream@@QEAAAEAV1@D@Z */
2546 /* ?put@ostream@@QAEAAV1@E@Z */
2547 /* ?put@ostream@@QEAAAEAV1@E@Z */
2548 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2549 ostream* __thiscall ostream_put(ostream *this, char c)
2551 ios *base = ostream_get_ios(this);
2553 TRACE("(%p %c)\n", this, c);
2555 if (ostream_opfx(this)) {
2556 if (streambuf_sputc(base->sb, c) == EOF)
2557 base->state = IOSTATE_badbit | IOSTATE_failbit;
2558 ostream_osfx(this);
2560 return this;
2563 /* ?seekp@ostream@@QAEAAV1@J@Z */
2564 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2565 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2566 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2568 ios *base = ostream_get_ios(this);
2570 TRACE("(%p %d)\n", this, pos);
2572 ios_lockbuf(base);
2573 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2574 ios_clear(base, base->state | IOSTATE_failbit);
2575 ios_unlockbuf(base);
2576 return this;
2579 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2580 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2581 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2582 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2584 ios *base = ostream_get_ios(this);
2586 TRACE("(%p %d %d)\n", this, off, dir);
2588 ios_lockbuf(base);
2589 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2590 ios_clear(base, base->state | IOSTATE_failbit);
2591 ios_unlockbuf(base);
2592 return this;
2595 /* ?tellp@ostream@@QAEJXZ */
2596 /* ?tellp@ostream@@QEAAJXZ */
2597 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2598 streampos __thiscall ostream_tellp(ostream *this)
2600 ios *base = ostream_get_ios(this);
2601 streampos pos;
2603 TRACE("(%p)\n", this);
2605 ios_lockbuf(base);
2606 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2607 ios_clear(base, base->state | IOSTATE_failbit);
2608 ios_unlockbuf(base);
2609 return pos;
2612 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2613 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2614 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2615 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2616 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2617 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2618 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2619 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2621 ios *base = ostream_get_ios(this);
2623 TRACE("(%p %p %d)\n", this, str, count);
2625 if (ostream_opfx(this)) {
2626 if (streambuf_sputn(base->sb, str, count) != count)
2627 base->state = IOSTATE_badbit | IOSTATE_failbit;
2628 ostream_osfx(this);
2630 return this;
2633 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2634 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2635 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2636 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2638 ios *base = ostream_get_ios(this);
2639 int len1 = strlen(str1), len2 = strlen(str2), i;
2641 TRACE("(%p %p %p)\n", this, str1, str2);
2643 /* left of the padding */
2644 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2645 if (streambuf_sputn(base->sb, str1, len1) != len1)
2646 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2647 if (!(base->flags & FLAGS_internal))
2648 if (streambuf_sputn(base->sb, str2, len2) != len2)
2649 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2651 /* add padding to fill the width */
2652 for (i = len1 + len2; i < base->width; i++)
2653 if (streambuf_sputc(base->sb, base->fill) == EOF)
2654 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2655 /* right of the padding */
2656 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2657 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2658 if (streambuf_sputn(base->sb, str1, len1) != len1)
2659 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2660 if (streambuf_sputn(base->sb, str2, len2) != len2)
2661 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2663 return this;
2666 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2668 ios *base = ostream_get_ios(ostr);
2669 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2671 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2673 if (ostream_opfx(ostr)) {
2674 if (base->flags & FLAGS_hex) {
2675 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2676 if (base->flags & FLAGS_showbase) {
2677 prefix_str[0] = '0';
2678 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2680 } else if (base->flags & FLAGS_oct) {
2681 sprintf_fmt[1] = 'o';
2682 if (base->flags & FLAGS_showbase)
2683 prefix_str[0] = '0';
2684 } else { /* FLAGS_dec */
2685 if (unsig)
2686 sprintf_fmt[1] = 'u';
2687 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2688 prefix_str[0] = '+';
2691 if (shrt) {
2692 sprintf_fmt[2] = sprintf_fmt[1];
2693 sprintf_fmt[1] = 'h';
2696 if (sprintf(number_str, sprintf_fmt, n) > 0)
2697 ostream_writepad(ostr, prefix_str, number_str);
2698 else
2699 base->state |= IOSTATE_failbit;
2700 ostream_osfx(ostr);
2702 return ostr;
2705 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2707 ios *base = ostream_get_ios(ostr);
2708 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2709 int prec, max_prec = dbl ? 15 : 6;
2710 int str_length = 1; /* null end char */
2712 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2714 if (ostream_opfx(ostr)) {
2715 if ((base->flags & FLAGS_showpos) && d > 0) {
2716 prefix_str[0] = '+';
2717 str_length++; /* plus sign */
2719 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2720 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2721 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2722 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2723 if (base->flags & FLAGS_showpoint) {
2724 sprintf_fmt[4] = sprintf_fmt[3];
2725 sprintf_fmt[3] = sprintf_fmt[2];
2726 sprintf_fmt[2] = sprintf_fmt[1];
2727 sprintf_fmt[1] = '#';
2730 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2731 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2732 if (str_length > 24) {
2733 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2734 ostream_writepad(ostr, "", "");
2735 } else {
2736 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2737 ostream_writepad(ostr, prefix_str, number_str);
2738 else
2739 base->state |= IOSTATE_failbit;
2741 ostream_osfx(ostr);
2743 return ostr;
2746 /* ??6ostream@@QAEAAV0@C@Z */
2747 /* ??6ostream@@QEAAAEAV0@C@Z */
2748 /* ??6ostream@@QAEAAV0@D@Z */
2749 /* ??6ostream@@QEAAAEAV0@D@Z */
2750 /* ??6ostream@@QAEAAV0@E@Z */
2751 /* ??6ostream@@QEAAAEAV0@E@Z */
2752 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2753 ostream* __thiscall ostream_print_char(ostream *this, char c)
2755 const char c_str[2] = {c, 0};
2757 TRACE("(%p %c)\n", this, c);
2759 if (ostream_opfx(this)) {
2760 ostream_writepad(this, "", c_str);
2761 ostream_osfx(this);
2763 return this;
2766 /* ??6ostream@@QAEAAV0@PBC@Z */
2767 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2768 /* ??6ostream@@QAEAAV0@PBD@Z */
2769 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2770 /* ??6ostream@@QAEAAV0@PBE@Z */
2771 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2772 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2773 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2775 TRACE("(%p %s)\n", this, str);
2776 if (ostream_opfx(this)) {
2777 ostream_writepad(this, "", str);
2778 ostream_osfx(this);
2780 return this;
2783 /* ??6ostream@@QAEAAV0@F@Z */
2784 /* ??6ostream@@QEAAAEAV0@F@Z */
2785 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2786 ostream* __thiscall ostream_print_short(ostream *this, short n)
2788 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2791 /* ??6ostream@@QAEAAV0@G@Z */
2792 /* ??6ostream@@QEAAAEAV0@G@Z */
2793 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2794 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2796 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2799 /* ??6ostream@@QAEAAV0@H@Z */
2800 /* ??6ostream@@QEAAAEAV0@H@Z */
2801 /* ??6ostream@@QAEAAV0@J@Z */
2802 /* ??6ostream@@QEAAAEAV0@J@Z */
2803 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2804 ostream* __thiscall ostream_print_int(ostream *this, int n)
2806 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2809 /* ??6ostream@@QAEAAV0@I@Z */
2810 /* ??6ostream@@QEAAAEAV0@I@Z */
2811 /* ??6ostream@@QAEAAV0@K@Z */
2812 /* ??6ostream@@QEAAAEAV0@K@Z */
2813 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2814 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2816 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2819 /* ??6ostream@@QAEAAV0@M@Z */
2820 /* ??6ostream@@QEAAAEAV0@M@Z */
2821 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2822 ostream* __thiscall ostream_print_float(ostream *this, float f)
2824 return ostream_internal_print_float(this, f, FALSE);
2827 /* ??6ostream@@QAEAAV0@N@Z */
2828 /* ??6ostream@@QEAAAEAV0@N@Z */
2829 /* ??6ostream@@QAEAAV0@O@Z */
2830 /* ??6ostream@@QEAAAEAV0@O@Z */
2831 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2832 ostream* __thiscall ostream_print_double(ostream *this, double d)
2834 return ostream_internal_print_float(this, d, TRUE);
2837 /* ??6ostream@@QAEAAV0@PBX@Z */
2838 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2839 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2840 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2842 ios *base = ostream_get_ios(this);
2843 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2845 TRACE("(%p %p)\n", this, ptr);
2847 if (ostream_opfx(this)) {
2848 if (ptr && base->flags & FLAGS_uppercase)
2849 prefix_str[1] = 'X';
2851 if (sprintf(pointer_str, "%p", ptr) > 0)
2852 ostream_writepad(this, prefix_str, pointer_str);
2853 else
2854 base->state |= IOSTATE_failbit;
2855 ostream_osfx(this);
2857 return this;
2860 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2861 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2862 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2863 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2865 ios *base = ostream_get_ios(this);
2866 int c;
2868 TRACE("(%p %p)\n", this, sb);
2870 if (ostream_opfx(this)) {
2871 while ((c = streambuf_sbumpc(sb)) != EOF) {
2872 if (streambuf_sputc(base->sb, c) == EOF) {
2873 base->state |= IOSTATE_failbit;
2874 break;
2877 ostream_osfx(this);
2879 return this;
2882 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2883 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2884 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2885 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2887 TRACE("(%p %p)\n", this, func);
2888 return func(this);
2891 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2892 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2893 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2894 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2896 TRACE("(%p %p)\n", this, func);
2897 func(ostream_get_ios(this));
2898 return this;
2901 /* ?endl@@YAAAVostream@@AAV1@@Z */
2902 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2903 ostream* __cdecl ostream_endl(ostream *this)
2905 TRACE("(%p)\n", this);
2906 ostream_put(this, '\n');
2907 return ostream_flush(this);
2910 /* ?ends@@YAAAVostream@@AAV1@@Z */
2911 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2912 ostream* __cdecl ostream_ends(ostream *this)
2914 TRACE("(%p)\n", this);
2915 return ostream_put(this, 0);
2918 /* ?flush@@YAAAVostream@@AAV1@@Z */
2919 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2920 ostream* __cdecl ostream_flush_manip(ostream *this)
2922 TRACE("(%p)\n", this);
2923 return ostream_flush(this);
2926 /* ??0ostream_withassign@@QAE@ABV0@@Z */
2927 /* ??0ostream_withassign@@QEAA@AEBV0@@Z */
2928 DEFINE_THISCALL_WRAPPER(ostream_withassign_copy_ctor, 12)
2929 ostream* __thiscall ostream_withassign_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2931 ios *base, *base_copy;
2933 TRACE("(%p %p %d)\n", this, copy, virt_init);
2935 base_copy = ostream_get_ios(copy);
2936 if (virt_init) {
2937 this->vbtable = ostream_vbtable;
2938 base = ostream_get_ios(this);
2939 ios_copy_ctor(base, base_copy);
2940 } else
2941 base = ostream_get_ios(this);
2942 ios_init(base, base_copy->sb);
2943 base->vtable = &MSVCP_ostream_withassign_vtable;
2944 this->unknown = 0;
2945 return this;
2948 /* ??0ostream_withassign@@QAE@PAVstreambuf@@@Z */
2949 /* ??0ostream_withassign@@QEAA@PEAVstreambuf@@@Z */
2950 DEFINE_THISCALL_WRAPPER(ostream_withassign_sb_ctor, 12)
2951 ostream* __thiscall ostream_withassign_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2953 ios *base;
2955 TRACE("(%p %p %d)\n", this, sb, virt_init);
2957 ostream_sb_ctor(this, sb, virt_init);
2958 base = ostream_get_ios(this);
2959 base->vtable = &MSVCP_ostream_withassign_vtable;
2960 return this;
2963 /* ??0ostream_withassign@@QAE@XZ */
2964 /* ??0ostream_withassign@@QEAA@XZ */
2965 DEFINE_THISCALL_WRAPPER(ostream_withassign_ctor, 8)
2966 ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init)
2968 ios *base;
2970 TRACE("(%p %d)\n", this, virt_init);
2972 ostream_ctor(this, virt_init);
2973 base = ostream_get_ios(this);
2974 base->vtable = &MSVCP_ostream_withassign_vtable;
2975 return this;
2978 static ostream* ostrstream_internal_sb_ctor(ostream *this, strstreambuf *ssb, BOOL virt_init)
2980 ios *base;
2982 if (ssb)
2983 ostream_sb_ctor(this, &ssb->base, virt_init);
2984 else
2985 ostream_ctor(this, virt_init);
2986 base = ostream_get_ios(this);
2987 base->vtable = &MSVCP_ostrstream_vtable;
2988 base->delbuf = 1;
2989 return this;
2992 /* ??0ostrstream@@QAE@ABV0@@Z */
2993 /* ??0ostrstream@@QEAA@AEBV0@@Z */
2994 DEFINE_THISCALL_WRAPPER(ostrstream_copy_ctor, 12)
2995 ostream* __thiscall ostrstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2997 TRACE("(%p %p %d)\n", this, copy, virt_init);
2998 ostream_withassign_copy_ctor(this, copy, virt_init);
2999 ostream_get_ios(this)->vtable = &MSVCP_ostrstream_vtable;
3000 return this;
3003 /* ??0ostrstream@@QAE@PADHH@Z */
3004 /* ??0ostrstream@@QEAA@PEADHH@Z */
3005 DEFINE_THISCALL_WRAPPER(ostrstream_buffer_ctor, 20)
3006 ostream* __thiscall ostrstream_buffer_ctor(ostream *this, char *buffer, int length, int mode, BOOL virt_init)
3008 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
3010 TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init);
3012 if (ssb) {
3013 strstreambuf_buffer_ctor(ssb, buffer, length, buffer);
3014 if (mode & (OPENMODE_app|OPENMODE_ate))
3015 ssb->base.pptr = buffer + strlen(buffer);
3017 return ostrstream_internal_sb_ctor(this, ssb, virt_init);
3020 /* ??0ostrstream@@QAE@XZ */
3021 /* ??0ostrstream@@QEAA@XZ */
3022 DEFINE_THISCALL_WRAPPER(ostrstream_ctor, 8)
3023 ostream* __thiscall ostrstream_ctor(ostream *this, BOOL virt_init)
3025 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
3027 TRACE("(%p %d)\n", this, virt_init);
3029 if (ssb)
3030 strstreambuf_ctor(ssb);
3031 return ostrstream_internal_sb_ctor(this, ssb, virt_init);
3034 /* ?pcount@ostrstream@@QBEHXZ */
3035 /* ?pcount@ostrstream@@QEBAHXZ */
3036 DEFINE_THISCALL_WRAPPER(ostrstream_pcount, 4)
3037 int __thiscall ostrstream_pcount(const ostream *this)
3039 return streambuf_out_waiting(ostream_get_ios(this)->sb);
3042 /* ?rdbuf@ostrstream@@QBEPAVstrstreambuf@@XZ */
3043 /* ?rdbuf@ostrstream@@QEBAPEAVstrstreambuf@@XZ */
3044 DEFINE_THISCALL_WRAPPER(ostrstream_rdbuf, 4)
3045 strstreambuf* __thiscall ostrstream_rdbuf(const ostream *this)
3047 return (strstreambuf*) ostream_get_ios(this)->sb;
3050 /* ?str@ostrstream@@QAEPADXZ */
3051 /* ?str@ostrstream@@QEAAPEADXZ */
3052 DEFINE_THISCALL_WRAPPER(ostrstream_str, 4)
3053 char* __thiscall ostrstream_str(ostream *this)
3055 return strstreambuf_str(ostrstream_rdbuf(this));
3058 static inline ios* istream_get_ios(const istream *this)
3060 return (ios*)((char*)this + this->vbtable[1]);
3063 static inline ios* istream_to_ios(const istream *this)
3065 return (ios*)((char*)this + istream_vbtable[1]);
3068 static inline istream* ios_to_istream(const ios *base)
3070 return (istream*)((char*)base - istream_vbtable[1]);
3073 /* ??0istream@@IAE@XZ */
3074 /* ??0istream@@IEAA@XZ */
3075 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
3076 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
3078 ios *base;
3080 TRACE("(%p %d)\n", this, virt_init);
3082 if (virt_init) {
3083 this->vbtable = istream_vbtable;
3084 base = istream_get_ios(this);
3085 ios_ctor(base);
3086 } else
3087 base = istream_get_ios(this);
3088 base->vtable = &MSVCP_istream_vtable;
3089 base->flags |= FLAGS_skipws;
3090 this->extract_delim = 0;
3091 this->count = 0;
3092 return this;
3095 /* ??0istream@@QAE@PAVstreambuf@@@Z */
3096 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
3097 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
3098 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
3100 TRACE("(%p %p %d)\n", this, sb, virt_init);
3101 istream_ctor(this, virt_init);
3102 ios_init(istream_get_ios(this), sb);
3103 return this;
3106 /* ??0istream@@IAE@ABV0@@Z */
3107 /* ??0istream@@IEAA@AEBV0@@Z */
3108 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
3109 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3111 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
3114 /* ??1istream@@UAE@XZ */
3115 /* ??1istream@@UEAA@XZ */
3116 /* ??1istream_withassign@@UAE@XZ */
3117 /* ??1istream_withassign@@UEAA@XZ */
3118 /* ??1istrstream@@UAE@XZ */
3119 /* ??1istrstream@@UEAA@XZ */
3120 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
3121 void __thiscall istream_dtor(ios *base)
3123 istream *this = ios_to_istream(base);
3125 TRACE("(%p)\n", this);
3128 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
3129 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3130 /* ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z */
3131 /* ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z */
3132 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
3133 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
3135 ios *base = istream_get_ios(this);
3137 TRACE("(%p %p)\n", this, sb);
3139 ios_init(base, sb);
3140 base->state &= IOSTATE_badbit;
3141 base->delbuf = 0;
3142 base->tie = NULL;
3143 base->flags = FLAGS_skipws;
3144 base->precision = 6;
3145 base->fill = ' ';
3146 base->width = 0;
3147 this->count = 0;
3148 return this;
3151 /* ??4istream@@IAEAAV0@ABV0@@Z */
3152 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
3153 /* ??4istream_withassign@@QAEAAV0@ABV0@@Z */
3154 /* ??4istream_withassign@@QEAAAEAV0@AEBV0@@Z */
3155 /* ??4istream_withassign@@QAEAAVistream@@ABV1@@Z */
3156 /* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */
3157 /* ??4istrstream@@QAEAAV0@ABV0@@Z */
3158 /* ??4istrstream@@QEAAAEAV0@AEBV0@@Z */
3159 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
3160 istream* __thiscall istream_assign(istream *this, const istream *rhs)
3162 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
3165 /* ??_Distream@@QAEXXZ */
3166 /* ??_Distream@@QEAAXXZ */
3167 /* ??_Distream_withassign@@QAEXXZ */
3168 /* ??_Distream_withassign@@QEAAXXZ */
3169 /* ??_Distrstream@@QAEXXZ */
3170 /* ??_Distrstream@@QEAAXXZ */
3171 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
3172 void __thiscall istream_vbase_dtor(istream *this)
3174 ios *base = istream_to_ios(this);
3176 TRACE("(%p)\n", this);
3178 istream_dtor(base);
3179 ios_dtor(base);
3182 /* ??_Eistream@@UAEPAXI@Z */
3183 /* ??_Eistream_withassign@@UAEPAXI@Z */
3184 /* ??_Eistrstream@@UAEPAXI@Z */
3185 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
3186 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
3188 istream *this = ios_to_istream(base);
3190 TRACE("(%p %x)\n", this, flags);
3192 if (flags & 2) {
3193 /* we have an array, with the number of elements stored before the first object */
3194 INT_PTR i, *ptr = (INT_PTR *)this-1;
3196 for (i = *ptr-1; i >= 0; i--)
3197 istream_vbase_dtor(this+i);
3198 MSVCRT_operator_delete(ptr);
3199 } else {
3200 istream_vbase_dtor(this);
3201 if (flags & 1)
3202 MSVCRT_operator_delete(this);
3204 return this;
3207 /* ??_Gistream@@UAEPAXI@Z */
3208 /* ??_Gistream_withassign@@UAEPAXI@Z */
3209 /* ??_Gistrstream@@UAEPAXI@Z */
3210 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
3211 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
3213 istream *this = ios_to_istream(base);
3215 TRACE("(%p %x)\n", this, flags);
3217 istream_vbase_dtor(this);
3218 if (flags & 1) MSVCRT_operator_delete(this);
3219 return this;
3222 /* ?eatwhite@istream@@QAEXXZ */
3223 /* ?eatwhite@istream@@QEAAXXZ */
3224 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3225 void __thiscall istream_eatwhite(istream *this)
3227 ios *base = istream_get_ios(this);
3228 int c;
3230 TRACE("(%p)\n", this);
3232 ios_lockbuf(base);
3233 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3234 ios_unlockbuf(base);
3235 if (c == EOF)
3236 ios_clear(base, base->state | IOSTATE_eofbit);
3239 /* ?gcount@istream@@QBEHXZ */
3240 /* ?gcount@istream@@QEBAHXZ */
3241 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3242 int __thiscall istream_gcount(const istream *this)
3244 TRACE("(%p)\n", this);
3245 return this->count;
3248 /* ?ipfx@istream@@QAEHH@Z */
3249 /* ?ipfx@istream@@QEAAHH@Z */
3250 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3251 int __thiscall istream_ipfx(istream *this, int need)
3253 ios *base = istream_get_ios(this);
3255 TRACE("(%p %d)\n", this, need);
3257 if (need)
3258 this->count = 0;
3259 if (!ios_good(base)) {
3260 ios_clear(base, base->state | IOSTATE_failbit);
3261 return 0;
3263 ios_lock(base);
3264 ios_lockbuf(base);
3265 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3266 ostream_flush(base->tie);
3267 if ((base->flags & FLAGS_skipws) && !need) {
3268 istream_eatwhite(this);
3269 if (base->state & IOSTATE_eofbit) {
3270 base->state |= IOSTATE_failbit;
3271 ios_unlockbuf(base);
3272 ios_unlock(base);
3273 return 0;
3276 return 1;
3279 /* ?isfx@istream@@QAEXXZ */
3280 /* ?isfx@istream@@QEAAXXZ */
3281 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3282 void __thiscall istream_isfx(istream *this)
3284 ios *base = istream_get_ios(this);
3286 TRACE("(%p)\n", this);
3288 ios_unlockbuf(base);
3289 ios_unlock(base);
3292 /* ?get@istream@@IAEAAV1@PADHH@Z */
3293 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3294 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3295 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3297 ios *base = istream_get_ios(this);
3298 int ch, i = 0;
3300 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3302 if (istream_ipfx(this, 1)) {
3303 while (i < count - 1) {
3304 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3305 base->state |= IOSTATE_eofbit;
3306 if (!i) /* tried to read, but not a single character was obtained */
3307 base->state |= IOSTATE_failbit;
3308 break;
3310 if (ch == delim) {
3311 if (this->extract_delim) { /* discard the delimiter */
3312 streambuf_stossc(base->sb);
3313 this->count++;
3315 break;
3317 if (str)
3318 str[i] = ch;
3319 streambuf_stossc(base->sb);
3320 i++;
3322 this->count += i;
3323 istream_isfx(this);
3325 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3326 str[i] = 0;
3327 this->extract_delim = 0;
3328 return this;
3331 /* ?get@istream@@QAEAAV1@PACHD@Z */
3332 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3333 /* ?get@istream@@QAEAAV1@PADHD@Z */
3334 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3335 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3336 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3337 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3338 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3340 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3343 static int istream_internal_get_char(istream *this, char *ch)
3345 ios *base = istream_get_ios(this);
3346 int ret = EOF;
3348 TRACE("(%p %p)\n", this, ch);
3350 if (istream_ipfx(this, 1)) {
3351 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3352 this->count = 1;
3353 } else {
3354 base->state |= IOSTATE_eofbit;
3355 if (ch)
3356 base->state |= IOSTATE_failbit;
3358 if (ch)
3359 *ch = ret;
3360 istream_isfx(this);
3362 return ret;
3365 /* ?get@istream@@QAEAAV1@AAC@Z */
3366 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3367 /* ?get@istream@@QAEAAV1@AAD@Z */
3368 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3369 /* ?get@istream@@QAEAAV1@AAE@Z */
3370 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3371 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3372 istream* __thiscall istream_get_char(istream *this, char *ch)
3374 istream_internal_get_char(this, ch);
3375 return this;
3378 /* ?get@istream@@QAEHXZ */
3379 /* ?get@istream@@QEAAHXZ */
3380 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3381 int __thiscall istream_get(istream *this)
3383 return istream_internal_get_char(this, NULL);
3386 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3387 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3388 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3389 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3391 ios *base = istream_get_ios(this);
3392 int ch;
3394 TRACE("(%p %p %c)\n", this, sb, delim);
3396 if (istream_ipfx(this, 1)) {
3397 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3398 if (ch == EOF) {
3399 base->state |= IOSTATE_eofbit;
3400 break;
3402 if (streambuf_sputc(sb, ch) == EOF)
3403 base->state |= IOSTATE_failbit;
3404 this->count++;
3406 istream_isfx(this);
3408 return this;
3411 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3412 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3413 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3414 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3415 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3416 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3417 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3418 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3420 ios *base = istream_get_ios(this);
3422 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3424 ios_lock(base);
3425 this->extract_delim++;
3426 istream_get_str_delim(this, str, count, (unsigned char) delim);
3427 ios_unlock(base);
3428 return this;
3431 /* ?ignore@istream@@QAEAAV1@HH@Z */
3432 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3433 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3434 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3436 ios *base = istream_get_ios(this);
3438 TRACE("(%p %d %d)\n", this, count, delim);
3440 ios_lock(base);
3441 this->extract_delim++;
3442 istream_get_str_delim(this, NULL, count + 1, delim);
3443 ios_unlock(base);
3444 return this;
3447 /* ?peek@istream@@QAEHXZ */
3448 /* ?peek@istream@@QEAAHXZ */
3449 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3450 int __thiscall istream_peek(istream *this)
3452 ios *base = istream_get_ios(this);
3453 int ret = EOF;
3455 TRACE("(%p)\n", this);
3457 if (istream_ipfx(this, 1)) {
3458 ret = streambuf_sgetc(base->sb);
3459 istream_isfx(this);
3461 return ret;
3464 /* ?putback@istream@@QAEAAV1@D@Z */
3465 /* ?putback@istream@@QEAAAEAV1@D@Z */
3466 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3467 istream* __thiscall istream_putback(istream *this, char ch)
3469 ios *base = istream_get_ios(this);
3471 TRACE("(%p %c)\n", this, ch);
3473 if (ios_good(base)) {
3474 ios_lockbuf(base);
3475 if (streambuf_sputbackc(base->sb, ch) == EOF)
3476 ios_clear(base, base->state | IOSTATE_failbit);
3477 ios_unlockbuf(base);
3479 return this;
3482 /* ?read@istream@@QAEAAV1@PACH@Z */
3483 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3484 /* ?read@istream@@QAEAAV1@PADH@Z */
3485 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3486 /* ?read@istream@@QAEAAV1@PAEH@Z */
3487 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3488 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3489 istream* __thiscall istream_read(istream *this, char *str, int count)
3491 ios *base = istream_get_ios(this);
3493 TRACE("(%p %p %d)\n", this, str, count);
3495 if (istream_ipfx(this, 1)) {
3496 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3497 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3498 istream_isfx(this);
3500 return this;
3503 /* ?seekg@istream@@QAEAAV1@J@Z */
3504 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3505 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3506 istream* __thiscall istream_seekg(istream *this, streampos pos)
3508 ios *base = istream_get_ios(this);
3510 TRACE("(%p %d)\n", this, pos);
3512 ios_lockbuf(base);
3513 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3514 ios_clear(base, base->state | IOSTATE_failbit);
3515 ios_unlockbuf(base);
3516 return this;
3519 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3520 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3521 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3522 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3524 ios *base = istream_get_ios(this);
3526 TRACE("(%p %d %d)\n", this, off, dir);
3528 ios_lockbuf(base);
3529 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3530 ios_clear(base, base->state | IOSTATE_failbit);
3531 ios_unlockbuf(base);
3532 return this;
3535 /* ?sync@istream@@QAEHXZ */
3536 /* ?sync@istream@@QEAAHXZ */
3537 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3538 int __thiscall istream_sync(istream *this)
3540 ios *base = istream_get_ios(this);
3541 int ret;
3543 TRACE("(%p)\n", this);
3545 ios_lockbuf(base);
3546 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3547 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3548 ios_unlockbuf(base);
3549 return ret;
3552 /* ?tellg@istream@@QAEJXZ */
3553 /* ?tellg@istream@@QEAAJXZ */
3554 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3555 streampos __thiscall istream_tellg(istream *this)
3557 ios *base = istream_get_ios(this);
3558 streampos pos;
3560 TRACE("(%p)\n", this);
3562 ios_lockbuf(base);
3563 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3564 ios_clear(base, base->state | IOSTATE_failbit);
3565 ios_unlockbuf(base);
3566 return pos;
3569 static int getint_is_valid_digit(char ch, int base)
3571 if (base == 8) return (ch >= '0' && ch <= '7');
3572 if (base == 16) return isxdigit(ch);
3573 return isdigit(ch);
3576 /* ?getint@istream@@AAEHPAD@Z */
3577 /* ?getint@istream@@AEAAHPEAD@Z */
3578 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3579 int __thiscall istream_getint(istream *this, char *str)
3581 ios *base = istream_get_ios(this);
3582 int ch, num_base = 0, i = 0;
3583 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3585 TRACE("(%p %p)\n", this, str);
3587 if (istream_ipfx(this, 0)) {
3588 num_base = (base->flags & FLAGS_dec) ? 10 :
3589 (base->flags & FLAGS_hex) ? 16 :
3590 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3591 /* scan valid characters, up to 15 (hard limit on Windows) */
3592 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3593 if ((ch == '+' || ch == '-') && scan_sign) {
3594 /* no additional sign allowed */
3595 scan_sign = FALSE;
3596 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3597 /* only hex digits can (and must) follow */
3598 scan_x = valid_integer = FALSE;
3599 num_base = 16;
3600 } else if (ch == '0' && scan_prefix) {
3601 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3602 scan_sign = scan_prefix = FALSE;
3603 scan_x = !num_base || num_base == 16;
3604 valid_integer = TRUE;
3605 if (!num_base)
3606 num_base = 8;
3607 } else if (getint_is_valid_digit(ch, num_base)) {
3608 /* only digits in the corresponding base can follow */
3609 scan_sign = scan_prefix = scan_x = FALSE;
3610 valid_integer = TRUE;
3611 } else {
3612 /* unexpected character, stop scanning */
3613 if (!valid_integer) {
3614 /* the result is not a valid integer */
3615 base->state |= IOSTATE_failbit;
3616 /* put any extracted character back into the stream */
3617 while (i > 0)
3618 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3619 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3620 } else if (ch == EOF) {
3621 base->state |= IOSTATE_eofbit;
3622 if (scan_x && !(base->flags & ios_basefield)) {
3623 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3624 num_base = 0;
3627 break;
3629 str[i++] = ch;
3631 /* append a null terminator */
3632 str[i] = 0;
3633 istream_isfx(this);
3635 return num_base;
3638 /* ?getdouble@istream@@AAEHPADH@Z */
3639 /* ?getdouble@istream@@AEAAHPEADH@Z */
3640 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3641 int __thiscall istream_getdouble(istream *this, char *str, int count)
3643 ios *base = istream_get_ios(this);
3644 int ch, i = 0;
3645 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3646 valid_mantissa = FALSE, valid_exponent = FALSE;
3648 TRACE("(%p %p %d)\n", this, str, count);
3650 if (istream_ipfx(this, 0)) {
3651 if (!count) {
3652 /* can't output anything */
3653 base->state |= IOSTATE_failbit;
3654 i = -1;
3655 } else {
3656 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3657 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3658 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3659 if ((ch == '+' || ch == '-') && scan_sign) {
3660 /* no additional sign allowed */
3661 scan_sign = FALSE;
3662 } else if (ch == '.' && scan_dot) {
3663 /* no sign or additional dot allowed */
3664 scan_sign = scan_dot = FALSE;
3665 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3666 /* sign is allowed again but not dots or exponents */
3667 scan_sign = TRUE;
3668 scan_dot = scan_exp = FALSE;
3669 } else if (isdigit(ch)) {
3670 if (scan_exp)
3671 valid_mantissa = TRUE;
3672 else
3673 valid_exponent = TRUE;
3674 /* no sign allowed after a digit */
3675 scan_sign = FALSE;
3676 } else {
3677 /* unexpected character, stop scanning */
3678 /* check whether the result is a valid double */
3679 if (!scan_exp && !valid_exponent) {
3680 /* put the last character back into the stream, usually the 'e' or 'E' */
3681 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3682 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3683 } else if (ch == EOF)
3684 base->state |= IOSTATE_eofbit;
3685 if (!valid_mantissa)
3686 base->state |= IOSTATE_failbit;
3687 break;
3689 str[i++] = ch;
3691 /* check if character limit has been reached */
3692 if (i == count) {
3693 base->state |= IOSTATE_failbit;
3694 i--;
3696 /* append a null terminator */
3697 str[i] = 0;
3699 istream_isfx(this);
3701 return i;
3704 /* ??5istream@@QAEAAV0@AAC@Z */
3705 /* ??5istream@@QEAAAEAV0@AEAC@Z */
3706 /* ??5istream@@QAEAAV0@AAD@Z */
3707 /* ??5istream@@QEAAAEAV0@AEAD@Z */
3708 /* ??5istream@@QAEAAV0@AAE@Z */
3709 /* ??5istream@@QEAAAEAV0@AEAE@Z */
3710 DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
3711 istream* __thiscall istream_read_char(istream *this, char *ch)
3713 ios *base = istream_get_ios(this);
3714 int ret;
3716 TRACE("(%p %p)\n", this, ch);
3718 if (istream_ipfx(this, 0)) {
3719 if ((ret = streambuf_sbumpc(base->sb)) == EOF)
3720 base->state |= IOSTATE_eofbit | IOSTATE_failbit;
3721 else
3722 *ch = ret;
3723 istream_isfx(this);
3725 return this;
3728 /* ??5istream@@QAEAAV0@PAC@Z */
3729 /* ??5istream@@QEAAAEAV0@PEAC@Z */
3730 /* ??5istream@@QAEAAV0@PAD@Z */
3731 /* ??5istream@@QEAAAEAV0@PEAD@Z */
3732 /* ??5istream@@QAEAAV0@PAE@Z */
3733 /* ??5istream@@QEAAAEAV0@PEAE@Z */
3734 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
3735 istream* __thiscall istream_read_str(istream *this, char *str)
3737 ios *base = istream_get_ios(this);
3738 int ch, count = 0;
3740 TRACE("(%p %p)\n", this, str);
3742 if (istream_ipfx(this, 0)) {
3743 if (str) {
3744 for (ch = streambuf_sgetc(base->sb);
3745 count < (unsigned int) base->width - 1 && !isspace(ch);
3746 ch = streambuf_snextc(base->sb)) {
3747 if (ch == EOF) {
3748 base->state |= IOSTATE_eofbit;
3749 break;
3751 str[count++] = ch;
3754 if (!count) /* nothing to output */
3755 base->state |= IOSTATE_failbit;
3756 else /* append a null terminator */
3757 str[count] = 0;
3758 base->width = 0;
3759 istream_isfx(this);
3761 return this;
3764 static LONG istream_internal_read_integer(istream *this, LONG min_value, LONG max_value, BOOL set_flag)
3766 ios *base = istream_get_ios(this);
3767 char buffer[16];
3768 int num_base;
3769 LONG ret;
3771 TRACE("(%p %d %d %d)\n", this, min_value, max_value, set_flag);
3773 num_base = istream_getint(this, buffer);
3774 errno = 0;
3775 ret = strtol(buffer, NULL, num_base);
3776 /* check for overflow and whether the value fits in the output var */
3777 if (set_flag && errno == ERANGE) {
3778 base->state |= IOSTATE_failbit;
3779 } else if (ret > max_value) {
3780 base->state |= IOSTATE_failbit;
3781 ret = max_value;
3782 } else if (ret < min_value) {
3783 base->state |= IOSTATE_failbit;
3784 ret = min_value;
3786 return ret;
3789 static ULONG istream_internal_read_unsigned_integer(istream *this, LONG min_value, ULONG max_value)
3791 ios *base = istream_get_ios(this);
3792 char buffer[16];
3793 int num_base;
3794 ULONG ret;
3796 TRACE("(%p %d %u)\n", this, min_value, max_value);
3798 num_base = istream_getint(this, buffer);
3799 errno = 0;
3800 ret = strtoul(buffer, NULL, num_base);
3801 /* check for overflow and whether the value fits in the output var */
3802 if ((ret == ULONG_MAX && errno == ERANGE) ||
3803 (ret > max_value && ret < (ULONG) min_value)) {
3804 base->state |= IOSTATE_failbit;
3805 ret = max_value;
3807 return ret;
3810 /* ??5istream@@QAEAAV0@AAF@Z */
3811 /* ??5istream@@QEAAAEAV0@AEAF@Z */
3812 DEFINE_THISCALL_WRAPPER(istream_read_short, 8)
3813 istream* __thiscall istream_read_short(istream *this, short *p)
3815 if (istream_ipfx(this, 0)) {
3816 *p = istream_internal_read_integer(this, SHRT_MIN, SHRT_MAX, FALSE);
3817 istream_isfx(this);
3819 return this;
3822 /* ??5istream@@QAEAAV0@AAG@Z */
3823 /* ??5istream@@QEAAAEAV0@AEAG@Z */
3824 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_short, 8)
3825 istream* __thiscall istream_read_unsigned_short(istream *this, unsigned short *p)
3827 if (istream_ipfx(this, 0)) {
3828 *p = istream_internal_read_unsigned_integer(this, SHRT_MIN, USHRT_MAX);
3829 istream_isfx(this);
3831 return this;
3834 /* ??5istream@@QAEAAV0@AAH@Z */
3835 /* ??5istream@@QEAAAEAV0@AEAH@Z */
3836 DEFINE_THISCALL_WRAPPER(istream_read_int, 8)
3837 istream* __thiscall istream_read_int(istream *this, int *p)
3839 if (istream_ipfx(this, 0)) {
3840 *p = istream_internal_read_integer(this, INT_MIN, INT_MAX, FALSE);
3841 istream_isfx(this);
3843 return this;
3846 /* ??5istream@@QAEAAV0@AAI@Z */
3847 /* ??5istream@@QEAAAEAV0@AEAI@Z */
3848 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_int, 8)
3849 istream* __thiscall istream_read_unsigned_int(istream *this, unsigned int *p)
3851 if (istream_ipfx(this, 0)) {
3852 *p = istream_internal_read_unsigned_integer(this, INT_MIN, UINT_MAX);
3853 istream_isfx(this);
3855 return this;
3858 /* ??5istream@@QAEAAV0@AAJ@Z */
3859 /* ??5istream@@QEAAAEAV0@AEAJ@Z */
3860 DEFINE_THISCALL_WRAPPER(istream_read_long, 8)
3861 istream* __thiscall istream_read_long(istream *this, LONG *p)
3863 if (istream_ipfx(this, 0)) {
3864 *p = istream_internal_read_integer(this, LONG_MIN, LONG_MAX, TRUE);
3865 istream_isfx(this);
3867 return this;
3870 /* ??5istream@@QAEAAV0@AAK@Z */
3871 /* ??5istream@@QEAAAEAV0@AEAK@Z */
3872 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_long, 8)
3873 istream* __thiscall istream_read_unsigned_long(istream *this, ULONG *p)
3875 if (istream_ipfx(this, 0)) {
3876 *p = istream_internal_read_unsigned_integer(this, LONG_MIN, ULONG_MAX);
3877 istream_isfx(this);
3879 return this;
3882 static BOOL istream_internal_read_float(istream *this, int max_chars, double *out)
3884 char buffer[32];
3885 BOOL read = FALSE;
3887 TRACE("(%p %d %p)\n", this, max_chars, out);
3889 if (istream_ipfx(this, 0)) {
3890 /* character count is limited on Windows */
3891 if (istream_getdouble(this, buffer, max_chars) > 0) {
3892 *out = strtod(buffer, NULL);
3893 read = TRUE;
3895 istream_isfx(this);
3897 return read;
3900 /* ??5istream@@QAEAAV0@AAM@Z */
3901 /* ??5istream@@QEAAAEAV0@AEAM@Z */
3902 DEFINE_THISCALL_WRAPPER(istream_read_float, 8)
3903 istream* __thiscall istream_read_float(istream *this, float *f)
3905 double tmp;
3906 if (istream_internal_read_float(this, 20, &tmp)) {
3907 /* check whether the value fits in the output var */
3908 if (tmp > FLT_MAX)
3909 tmp = FLT_MAX;
3910 else if (tmp < -FLT_MAX)
3911 tmp = -FLT_MAX;
3912 else if (tmp > 0 && tmp < FLT_MIN)
3913 tmp = FLT_MIN;
3914 else if (tmp < 0 && tmp > -FLT_MIN)
3915 tmp = -FLT_MIN;
3916 *f = tmp;
3918 return this;
3921 /* ??5istream@@QAEAAV0@AAN@Z */
3922 /* ??5istream@@QEAAAEAV0@AEAN@Z */
3923 DEFINE_THISCALL_WRAPPER(istream_read_double, 8)
3924 istream* __thiscall istream_read_double(istream *this, double *d)
3926 istream_internal_read_float(this, 28, d);
3927 return this;
3930 /* ??5istream@@QAEAAV0@AAO@Z */
3931 /* ??5istream@@QEAAAEAV0@AEAO@Z */
3932 DEFINE_THISCALL_WRAPPER(istream_read_long_double, 8)
3933 istream* __thiscall istream_read_long_double(istream *this, double *ld)
3935 istream_internal_read_float(this, 32, ld);
3936 return this;
3939 /* ??5istream@@QAEAAV0@PAVstreambuf@@@Z */
3940 /* ??5istream@@QEAAAEAV0@PEAVstreambuf@@@Z */
3941 DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
3942 istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
3944 ios *base = istream_get_ios(this);
3945 int ch;
3947 TRACE("(%p %p)\n", this, sb);
3949 if (istream_ipfx(this, 0)) {
3950 while ((ch = streambuf_sbumpc(base->sb)) != EOF)
3951 if (streambuf_sputc(sb, ch) == EOF)
3952 base->state |= IOSTATE_failbit;
3953 istream_isfx(this);
3955 return this;
3958 /* ??5istream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
3959 /* ??5istream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
3960 DEFINE_THISCALL_WRAPPER(istream_read_manip, 8)
3961 istream* __thiscall istream_read_manip(istream *this, istream* (__cdecl *func)(istream*))
3963 TRACE("(%p %p)\n", this, func);
3964 return func(this);
3967 /* ??5istream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
3968 /* ??5istream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
3969 DEFINE_THISCALL_WRAPPER(istream_read_ios_manip, 8)
3970 istream* __thiscall istream_read_ios_manip(istream *this, ios* (__cdecl *func)(ios*))
3972 TRACE("(%p %p)\n", this, func);
3973 func(istream_get_ios(this));
3974 return this;
3977 /* ?ws@@YAAAVistream@@AAV1@@Z */
3978 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
3979 istream* __cdecl istream_ws(istream *this)
3981 TRACE("(%p)\n", this);
3982 istream_eatwhite(this);
3983 return this;
3986 /* ??0istream_withassign@@QAE@ABV0@@Z */
3987 /* ??0istream_withassign@@QEAA@AEBV0@@Z */
3988 DEFINE_THISCALL_WRAPPER(istream_withassign_copy_ctor, 12)
3989 istream* __thiscall istream_withassign_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3991 ios *base, *base_copy;
3993 TRACE("(%p %p %d)\n", this, copy, virt_init);
3995 base_copy = istream_get_ios(copy);
3996 if (virt_init) {
3997 this->vbtable = istream_vbtable;
3998 base = istream_get_ios(this);
3999 ios_copy_ctor(base, base_copy);
4000 } else
4001 base = istream_get_ios(this);
4002 ios_init(base, base_copy->sb);
4003 base->vtable = &MSVCP_istream_withassign_vtable;
4004 base->flags |= FLAGS_skipws;
4005 this->extract_delim = 0;
4006 this->count = 0;
4007 return this;
4010 /* ??0istream_withassign@@QAE@PAVstreambuf@@@Z */
4011 /* ??0istream_withassign@@QEAA@PEAVstreambuf@@@Z */
4012 DEFINE_THISCALL_WRAPPER(istream_withassign_sb_ctor, 12)
4013 istream* __thiscall istream_withassign_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
4015 ios *base;
4017 TRACE("(%p %p %d)\n", this, sb, virt_init);
4019 istream_sb_ctor(this, sb, virt_init);
4020 base = istream_get_ios(this);
4021 base->vtable = &MSVCP_istream_withassign_vtable;
4022 return this;
4025 /* ??0istream_withassign@@QAE@XZ */
4026 /* ??0istream_withassign@@QEAA@XZ */
4027 DEFINE_THISCALL_WRAPPER(istream_withassign_ctor, 8)
4028 istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init)
4030 ios *base;
4032 TRACE("(%p %d)\n", this, virt_init);
4034 istream_ctor(this, virt_init);
4035 base = istream_get_ios(this);
4036 base->vtable = &MSVCP_istream_withassign_vtable;
4037 return this;
4040 /* ??0istrstream@@QAE@ABV0@@Z */
4041 /* ??0istrstream@@QEAA@AEBV0@@Z */
4042 DEFINE_THISCALL_WRAPPER(istrstream_copy_ctor, 12)
4043 istream* __thiscall istrstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
4045 TRACE("(%p %p %d)\n", this, copy, virt_init);
4046 istream_withassign_copy_ctor(this, copy, virt_init);
4047 istream_get_ios(this)->vtable = &MSVCP_istrstream_vtable;
4048 return this;
4051 /* ??0istrstream@@QAE@PADH@Z */
4052 /* ??0istrstream@@QEAA@PEADH@Z */
4053 DEFINE_THISCALL_WRAPPER(istrstream_buffer_ctor, 16)
4054 istream* __thiscall istrstream_buffer_ctor(istream *this, char *buffer, int length, BOOL virt_init)
4056 ios *base;
4057 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
4059 TRACE("(%p %p %d %d)\n", this, buffer, length, virt_init);
4061 if (ssb) {
4062 strstreambuf_buffer_ctor(ssb, buffer, length, NULL);
4063 istream_sb_ctor(this, &ssb->base, virt_init);
4064 } else
4065 istream_ctor(this, virt_init);
4066 base = istream_get_ios(this);
4067 base->vtable = &MSVCP_istrstream_vtable;
4068 base->delbuf = 1;
4069 return this;
4072 /* ??0istrstream@@QAE@PAD@Z */
4073 /* ??0istrstream@@QEAA@PEAD@Z */
4074 DEFINE_THISCALL_WRAPPER(istrstream_str_ctor, 12)
4075 istream* __thiscall istrstream_str_ctor(istream *this, char *str, BOOL virt_init)
4077 return istrstream_buffer_ctor(this, str, 0, virt_init);
4080 /* ?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ */
4081 /* ?rdbuf@istrstream@@QEBAPEAVstrstreambuf@@XZ */
4082 DEFINE_THISCALL_WRAPPER(istrstream_rdbuf, 4)
4083 strstreambuf* __thiscall istrstream_rdbuf(const istream *this)
4085 return (strstreambuf*) istream_get_ios(this)->sb;
4088 /* ?str@istrstream@@QAEPADXZ */
4089 /* ?str@istrstream@@QEAAPEADXZ */
4090 DEFINE_THISCALL_WRAPPER(istrstream_str, 4)
4091 char* __thiscall istrstream_str(istream *this)
4093 return strstreambuf_str(istrstream_rdbuf(this));
4096 static inline ios* iostream_to_ios(const iostream *this)
4098 return (ios*)((char*)this + iostream_vbtable_istream[1]);
4101 static inline iostream* ios_to_iostream(const ios *base)
4103 return (iostream*)((char*)base - iostream_vbtable_istream[1]);
4106 /* ??0iostream@@IAE@XZ */
4107 /* ??0iostream@@IEAA@XZ */
4108 DEFINE_THISCALL_WRAPPER(iostream_ctor, 8)
4109 iostream* __thiscall iostream_ctor(iostream *this, BOOL virt_init)
4111 ios *base;
4113 TRACE("(%p %d)\n", this, virt_init);
4115 if (virt_init) {
4116 this->base1.vbtable = iostream_vbtable_istream;
4117 this->base2.vbtable = iostream_vbtable_ostream;
4118 base = istream_get_ios(&this->base1);
4119 ios_ctor(base);
4120 } else
4121 base = istream_get_ios(&this->base1);
4122 istream_ctor(&this->base1, FALSE);
4123 ostream_ctor(&this->base2, FALSE);
4124 base->vtable = &MSVCP_iostream_vtable;
4125 return this;
4128 /* ??0iostream@@QAE@PAVstreambuf@@@Z */
4129 /* ??0iostream@@QEAA@PEAVstreambuf@@@Z */
4130 DEFINE_THISCALL_WRAPPER(iostream_sb_ctor, 12)
4131 iostream* __thiscall iostream_sb_ctor(iostream *this, streambuf *sb, BOOL virt_init)
4133 TRACE("(%p %p %d)\n", this, sb, virt_init);
4134 iostream_ctor(this, virt_init);
4135 ios_init(istream_get_ios(&this->base1), sb);
4136 return this;
4139 /* ??0iostream@@IAE@ABV0@@Z */
4140 /* ??0iostream@@IEAA@AEBV0@@Z */
4141 DEFINE_THISCALL_WRAPPER(iostream_copy_ctor, 12)
4142 iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4144 return iostream_sb_ctor(this, istream_get_ios(&copy->base1)->sb, virt_init);
4147 /* ??1iostream@@UAE@XZ */
4148 /* ??1iostream@@UEAA@XZ */
4149 /* ??1stdiostream@@UAE@XZ */
4150 /* ??1stdiostream@@UEAA@XZ */
4151 /* ??1strstream@@UAE@XZ */
4152 /* ??1strstream@@UEAA@XZ */
4153 DEFINE_THISCALL_WRAPPER(iostream_dtor, 4)
4154 void __thiscall iostream_dtor(ios *base)
4156 iostream *this = ios_to_iostream(base);
4158 TRACE("(%p)\n", this);
4160 ostream_dtor(ostream_to_ios(&this->base2));
4161 istream_dtor(istream_to_ios(&this->base1));
4164 /* ??4iostream@@IAEAAV0@PAVstreambuf@@@Z */
4165 /* ??4iostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
4166 DEFINE_THISCALL_WRAPPER(iostream_assign_sb, 8)
4167 iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb)
4169 TRACE("(%p %p)\n", this, sb);
4170 this->base1.count = 0;
4171 ostream_assign_sb(&this->base2, sb);
4172 return this;
4175 /* ??4iostream@@IAEAAV0@AAV0@@Z */
4176 /* ??4iostream@@IEAAAEAV0@AEAV0@@Z */
4177 /* ??4stdiostream@@QAEAAV0@AAV0@@Z */
4178 /* ??4stdiostream@@QEAAAEAV0@AEAV0@@Z */
4179 /* ??4strstream@@QAEAAV0@ABV0@@Z */
4180 /* ??4strstream@@QEAAAEAV0@AEBV0@@Z */
4181 DEFINE_THISCALL_WRAPPER(iostream_assign, 8)
4182 iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs)
4184 return iostream_assign_sb(this, istream_get_ios(&rhs->base1)->sb);
4187 /* ??_Diostream@@QAEXXZ */
4188 /* ??_Diostream@@QEAAXXZ */
4189 /* ??_Dstdiostream@@QAEXXZ */
4190 /* ??_Dstdiostream@@QEAAXXZ */
4191 /* ??_Dstrstream@@QAEXXZ */
4192 /* ??_Dstrstream@@QEAAXXZ */
4193 DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4)
4194 void __thiscall iostream_vbase_dtor(iostream *this)
4196 ios *base = iostream_to_ios(this);
4198 TRACE("(%p)\n", this);
4200 iostream_dtor(base);
4201 ios_dtor(base);
4204 /* ??_Eiostream@@UAEPAXI@Z */
4205 /* ??_Estdiostream@@UAEPAXI@Z */
4206 /* ??_Estrstream@@UAEPAXI@Z */
4207 DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8)
4208 iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags)
4210 iostream *this = ios_to_iostream(base);
4212 TRACE("(%p %x)\n", this, flags);
4214 if (flags & 2) {
4215 /* we have an array, with the number of elements stored before the first object */
4216 INT_PTR i, *ptr = (INT_PTR *)this-1;
4218 for (i = *ptr-1; i >= 0; i--)
4219 iostream_vbase_dtor(this+i);
4220 MSVCRT_operator_delete(ptr);
4221 } else {
4222 iostream_vbase_dtor(this);
4223 if (flags & 1)
4224 MSVCRT_operator_delete(this);
4226 return this;
4229 /* ??_Giostream@@UAEPAXI@Z */
4230 /* ??_Gstdiostream@@UAEPAXI@Z */
4231 /* ??_Gstrstream@@UAEPAXI@Z */
4232 DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8)
4233 iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags)
4235 iostream *this = ios_to_iostream(base);
4237 TRACE("(%p %x)\n", this, flags);
4239 iostream_vbase_dtor(this);
4240 if (flags & 1) MSVCRT_operator_delete(this);
4241 return this;
4244 static iostream* iostream_internal_copy_ctor(iostream *this, const iostream *copy, const vtable_ptr *vtbl, BOOL virt_init)
4246 ios *base, *base_copy = istream_get_ios(&copy->base1);
4248 if (virt_init) {
4249 this->base1.vbtable = iostream_vbtable_istream;
4250 this->base2.vbtable = iostream_vbtable_ostream;
4251 base = istream_get_ios(&this->base1);
4252 ios_copy_ctor(base, base_copy);
4253 } else
4254 base = istream_get_ios(&this->base1);
4255 ios_init(base, base_copy->sb);
4256 istream_ctor(&this->base1, FALSE);
4257 ostream_ctor(&this->base2, FALSE);
4258 base->vtable = vtbl;
4259 return this;
4262 static iostream* iostream_internal_sb_ctor(iostream *this, streambuf *sb, const vtable_ptr *vtbl, BOOL virt_init)
4264 ios *base;
4266 iostream_ctor(this, virt_init);
4267 base = istream_get_ios(&this->base1);
4268 if (sb)
4269 ios_init(base, sb);
4270 base->vtable = vtbl;
4271 base->delbuf = 1;
4272 return this;
4275 /* ??0strstream@@QAE@ABV0@@Z */
4276 /* ??0strstream@@QEAA@AEBV0@@Z */
4277 DEFINE_THISCALL_WRAPPER(strstream_copy_ctor, 12)
4278 iostream* __thiscall strstream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4280 TRACE("(%p %p %d)\n", this, copy, virt_init);
4281 return iostream_internal_copy_ctor(this, copy, &MSVCP_strstream_vtable, virt_init);
4284 /* ??0strstream@@QAE@PADHH@Z */
4285 /* ??0strstream@@QEAA@PEADHH@Z */
4286 DEFINE_THISCALL_WRAPPER(strstream_buffer_ctor, 20)
4287 iostream* __thiscall strstream_buffer_ctor(iostream *this, char *buffer, int length, int mode, BOOL virt_init)
4289 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
4291 TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init);
4293 if (ssb) {
4294 strstreambuf_buffer_ctor(ssb, buffer, length, buffer);
4295 if ((mode & OPENMODE_out) && (mode & (OPENMODE_app|OPENMODE_ate)))
4296 ssb->base.pptr = buffer + strlen(buffer);
4297 return iostream_internal_sb_ctor(this, &ssb->base, &MSVCP_strstream_vtable, virt_init);
4299 return iostream_internal_sb_ctor(this, NULL, &MSVCP_strstream_vtable, virt_init);
4302 /* ??0strstream@@QAE@XZ */
4303 /* ??0strstream@@QEAA@XZ */
4304 DEFINE_THISCALL_WRAPPER(strstream_ctor, 8)
4305 iostream* __thiscall strstream_ctor(iostream *this, BOOL virt_init)
4307 strstreambuf *ssb = MSVCRT_operator_new(sizeof(strstreambuf));
4309 TRACE("(%p %d)\n", this, virt_init);
4311 if (ssb) {
4312 strstreambuf_ctor(ssb);
4313 return iostream_internal_sb_ctor(this, &ssb->base, &MSVCP_strstream_vtable, virt_init);
4315 return iostream_internal_sb_ctor(this, NULL, &MSVCP_strstream_vtable, virt_init);
4318 /* ?pcount@strstream@@QBEHXZ */
4319 /* ?pcount@strstream@@QEBAHXZ */
4320 DEFINE_THISCALL_WRAPPER(strstream_pcount, 4)
4321 int __thiscall strstream_pcount(const iostream *this)
4323 return streambuf_out_waiting(istream_get_ios(&this->base1)->sb);
4326 /* ?rdbuf@strstream@@QBEPAVstrstreambuf@@XZ */
4327 /* ?rdbuf@strstream@@QEBAPEAVstrstreambuf@@XZ */
4328 DEFINE_THISCALL_WRAPPER(strstream_rdbuf, 4)
4329 strstreambuf* __thiscall strstream_rdbuf(const iostream *this)
4331 return (strstreambuf*) istream_get_ios(&this->base1)->sb;
4334 /* ?str@strstream@@QAEPADXZ */
4335 /* ?str@strstream@@QEAAPEADXZ */
4336 DEFINE_THISCALL_WRAPPER(strstream_str, 4)
4337 char* __thiscall strstream_str(iostream *this)
4339 return strstreambuf_str(strstream_rdbuf(this));
4342 /* ??0stdiostream@@QAE@ABV0@@Z */
4343 /* ??0stdiostream@@QEAA@AEBV0@@Z */
4344 DEFINE_THISCALL_WRAPPER(stdiostream_copy_ctor, 12)
4345 iostream* __thiscall stdiostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4347 TRACE("(%p %p %d)\n", this, copy, virt_init);
4348 return iostream_internal_copy_ctor(this, copy, &MSVCP_stdiostream_vtable, virt_init);
4351 /* ??0stdiostream@@QAE@PAU_iobuf@@@Z */
4352 /* ??0stdiostream@@QEAA@PEAU_iobuf@@@Z */
4353 DEFINE_THISCALL_WRAPPER(stdiostream_file_ctor, 12)
4354 iostream* __thiscall stdiostream_file_ctor(iostream *this, FILE *file, BOOL virt_init)
4356 stdiobuf *stb = MSVCRT_operator_new(sizeof(stdiobuf));
4358 TRACE("(%p %p %d)\n", this, file, virt_init);
4360 if (stb) {
4361 stdiobuf_file_ctor(stb, file);
4362 return iostream_internal_sb_ctor(this, &stb->base, &MSVCP_stdiostream_vtable, virt_init);
4364 return iostream_internal_sb_ctor(this, NULL, &MSVCP_stdiostream_vtable, virt_init);
4367 /* ?rdbuf@stdiostream@@QBEPAVstdiobuf@@XZ */
4368 /* ?rdbuf@stdiostream@@QEBAPEAVstdiobuf@@XZ */
4369 DEFINE_THISCALL_WRAPPER(stdiostream_rdbuf, 4)
4370 stdiobuf* __thiscall stdiostream_rdbuf(const iostream *this)
4372 return (stdiobuf*) istream_get_ios(&this->base1)->sb;
4375 /* ??0Iostream_init@@QAE@AAVios@@H@Z */
4376 /* ??0Iostream_init@@QEAA@AEAVios@@H@Z */
4377 DEFINE_THISCALL_WRAPPER(Iostream_init_ios_ctor, 12)
4378 void* __thiscall Iostream_init_ios_ctor(void *this, ios *obj, int n)
4380 TRACE("(%p %p %d)\n", this, obj, n);
4381 obj->delbuf = 1;
4382 if (n >= 0) {
4383 obj->tie = &cout.os;
4384 if (n > 0)
4385 ios_setf(obj, FLAGS_unitbuf);
4387 return this;
4390 /* ??0Iostream_init@@QAE@XZ */
4391 /* ??0Iostream_init@@QEAA@XZ */
4392 DEFINE_THISCALL_WRAPPER(Iostream_init_ctor, 4)
4393 void* __thiscall Iostream_init_ctor(void *this)
4395 TRACE("(%p)\n", this);
4396 return this;
4399 /* ??1Iostream_init@@QAE@XZ */
4400 /* ??1Iostream_init@@QEAA@XZ */
4401 DEFINE_THISCALL_WRAPPER(Iostream_init_dtor, 4)
4402 void __thiscall Iostream_init_dtor(void *this)
4404 TRACE("(%p)\n", this);
4407 /* ??4Iostream_init@@QAEAAV0@ABV0@@Z */
4408 /* ??4Iostream_init@@QEAAAEAV0@AEBV0@@Z */
4409 DEFINE_THISCALL_WRAPPER(Iostream_init_assign, 8)
4410 void* __thiscall Iostream_init_assign(void *this, const void *rhs)
4412 TRACE("(%p %p)\n", this, rhs);
4413 return this;
4416 /* ?sync_with_stdio@ios@@SAXXZ */
4417 void __cdecl ios_sync_with_stdio(void)
4419 if (!ios_sunk_with_stdio) {
4420 stdiobuf *new_buf;
4422 TRACE("()\n");
4424 /* run at most once */
4425 ios_sunk_with_stdio++;
4427 /* calls to [io]stream_assign_sb automatically destroy the old buffers */
4428 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4429 stdiobuf_file_ctor(new_buf, stdin);
4430 istream_assign_sb(&cin.is, &new_buf->base);
4431 } else
4432 istream_assign_sb(&cin.is, NULL);
4433 cin.vbase.delbuf = 1;
4434 ios_setf(&cin.vbase, FLAGS_stdio);
4436 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4437 stdiobuf_file_ctor(new_buf, stdout);
4438 stdiobuf_setrwbuf(new_buf, 0, 80);
4439 ostream_assign_sb(&cout.os, &new_buf->base);
4440 } else
4441 ostream_assign_sb(&cout.os, NULL);
4442 cout.vbase.delbuf = 1;
4443 ios_setf(&cout.vbase, FLAGS_unitbuf | FLAGS_stdio);
4445 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4446 stdiobuf_file_ctor(new_buf, stderr);
4447 stdiobuf_setrwbuf(new_buf, 0, 80);
4448 ostream_assign_sb(&cerr.os, &new_buf->base);
4449 } else
4450 ostream_assign_sb(&cerr.os, NULL);
4451 cerr.vbase.delbuf = 1;
4452 ios_setf(&cerr.vbase, FLAGS_unitbuf | FLAGS_stdio);
4454 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4455 stdiobuf_file_ctor(new_buf, stderr);
4456 stdiobuf_setrwbuf(new_buf, 0, 512);
4457 ostream_assign_sb(&MSVCP_clog.os, &new_buf->base);
4458 } else
4459 ostream_assign_sb(&MSVCP_clog.os, NULL);
4460 MSVCP_clog.vbase.delbuf = 1;
4461 ios_setf(&MSVCP_clog.vbase, FLAGS_stdio);
4466 #if defined(__i386__) && !defined(__MINGW32__)
4468 #define DEFINE_VTBL_WRAPPER(off) \
4469 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
4470 "popl %eax\n\t" \
4471 "popl %ecx\n\t" \
4472 "pushl %eax\n\t" \
4473 "movl 0(%ecx), %eax\n\t" \
4474 "jmp *" #off "(%eax)\n\t")
4476 DEFINE_VTBL_WRAPPER(0);
4477 DEFINE_VTBL_WRAPPER(4);
4478 DEFINE_VTBL_WRAPPER(8);
4479 DEFINE_VTBL_WRAPPER(12);
4480 DEFINE_VTBL_WRAPPER(16);
4481 DEFINE_VTBL_WRAPPER(20);
4482 DEFINE_VTBL_WRAPPER(24);
4483 DEFINE_VTBL_WRAPPER(28);
4484 DEFINE_VTBL_WRAPPER(32);
4485 DEFINE_VTBL_WRAPPER(36);
4486 DEFINE_VTBL_WRAPPER(40);
4487 DEFINE_VTBL_WRAPPER(44);
4488 DEFINE_VTBL_WRAPPER(48);
4489 DEFINE_VTBL_WRAPPER(52);
4490 DEFINE_VTBL_WRAPPER(56);
4492 #endif
4494 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
4495 void (__cdecl *MSVCRT_operator_delete)(void*);
4497 static void init_cxx_funcs(void)
4499 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
4501 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
4503 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
4504 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
4506 else
4508 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
4509 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
4513 static void init_io(void *base)
4515 filebuf *fb;
4517 #ifdef __x86_64__
4518 init_streambuf_rtti(base);
4519 init_filebuf_rtti(base);
4520 init_strstreambuf_rtti(base);
4521 init_stdiobuf_rtti(base);
4522 init_ios_rtti(base);
4523 init_ostream_rtti(base);
4524 init_ostream_withassign_rtti(base);
4525 init_ostrstream_rtti(base);
4526 init_istream_rtti(base);
4527 init_istream_withassign_rtti(base);
4528 init_istrstream_rtti(base);
4529 init_iostream_rtti(base);
4530 init_strstream_rtti(base);
4531 init_stdiostream_rtti(base);
4532 #endif
4534 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4535 filebuf_fd_ctor(fb, 0);
4536 istream_withassign_sb_ctor(&cin.is, &fb->base, TRUE);
4537 } else
4538 istream_withassign_sb_ctor(&cin.is, NULL, TRUE);
4539 Iostream_init_ios_ctor(NULL, &cin.vbase, 0);
4541 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4542 filebuf_fd_ctor(fb, 1);
4543 ostream_withassign_sb_ctor(&cout.os, &fb->base, TRUE);
4544 } else
4545 ostream_withassign_sb_ctor(&cout.os, NULL, TRUE);
4546 Iostream_init_ios_ctor(NULL, &cout.vbase, -1);
4548 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4549 filebuf_fd_ctor(fb, 2);
4550 ostream_withassign_sb_ctor(&cerr.os, &fb->base, TRUE);
4551 } else
4552 ostream_withassign_sb_ctor(&cerr.os, NULL, TRUE);
4553 Iostream_init_ios_ctor(NULL, &cerr.vbase, 1);
4555 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4556 filebuf_fd_ctor(fb, 2);
4557 ostream_withassign_sb_ctor(&MSVCP_clog.os, &fb->base, TRUE);
4558 } else
4559 ostream_withassign_sb_ctor(&MSVCP_clog.os, NULL, TRUE);
4560 Iostream_init_ios_ctor(NULL, &MSVCP_clog.vbase, 0);
4563 static void free_io(void)
4565 /* destructors take care of deleting the buffers */
4566 istream_vbase_dtor(&cin.is);
4567 ostream_vbase_dtor(&cout.os);
4568 ostream_vbase_dtor(&cerr.os);
4569 ostream_vbase_dtor(&MSVCP_clog.os);
4572 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
4574 switch (reason)
4576 case DLL_WINE_PREATTACH:
4577 return FALSE; /* prefer native version */
4578 case DLL_PROCESS_ATTACH:
4579 init_cxx_funcs();
4580 init_exception(inst);
4581 init_io(inst);
4582 DisableThreadLibraryCalls( inst );
4583 break;
4584 case DLL_PROCESS_DETACH:
4585 if (reserved) break;
4586 free_io();
4587 break;
4589 return TRUE;