ddraw/tests: Test matrices in TransformVertices.
[wine.git] / dlls / msvcirt / msvcirt.c
blob8dfe988b4d099145a2ea384fcfff5b7810cadd21
1 /*
2 * Copyright (C) 2007 Alexandre Julliard
3 * Copyright (C) 2015-2016 Iván Matellanes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <float.h>
25 #include <io.h>
26 #include <limits.h>
27 #include <share.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <sys/stat.h>
32 #include "msvcirt.h"
33 #include "windef.h"
34 #include "winbase.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
39 #define RESERVE_SIZE 512
40 #define STATEBUF_SIZE 8
42 /* ?sh_none@filebuf@@2HB */
43 const int filebuf_sh_none = 0x800;
44 /* ?sh_read@filebuf@@2HB */
45 const int filebuf_sh_read = 0xa00;
46 /* ?sh_write@filebuf@@2HB */
47 const int filebuf_sh_write = 0xc00;
48 /* ?openprot@filebuf@@2HB */
49 const int filebuf_openprot = 420;
50 /* ?binary@filebuf@@2HB */
51 const int filebuf_binary = _O_BINARY;
52 /* ?text@filebuf@@2HB */
53 const int filebuf_text = _O_TEXT;
55 /* ?adjustfield@ios@@2JB */
56 const LONG ios_adjustfield = FLAGS_left | FLAGS_right | FLAGS_internal;
57 /* ?basefield@ios@@2JB */
58 const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
59 /* ?floatfield@ios@@2JB */
60 const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
61 /* ?fLockcInit@ios@@0HA */
62 int ios_fLockcInit = 0;
63 /* ?sunk_with_stdio@ios@@0HA */
64 int ios_sunk_with_stdio = 0;
65 /* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
66 extern CRITICAL_SECTION ios_static_lock;
67 CRITICAL_SECTION_DEBUG ios_static_lock_debug =
69 0, 0, &ios_static_lock,
70 { &ios_static_lock_debug.ProcessLocksList, &ios_static_lock_debug.ProcessLocksList },
71 0, 0, { (DWORD_PTR)(__FILE__ ": ios_static_lock") }
73 CRITICAL_SECTION ios_static_lock = { &ios_static_lock_debug, -1, 0, 0, 0, 0 };
74 /* ?x_maxbit@ios@@0JA */
75 LONG ios_maxbit = 0x8000;
76 /* ?x_curindex@ios@@0HA */
77 int ios_curindex = -1;
78 /* ?x_statebuf@ios@@0PAJA */
79 LONG ios_statebuf[STATEBUF_SIZE] = {0};
81 /* class streambuf */
82 typedef struct {
83 const vtable_ptr *vtable;
84 int allocated;
85 int unbuffered;
86 int stored_char;
87 char *base;
88 char *ebuf;
89 char *pbase;
90 char *pptr;
91 char *epptr;
92 char *eback;
93 char *gptr;
94 char *egptr;
95 int do_lock;
96 CRITICAL_SECTION lock;
97 } streambuf;
99 void __thiscall streambuf_setb(streambuf*, char*, char*, int);
100 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
101 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
102 void __thiscall streambuf_setp(streambuf*, char*, char*);
104 /* class filebuf */
105 typedef struct {
106 streambuf base;
107 filedesc fd;
108 int close;
109 } filebuf;
111 filebuf* __thiscall filebuf_close(filebuf*);
113 /* class strstreambuf */
114 typedef struct {
115 streambuf base;
116 int dynamic;
117 int increase;
118 int unknown;
119 int constant;
120 allocFunction f_alloc;
121 freeFunction f_free;
122 } strstreambuf;
124 /* class stdiobuf */
125 typedef struct {
126 streambuf base;
127 FILE *file;
128 } stdiobuf;
130 /* class ios */
131 struct _ostream;
132 typedef struct {
133 const vtable_ptr *vtable;
134 streambuf *sb;
135 ios_io_state state;
136 int special[4];
137 int delbuf;
138 struct _ostream *tie;
139 ios_flags flags;
140 int precision;
141 char fill;
142 int width;
143 int do_lock;
144 CRITICAL_SECTION lock;
145 } ios;
147 ios* __thiscall ios_assign(ios*, const ios*);
148 int __thiscall ios_fail(const ios*);
149 void __cdecl ios_lock(ios*);
150 void __cdecl ios_lockc(void);
151 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
152 void __cdecl ios_unlock(ios*);
153 void __cdecl ios_unlockc(void);
155 /* class ostream */
156 typedef struct _ostream {
157 const int *vbtable;
158 int unknown;
159 } ostream;
161 /* class istream */
162 typedef struct {
163 const int *vbtable;
164 int extract_delim;
165 int count;
166 } istream;
168 /* class iostream */
169 typedef struct {
170 istream base1;
171 ostream base2;
172 } iostream;
174 /* ??_7streambuf@@6B@ */
175 extern const vtable_ptr MSVCP_streambuf_vtable;
176 /* ??_7filebuf@@6B@ */
177 extern const vtable_ptr MSVCP_filebuf_vtable;
178 /* ??_7strstreambuf@@6B@ */
179 extern const vtable_ptr MSVCP_strstreambuf_vtable;
180 /* ??_7stdiobuf@@6B@ */
181 extern const vtable_ptr MSVCP_stdiobuf_vtable;
182 /* ??_7ios@@6B@ */
183 extern const vtable_ptr MSVCP_ios_vtable;
184 /* ??_7ostream@@6B@ */
185 extern const vtable_ptr MSVCP_ostream_vtable;
186 /* ??_7ostream_withassign@@6B@ */
187 extern const vtable_ptr MSVCP_ostream_withassign_vtable;
188 /* ??_7istream@@6B@ */
189 extern const vtable_ptr MSVCP_istream_vtable;
190 /* ??_7istream_withassign@@6B@ */
191 extern const vtable_ptr MSVCP_istream_withassign_vtable;
192 /* ??_7iostream@@6B@ */
193 extern const vtable_ptr MSVCP_iostream_vtable;
195 #ifndef __GNUC__
196 void __asm_dummy_vtables(void) {
197 #endif
198 __ASM_VTABLE(streambuf,
199 VTABLE_ADD_FUNC(streambuf_vector_dtor)
200 VTABLE_ADD_FUNC(streambuf_sync)
201 VTABLE_ADD_FUNC(streambuf_setbuf)
202 VTABLE_ADD_FUNC(streambuf_seekoff)
203 VTABLE_ADD_FUNC(streambuf_seekpos)
204 VTABLE_ADD_FUNC(streambuf_xsputn)
205 VTABLE_ADD_FUNC(streambuf_xsgetn)
206 VTABLE_ADD_FUNC(streambuf_overflow)
207 VTABLE_ADD_FUNC(streambuf_underflow)
208 VTABLE_ADD_FUNC(streambuf_pbackfail)
209 VTABLE_ADD_FUNC(streambuf_doallocate));
210 __ASM_VTABLE(filebuf,
211 VTABLE_ADD_FUNC(filebuf_vector_dtor)
212 VTABLE_ADD_FUNC(filebuf_sync)
213 VTABLE_ADD_FUNC(filebuf_setbuf)
214 VTABLE_ADD_FUNC(filebuf_seekoff)
215 VTABLE_ADD_FUNC(streambuf_seekpos)
216 VTABLE_ADD_FUNC(streambuf_xsputn)
217 VTABLE_ADD_FUNC(streambuf_xsgetn)
218 VTABLE_ADD_FUNC(filebuf_overflow)
219 VTABLE_ADD_FUNC(filebuf_underflow)
220 VTABLE_ADD_FUNC(streambuf_pbackfail)
221 VTABLE_ADD_FUNC(streambuf_doallocate));
222 __ASM_VTABLE(strstreambuf,
223 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
224 VTABLE_ADD_FUNC(strstreambuf_sync)
225 VTABLE_ADD_FUNC(strstreambuf_setbuf)
226 VTABLE_ADD_FUNC(strstreambuf_seekoff)
227 VTABLE_ADD_FUNC(streambuf_seekpos)
228 VTABLE_ADD_FUNC(streambuf_xsputn)
229 VTABLE_ADD_FUNC(streambuf_xsgetn)
230 VTABLE_ADD_FUNC(strstreambuf_overflow)
231 VTABLE_ADD_FUNC(strstreambuf_underflow)
232 VTABLE_ADD_FUNC(streambuf_pbackfail)
233 VTABLE_ADD_FUNC(strstreambuf_doallocate));
234 __ASM_VTABLE(stdiobuf,
235 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
236 VTABLE_ADD_FUNC(stdiobuf_sync)
237 VTABLE_ADD_FUNC(streambuf_setbuf)
238 VTABLE_ADD_FUNC(stdiobuf_seekoff)
239 VTABLE_ADD_FUNC(streambuf_seekpos)
240 VTABLE_ADD_FUNC(streambuf_xsputn)
241 VTABLE_ADD_FUNC(streambuf_xsgetn)
242 VTABLE_ADD_FUNC(stdiobuf_overflow)
243 VTABLE_ADD_FUNC(stdiobuf_underflow)
244 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
245 VTABLE_ADD_FUNC(streambuf_doallocate));
246 __ASM_VTABLE(ios,
247 VTABLE_ADD_FUNC(ios_vector_dtor));
248 __ASM_VTABLE(ostream,
249 VTABLE_ADD_FUNC(ostream_vector_dtor));
250 __ASM_VTABLE(ostream_withassign,
251 VTABLE_ADD_FUNC(ostream_vector_dtor));
252 __ASM_VTABLE(istream,
253 VTABLE_ADD_FUNC(istream_vector_dtor));
254 __ASM_VTABLE(istream_withassign,
255 VTABLE_ADD_FUNC(istream_vector_dtor));
256 __ASM_VTABLE(iostream,
257 VTABLE_ADD_FUNC(iostream_vector_dtor));
258 #ifndef __GNUC__
260 #endif
262 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
263 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
265 /* ??_8ostream@@7B@ */
266 /* ??_8ostream_withassign@@7B@ */
267 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
268 /* ??_8istream@@7B@ */
269 /* ??_8istream_withassign@@7B@ */
270 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
271 /* ??_8iostream@@7Bistream@@@ */
272 const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)};
273 /* ??_8iostream@@7Bostream@@@ */
274 const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)};
276 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
277 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
278 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
279 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
280 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
281 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
282 DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream),
283 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@")
284 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
285 DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
286 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
287 DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
288 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
289 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
291 /* ?cin@@3Vistream_withassign@@A */
292 struct {
293 istream is;
294 ios vbase;
295 } cin = { { 0 } };
297 /* ?cout@@3Vostream_withassign@@A */
298 /* ?cerr@@3Vostream_withassign@@A */
299 /* ?clog@@3Vostream_withassign@@A */
300 struct {
301 ostream os;
302 ios vbase;
303 } cout = { { 0 } }, cerr = { { 0 } }, clog = { { 0 } };
306 /* ??0streambuf@@IAE@PADH@Z */
307 /* ??0streambuf@@IEAA@PEADH@Z */
308 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
309 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
311 TRACE("(%p %p %d)\n", this, buffer, length);
312 this->vtable = &MSVCP_streambuf_vtable;
313 this->allocated = 0;
314 this->stored_char = EOF;
315 this->do_lock = -1;
316 this->base = NULL;
317 streambuf_setbuf(this, buffer, length);
318 streambuf_setg(this, NULL, NULL, NULL);
319 streambuf_setp(this, NULL, NULL);
320 InitializeCriticalSection(&this->lock);
321 return this;
324 /* ??0streambuf@@IAE@XZ */
325 /* ??0streambuf@@IEAA@XZ */
326 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
327 streambuf* __thiscall streambuf_ctor(streambuf *this)
329 streambuf_reserve_ctor(this, NULL, 0);
330 this->unbuffered = 0;
331 return this;
334 /* ??0streambuf@@QAE@ABV0@@Z */
335 /* ??0streambuf@@QEAA@AEBV0@@Z */
336 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
337 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
339 TRACE("(%p %p)\n", this, copy);
340 *this = *copy;
341 this->vtable = &MSVCP_streambuf_vtable;
342 return this;
345 /* ??1streambuf@@UAE@XZ */
346 /* ??1streambuf@@UEAA@XZ */
347 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
348 void __thiscall streambuf_dtor(streambuf *this)
350 TRACE("(%p)\n", this);
351 if (this->allocated)
352 MSVCRT_operator_delete(this->base);
353 DeleteCriticalSection(&this->lock);
356 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
357 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
358 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
359 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
361 streambuf_dtor(this);
362 return streambuf_copy_ctor(this, rhs);
365 /* ??_Estreambuf@@UAEPAXI@Z */
366 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
367 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
368 streambuf*, (streambuf*, unsigned int), (this, flags))
369 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
371 TRACE("(%p %x)\n", this, flags);
372 if (flags & 2) {
373 /* we have an array, with the number of elements stored before the first object */
374 INT_PTR i, *ptr = (INT_PTR *)this-1;
376 for (i = *ptr-1; i >= 0; i--)
377 streambuf_dtor(this+i);
378 MSVCRT_operator_delete(ptr);
379 } else {
380 streambuf_dtor(this);
381 if (flags & 1)
382 MSVCRT_operator_delete(this);
384 return this;
387 /* ??_Gstreambuf@@UAEPAXI@Z */
388 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
389 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
391 TRACE("(%p %x)\n", this, flags);
392 streambuf_dtor(this);
393 if (flags & 1) MSVCRT_operator_delete(this);
394 return this;
397 /* ?doallocate@streambuf@@MAEHXZ */
398 /* ?doallocate@streambuf@@MEAAHXZ */
399 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
400 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
401 int __thiscall streambuf_doallocate(streambuf *this)
403 char *reserve;
405 TRACE("(%p)\n", this);
406 reserve = MSVCRT_operator_new(RESERVE_SIZE);
407 if (!reserve)
408 return EOF;
410 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
411 return 1;
414 /* ?allocate@streambuf@@IAEHXZ */
415 /* ?allocate@streambuf@@IEAAHXZ */
416 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
417 int __thiscall streambuf_allocate(streambuf *this)
419 TRACE("(%p)\n", this);
420 if (this->base != NULL || this->unbuffered)
421 return 0;
422 return call_streambuf_doallocate(this);
425 /* ?base@streambuf@@IBEPADXZ */
426 /* ?base@streambuf@@IEBAPEADXZ */
427 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
428 char* __thiscall streambuf_base(const streambuf *this)
430 TRACE("(%p)\n", this);
431 return this->base;
434 /* ?blen@streambuf@@IBEHXZ */
435 /* ?blen@streambuf@@IEBAHXZ */
436 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
437 int __thiscall streambuf_blen(const streambuf *this)
439 TRACE("(%p)\n", this);
440 return this->ebuf - this->base;
443 /* ?eback@streambuf@@IBEPADXZ */
444 /* ?eback@streambuf@@IEBAPEADXZ */
445 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
446 char* __thiscall streambuf_eback(const streambuf *this)
448 TRACE("(%p)\n", this);
449 return this->eback;
452 /* ?ebuf@streambuf@@IBEPADXZ */
453 /* ?ebuf@streambuf@@IEBAPEADXZ */
454 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
455 char* __thiscall streambuf_ebuf(const streambuf *this)
457 TRACE("(%p)\n", this);
458 return this->ebuf;
461 /* ?egptr@streambuf@@IBEPADXZ */
462 /* ?egptr@streambuf@@IEBAPEADXZ */
463 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
464 char* __thiscall streambuf_egptr(const streambuf *this)
466 TRACE("(%p)\n", this);
467 return this->egptr;
470 /* ?epptr@streambuf@@IBEPADXZ */
471 /* ?epptr@streambuf@@IEBAPEADXZ */
472 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
473 char* __thiscall streambuf_epptr(const streambuf *this)
475 TRACE("(%p)\n", this);
476 return this->epptr;
479 /* ?gptr@streambuf@@IBEPADXZ */
480 /* ?gptr@streambuf@@IEBAPEADXZ */
481 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
482 char* __thiscall streambuf_gptr(const streambuf *this)
484 TRACE("(%p)\n", this);
485 return this->gptr;
488 /* ?pbase@streambuf@@IBEPADXZ */
489 /* ?pbase@streambuf@@IEBAPEADXZ */
490 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
491 char* __thiscall streambuf_pbase(const streambuf *this)
493 TRACE("(%p)\n", this);
494 return this->pbase;
497 /* ?pptr@streambuf@@IBEPADXZ */
498 /* ?pptr@streambuf@@IEBAPEADXZ */
499 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
500 char* __thiscall streambuf_pptr(const streambuf *this)
502 TRACE("(%p)\n", this);
503 return this->pptr;
506 /* ?clrlock@streambuf@@QAEXXZ */
507 /* ?clrlock@streambuf@@QEAAXXZ */
508 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
509 void __thiscall streambuf_clrlock(streambuf *this)
511 TRACE("(%p)\n", this);
512 if (this->do_lock <= 0)
513 this->do_lock++;
516 /* ?lock@streambuf@@QAEXXZ */
517 /* ?lock@streambuf@@QEAAXXZ */
518 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
519 void __thiscall streambuf_lock(streambuf *this)
521 TRACE("(%p)\n", this);
522 if (this->do_lock < 0)
523 EnterCriticalSection(&this->lock);
526 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
527 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
528 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
529 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
531 TRACE("(%p)\n", this);
532 return &this->lock;
535 /* ?gbump@streambuf@@IAEXH@Z */
536 /* ?gbump@streambuf@@IEAAXH@Z */
537 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
538 void __thiscall streambuf_gbump(streambuf *this, int count)
540 TRACE("(%p %d)\n", this, count);
541 this->gptr += count;
544 /* ?pbump@streambuf@@IAEXH@Z */
545 /* ?pbump@streambuf@@IEAAXH@Z */
546 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
547 void __thiscall streambuf_pbump(streambuf *this, int count)
549 TRACE("(%p %d)\n", this, count);
550 this->pptr += count;
553 /* ?in_avail@streambuf@@QBEHXZ */
554 /* ?in_avail@streambuf@@QEBAHXZ */
555 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
556 int __thiscall streambuf_in_avail(const streambuf *this)
558 TRACE("(%p)\n", this);
559 return this->egptr - this->gptr;
562 /* ?out_waiting@streambuf@@QBEHXZ */
563 /* ?out_waiting@streambuf@@QEBAHXZ */
564 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
565 int __thiscall streambuf_out_waiting(const streambuf *this)
567 TRACE("(%p)\n", this);
568 return this->pptr - this->pbase;
571 /* Unexported */
572 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
573 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
574 int __thiscall streambuf_overflow(streambuf *this, int c)
576 ERR("overflow is not implemented in streambuf\n");
577 return EOF;
580 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
581 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
582 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
583 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
584 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
586 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
587 return EOF;
590 /* ?seekpos@streambuf@@UAEJJH@Z */
591 /* ?seekpos@streambuf@@UEAAJJH@Z */
592 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
593 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
595 TRACE("(%p %d %d)\n", this, pos, mode);
596 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
599 /* ?pbackfail@streambuf@@UAEHH@Z */
600 /* ?pbackfail@streambuf@@UEAAHH@Z */
601 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
602 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
603 int __thiscall streambuf_pbackfail(streambuf *this, int c)
605 TRACE("(%p %d)\n", this, c);
606 if (this->gptr > this->eback)
607 return *--this->gptr = c;
608 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
609 return EOF;
610 if (!this->unbuffered && this->egptr) {
611 /* 'c' should be the next character read */
612 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
613 *this->gptr = c;
615 return c;
618 /* ?setb@streambuf@@IAEXPAD0H@Z */
619 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
620 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
621 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
623 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
624 if (this->allocated)
625 MSVCRT_operator_delete(this->base);
626 this->allocated = delete;
627 this->base = ba;
628 this->ebuf = eb;
631 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
632 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
633 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
634 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
636 TRACE("(%p %p %d)\n", this, buffer, length);
637 if (this->base != NULL)
638 return NULL;
640 if (buffer == NULL || !length) {
641 this->unbuffered = 1;
642 this->base = this->ebuf = NULL;
643 } else {
644 this->unbuffered = 0;
645 this->base = buffer;
646 this->ebuf = buffer + length;
648 return this;
651 /* ?setg@streambuf@@IAEXPAD00@Z */
652 /* ?setg@streambuf@@IEAAXPEAD00@Z */
653 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
654 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
656 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
657 this->eback = ek;
658 this->gptr = gp;
659 this->egptr = eg;
662 /* ?setlock@streambuf@@QAEXXZ */
663 /* ?setlock@streambuf@@QEAAXXZ */
664 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
665 void __thiscall streambuf_setlock(streambuf *this)
667 TRACE("(%p)\n", this);
668 this->do_lock--;
671 /* ?setp@streambuf@@IAEXPAD0@Z */
672 /* ?setp@streambuf@@IEAAXPEAD0@Z */
673 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
674 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
676 TRACE("(%p %p %p)\n", this, pb, ep);
677 this->pbase = this->pptr = pb;
678 this->epptr = ep;
681 /* ?sync@streambuf@@UAEHXZ */
682 /* ?sync@streambuf@@UEAAHXZ */
683 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
684 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
685 int __thiscall streambuf_sync(streambuf *this)
687 TRACE("(%p)\n", this);
688 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
691 /* ?unbuffered@streambuf@@IAEXH@Z */
692 /* ?unbuffered@streambuf@@IEAAXH@Z */
693 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
694 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
696 TRACE("(%p %d)\n", this, buf);
697 this->unbuffered = buf;
700 /* ?unbuffered@streambuf@@IBEHXZ */
701 /* ?unbuffered@streambuf@@IEBAHXZ */
702 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
703 int __thiscall streambuf_unbuffered_get(const streambuf *this)
705 TRACE("(%p)\n", this);
706 return this->unbuffered;
709 /* Unexported */
710 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
711 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
712 int __thiscall streambuf_underflow(streambuf *this)
714 ERR("underflow is not implemented in streambuf\n");
715 return EOF;
718 /* ?unlock@streambuf@@QAEXXZ */
719 /* ?unlock@streambuf@@QEAAXXZ */
720 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
721 void __thiscall streambuf_unlock(streambuf *this)
723 TRACE("(%p)\n", this);
724 if (this->do_lock < 0)
725 LeaveCriticalSection(&this->lock);
728 /* ?xsgetn@streambuf@@UAEHPADH@Z */
729 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
730 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
731 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
732 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
734 int copied = 0, chunk;
736 TRACE("(%p %p %d)\n", this, buffer, count);
738 if (this->unbuffered) {
739 if (this->stored_char == EOF)
740 this->stored_char = call_streambuf_underflow(this);
741 while (copied < count && this->stored_char != EOF) {
742 buffer[copied++] = this->stored_char;
743 this->stored_char = call_streambuf_underflow(this);
745 } else {
746 while (copied < count) {
747 if (call_streambuf_underflow(this) == EOF)
748 break;
749 chunk = this->egptr - this->gptr;
750 if (chunk > count - copied)
751 chunk = count - copied;
752 memcpy(buffer+copied, this->gptr, chunk);
753 this->gptr += chunk;
754 copied += chunk;
757 return copied;
760 /* ?xsputn@streambuf@@UAEHPBDH@Z */
761 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
762 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
763 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
764 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
766 int copied = 0, chunk;
768 TRACE("(%p %p %d)\n", this, data, length);
770 while (copied < length) {
771 if (this->unbuffered || this->pptr == this->epptr) {
772 if (call_streambuf_overflow(this, data[copied]) == EOF)
773 break;
774 copied++;
775 } else {
776 chunk = this->epptr - this->pptr;
777 if (chunk > length - copied)
778 chunk = length - copied;
779 memcpy(this->pptr, data+copied, chunk);
780 this->pptr += chunk;
781 copied += chunk;
784 return copied;
787 /* ?sgetc@streambuf@@QAEHXZ */
788 /* ?sgetc@streambuf@@QEAAHXZ */
789 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
790 int __thiscall streambuf_sgetc(streambuf *this)
792 TRACE("(%p)\n", this);
793 if (this->unbuffered) {
794 if (this->stored_char == EOF)
795 this->stored_char = call_streambuf_underflow(this);
796 return this->stored_char;
797 } else
798 return call_streambuf_underflow(this);
801 /* ?sputc@streambuf@@QAEHH@Z */
802 /* ?sputc@streambuf@@QEAAHH@Z */
803 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
804 int __thiscall streambuf_sputc(streambuf *this, int ch)
806 TRACE("(%p %d)\n", this, ch);
807 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
810 /* ?sgetn@streambuf@@QAEHPADH@Z */
811 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
812 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
813 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
815 return call_streambuf_xsgetn(this, buffer, count);
818 /* ?sputn@streambuf@@QAEHPBDH@Z */
819 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
820 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
821 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
823 return call_streambuf_xsputn(this, data, length);
826 /* ?snextc@streambuf@@QAEHXZ */
827 /* ?snextc@streambuf@@QEAAHXZ */
828 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
829 int __thiscall streambuf_snextc(streambuf *this)
831 TRACE("(%p)\n", this);
832 if (this->unbuffered) {
833 if (this->stored_char == EOF)
834 call_streambuf_underflow(this);
835 return this->stored_char = call_streambuf_underflow(this);
836 } else {
837 if (this->gptr >= this->egptr)
838 call_streambuf_underflow(this);
839 this->gptr++;
840 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
844 /* ?sbumpc@streambuf@@QAEHXZ */
845 /* ?sbumpc@streambuf@@QEAAHXZ */
846 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
847 int __thiscall streambuf_sbumpc(streambuf *this)
849 int ret;
851 TRACE("(%p)\n", this);
853 if (this->unbuffered) {
854 ret = this->stored_char;
855 this->stored_char = EOF;
856 if (ret == EOF)
857 ret = call_streambuf_underflow(this);
858 } else {
859 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
860 this->gptr++;
862 return ret;
865 /* ?stossc@streambuf@@QAEXXZ */
866 /* ?stossc@streambuf@@QEAAXXZ */
867 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
868 void __thiscall streambuf_stossc(streambuf *this)
870 TRACE("(%p)\n", this);
871 if (this->unbuffered) {
872 if (this->stored_char == EOF)
873 call_streambuf_underflow(this);
874 else
875 this->stored_char = EOF;
876 } else {
877 if (this->gptr >= this->egptr)
878 call_streambuf_underflow(this);
879 if (this->gptr < this->egptr)
880 this->gptr++;
884 /* ?sputbackc@streambuf@@QAEHD@Z */
885 /* ?sputbackc@streambuf@@QEAAHD@Z */
886 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
887 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
889 TRACE("(%p %d)\n", this, ch);
890 return call_streambuf_pbackfail(this, ch);
893 /* ?dbp@streambuf@@QAEXXZ */
894 /* ?dbp@streambuf@@QEAAXXZ */
895 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
896 void __thiscall streambuf_dbp(streambuf *this)
898 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
899 if (this->unbuffered) {
900 printf("unbuffered\n");
901 } else {
902 printf("_fAlloc=%d\n", this->allocated);
903 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
904 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
905 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
909 /* ??0filebuf@@QAE@ABV0@@Z */
910 /* ??0filebuf@@QEAA@AEBV0@@Z */
911 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
912 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
914 TRACE("(%p %p)\n", this, copy);
915 *this = *copy;
916 this->base.vtable = &MSVCP_filebuf_vtable;
917 return this;
920 /* ??0filebuf@@QAE@HPADH@Z */
921 /* ??0filebuf@@QEAA@HPEADH@Z */
922 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
923 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
925 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
926 streambuf_reserve_ctor(&this->base, buffer, length);
927 this->base.vtable = &MSVCP_filebuf_vtable;
928 this->fd = fd;
929 this->close = 0;
930 return this;
933 /* ??0filebuf@@QAE@H@Z */
934 /* ??0filebuf@@QEAA@H@Z */
935 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
936 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
938 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
939 this->base.unbuffered = 0;
940 return this;
943 /* ??0filebuf@@QAE@XZ */
944 /* ??0filebuf@@QEAA@XZ */
945 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
946 filebuf* __thiscall filebuf_ctor(filebuf* this)
948 return filebuf_fd_ctor(this, -1);
951 /* ??1filebuf@@UAE@XZ */
952 /* ??1filebuf@@UEAA@XZ */
953 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
954 void __thiscall filebuf_dtor(filebuf* this)
956 TRACE("(%p)\n", this);
957 if (this->close)
958 filebuf_close(this);
959 streambuf_dtor(&this->base);
962 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
963 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
964 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
965 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
967 filebuf_dtor(this);
968 return filebuf_copy_ctor(this, rhs);
971 /* ??_Efilebuf@@UAEPAXI@Z */
972 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
973 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
975 TRACE("(%p %x)\n", this, flags);
976 if (flags & 2) {
977 /* we have an array, with the number of elements stored before the first object */
978 INT_PTR i, *ptr = (INT_PTR *)this-1;
980 for (i = *ptr-1; i >= 0; i--)
981 filebuf_dtor(this+i);
982 MSVCRT_operator_delete(ptr);
983 } else {
984 filebuf_dtor(this);
985 if (flags & 1)
986 MSVCRT_operator_delete(this);
988 return this;
991 /* ??_Gfilebuf@@UAEPAXI@Z */
992 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
993 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
995 TRACE("(%p %x)\n", this, flags);
996 filebuf_dtor(this);
997 if (flags & 1) MSVCRT_operator_delete(this);
998 return this;
1001 /* ?attach@filebuf@@QAEPAV1@H@Z */
1002 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
1003 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
1004 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
1006 TRACE("(%p %d)\n", this, fd);
1007 if (this->fd != -1)
1008 return NULL;
1010 streambuf_lock(&this->base);
1011 this->fd = fd;
1012 streambuf_allocate(&this->base);
1013 streambuf_unlock(&this->base);
1014 return this;
1017 /* ?close@filebuf@@QAEPAV1@XZ */
1018 /* ?close@filebuf@@QEAAPEAV1@XZ */
1019 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
1020 filebuf* __thiscall filebuf_close(filebuf *this)
1022 filebuf *ret;
1024 TRACE("(%p)\n", this);
1025 if (this->fd == -1)
1026 return NULL;
1028 streambuf_lock(&this->base);
1029 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
1030 ret = NULL;
1031 } else {
1032 this->fd = -1;
1033 ret = this;
1035 streambuf_unlock(&this->base);
1036 return ret;
1039 /* ?fd@filebuf@@QBEHXZ */
1040 /* ?fd@filebuf@@QEBAHXZ */
1041 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
1042 filedesc __thiscall filebuf_fd(const filebuf *this)
1044 TRACE("(%p)\n", this);
1045 return this->fd;
1048 /* ?is_open@filebuf@@QBEHXZ */
1049 /* ?is_open@filebuf@@QEBAHXZ */
1050 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1051 int __thiscall filebuf_is_open(const filebuf *this)
1053 TRACE("(%p)\n", this);
1054 return this->fd != -1;
1057 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1058 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1059 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1060 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1062 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1063 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1064 int op_flags, sh_flags, fd;
1066 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1067 if (this->fd != -1)
1068 return NULL;
1070 /* mode */
1071 if (mode & (OPENMODE_app|OPENMODE_trunc))
1072 mode |= OPENMODE_out;
1073 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1074 if (op_flags < 0)
1075 return NULL;
1076 if (mode & OPENMODE_app)
1077 op_flags |= _O_APPEND;
1078 if ((mode & OPENMODE_trunc) ||
1079 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1080 op_flags |= _O_TRUNC;
1081 if (!(mode & OPENMODE_nocreate))
1082 op_flags |= _O_CREAT;
1083 if (mode & OPENMODE_noreplace)
1084 op_flags |= _O_EXCL;
1085 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1087 /* share protection */
1088 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1090 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1091 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1092 if (fd < 0)
1093 return NULL;
1095 streambuf_lock(&this->base);
1096 this->close = 1;
1097 this->fd = fd;
1098 if ((mode & OPENMODE_ate) &&
1099 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1100 _close(fd);
1101 this->fd = -1;
1103 streambuf_allocate(&this->base);
1104 streambuf_unlock(&this->base);
1105 return (this->fd == -1) ? NULL : this;
1108 /* ?overflow@filebuf@@UAEHH@Z */
1109 /* ?overflow@filebuf@@UEAAHH@Z */
1110 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1111 int __thiscall filebuf_overflow(filebuf *this, int c)
1113 TRACE("(%p %d)\n", this, c);
1114 if (call_streambuf_sync(&this->base) == EOF)
1115 return EOF;
1116 if (this->base.unbuffered)
1117 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1118 if (streambuf_allocate(&this->base) == EOF)
1119 return EOF;
1121 this->base.pbase = this->base.pptr = this->base.base;
1122 this->base.epptr = this->base.ebuf;
1123 if (c != EOF)
1124 *this->base.pptr++ = c;
1125 return 1;
1128 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1129 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1130 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1131 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1133 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1134 if (call_streambuf_sync(&this->base) == EOF)
1135 return EOF;
1136 return _lseek(this->fd, offset, dir);
1139 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1140 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1141 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1142 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1144 streambuf *ret;
1146 TRACE("(%p %p %d)\n", this, buffer, length);
1147 if (this->base.base != NULL)
1148 return NULL;
1150 streambuf_lock(&this->base);
1151 ret = streambuf_setbuf(&this->base, buffer, length);
1152 streambuf_unlock(&this->base);
1153 return ret;
1156 /* ?setmode@filebuf@@QAEHH@Z */
1157 /* ?setmode@filebuf@@QEAAHH@Z */
1158 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1159 int __thiscall filebuf_setmode(filebuf *this, int mode)
1161 int ret;
1163 TRACE("(%p %d)\n", this, mode);
1164 if (mode != filebuf_text && mode != filebuf_binary)
1165 return -1;
1167 streambuf_lock(&this->base);
1168 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1169 streambuf_unlock(&this->base);
1170 return ret;
1173 /* ?sync@filebuf@@UAEHXZ */
1174 /* ?sync@filebuf@@UEAAHXZ */
1175 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1176 int __thiscall filebuf_sync(filebuf *this)
1178 int count, mode;
1179 char *ptr;
1180 LONG offset;
1182 TRACE("(%p)\n", this);
1183 if (this->fd == -1)
1184 return EOF;
1185 if (this->base.unbuffered)
1186 return 0;
1188 /* flush output buffer */
1189 if (this->base.pptr != NULL) {
1190 count = this->base.pptr - this->base.pbase;
1191 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1192 return EOF;
1194 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1195 /* flush input buffer */
1196 if (this->base.egptr != NULL) {
1197 offset = this->base.egptr - this->base.gptr;
1198 if (offset > 0) {
1199 mode = _setmode(this->fd, _O_TEXT);
1200 _setmode(this->fd, mode);
1201 if (mode & _O_TEXT) {
1202 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1203 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1204 if (*ptr == '\n')
1205 offset++;
1207 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1208 return EOF;
1211 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1212 return 0;
1215 /* ?underflow@filebuf@@UAEHXZ */
1216 /* ?underflow@filebuf@@UEAAHXZ */
1217 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1218 int __thiscall filebuf_underflow(filebuf *this)
1220 int buffer_size, read_bytes;
1221 char c;
1223 TRACE("(%p)\n", this);
1225 if (this->base.unbuffered)
1226 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1228 if (this->base.gptr >= this->base.egptr) {
1229 if (call_streambuf_sync(&this->base) == EOF)
1230 return EOF;
1231 buffer_size = this->base.ebuf - this->base.base;
1232 read_bytes = _read(this->fd, this->base.base, buffer_size);
1233 if (read_bytes <= 0)
1234 return EOF;
1235 this->base.eback = this->base.gptr = this->base.base;
1236 this->base.egptr = this->base.base + read_bytes;
1238 return (unsigned char) *this->base.gptr;
1241 /* ??0strstreambuf@@QAE@ABV0@@Z */
1242 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1243 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1244 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1246 TRACE("(%p %p)\n", this, copy);
1247 *this = *copy;
1248 this->base.vtable = &MSVCP_strstreambuf_vtable;
1249 return this;
1252 /* ??0strstreambuf@@QAE@H@Z */
1253 /* ??0strstreambuf@@QEAA@H@Z */
1254 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1255 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1257 TRACE("(%p %d)\n", this, length);
1258 streambuf_ctor(&this->base);
1259 this->base.vtable = &MSVCP_strstreambuf_vtable;
1260 this->dynamic = 1;
1261 this->increase = length;
1262 this->constant = 0;
1263 this->f_alloc = NULL;
1264 this->f_free = NULL;
1265 return this;
1268 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1269 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1270 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1271 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1273 TRACE("(%p %p %p)\n", this, falloc, ffree);
1274 strstreambuf_dynamic_ctor(this, 1);
1275 this->f_alloc = falloc;
1276 this->f_free = ffree;
1277 return this;
1280 /* ??0strstreambuf@@QAE@PADH0@Z */
1281 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1282 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1283 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1285 char *end_buffer;
1287 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1289 if (length > 0)
1290 end_buffer = buffer + length;
1291 else if (length == 0)
1292 end_buffer = buffer + strlen(buffer);
1293 else
1294 end_buffer = (char*) -1;
1296 streambuf_ctor(&this->base);
1297 streambuf_setb(&this->base, buffer, end_buffer, 0);
1298 if (put == NULL) {
1299 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1300 } else {
1301 streambuf_setg(&this->base, buffer, buffer, put);
1302 streambuf_setp(&this->base, put, end_buffer);
1304 this->base.vtable = &MSVCP_strstreambuf_vtable;
1305 this->dynamic = 0;
1306 this->constant = 1;
1307 return this;
1310 /* ??0strstreambuf@@QAE@PAEH0@Z */
1311 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1312 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1313 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1315 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1316 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1319 /* ??0strstreambuf@@QAE@XZ */
1320 /* ??0strstreambuf@@QEAA@XZ */
1321 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1322 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1324 TRACE("(%p)\n", this);
1325 return strstreambuf_dynamic_ctor(this, 1);
1328 /* ??1strstreambuf@@UAE@XZ */
1329 /* ??1strstreambuf@@UEAA@XZ */
1330 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1331 void __thiscall strstreambuf_dtor(strstreambuf *this)
1333 TRACE("(%p)\n", this);
1334 if (this->dynamic && this->base.base) {
1335 if (this->f_free)
1336 this->f_free(this->base.base);
1337 else
1338 MSVCRT_operator_delete(this->base.base);
1340 streambuf_dtor(&this->base);
1343 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1344 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1345 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1346 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1348 strstreambuf_dtor(this);
1349 return strstreambuf_copy_ctor(this, rhs);
1352 /* ??_Estrstreambuf@@UAEPAXI@Z */
1353 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1354 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1356 TRACE("(%p %x)\n", this, flags);
1357 if (flags & 2) {
1358 /* we have an array, with the number of elements stored before the first object */
1359 INT_PTR i, *ptr = (INT_PTR *)this-1;
1361 for (i = *ptr-1; i >= 0; i--)
1362 strstreambuf_dtor(this+i);
1363 MSVCRT_operator_delete(ptr);
1364 } else {
1365 strstreambuf_dtor(this);
1366 if (flags & 1)
1367 MSVCRT_operator_delete(this);
1369 return this;
1372 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1373 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1374 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1376 TRACE("(%p %x)\n", this, flags);
1377 strstreambuf_dtor(this);
1378 if (flags & 1) MSVCRT_operator_delete(this);
1379 return this;
1382 /* ?doallocate@strstreambuf@@MAEHXZ */
1383 /* ?doallocate@strstreambuf@@MEAAHXZ */
1384 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1385 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1387 char *prev_buffer = this->base.base, *new_buffer;
1388 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1390 TRACE("(%p)\n", this);
1392 /* calculate the size of the new buffer */
1393 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1394 /* get a new buffer */
1395 if (this->f_alloc)
1396 new_buffer = this->f_alloc(new_size);
1397 else
1398 new_buffer = MSVCRT_operator_new(new_size);
1399 if (!new_buffer)
1400 return EOF;
1401 if (this->base.ebuf) {
1402 /* copy the contents and adjust the pointers */
1403 memcpy(new_buffer, this->base.base, prev_size);
1404 if (this->base.egptr) {
1405 this->base.eback += new_buffer - prev_buffer;
1406 this->base.gptr += new_buffer - prev_buffer;
1407 this->base.egptr += new_buffer - prev_buffer;
1409 if (this->base.epptr) {
1410 this->base.pbase += new_buffer - prev_buffer;
1411 this->base.pptr += new_buffer - prev_buffer;
1412 this->base.epptr += new_buffer - prev_buffer;
1414 /* free the old buffer */
1415 if (this->f_free)
1416 this->f_free(this->base.base);
1417 else
1418 MSVCRT_operator_delete(this->base.base);
1420 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1421 return 1;
1424 /* ?freeze@strstreambuf@@QAEXH@Z */
1425 /* ?freeze@strstreambuf@@QEAAXH@Z */
1426 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1427 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1429 TRACE("(%p %d)\n", this, frozen);
1430 if (!this->constant)
1431 this->dynamic = !frozen;
1434 /* ?overflow@strstreambuf@@UAEHH@Z */
1435 /* ?overflow@strstreambuf@@UEAAHH@Z */
1436 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1437 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1439 TRACE("(%p %d)\n", this, c);
1440 if (this->base.pptr >= this->base.epptr) {
1441 /* increase the buffer size if it's dynamic */
1442 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1443 return EOF;
1444 if (!this->base.epptr)
1445 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1446 this->base.epptr = this->base.ebuf;
1448 if (c != EOF)
1449 *this->base.pptr++ = c;
1450 return 1;
1453 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1454 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1455 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1456 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1458 char *base[3];
1460 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1462 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1463 return EOF;
1464 /* read buffer */
1465 if (mode & OPENMODE_in) {
1466 call_streambuf_underflow(&this->base);
1467 base[SEEKDIR_beg] = this->base.eback;
1468 base[SEEKDIR_cur] = this->base.gptr;
1469 base[SEEKDIR_end] = this->base.egptr;
1470 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1471 return EOF;
1472 this->base.gptr = base[dir] + offset;
1474 /* write buffer */
1475 if (mode & OPENMODE_out) {
1476 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1477 return EOF;
1478 base[SEEKDIR_beg] = this->base.pbase;
1479 base[SEEKDIR_cur] = this->base.pptr;
1480 base[SEEKDIR_end] = this->base.epptr;
1481 if (base[dir] + offset < this->base.pbase)
1482 return EOF;
1483 if (base[dir] + offset > this->base.epptr) {
1484 /* make room if the buffer is dynamic */
1485 if (!this->dynamic)
1486 return EOF;
1487 this->increase = offset;
1488 if (call_streambuf_doallocate(&this->base) == EOF)
1489 return EOF;
1491 this->base.pptr = base[dir] + offset;
1492 return this->base.pptr - base[SEEKDIR_beg];
1494 return this->base.gptr - base[SEEKDIR_beg];
1497 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1498 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1499 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1500 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1502 TRACE("(%p %p %d)\n", this, buffer, length);
1503 if (length)
1504 this->increase = length;
1505 return &this->base;
1508 /* ?str@strstreambuf@@QAEPADXZ */
1509 /* ?str@strstreambuf@@QEAAPEADXZ */
1510 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1511 char* __thiscall strstreambuf_str(strstreambuf *this)
1513 TRACE("(%p)\n", this);
1514 strstreambuf_freeze(this, 1);
1515 return this->base.base;
1518 /* ?sync@strstreambuf@@UAEHXZ */
1519 /* ?sync@strstreambuf@@UEAAHXZ */
1520 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1521 int __thiscall strstreambuf_sync(strstreambuf *this)
1523 TRACE("(%p)\n", this);
1524 return 0;
1527 /* ?underflow@strstreambuf@@UAEHXZ */
1528 /* ?underflow@strstreambuf@@UEAAHXZ */
1529 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1530 int __thiscall strstreambuf_underflow(strstreambuf *this)
1532 TRACE("(%p)\n", this);
1533 if (this->base.gptr < this->base.egptr)
1534 return (unsigned char) *this->base.gptr;
1535 /* extend the get area to include the characters written */
1536 if (this->base.egptr < this->base.pptr) {
1537 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1538 this->base.eback = this->base.base;
1539 this->base.egptr = this->base.pptr;
1541 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1544 /* ??0stdiobuf@@QAE@ABV0@@Z */
1545 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1546 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1547 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1549 TRACE("(%p %p)\n", this, copy);
1550 *this = *copy;
1551 this->base.vtable = &MSVCP_stdiobuf_vtable;
1552 return this;
1555 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1556 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1557 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1558 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1560 TRACE("(%p %p)\n", this, file);
1561 streambuf_reserve_ctor(&this->base, NULL, 0);
1562 this->base.vtable = &MSVCP_stdiobuf_vtable;
1563 this->file = file;
1564 return this;
1567 /* ??1stdiobuf@@UAE@XZ */
1568 /* ??1stdiobuf@@UEAA@XZ */
1569 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1570 void __thiscall stdiobuf_dtor(stdiobuf *this)
1572 TRACE("(%p)\n", this);
1573 call_streambuf_sync(&this->base);
1574 streambuf_dtor(&this->base);
1577 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1578 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1579 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1580 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1582 stdiobuf_dtor(this);
1583 return stdiobuf_copy_ctor(this, rhs);
1586 /* ??_Estdiobuf@@UAEPAXI@Z */
1587 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1588 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1590 TRACE("(%p %x)\n", this, flags);
1591 if (flags & 2) {
1592 /* we have an array, with the number of elements stored before the first object */
1593 INT_PTR i, *ptr = (INT_PTR *)this-1;
1595 for (i = *ptr-1; i >= 0; i--)
1596 stdiobuf_dtor(this+i);
1597 MSVCRT_operator_delete(ptr);
1598 } else {
1599 stdiobuf_dtor(this);
1600 if (flags & 1)
1601 MSVCRT_operator_delete(this);
1603 return this;
1606 /* ??_Gstdiobuf@@UAEPAXI@Z */
1607 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1608 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1610 TRACE("(%p %x)\n", this, flags);
1611 stdiobuf_dtor(this);
1612 if (flags & 1) MSVCRT_operator_delete(this);
1613 return this;
1616 /* ?overflow@stdiobuf@@UAEHH@Z */
1617 /* ?overflow@stdiobuf@@UEAAHH@Z */
1618 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1619 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1621 TRACE("(%p %d)\n", this, c);
1622 if (this->base.unbuffered)
1623 return (c == EOF) ? 1 : fputc(c, this->file);
1624 if (streambuf_allocate(&this->base) == EOF)
1625 return EOF;
1627 if (!this->base.epptr) {
1628 /* set the put area to the second half of the buffer */
1629 streambuf_setp(&this->base,
1630 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1631 } else if (this->base.pptr > this->base.pbase) {
1632 /* flush the put area */
1633 int count = this->base.pptr - this->base.pbase;
1634 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1635 return EOF;
1636 this->base.pptr = this->base.pbase;
1638 if (c != EOF) {
1639 if (this->base.pbase >= this->base.epptr)
1640 return fputc(c, this->file);
1641 *this->base.pptr++ = c;
1643 return 1;
1646 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1647 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1648 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1649 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1651 TRACE("(%p %d)\n", this, c);
1652 return streambuf_pbackfail(&this->base, c);
1655 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1656 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1657 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1658 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1660 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1661 call_streambuf_overflow(&this->base, EOF);
1662 if (fseek(this->file, offset, dir))
1663 return EOF;
1664 return ftell(this->file);
1667 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1668 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1669 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1670 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1672 char *reserve;
1673 int buffer_size = read_size + write_size;
1675 TRACE("(%p %d %d)\n", this, read_size, write_size);
1676 if (read_size < 0 || write_size < 0)
1677 return 0;
1678 if (!buffer_size) {
1679 this->base.unbuffered = 1;
1680 return 0;
1682 /* get a new buffer */
1683 reserve = MSVCRT_operator_new(buffer_size);
1684 if (!reserve)
1685 return 0;
1686 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1687 this->base.unbuffered = 0;
1688 /* set the get/put areas */
1689 if (read_size > 0)
1690 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1691 else
1692 streambuf_setg(&this->base, NULL, NULL, NULL);
1693 if (write_size > 0)
1694 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1695 else
1696 streambuf_setp(&this->base, NULL, NULL);
1697 return 1;
1700 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1701 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1702 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1703 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1705 TRACE("(%p)\n", this);
1706 return this->file;
1709 /* ?sync@stdiobuf@@UAEHXZ */
1710 /* ?sync@stdiobuf@@UEAAHXZ */
1711 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1712 int __thiscall stdiobuf_sync(stdiobuf *this)
1714 TRACE("(%p)\n", this);
1715 if (this->base.unbuffered)
1716 return 0;
1717 /* flush the put area */
1718 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1719 return EOF;
1720 /* flush the get area */
1721 if (this->base.gptr < this->base.egptr) {
1722 char *ptr;
1723 int fd, mode, offset = this->base.egptr - this->base.gptr;
1724 if ((fd = fileno(this->file)) < 0)
1725 return EOF;
1726 mode = _setmode(fd, _O_TEXT);
1727 _setmode(fd, mode);
1728 if (mode & _O_TEXT) {
1729 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1730 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1731 if (*ptr == '\n')
1732 offset++;
1734 if (fseek(this->file, -offset, SEEK_CUR))
1735 return EOF;
1736 this->base.gptr = this->base.egptr;
1738 return 0;
1741 /* ?underflow@stdiobuf@@UAEHXZ */
1742 /* ?underflow@stdiobuf@@UEAAHXZ */
1743 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1744 int __thiscall stdiobuf_underflow(stdiobuf *this)
1746 TRACE("(%p)\n", this);
1747 if (!this->file)
1748 return EOF;
1749 if (this->base.unbuffered)
1750 return fgetc(this->file);
1751 if (streambuf_allocate(&this->base) == EOF)
1752 return EOF;
1754 if (!this->base.egptr) {
1755 /* set the get area to the first half of the buffer */
1756 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1757 streambuf_setg(&this->base, this->base.base, middle, middle);
1759 if (this->base.gptr >= this->base.egptr) {
1760 /* read characters from the file */
1761 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1762 if (!this->base.eback ||
1763 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1764 return EOF;
1765 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1766 this->base.gptr = this->base.egptr - read_bytes;
1768 return (unsigned char) *this->base.gptr++;
1771 /* ??0ios@@IAE@ABV0@@Z */
1772 /* ??0ios@@IEAA@AEBV0@@Z */
1773 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1774 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1776 TRACE("(%p %p)\n", this, copy);
1777 ios_fLockcInit++;
1778 this->vtable = &MSVCP_ios_vtable;
1779 this->sb = NULL;
1780 this->delbuf = 0;
1781 this->do_lock = -1;
1782 InitializeCriticalSection(&this->lock);
1783 return ios_assign(this, copy);
1786 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1787 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1788 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1789 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1791 TRACE("(%p %p)\n", this, sb);
1792 ios_fLockcInit++;
1793 this->vtable = &MSVCP_ios_vtable;
1794 this->sb = sb;
1795 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1796 this->special[0] = this->special[1] = 0;
1797 this->delbuf = 0;
1798 this->tie = NULL;
1799 this->flags = 0;
1800 this->precision = 6;
1801 this->fill = ' ';
1802 this->width = 0;
1803 this->do_lock = -1;
1804 InitializeCriticalSection(&this->lock);
1805 return this;
1808 /* ??0ios@@IAE@XZ */
1809 /* ??0ios@@IEAA@XZ */
1810 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1811 ios* __thiscall ios_ctor(ios *this)
1813 return ios_sb_ctor(this, NULL);
1816 /* ??1ios@@UAE@XZ */
1817 /* ??1ios@@UEAA@XZ */
1818 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1819 void __thiscall ios_dtor(ios *this)
1821 TRACE("(%p)\n", this);
1822 ios_fLockcInit--;
1823 if (this->delbuf && this->sb)
1824 call_streambuf_vector_dtor(this->sb, 1);
1825 this->sb = NULL;
1826 this->state = IOSTATE_badbit;
1827 DeleteCriticalSection(&this->lock);
1830 /* ??4ios@@IAEAAV0@ABV0@@Z */
1831 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1832 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1833 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1835 TRACE("(%p %p)\n", this, rhs);
1836 this->state = rhs->state;
1837 if (!this->sb)
1838 this->state |= IOSTATE_badbit;
1839 this->tie = rhs->tie;
1840 this->flags = rhs->flags;
1841 this->precision = (char) rhs->precision;
1842 this->fill = rhs->fill;
1843 this->width = (char) rhs->width;
1844 return this;
1847 /* ??7ios@@QBEHXZ */
1848 /* ??7ios@@QEBAHXZ */
1849 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1850 int __thiscall ios_op_not(const ios *this)
1852 TRACE("(%p)\n", this);
1853 return ios_fail(this);
1856 /* ??Bios@@QBEPAXXZ */
1857 /* ??Bios@@QEBAPEAXXZ */
1858 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1859 void* __thiscall ios_op_void(const ios *this)
1861 TRACE("(%p)\n", this);
1862 return ios_fail(this) ? NULL : (void*)this;
1865 /* ??_Eios@@UAEPAXI@Z */
1866 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1867 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1869 TRACE("(%p %x)\n", this, flags);
1870 if (flags & 2) {
1871 /* we have an array, with the number of elements stored before the first object */
1872 INT_PTR i, *ptr = (INT_PTR *)this-1;
1874 for (i = *ptr-1; i >= 0; i--)
1875 ios_dtor(this+i);
1876 MSVCRT_operator_delete(ptr);
1877 } else {
1878 ios_dtor(this);
1879 if (flags & 1)
1880 MSVCRT_operator_delete(this);
1882 return this;
1885 /* ??_Gios@@UAEPAXI@Z */
1886 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1887 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1889 TRACE("(%p %x)\n", this, flags);
1890 ios_dtor(this);
1891 if (flags & 1) MSVCRT_operator_delete(this);
1892 return this;
1895 /* ?bad@ios@@QBEHXZ */
1896 /* ?bad@ios@@QEBAHXZ */
1897 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1898 int __thiscall ios_bad(const ios *this)
1900 TRACE("(%p)\n", this);
1901 return (this->state & IOSTATE_badbit);
1904 /* ?bitalloc@ios@@SAJXZ */
1905 LONG __cdecl ios_bitalloc(void)
1907 TRACE("()\n");
1908 ios_lockc();
1909 ios_maxbit <<= 1;
1910 ios_unlockc();
1911 return ios_maxbit;
1914 /* ?clear@ios@@QAEXH@Z */
1915 /* ?clear@ios@@QEAAXH@Z */
1916 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1917 void __thiscall ios_clear(ios *this, int state)
1919 TRACE("(%p %d)\n", this, state);
1920 ios_lock(this);
1921 this->state = state;
1922 ios_unlock(this);
1925 /* ?clrlock@ios@@QAAXXZ */
1926 /* ?clrlock@ios@@QEAAXXZ */
1927 void __cdecl ios_clrlock(ios *this)
1929 TRACE("(%p)\n", this);
1930 if (this->do_lock <= 0)
1931 this->do_lock++;
1932 if (this->sb)
1933 streambuf_clrlock(this->sb);
1936 /* ?delbuf@ios@@QAEXH@Z */
1937 /* ?delbuf@ios@@QEAAXH@Z */
1938 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1939 void __thiscall ios_delbuf_set(ios *this, int delete)
1941 TRACE("(%p %d)\n", this, delete);
1942 this->delbuf = delete;
1945 /* ?delbuf@ios@@QBEHXZ */
1946 /* ?delbuf@ios@@QEBAHXZ */
1947 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1948 int __thiscall ios_delbuf_get(const ios *this)
1950 TRACE("(%p)\n", this);
1951 return this->delbuf;
1954 /* ?dec@@YAAAVios@@AAV1@@Z */
1955 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1956 ios* __cdecl ios_dec(ios *this)
1958 TRACE("(%p)\n", this);
1959 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1960 return this;
1963 /* ?eof@ios@@QBEHXZ */
1964 /* ?eof@ios@@QEBAHXZ */
1965 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1966 int __thiscall ios_eof(const ios *this)
1968 TRACE("(%p)\n", this);
1969 return (this->state & IOSTATE_eofbit);
1972 /* ?fail@ios@@QBEHXZ */
1973 /* ?fail@ios@@QEBAHXZ */
1974 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1975 int __thiscall ios_fail(const ios *this)
1977 TRACE("(%p)\n", this);
1978 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1981 /* ?fill@ios@@QAEDD@Z */
1982 /* ?fill@ios@@QEAADD@Z */
1983 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1984 char __thiscall ios_fill_set(ios *this, char fill)
1986 char prev = this->fill;
1988 TRACE("(%p %d)\n", this, fill);
1990 this->fill = fill;
1991 return prev;
1994 /* ?fill@ios@@QBEDXZ */
1995 /* ?fill@ios@@QEBADXZ */
1996 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1997 char __thiscall ios_fill_get(const ios *this)
1999 TRACE("(%p)\n", this);
2000 return this->fill;
2003 /* ?flags@ios@@QAEJJ@Z */
2004 /* ?flags@ios@@QEAAJJ@Z */
2005 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
2006 LONG __thiscall ios_flags_set(ios *this, LONG flags)
2008 LONG prev = this->flags;
2010 TRACE("(%p %x)\n", this, flags);
2012 this->flags = flags;
2013 return prev;
2016 /* ?flags@ios@@QBEJXZ */
2017 /* ?flags@ios@@QEBAJXZ */
2018 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
2019 LONG __thiscall ios_flags_get(const ios *this)
2021 TRACE("(%p)\n", this);
2022 return this->flags;
2025 /* ?good@ios@@QBEHXZ */
2026 /* ?good@ios@@QEBAHXZ */
2027 DEFINE_THISCALL_WRAPPER(ios_good, 4)
2028 int __thiscall ios_good(const ios *this)
2030 TRACE("(%p)\n", this);
2031 return this->state == IOSTATE_goodbit;
2034 /* ?hex@@YAAAVios@@AAV1@@Z */
2035 /* ?hex@@YAAEAVios@@AEAV1@@Z */
2036 ios* __cdecl ios_hex(ios *this)
2038 TRACE("(%p)\n", this);
2039 ios_setf_mask(this, FLAGS_hex, ios_basefield);
2040 return this;
2043 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
2044 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
2045 DEFINE_THISCALL_WRAPPER(ios_init, 8)
2046 void __thiscall ios_init(ios *this, streambuf *sb)
2048 TRACE("(%p %p)\n", this, sb);
2049 if (this->delbuf && this->sb)
2050 call_streambuf_vector_dtor(this->sb, 1);
2051 this->sb = sb;
2052 if (sb == NULL)
2053 this->state |= IOSTATE_badbit;
2054 else
2055 this->state &= ~IOSTATE_badbit;
2058 /* ?iword@ios@@QBEAAJH@Z */
2059 /* ?iword@ios@@QEBAAEAJH@Z */
2060 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2061 LONG* __thiscall ios_iword(const ios *this, int index)
2063 TRACE("(%p %d)\n", this, index);
2064 return &ios_statebuf[index];
2067 /* ?lock@ios@@QAAXXZ */
2068 /* ?lock@ios@@QEAAXXZ */
2069 void __cdecl ios_lock(ios *this)
2071 TRACE("(%p)\n", this);
2072 if (this->do_lock < 0)
2073 EnterCriticalSection(&this->lock);
2076 /* ?lockbuf@ios@@QAAXXZ */
2077 /* ?lockbuf@ios@@QEAAXXZ */
2078 void __cdecl ios_lockbuf(ios *this)
2080 TRACE("(%p)\n", this);
2081 streambuf_lock(this->sb);
2084 /* ?lockc@ios@@KAXXZ */
2085 void __cdecl ios_lockc(void)
2087 TRACE("()\n");
2088 EnterCriticalSection(&ios_static_lock);
2091 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2092 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2093 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2094 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2096 TRACE("(%p)\n", this);
2097 return &this->lock;
2100 /* ?oct@@YAAAVios@@AAV1@@Z */
2101 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2102 ios* __cdecl ios_oct(ios *this)
2104 TRACE("(%p)\n", this);
2105 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2106 return this;
2109 /* ?precision@ios@@QAEHH@Z */
2110 /* ?precision@ios@@QEAAHH@Z */
2111 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2112 int __thiscall ios_precision_set(ios *this, int prec)
2114 int prev = this->precision;
2116 TRACE("(%p %d)\n", this, prec);
2118 this->precision = prec;
2119 return prev;
2122 /* ?precision@ios@@QBEHXZ */
2123 /* ?precision@ios@@QEBAHXZ */
2124 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2125 int __thiscall ios_precision_get(const ios *this)
2127 TRACE("(%p)\n", this);
2128 return this->precision;
2131 /* ?pword@ios@@QBEAAPAXH@Z */
2132 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2133 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2134 void** __thiscall ios_pword(const ios *this, int index)
2136 TRACE("(%p %d)\n", this, index);
2137 return (void**)&ios_statebuf[index];
2140 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2141 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2142 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2143 streambuf* __thiscall ios_rdbuf(const ios *this)
2145 TRACE("(%p)\n", this);
2146 return this->sb;
2149 /* ?rdstate@ios@@QBEHXZ */
2150 /* ?rdstate@ios@@QEBAHXZ */
2151 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2152 int __thiscall ios_rdstate(const ios *this)
2154 TRACE("(%p)\n", this);
2155 return this->state;
2158 /* ?setf@ios@@QAEJJ@Z */
2159 /* ?setf@ios@@QEAAJJ@Z */
2160 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2161 LONG __thiscall ios_setf(ios *this, LONG flags)
2163 LONG prev = this->flags;
2165 TRACE("(%p %x)\n", this, flags);
2167 ios_lock(this);
2168 this->flags |= flags;
2169 ios_unlock(this);
2170 return prev;
2173 /* ?setf@ios@@QAEJJJ@Z */
2174 /* ?setf@ios@@QEAAJJJ@Z */
2175 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2176 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2178 LONG prev = this->flags;
2180 TRACE("(%p %x %x)\n", this, flags, mask);
2182 ios_lock(this);
2183 this->flags = (this->flags & (~mask)) | (flags & mask);
2184 ios_unlock(this);
2185 return prev;
2188 /* ?setlock@ios@@QAAXXZ */
2189 /* ?setlock@ios@@QEAAXXZ */
2190 void __cdecl ios_setlock(ios *this)
2192 TRACE("(%p)\n", this);
2193 this->do_lock--;
2194 if (this->sb)
2195 streambuf_setlock(this->sb);
2198 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2199 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2200 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2201 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2203 ostream *prev = this->tie;
2205 TRACE("(%p %p)\n", this, ostr);
2207 this->tie = ostr;
2208 return prev;
2211 /* ?tie@ios@@QBEPAVostream@@XZ */
2212 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2213 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2214 ostream* __thiscall ios_tie_get(const ios *this)
2216 TRACE("(%p)\n", this);
2217 return this->tie;
2220 /* ?unlock@ios@@QAAXXZ */
2221 /* ?unlock@ios@@QEAAXXZ */
2222 void __cdecl ios_unlock(ios *this)
2224 TRACE("(%p)\n", this);
2225 if (this->do_lock < 0)
2226 LeaveCriticalSection(&this->lock);
2229 /* ?unlockbuf@ios@@QAAXXZ */
2230 /* ?unlockbuf@ios@@QEAAXXZ */
2231 void __cdecl ios_unlockbuf(ios *this)
2233 TRACE("(%p)\n", this);
2234 streambuf_unlock(this->sb);
2237 /* ?unlockc@ios@@KAXXZ */
2238 void __cdecl ios_unlockc(void)
2240 TRACE("()\n");
2241 LeaveCriticalSection(&ios_static_lock);
2244 /* ?unsetf@ios@@QAEJJ@Z */
2245 /* ?unsetf@ios@@QEAAJJ@Z */
2246 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2247 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2249 LONG prev = this->flags;
2251 TRACE("(%p %x)\n", this, flags);
2253 ios_lock(this);
2254 this->flags &= ~flags;
2255 ios_unlock(this);
2256 return prev;
2259 /* ?width@ios@@QAEHH@Z */
2260 /* ?width@ios@@QEAAHH@Z */
2261 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2262 int __thiscall ios_width_set(ios *this, int width)
2264 int prev = this->width;
2266 TRACE("(%p %d)\n", this, width);
2268 this->width = width;
2269 return prev;
2272 /* ?width@ios@@QBEHXZ */
2273 /* ?width@ios@@QEBAHXZ */
2274 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2275 int __thiscall ios_width_get(const ios *this)
2277 TRACE("(%p)\n", this);
2278 return this->width;
2281 /* ?xalloc@ios@@SAHXZ */
2282 int __cdecl ios_xalloc(void)
2284 int ret;
2286 TRACE("()\n");
2288 ios_lockc();
2289 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2290 ios_unlockc();
2291 return ret;
2294 static inline ios* ostream_get_ios(const ostream *this)
2296 return (ios*)((char*)this + this->vbtable[1]);
2299 static inline ios* ostream_to_ios(const ostream *this)
2301 return (ios*)((char*)this + ostream_vbtable[1]);
2304 static inline ostream* ios_to_ostream(const ios *base)
2306 return (ostream*)((char*)base - ostream_vbtable[1]);
2309 /* ??0ostream@@IAE@XZ */
2310 /* ??0ostream@@IEAA@XZ */
2311 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2312 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2314 ios *base;
2316 TRACE("(%p %d)\n", this, virt_init);
2318 if (virt_init) {
2319 this->vbtable = ostream_vbtable;
2320 base = ostream_get_ios(this);
2321 ios_ctor(base);
2322 } else
2323 base = ostream_get_ios(this);
2324 base->vtable = &MSVCP_ostream_vtable;
2325 this->unknown = 0;
2326 return this;
2329 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2330 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2331 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2332 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2334 TRACE("(%p %p %d)\n", this, sb, virt_init);
2335 ostream_ctor(this, virt_init);
2336 ios_init(ostream_get_ios(this), sb);
2337 return this;
2340 /* ??0ostream@@IAE@ABV0@@Z */
2341 /* ??0ostream@@IEAA@AEBV0@@Z */
2342 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2343 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2345 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2348 /* ??1ostream@@UAE@XZ */
2349 /* ??1ostream@@UEAA@XZ */
2350 /* ??1ostream_withassign@@UAE@XZ */
2351 /* ??1ostream_withassign@@UEAA@XZ */
2352 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2353 void __thiscall ostream_dtor(ios *base)
2355 ostream *this = ios_to_ostream(base);
2357 TRACE("(%p)\n", this);
2360 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2361 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2362 /* ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z */
2363 /* ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z */
2364 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2365 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2367 ios *base = ostream_get_ios(this);
2369 TRACE("(%p %p)\n", this, sb);
2371 ios_init(base, sb);
2372 base->state &= IOSTATE_badbit;
2373 base->delbuf = 0;
2374 base->tie = NULL;
2375 base->flags = 0;
2376 base->precision = 6;
2377 base->fill = ' ';
2378 base->width = 0;
2379 return this;
2382 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2383 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2384 /* ??4ostream_withassign@@QAEAAV0@ABV0@@Z */
2385 /* ??4ostream_withassign@@QEAAAEAV0@AEBV0@@Z */
2386 /* ??4ostream_withassign@@QAEAAVostream@@ABV1@@Z */
2387 /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */
2388 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2389 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2391 return ostream_assign_sb(this, ostream_get_ios(rhs)->sb);
2394 /* ??_Dostream@@QAEXXZ */
2395 /* ??_Dostream@@QEAAXXZ */
2396 /* ??_Dostream_withassign@@QAEXXZ */
2397 /* ??_Dostream_withassign@@QEAAXXZ */
2398 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2399 void __thiscall ostream_vbase_dtor(ostream *this)
2401 ios *base = ostream_to_ios(this);
2403 TRACE("(%p)\n", this);
2405 ostream_dtor(base);
2406 ios_dtor(base);
2409 /* ??_Eostream@@UAEPAXI@Z */
2410 /* ??_Eostream_withassign@@UAEPAXI@Z */
2411 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2412 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2414 ostream *this = ios_to_ostream(base);
2416 TRACE("(%p %x)\n", this, flags);
2418 if (flags & 2) {
2419 /* we have an array, with the number of elements stored before the first object */
2420 INT_PTR i, *ptr = (INT_PTR *)this-1;
2422 for (i = *ptr-1; i >= 0; i--)
2423 ostream_vbase_dtor(this+i);
2424 MSVCRT_operator_delete(ptr);
2425 } else {
2426 ostream_vbase_dtor(this);
2427 if (flags & 1)
2428 MSVCRT_operator_delete(this);
2430 return this;
2433 /* ??_Gostream@@UAEPAXI@Z */
2434 /* ??_Gostream_withassign@@UAEPAXI@Z */
2435 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2436 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2438 ostream *this = ios_to_ostream(base);
2440 TRACE("(%p %x)\n", this, flags);
2442 ostream_vbase_dtor(this);
2443 if (flags & 1) MSVCRT_operator_delete(this);
2444 return this;
2447 /* ?flush@ostream@@QAEAAV1@XZ */
2448 /* ?flush@ostream@@QEAAAEAV1@XZ */
2449 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2450 ostream* __thiscall ostream_flush(ostream *this)
2452 ios *base = ostream_get_ios(this);
2454 TRACE("(%p)\n", this);
2456 ios_lockbuf(base);
2457 if (call_streambuf_sync(base->sb) == EOF)
2458 ios_clear(base, base->state | IOSTATE_failbit);
2459 ios_unlockbuf(base);
2460 return this;
2463 /* ?opfx@ostream@@QAEHXZ */
2464 /* ?opfx@ostream@@QEAAHXZ */
2465 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2466 int __thiscall ostream_opfx(ostream *this)
2468 ios *base = ostream_get_ios(this);
2470 TRACE("(%p)\n", this);
2472 if (!ios_good(base)) {
2473 ios_clear(base, base->state | IOSTATE_failbit);
2474 return 0;
2476 ios_lock(base);
2477 ios_lockbuf(base);
2478 if (base->tie)
2479 ostream_flush(base->tie);
2480 return 1;
2483 /* ?osfx@ostream@@QAEXXZ */
2484 /* ?osfx@ostream@@QEAAXXZ */
2485 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2486 void __thiscall ostream_osfx(ostream *this)
2488 ios *base = ostream_get_ios(this);
2490 TRACE("(%p)\n", this);
2492 ios_unlockbuf(base);
2493 ios_width_set(base, 0);
2494 if (base->flags & FLAGS_unitbuf)
2495 ostream_flush(this);
2496 if (base->flags & FLAGS_stdio) {
2497 fflush(stdout);
2498 fflush(stderr);
2500 ios_unlock(base);
2503 /* ?put@ostream@@QAEAAV1@C@Z */
2504 /* ?put@ostream@@QEAAAEAV1@C@Z */
2505 /* ?put@ostream@@QAEAAV1@D@Z */
2506 /* ?put@ostream@@QEAAAEAV1@D@Z */
2507 /* ?put@ostream@@QAEAAV1@E@Z */
2508 /* ?put@ostream@@QEAAAEAV1@E@Z */
2509 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2510 ostream* __thiscall ostream_put(ostream *this, char c)
2512 ios *base = ostream_get_ios(this);
2514 TRACE("(%p %c)\n", this, c);
2516 if (ostream_opfx(this)) {
2517 if (streambuf_sputc(base->sb, c) == EOF)
2518 base->state = IOSTATE_badbit | IOSTATE_failbit;
2519 ostream_osfx(this);
2521 return this;
2524 /* ?seekp@ostream@@QAEAAV1@J@Z */
2525 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2526 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2527 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2529 ios *base = ostream_get_ios(this);
2531 TRACE("(%p %d)\n", this, pos);
2533 ios_lockbuf(base);
2534 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2535 ios_clear(base, base->state | IOSTATE_failbit);
2536 ios_unlockbuf(base);
2537 return this;
2540 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2541 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2542 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2543 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2545 ios *base = ostream_get_ios(this);
2547 TRACE("(%p %d %d)\n", this, off, dir);
2549 ios_lockbuf(base);
2550 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2551 ios_clear(base, base->state | IOSTATE_failbit);
2552 ios_unlockbuf(base);
2553 return this;
2556 /* ?tellp@ostream@@QAEJXZ */
2557 /* ?tellp@ostream@@QEAAJXZ */
2558 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2559 streampos __thiscall ostream_tellp(ostream *this)
2561 ios *base = ostream_get_ios(this);
2562 streampos pos;
2564 TRACE("(%p)\n", this);
2566 ios_lockbuf(base);
2567 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2568 ios_clear(base, base->state | IOSTATE_failbit);
2569 ios_unlockbuf(base);
2570 return pos;
2573 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2574 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2575 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2576 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2577 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2578 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2579 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2580 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2582 ios *base = ostream_get_ios(this);
2584 TRACE("(%p %p %d)\n", this, str, count);
2586 if (ostream_opfx(this)) {
2587 if (streambuf_sputn(base->sb, str, count) != count)
2588 base->state = IOSTATE_badbit | IOSTATE_failbit;
2589 ostream_osfx(this);
2591 return this;
2594 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2595 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2596 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2597 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2599 ios *base = ostream_get_ios(this);
2600 int len1 = strlen(str1), len2 = strlen(str2), i;
2602 TRACE("(%p %p %p)\n", this, str1, str2);
2604 /* left of the padding */
2605 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2606 if (streambuf_sputn(base->sb, str1, len1) != len1)
2607 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2608 if (!(base->flags & FLAGS_internal))
2609 if (streambuf_sputn(base->sb, str2, len2) != len2)
2610 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2612 /* add padding to fill the width */
2613 for (i = len1 + len2; i < base->width; i++)
2614 if (streambuf_sputc(base->sb, base->fill) == EOF)
2615 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2616 /* right of the padding */
2617 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2618 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2619 if (streambuf_sputn(base->sb, str1, len1) != len1)
2620 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2621 if (streambuf_sputn(base->sb, str2, len2) != len2)
2622 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2624 return this;
2627 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2629 ios *base = ostream_get_ios(ostr);
2630 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2632 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2634 if (ostream_opfx(ostr)) {
2635 if (base->flags & FLAGS_hex) {
2636 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2637 if (base->flags & FLAGS_showbase) {
2638 prefix_str[0] = '0';
2639 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2641 } else if (base->flags & FLAGS_oct) {
2642 sprintf_fmt[1] = 'o';
2643 if (base->flags & FLAGS_showbase)
2644 prefix_str[0] = '0';
2645 } else { /* FLAGS_dec */
2646 if (unsig)
2647 sprintf_fmt[1] = 'u';
2648 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2649 prefix_str[0] = '+';
2652 if (shrt) {
2653 sprintf_fmt[2] = sprintf_fmt[1];
2654 sprintf_fmt[1] = 'h';
2657 if (sprintf(number_str, sprintf_fmt, n) > 0)
2658 ostream_writepad(ostr, prefix_str, number_str);
2659 else
2660 base->state |= IOSTATE_failbit;
2661 ostream_osfx(ostr);
2663 return ostr;
2666 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2668 ios *base = ostream_get_ios(ostr);
2669 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2670 int prec, max_prec = dbl ? 15 : 6;
2671 int str_length = 1; /* null end char */
2673 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2675 if (ostream_opfx(ostr)) {
2676 if ((base->flags & FLAGS_showpos) && d > 0) {
2677 prefix_str[0] = '+';
2678 str_length++; /* plus sign */
2680 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2681 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2682 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2683 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2684 if (base->flags & FLAGS_showpoint) {
2685 sprintf_fmt[4] = sprintf_fmt[3];
2686 sprintf_fmt[3] = sprintf_fmt[2];
2687 sprintf_fmt[2] = sprintf_fmt[1];
2688 sprintf_fmt[1] = '#';
2691 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2692 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2693 if (str_length > 24) {
2694 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2695 ostream_writepad(ostr, "", "");
2696 } else {
2697 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2698 ostream_writepad(ostr, prefix_str, number_str);
2699 else
2700 base->state |= IOSTATE_failbit;
2702 ostream_osfx(ostr);
2704 return ostr;
2707 /* ??6ostream@@QAEAAV0@C@Z */
2708 /* ??6ostream@@QEAAAEAV0@C@Z */
2709 /* ??6ostream@@QAEAAV0@D@Z */
2710 /* ??6ostream@@QEAAAEAV0@D@Z */
2711 /* ??6ostream@@QAEAAV0@E@Z */
2712 /* ??6ostream@@QEAAAEAV0@E@Z */
2713 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2714 ostream* __thiscall ostream_print_char(ostream *this, char c)
2716 const char c_str[2] = {c, 0};
2718 TRACE("(%p %c)\n", this, c);
2720 if (ostream_opfx(this)) {
2721 ostream_writepad(this, "", c_str);
2722 ostream_osfx(this);
2724 return this;
2727 /* ??6ostream@@QAEAAV0@PBC@Z */
2728 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2729 /* ??6ostream@@QAEAAV0@PBD@Z */
2730 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2731 /* ??6ostream@@QAEAAV0@PBE@Z */
2732 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2733 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2734 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2736 TRACE("(%p %s)\n", this, str);
2737 if (ostream_opfx(this)) {
2738 ostream_writepad(this, "", str);
2739 ostream_osfx(this);
2741 return this;
2744 /* ??6ostream@@QAEAAV0@F@Z */
2745 /* ??6ostream@@QEAAAEAV0@F@Z */
2746 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2747 ostream* __thiscall ostream_print_short(ostream *this, short n)
2749 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2752 /* ??6ostream@@QAEAAV0@G@Z */
2753 /* ??6ostream@@QEAAAEAV0@G@Z */
2754 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2755 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2757 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2760 /* ??6ostream@@QAEAAV0@H@Z */
2761 /* ??6ostream@@QEAAAEAV0@H@Z */
2762 /* ??6ostream@@QAEAAV0@J@Z */
2763 /* ??6ostream@@QEAAAEAV0@J@Z */
2764 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2765 ostream* __thiscall ostream_print_int(ostream *this, int n)
2767 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2770 /* ??6ostream@@QAEAAV0@I@Z */
2771 /* ??6ostream@@QEAAAEAV0@I@Z */
2772 /* ??6ostream@@QAEAAV0@K@Z */
2773 /* ??6ostream@@QEAAAEAV0@K@Z */
2774 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2775 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2777 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2780 /* ??6ostream@@QAEAAV0@M@Z */
2781 /* ??6ostream@@QEAAAEAV0@M@Z */
2782 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2783 ostream* __thiscall ostream_print_float(ostream *this, float f)
2785 return ostream_internal_print_float(this, f, FALSE);
2788 /* ??6ostream@@QAEAAV0@N@Z */
2789 /* ??6ostream@@QEAAAEAV0@N@Z */
2790 /* ??6ostream@@QAEAAV0@O@Z */
2791 /* ??6ostream@@QEAAAEAV0@O@Z */
2792 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2793 ostream* __thiscall ostream_print_double(ostream *this, double d)
2795 return ostream_internal_print_float(this, d, TRUE);
2798 /* ??6ostream@@QAEAAV0@PBX@Z */
2799 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2800 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2801 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2803 ios *base = ostream_get_ios(this);
2804 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2806 TRACE("(%p %p)\n", this, ptr);
2808 if (ostream_opfx(this)) {
2809 if (ptr && base->flags & FLAGS_uppercase)
2810 prefix_str[1] = 'X';
2812 if (sprintf(pointer_str, "%p", ptr) > 0)
2813 ostream_writepad(this, prefix_str, pointer_str);
2814 else
2815 base->state |= IOSTATE_failbit;
2816 ostream_osfx(this);
2818 return this;
2821 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2822 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2823 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2824 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2826 ios *base = ostream_get_ios(this);
2827 int c;
2829 TRACE("(%p %p)\n", this, sb);
2831 if (ostream_opfx(this)) {
2832 while ((c = streambuf_sbumpc(sb)) != EOF) {
2833 if (streambuf_sputc(base->sb, c) == EOF) {
2834 base->state |= IOSTATE_failbit;
2835 break;
2838 ostream_osfx(this);
2840 return this;
2843 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2844 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2845 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2846 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2848 TRACE("(%p %p)\n", this, func);
2849 return func(this);
2852 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2853 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2854 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2855 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2857 TRACE("(%p %p)\n", this, func);
2858 func(ostream_get_ios(this));
2859 return this;
2862 /* ?endl@@YAAAVostream@@AAV1@@Z */
2863 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2864 ostream* __cdecl ostream_endl(ostream *this)
2866 TRACE("(%p)\n", this);
2867 ostream_put(this, '\n');
2868 return ostream_flush(this);
2871 /* ?ends@@YAAAVostream@@AAV1@@Z */
2872 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2873 ostream* __cdecl ostream_ends(ostream *this)
2875 TRACE("(%p)\n", this);
2876 return ostream_put(this, 0);
2879 /* ?flush@@YAAAVostream@@AAV1@@Z */
2880 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2881 ostream* __cdecl ostream_flush_manip(ostream *this)
2883 TRACE("(%p)\n", this);
2884 return ostream_flush(this);
2887 /* ??0ostream_withassign@@QAE@ABV0@@Z */
2888 /* ??0ostream_withassign@@QEAA@AEBV0@@Z */
2889 DEFINE_THISCALL_WRAPPER(ostream_withassign_copy_ctor, 12)
2890 ostream* __thiscall ostream_withassign_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2892 ios *base, *base_copy;
2894 TRACE("(%p %p %d)\n", this, copy, virt_init);
2896 base_copy = ostream_get_ios(copy);
2897 if (virt_init) {
2898 this->vbtable = ostream_vbtable;
2899 base = ostream_get_ios(this);
2900 ios_copy_ctor(base, base_copy);
2901 } else
2902 base = ostream_get_ios(this);
2903 ios_init(base, base_copy->sb);
2904 base->vtable = &MSVCP_ostream_withassign_vtable;
2905 this->unknown = 0;
2906 return this;
2909 /* ??0ostream_withassign@@QAE@PAVstreambuf@@@Z */
2910 /* ??0ostream_withassign@@QEAA@PEAVstreambuf@@@Z */
2911 DEFINE_THISCALL_WRAPPER(ostream_withassign_sb_ctor, 12)
2912 ostream* __thiscall ostream_withassign_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2914 ios *base;
2916 TRACE("(%p %p %d)\n", this, sb, virt_init);
2918 ostream_sb_ctor(this, sb, virt_init);
2919 base = ostream_get_ios(this);
2920 base->vtable = &MSVCP_ostream_withassign_vtable;
2921 return this;
2924 /* ??0ostream_withassign@@QAE@XZ */
2925 /* ??0ostream_withassign@@QEAA@XZ */
2926 DEFINE_THISCALL_WRAPPER(ostream_withassign_ctor, 8)
2927 ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init)
2929 ios *base;
2931 TRACE("(%p %d)\n", this, virt_init);
2933 ostream_ctor(this, virt_init);
2934 base = ostream_get_ios(this);
2935 base->vtable = &MSVCP_ostream_withassign_vtable;
2936 return this;
2939 static inline ios* istream_get_ios(const istream *this)
2941 return (ios*)((char*)this + this->vbtable[1]);
2944 static inline ios* istream_to_ios(const istream *this)
2946 return (ios*)((char*)this + istream_vbtable[1]);
2949 static inline istream* ios_to_istream(const ios *base)
2951 return (istream*)((char*)base - istream_vbtable[1]);
2954 /* ??0istream@@IAE@XZ */
2955 /* ??0istream@@IEAA@XZ */
2956 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
2957 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
2959 ios *base;
2961 TRACE("(%p %d)\n", this, virt_init);
2963 if (virt_init) {
2964 this->vbtable = istream_vbtable;
2965 base = istream_get_ios(this);
2966 ios_ctor(base);
2967 } else
2968 base = istream_get_ios(this);
2969 base->vtable = &MSVCP_istream_vtable;
2970 base->flags |= FLAGS_skipws;
2971 this->extract_delim = 0;
2972 this->count = 0;
2973 return this;
2976 /* ??0istream@@QAE@PAVstreambuf@@@Z */
2977 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
2978 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
2979 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
2981 TRACE("(%p %p %d)\n", this, sb, virt_init);
2982 istream_ctor(this, virt_init);
2983 ios_init(istream_get_ios(this), sb);
2984 return this;
2987 /* ??0istream@@IAE@ABV0@@Z */
2988 /* ??0istream@@IEAA@AEBV0@@Z */
2989 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
2990 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
2992 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
2995 /* ??1istream@@UAE@XZ */
2996 /* ??1istream@@UEAA@XZ */
2997 /* ??1istream_withassign@@UAE@XZ */
2998 /* ??1istream_withassign@@UEAA@XZ */
2999 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
3000 void __thiscall istream_dtor(ios *base)
3002 istream *this = ios_to_istream(base);
3004 TRACE("(%p)\n", this);
3007 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
3008 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3009 /* ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z */
3010 /* ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z */
3011 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
3012 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
3014 ios *base = istream_get_ios(this);
3016 TRACE("(%p %p)\n", this, sb);
3018 ios_init(base, sb);
3019 base->state &= IOSTATE_badbit;
3020 base->delbuf = 0;
3021 base->tie = NULL;
3022 base->flags = FLAGS_skipws;
3023 base->precision = 6;
3024 base->fill = ' ';
3025 base->width = 0;
3026 this->count = 0;
3027 return this;
3030 /* ??4istream@@IAEAAV0@ABV0@@Z */
3031 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
3032 /* ??4istream_withassign@@QAEAAV0@ABV0@@Z */
3033 /* ??4istream_withassign@@QEAAAEAV0@AEBV0@@Z */
3034 /* ??4istream_withassign@@QAEAAVistream@@ABV1@@Z */
3035 /* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */
3036 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
3037 istream* __thiscall istream_assign(istream *this, const istream *rhs)
3039 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
3042 /* ??_Distream@@QAEXXZ */
3043 /* ??_Distream@@QEAAXXZ */
3044 /* ??_Distream_withassign@@QAEXXZ */
3045 /* ??_Distream_withassign@@QEAAXXZ */
3046 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
3047 void __thiscall istream_vbase_dtor(istream *this)
3049 ios *base = istream_to_ios(this);
3051 TRACE("(%p)\n", this);
3053 istream_dtor(base);
3054 ios_dtor(base);
3057 /* ??_Eistream@@UAEPAXI@Z */
3058 /* ??_Eistream_withassign@@UAEPAXI@Z */
3059 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
3060 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
3062 istream *this = ios_to_istream(base);
3064 TRACE("(%p %x)\n", this, flags);
3066 if (flags & 2) {
3067 /* we have an array, with the number of elements stored before the first object */
3068 INT_PTR i, *ptr = (INT_PTR *)this-1;
3070 for (i = *ptr-1; i >= 0; i--)
3071 istream_vbase_dtor(this+i);
3072 MSVCRT_operator_delete(ptr);
3073 } else {
3074 istream_vbase_dtor(this);
3075 if (flags & 1)
3076 MSVCRT_operator_delete(this);
3078 return this;
3081 /* ??_Gistream@@UAEPAXI@Z */
3082 /* ??_Gistream_withassign@@UAEPAXI@Z */
3083 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
3084 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
3086 istream *this = ios_to_istream(base);
3088 TRACE("(%p %x)\n", this, flags);
3090 istream_vbase_dtor(this);
3091 if (flags & 1) MSVCRT_operator_delete(this);
3092 return this;
3095 /* ?eatwhite@istream@@QAEXXZ */
3096 /* ?eatwhite@istream@@QEAAXXZ */
3097 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3098 void __thiscall istream_eatwhite(istream *this)
3100 ios *base = istream_get_ios(this);
3101 int c;
3103 TRACE("(%p)\n", this);
3105 ios_lockbuf(base);
3106 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3107 ios_unlockbuf(base);
3108 if (c == EOF)
3109 ios_clear(base, base->state | IOSTATE_eofbit);
3112 /* ?gcount@istream@@QBEHXZ */
3113 /* ?gcount@istream@@QEBAHXZ */
3114 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3115 int __thiscall istream_gcount(const istream *this)
3117 TRACE("(%p)\n", this);
3118 return this->count;
3121 /* ?ipfx@istream@@QAEHH@Z */
3122 /* ?ipfx@istream@@QEAAHH@Z */
3123 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3124 int __thiscall istream_ipfx(istream *this, int need)
3126 ios *base = istream_get_ios(this);
3128 TRACE("(%p %d)\n", this, need);
3130 if (need)
3131 this->count = 0;
3132 if (!ios_good(base)) {
3133 ios_clear(base, base->state | IOSTATE_failbit);
3134 return 0;
3136 ios_lock(base);
3137 ios_lockbuf(base);
3138 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3139 ostream_flush(base->tie);
3140 if ((base->flags & FLAGS_skipws) && !need) {
3141 istream_eatwhite(this);
3142 if (base->state & IOSTATE_eofbit) {
3143 base->state |= IOSTATE_failbit;
3144 ios_unlockbuf(base);
3145 ios_unlock(base);
3146 return 0;
3149 return 1;
3152 /* ?isfx@istream@@QAEXXZ */
3153 /* ?isfx@istream@@QEAAXXZ */
3154 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3155 void __thiscall istream_isfx(istream *this)
3157 ios *base = istream_get_ios(this);
3159 TRACE("(%p)\n", this);
3161 ios_unlockbuf(base);
3162 ios_unlock(base);
3165 /* ?get@istream@@IAEAAV1@PADHH@Z */
3166 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3167 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3168 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3170 ios *base = istream_get_ios(this);
3171 int ch, i = 0;
3173 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3175 if (istream_ipfx(this, 1)) {
3176 while (i < count - 1) {
3177 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3178 base->state |= IOSTATE_eofbit;
3179 if (!i) /* tried to read, but not a single character was obtained */
3180 base->state |= IOSTATE_failbit;
3181 break;
3183 if (ch == delim) {
3184 if (this->extract_delim) { /* discard the delimiter */
3185 streambuf_stossc(base->sb);
3186 this->count++;
3188 break;
3190 if (str)
3191 str[i] = ch;
3192 streambuf_stossc(base->sb);
3193 i++;
3195 this->count += i;
3196 istream_isfx(this);
3198 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3199 str[i] = 0;
3200 this->extract_delim = 0;
3201 return this;
3204 /* ?get@istream@@QAEAAV1@PACHD@Z */
3205 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3206 /* ?get@istream@@QAEAAV1@PADHD@Z */
3207 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3208 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3209 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3210 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3211 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3213 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3216 static int istream_internal_get_char(istream *this, char *ch)
3218 ios *base = istream_get_ios(this);
3219 int ret = EOF;
3221 TRACE("(%p %p)\n", this, ch);
3223 if (istream_ipfx(this, 1)) {
3224 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3225 this->count = 1;
3226 } else {
3227 base->state |= IOSTATE_eofbit;
3228 if (ch)
3229 base->state |= IOSTATE_failbit;
3231 if (ch)
3232 *ch = ret;
3233 istream_isfx(this);
3235 return ret;
3238 /* ?get@istream@@QAEAAV1@AAC@Z */
3239 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3240 /* ?get@istream@@QAEAAV1@AAD@Z */
3241 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3242 /* ?get@istream@@QAEAAV1@AAE@Z */
3243 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3244 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3245 istream* __thiscall istream_get_char(istream *this, char *ch)
3247 istream_internal_get_char(this, ch);
3248 return this;
3251 /* ?get@istream@@QAEHXZ */
3252 /* ?get@istream@@QEAAHXZ */
3253 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3254 int __thiscall istream_get(istream *this)
3256 return istream_internal_get_char(this, NULL);
3259 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3260 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3261 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3262 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3264 ios *base = istream_get_ios(this);
3265 int ch;
3267 TRACE("(%p %p %c)\n", this, sb, delim);
3269 if (istream_ipfx(this, 1)) {
3270 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3271 if (ch == EOF) {
3272 base->state |= IOSTATE_eofbit;
3273 break;
3275 if (streambuf_sputc(sb, ch) == EOF)
3276 base->state |= IOSTATE_failbit;
3277 this->count++;
3279 istream_isfx(this);
3281 return this;
3284 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3285 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3286 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3287 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3288 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3289 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3290 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3291 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3293 ios *base = istream_get_ios(this);
3295 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3297 ios_lock(base);
3298 this->extract_delim++;
3299 istream_get_str_delim(this, str, count, (unsigned char) delim);
3300 ios_unlock(base);
3301 return this;
3304 /* ?ignore@istream@@QAEAAV1@HH@Z */
3305 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3306 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3307 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3309 ios *base = istream_get_ios(this);
3311 TRACE("(%p %d %d)\n", this, count, delim);
3313 ios_lock(base);
3314 this->extract_delim++;
3315 istream_get_str_delim(this, NULL, count + 1, delim);
3316 ios_unlock(base);
3317 return this;
3320 /* ?peek@istream@@QAEHXZ */
3321 /* ?peek@istream@@QEAAHXZ */
3322 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3323 int __thiscall istream_peek(istream *this)
3325 ios *base = istream_get_ios(this);
3326 int ret = EOF;
3328 TRACE("(%p)\n", this);
3330 if (istream_ipfx(this, 1)) {
3331 ret = streambuf_sgetc(base->sb);
3332 istream_isfx(this);
3334 return ret;
3337 /* ?putback@istream@@QAEAAV1@D@Z */
3338 /* ?putback@istream@@QEAAAEAV1@D@Z */
3339 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3340 istream* __thiscall istream_putback(istream *this, char ch)
3342 ios *base = istream_get_ios(this);
3344 TRACE("(%p %c)\n", this, ch);
3346 if (ios_good(base)) {
3347 ios_lockbuf(base);
3348 if (streambuf_sputbackc(base->sb, ch) == EOF)
3349 ios_clear(base, base->state | IOSTATE_failbit);
3350 ios_unlockbuf(base);
3352 return this;
3355 /* ?read@istream@@QAEAAV1@PACH@Z */
3356 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3357 /* ?read@istream@@QAEAAV1@PADH@Z */
3358 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3359 /* ?read@istream@@QAEAAV1@PAEH@Z */
3360 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3361 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3362 istream* __thiscall istream_read(istream *this, char *str, int count)
3364 ios *base = istream_get_ios(this);
3366 TRACE("(%p %p %d)\n", this, str, count);
3368 if (istream_ipfx(this, 1)) {
3369 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3370 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3371 istream_isfx(this);
3373 return this;
3376 /* ?seekg@istream@@QAEAAV1@J@Z */
3377 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3378 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3379 istream* __thiscall istream_seekg(istream *this, streampos pos)
3381 ios *base = istream_get_ios(this);
3383 TRACE("(%p %d)\n", this, pos);
3385 ios_lockbuf(base);
3386 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3387 ios_clear(base, base->state | IOSTATE_failbit);
3388 ios_unlockbuf(base);
3389 return this;
3392 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3393 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3394 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3395 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3397 ios *base = istream_get_ios(this);
3399 TRACE("(%p %d %d)\n", this, off, dir);
3401 ios_lockbuf(base);
3402 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3403 ios_clear(base, base->state | IOSTATE_failbit);
3404 ios_unlockbuf(base);
3405 return this;
3408 /* ?sync@istream@@QAEHXZ */
3409 /* ?sync@istream@@QEAAHXZ */
3410 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3411 int __thiscall istream_sync(istream *this)
3413 ios *base = istream_get_ios(this);
3414 int ret;
3416 TRACE("(%p)\n", this);
3418 ios_lockbuf(base);
3419 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3420 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3421 ios_unlockbuf(base);
3422 return ret;
3425 /* ?tellg@istream@@QAEJXZ */
3426 /* ?tellg@istream@@QEAAJXZ */
3427 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3428 streampos __thiscall istream_tellg(istream *this)
3430 ios *base = istream_get_ios(this);
3431 streampos pos;
3433 TRACE("(%p)\n", this);
3435 ios_lockbuf(base);
3436 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3437 ios_clear(base, base->state | IOSTATE_failbit);
3438 ios_unlockbuf(base);
3439 return pos;
3442 static int getint_is_valid_digit(char ch, int base)
3444 if (base == 8) return (ch >= '0' && ch <= '7');
3445 if (base == 16) return isxdigit(ch);
3446 return isdigit(ch);
3449 /* ?getint@istream@@AAEHPAD@Z */
3450 /* ?getint@istream@@AEAAHPEAD@Z */
3451 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3452 int __thiscall istream_getint(istream *this, char *str)
3454 ios *base = istream_get_ios(this);
3455 int ch, num_base = 0, i = 0;
3456 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3458 TRACE("(%p %p)\n", this, str);
3460 if (istream_ipfx(this, 0)) {
3461 num_base = (base->flags & FLAGS_dec) ? 10 :
3462 (base->flags & FLAGS_hex) ? 16 :
3463 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3464 /* scan valid characters, up to 15 (hard limit on Windows) */
3465 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3466 if ((ch == '+' || ch == '-') && scan_sign) {
3467 /* no additional sign allowed */
3468 scan_sign = FALSE;
3469 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3470 /* only hex digits can (and must) follow */
3471 scan_x = valid_integer = FALSE;
3472 num_base = 16;
3473 } else if (ch == '0' && scan_prefix) {
3474 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3475 scan_sign = scan_prefix = FALSE;
3476 scan_x = !num_base || num_base == 16;
3477 valid_integer = TRUE;
3478 if (!num_base)
3479 num_base = 8;
3480 } else if (getint_is_valid_digit(ch, num_base)) {
3481 /* only digits in the corresponding base can follow */
3482 scan_sign = scan_prefix = scan_x = FALSE;
3483 valid_integer = TRUE;
3484 } else {
3485 /* unexpected character, stop scanning */
3486 if (!valid_integer) {
3487 /* the result is not a valid integer */
3488 base->state |= IOSTATE_failbit;
3489 /* put any extracted character back into the stream */
3490 while (i > 0)
3491 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3492 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3493 } else if (ch == EOF) {
3494 base->state |= IOSTATE_eofbit;
3495 if (scan_x && !(base->flags & ios_basefield)) {
3496 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3497 num_base = 0;
3500 break;
3502 str[i++] = ch;
3504 /* append a null terminator */
3505 str[i] = 0;
3506 istream_isfx(this);
3508 return num_base;
3511 /* ?getdouble@istream@@AAEHPADH@Z */
3512 /* ?getdouble@istream@@AEAAHPEADH@Z */
3513 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3514 int __thiscall istream_getdouble(istream *this, char *str, int count)
3516 ios *base = istream_get_ios(this);
3517 int ch, i = 0;
3518 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3519 valid_mantissa = FALSE, valid_exponent = FALSE;
3521 TRACE("(%p %p %d)\n", this, str, count);
3523 if (istream_ipfx(this, 0)) {
3524 if (!count) {
3525 /* can't output anything */
3526 base->state |= IOSTATE_failbit;
3527 i = -1;
3528 } else {
3529 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3530 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3531 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3532 if ((ch == '+' || ch == '-') && scan_sign) {
3533 /* no additional sign allowed */
3534 scan_sign = FALSE;
3535 } else if (ch == '.' && scan_dot) {
3536 /* no sign or additional dot allowed */
3537 scan_sign = scan_dot = FALSE;
3538 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3539 /* sign is allowed again but not dots or exponents */
3540 scan_sign = TRUE;
3541 scan_dot = scan_exp = FALSE;
3542 } else if (isdigit(ch)) {
3543 if (scan_exp)
3544 valid_mantissa = TRUE;
3545 else
3546 valid_exponent = TRUE;
3547 /* no sign allowed after a digit */
3548 scan_sign = FALSE;
3549 } else {
3550 /* unexpected character, stop scanning */
3551 /* check whether the result is a valid double */
3552 if (!scan_exp && !valid_exponent) {
3553 /* put the last character back into the stream, usually the 'e' or 'E' */
3554 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3555 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3556 } else if (ch == EOF)
3557 base->state |= IOSTATE_eofbit;
3558 if (!valid_mantissa)
3559 base->state |= IOSTATE_failbit;
3560 break;
3562 str[i++] = ch;
3564 /* check if character limit has been reached */
3565 if (i == count) {
3566 base->state |= IOSTATE_failbit;
3567 i--;
3569 /* append a null terminator */
3570 str[i] = 0;
3572 istream_isfx(this);
3574 return i;
3577 /* ??5istream@@QAEAAV0@AAC@Z */
3578 /* ??5istream@@QEAAAEAV0@AEAC@Z */
3579 /* ??5istream@@QAEAAV0@AAD@Z */
3580 /* ??5istream@@QEAAAEAV0@AEAD@Z */
3581 /* ??5istream@@QAEAAV0@AAE@Z */
3582 /* ??5istream@@QEAAAEAV0@AEAE@Z */
3583 DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
3584 istream* __thiscall istream_read_char(istream *this, char *ch)
3586 ios *base = istream_get_ios(this);
3587 int ret;
3589 TRACE("(%p %p)\n", this, ch);
3591 if (istream_ipfx(this, 0)) {
3592 if ((ret = streambuf_sbumpc(base->sb)) == EOF)
3593 base->state |= IOSTATE_eofbit | IOSTATE_failbit;
3594 else
3595 *ch = ret;
3596 istream_isfx(this);
3598 return this;
3601 /* ??5istream@@QAEAAV0@PAC@Z */
3602 /* ??5istream@@QEAAAEAV0@PEAC@Z */
3603 /* ??5istream@@QAEAAV0@PAD@Z */
3604 /* ??5istream@@QEAAAEAV0@PEAD@Z */
3605 /* ??5istream@@QAEAAV0@PAE@Z */
3606 /* ??5istream@@QEAAAEAV0@PEAE@Z */
3607 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
3608 istream* __thiscall istream_read_str(istream *this, char *str)
3610 ios *base = istream_get_ios(this);
3611 int ch, count = 0;
3613 TRACE("(%p %p)\n", this, str);
3615 if (istream_ipfx(this, 0)) {
3616 if (str) {
3617 for (ch = streambuf_sgetc(base->sb);
3618 count < (unsigned int) base->width - 1 && !isspace(ch);
3619 ch = streambuf_snextc(base->sb)) {
3620 if (ch == EOF) {
3621 base->state |= IOSTATE_eofbit;
3622 break;
3624 str[count++] = ch;
3627 if (!count) /* nothing to output */
3628 base->state |= IOSTATE_failbit;
3629 else /* append a null terminator */
3630 str[count] = 0;
3631 base->width = 0;
3632 istream_isfx(this);
3634 return this;
3637 static LONG istream_internal_read_integer(istream *this, LONG min_value, LONG max_value, BOOL set_flag)
3639 ios *base = istream_get_ios(this);
3640 char buffer[16];
3641 int num_base;
3642 LONG ret;
3644 TRACE("(%p %d %d %d)\n", this, min_value, max_value, set_flag);
3646 num_base = istream_getint(this, buffer);
3647 errno = 0;
3648 ret = strtol(buffer, NULL, num_base);
3649 /* check for overflow and whether the value fits in the output var */
3650 if (set_flag && errno == ERANGE) {
3651 base->state |= IOSTATE_failbit;
3652 } else if (ret > max_value) {
3653 base->state |= IOSTATE_failbit;
3654 ret = max_value;
3655 } else if (ret < min_value) {
3656 base->state |= IOSTATE_failbit;
3657 ret = min_value;
3659 return ret;
3662 static ULONG istream_internal_read_unsigned_integer(istream *this, LONG min_value, ULONG max_value)
3664 ios *base = istream_get_ios(this);
3665 char buffer[16];
3666 int num_base;
3667 ULONG ret;
3669 TRACE("(%p %d %u)\n", this, min_value, max_value);
3671 num_base = istream_getint(this, buffer);
3672 errno = 0;
3673 ret = strtoul(buffer, NULL, num_base);
3674 /* check for overflow and whether the value fits in the output var */
3675 if ((ret == ULONG_MAX && errno == ERANGE) ||
3676 (ret > max_value && ret < (ULONG) min_value)) {
3677 base->state |= IOSTATE_failbit;
3678 ret = max_value;
3680 return ret;
3683 /* ??5istream@@QAEAAV0@AAF@Z */
3684 /* ??5istream@@QEAAAEAV0@AEAF@Z */
3685 DEFINE_THISCALL_WRAPPER(istream_read_short, 8)
3686 istream* __thiscall istream_read_short(istream *this, short *p)
3688 if (istream_ipfx(this, 0)) {
3689 *p = istream_internal_read_integer(this, SHRT_MIN, SHRT_MAX, FALSE);
3690 istream_isfx(this);
3692 return this;
3695 /* ??5istream@@QAEAAV0@AAG@Z */
3696 /* ??5istream@@QEAAAEAV0@AEAG@Z */
3697 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_short, 8)
3698 istream* __thiscall istream_read_unsigned_short(istream *this, unsigned short *p)
3700 if (istream_ipfx(this, 0)) {
3701 *p = istream_internal_read_unsigned_integer(this, SHRT_MIN, USHRT_MAX);
3702 istream_isfx(this);
3704 return this;
3707 /* ??5istream@@QAEAAV0@AAH@Z */
3708 /* ??5istream@@QEAAAEAV0@AEAH@Z */
3709 DEFINE_THISCALL_WRAPPER(istream_read_int, 8)
3710 istream* __thiscall istream_read_int(istream *this, int *p)
3712 if (istream_ipfx(this, 0)) {
3713 *p = istream_internal_read_integer(this, INT_MIN, INT_MAX, FALSE);
3714 istream_isfx(this);
3716 return this;
3719 /* ??5istream@@QAEAAV0@AAI@Z */
3720 /* ??5istream@@QEAAAEAV0@AEAI@Z */
3721 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_int, 8)
3722 istream* __thiscall istream_read_unsigned_int(istream *this, unsigned int *p)
3724 if (istream_ipfx(this, 0)) {
3725 *p = istream_internal_read_unsigned_integer(this, INT_MIN, UINT_MAX);
3726 istream_isfx(this);
3728 return this;
3731 /* ??5istream@@QAEAAV0@AAJ@Z */
3732 /* ??5istream@@QEAAAEAV0@AEAJ@Z */
3733 DEFINE_THISCALL_WRAPPER(istream_read_long, 8)
3734 istream* __thiscall istream_read_long(istream *this, LONG *p)
3736 if (istream_ipfx(this, 0)) {
3737 *p = istream_internal_read_integer(this, LONG_MIN, LONG_MAX, TRUE);
3738 istream_isfx(this);
3740 return this;
3743 /* ??5istream@@QAEAAV0@AAK@Z */
3744 /* ??5istream@@QEAAAEAV0@AEAK@Z */
3745 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_long, 8)
3746 istream* __thiscall istream_read_unsigned_long(istream *this, ULONG *p)
3748 if (istream_ipfx(this, 0)) {
3749 *p = istream_internal_read_unsigned_integer(this, LONG_MIN, ULONG_MAX);
3750 istream_isfx(this);
3752 return this;
3755 static BOOL istream_internal_read_float(istream *this, int max_chars, double *out)
3757 char buffer[32];
3758 BOOL read = FALSE;
3760 TRACE("(%p %d %p)\n", this, max_chars, out);
3762 if (istream_ipfx(this, 0)) {
3763 /* character count is limited on Windows */
3764 if (istream_getdouble(this, buffer, max_chars) > 0) {
3765 *out = strtod(buffer, NULL);
3766 read = TRUE;
3768 istream_isfx(this);
3770 return read;
3773 /* ??5istream@@QAEAAV0@AAM@Z */
3774 /* ??5istream@@QEAAAEAV0@AEAM@Z */
3775 DEFINE_THISCALL_WRAPPER(istream_read_float, 8)
3776 istream* __thiscall istream_read_float(istream *this, float *f)
3778 double tmp;
3779 if (istream_internal_read_float(this, 20, &tmp)) {
3780 /* check whether the value fits in the output var */
3781 if (tmp > FLT_MAX)
3782 tmp = FLT_MAX;
3783 else if (tmp < -FLT_MAX)
3784 tmp = -FLT_MAX;
3785 else if (tmp > 0 && tmp < FLT_MIN)
3786 tmp = FLT_MIN;
3787 else if (tmp < 0 && tmp > -FLT_MIN)
3788 tmp = -FLT_MIN;
3789 *f = tmp;
3791 return this;
3794 /* ??5istream@@QAEAAV0@AAN@Z */
3795 /* ??5istream@@QEAAAEAV0@AEAN@Z */
3796 DEFINE_THISCALL_WRAPPER(istream_read_double, 8)
3797 istream* __thiscall istream_read_double(istream *this, double *d)
3799 istream_internal_read_float(this, 28, d);
3800 return this;
3803 /* ??5istream@@QAEAAV0@AAO@Z */
3804 /* ??5istream@@QEAAAEAV0@AEAO@Z */
3805 DEFINE_THISCALL_WRAPPER(istream_read_long_double, 8)
3806 istream* __thiscall istream_read_long_double(istream *this, double *ld)
3808 istream_internal_read_float(this, 32, ld);
3809 return this;
3812 /* ??5istream@@QAEAAV0@PAVstreambuf@@@Z */
3813 /* ??5istream@@QEAAAEAV0@PEAVstreambuf@@@Z */
3814 DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
3815 istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
3817 ios *base = istream_get_ios(this);
3818 int ch;
3820 TRACE("(%p %p)\n", this, sb);
3822 if (istream_ipfx(this, 0)) {
3823 while ((ch = streambuf_sbumpc(base->sb)) != EOF)
3824 if (streambuf_sputc(sb, ch) == EOF)
3825 base->state |= IOSTATE_failbit;
3826 istream_isfx(this);
3828 return this;
3831 /* ??5istream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
3832 /* ??5istream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
3833 DEFINE_THISCALL_WRAPPER(istream_read_manip, 8)
3834 istream* __thiscall istream_read_manip(istream *this, istream* (__cdecl *func)(istream*))
3836 TRACE("(%p %p)\n", this, func);
3837 return func(this);
3840 /* ??5istream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
3841 /* ??5istream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
3842 DEFINE_THISCALL_WRAPPER(istream_read_ios_manip, 8)
3843 istream* __thiscall istream_read_ios_manip(istream *this, ios* (__cdecl *func)(ios*))
3845 TRACE("(%p %p)\n", this, func);
3846 func(istream_get_ios(this));
3847 return this;
3850 /* ?ws@@YAAAVistream@@AAV1@@Z */
3851 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
3852 istream* __cdecl istream_ws(istream *this)
3854 TRACE("(%p)\n", this);
3855 istream_eatwhite(this);
3856 return this;
3859 /* ??0istream_withassign@@QAE@ABV0@@Z */
3860 /* ??0istream_withassign@@QEAA@AEBV0@@Z */
3861 DEFINE_THISCALL_WRAPPER(istream_withassign_copy_ctor, 12)
3862 istream* __thiscall istream_withassign_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3864 ios *base, *base_copy;
3866 TRACE("(%p %p %d)\n", this, copy, virt_init);
3868 base_copy = istream_get_ios(copy);
3869 if (virt_init) {
3870 this->vbtable = istream_vbtable;
3871 base = istream_get_ios(this);
3872 ios_copy_ctor(base, base_copy);
3873 } else
3874 base = istream_get_ios(this);
3875 ios_init(base, base_copy->sb);
3876 base->vtable = &MSVCP_istream_withassign_vtable;
3877 base->flags |= FLAGS_skipws;
3878 this->extract_delim = 0;
3879 this->count = 0;
3880 return this;
3883 /* ??0istream_withassign@@QAE@PAVstreambuf@@@Z */
3884 /* ??0istream_withassign@@QEAA@PEAVstreambuf@@@Z */
3885 DEFINE_THISCALL_WRAPPER(istream_withassign_sb_ctor, 12)
3886 istream* __thiscall istream_withassign_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
3888 ios *base;
3890 TRACE("(%p %p %d)\n", this, sb, virt_init);
3892 istream_sb_ctor(this, sb, virt_init);
3893 base = istream_get_ios(this);
3894 base->vtable = &MSVCP_istream_withassign_vtable;
3895 return this;
3898 /* ??0istream_withassign@@QAE@XZ */
3899 /* ??0istream_withassign@@QEAA@XZ */
3900 DEFINE_THISCALL_WRAPPER(istream_withassign_ctor, 8)
3901 istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init)
3903 ios *base;
3905 TRACE("(%p %d)\n", this, virt_init);
3907 istream_ctor(this, virt_init);
3908 base = istream_get_ios(this);
3909 base->vtable = &MSVCP_istream_withassign_vtable;
3910 return this;
3913 static inline ios* iostream_to_ios(const iostream *this)
3915 return (ios*)((char*)this + iostream_vbtable_istream[1]);
3918 static inline iostream* ios_to_iostream(const ios *base)
3920 return (iostream*)((char*)base - iostream_vbtable_istream[1]);
3923 /* ??0iostream@@IAE@XZ */
3924 /* ??0iostream@@IEAA@XZ */
3925 DEFINE_THISCALL_WRAPPER(iostream_ctor, 8)
3926 iostream* __thiscall iostream_ctor(iostream *this, BOOL virt_init)
3928 ios *base;
3930 TRACE("(%p %d)\n", this, virt_init);
3932 if (virt_init) {
3933 this->base1.vbtable = iostream_vbtable_istream;
3934 this->base2.vbtable = iostream_vbtable_ostream;
3935 base = istream_get_ios(&this->base1);
3936 ios_ctor(base);
3937 } else
3938 base = istream_get_ios(&this->base1);
3939 istream_ctor(&this->base1, FALSE);
3940 ostream_ctor(&this->base2, FALSE);
3941 base->vtable = &MSVCP_iostream_vtable;
3942 return this;
3945 /* ??0iostream@@QAE@PAVstreambuf@@@Z */
3946 /* ??0iostream@@QEAA@PEAVstreambuf@@@Z */
3947 DEFINE_THISCALL_WRAPPER(iostream_sb_ctor, 12)
3948 iostream* __thiscall iostream_sb_ctor(iostream *this, streambuf *sb, BOOL virt_init)
3950 TRACE("(%p %p %d)\n", this, sb, virt_init);
3951 iostream_ctor(this, virt_init);
3952 ios_init(istream_get_ios(&this->base1), sb);
3953 return this;
3956 /* ??0iostream@@IAE@ABV0@@Z */
3957 /* ??0iostream@@IEAA@AEBV0@@Z */
3958 DEFINE_THISCALL_WRAPPER(iostream_copy_ctor, 12)
3959 iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
3961 return iostream_sb_ctor(this, istream_get_ios(&copy->base1)->sb, virt_init);
3964 /* ??1iostream@@UAE@XZ */
3965 /* ??1iostream@@UEAA@XZ */
3966 DEFINE_THISCALL_WRAPPER(iostream_dtor, 4)
3967 void __thiscall iostream_dtor(ios *base)
3969 iostream *this = ios_to_iostream(base);
3971 TRACE("(%p)\n", this);
3973 ostream_dtor(ostream_to_ios(&this->base2));
3974 istream_dtor(istream_to_ios(&this->base1));
3977 /* ??4iostream@@IAEAAV0@PAVstreambuf@@@Z */
3978 /* ??4iostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3979 DEFINE_THISCALL_WRAPPER(iostream_assign_sb, 8)
3980 iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb)
3982 TRACE("(%p %p)\n", this, sb);
3983 this->base1.count = 0;
3984 ostream_assign_sb(&this->base2, sb);
3985 return this;
3988 /* ??4iostream@@IAEAAV0@AAV0@@Z */
3989 /* ??4iostream@@IEAAAEAV0@AEAV0@@Z */
3990 DEFINE_THISCALL_WRAPPER(iostream_assign, 8)
3991 iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs)
3993 return iostream_assign_sb(this, istream_get_ios(&rhs->base1)->sb);
3996 /* ??_Diostream@@QAEXXZ */
3997 /* ??_Diostream@@QEAAXXZ */
3998 DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4)
3999 void __thiscall iostream_vbase_dtor(iostream *this)
4001 ios *base = iostream_to_ios(this);
4003 TRACE("(%p)\n", this);
4005 iostream_dtor(base);
4006 ios_dtor(base);
4009 /* ??_Eiostream@@UAEPAXI@Z */
4010 DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8)
4011 iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags)
4013 iostream *this = ios_to_iostream(base);
4015 TRACE("(%p %x)\n", this, flags);
4017 if (flags & 2) {
4018 /* we have an array, with the number of elements stored before the first object */
4019 INT_PTR i, *ptr = (INT_PTR *)this-1;
4021 for (i = *ptr-1; i >= 0; i--)
4022 iostream_vbase_dtor(this+i);
4023 MSVCRT_operator_delete(ptr);
4024 } else {
4025 iostream_vbase_dtor(this);
4026 if (flags & 1)
4027 MSVCRT_operator_delete(this);
4029 return this;
4032 /* ??_Giostream@@UAEPAXI@Z */
4033 DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8)
4034 iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags)
4036 iostream *this = ios_to_iostream(base);
4038 TRACE("(%p %x)\n", this, flags);
4040 iostream_vbase_dtor(this);
4041 if (flags & 1) MSVCRT_operator_delete(this);
4042 return this;
4045 /* ??0Iostream_init@@QAE@AAVios@@H@Z */
4046 /* ??0Iostream_init@@QEAA@AEAVios@@H@Z */
4047 DEFINE_THISCALL_WRAPPER(Iostream_init_ios_ctor, 12)
4048 void* __thiscall Iostream_init_ios_ctor(void *this, ios *obj, int n)
4050 TRACE("(%p %p %d)\n", this, obj, n);
4051 obj->delbuf = 1;
4052 if (n >= 0) {
4053 obj->tie = &cout.os;
4054 if (n > 0)
4055 ios_setf(obj, FLAGS_unitbuf);
4057 return this;
4060 /* ??0Iostream_init@@QAE@XZ */
4061 /* ??0Iostream_init@@QEAA@XZ */
4062 DEFINE_THISCALL_WRAPPER(Iostream_init_ctor, 4)
4063 void* __thiscall Iostream_init_ctor(void *this)
4065 TRACE("(%p)\n", this);
4066 return this;
4069 /* ??1Iostream_init@@QAE@XZ */
4070 /* ??1Iostream_init@@QEAA@XZ */
4071 DEFINE_THISCALL_WRAPPER(Iostream_init_dtor, 4)
4072 void __thiscall Iostream_init_dtor(void *this)
4074 TRACE("(%p)\n", this);
4077 /* ??4Iostream_init@@QAEAAV0@ABV0@@Z */
4078 /* ??4Iostream_init@@QEAAAEAV0@AEBV0@@Z */
4079 DEFINE_THISCALL_WRAPPER(Iostream_init_assign, 8)
4080 void* __thiscall Iostream_init_assign(void *this, const void *rhs)
4082 TRACE("(%p %p)\n", this, rhs);
4083 return this;
4086 /* ?sync_with_stdio@ios@@SAXXZ */
4087 void __cdecl ios_sync_with_stdio(void)
4089 if (!ios_sunk_with_stdio) {
4090 stdiobuf *new_buf;
4092 TRACE("()\n");
4094 /* run at most once */
4095 ios_sunk_with_stdio++;
4097 /* calls to [io]stream_assign_sb automatically destroy the old buffers */
4098 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4099 stdiobuf_file_ctor(new_buf, stdin);
4100 istream_assign_sb(&cin.is, &new_buf->base);
4101 } else
4102 istream_assign_sb(&cin.is, NULL);
4103 cin.vbase.delbuf = 1;
4104 ios_setf(&cin.vbase, FLAGS_stdio);
4106 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4107 stdiobuf_file_ctor(new_buf, stdout);
4108 stdiobuf_setrwbuf(new_buf, 0, 80);
4109 ostream_assign_sb(&cout.os, &new_buf->base);
4110 } else
4111 ostream_assign_sb(&cout.os, NULL);
4112 cout.vbase.delbuf = 1;
4113 ios_setf(&cout.vbase, FLAGS_unitbuf | FLAGS_stdio);
4115 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4116 stdiobuf_file_ctor(new_buf, stderr);
4117 stdiobuf_setrwbuf(new_buf, 0, 80);
4118 ostream_assign_sb(&cerr.os, &new_buf->base);
4119 } else
4120 ostream_assign_sb(&cerr.os, NULL);
4121 cerr.vbase.delbuf = 1;
4122 ios_setf(&cerr.vbase, FLAGS_unitbuf | FLAGS_stdio);
4124 if ((new_buf = MSVCRT_operator_new(sizeof(stdiobuf)))) {
4125 stdiobuf_file_ctor(new_buf, stderr);
4126 stdiobuf_setrwbuf(new_buf, 0, 512);
4127 ostream_assign_sb(&clog.os, &new_buf->base);
4128 } else
4129 ostream_assign_sb(&clog.os, NULL);
4130 clog.vbase.delbuf = 1;
4131 ios_setf(&clog.vbase, FLAGS_stdio);
4135 /******************************************************************
4136 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
4138 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
4139 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
4141 FIXME("(%p %x) stub\n", this, virt_init);
4142 return this;
4145 /******************************************************************
4146 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
4148 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
4149 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
4151 FIXME("(%p) stub\n", base);
4154 #ifdef __i386__
4156 #define DEFINE_VTBL_WRAPPER(off) \
4157 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
4158 "popl %eax\n\t" \
4159 "popl %ecx\n\t" \
4160 "pushl %eax\n\t" \
4161 "movl 0(%ecx), %eax\n\t" \
4162 "jmp *" #off "(%eax)\n\t")
4164 DEFINE_VTBL_WRAPPER(0);
4165 DEFINE_VTBL_WRAPPER(4);
4166 DEFINE_VTBL_WRAPPER(8);
4167 DEFINE_VTBL_WRAPPER(12);
4168 DEFINE_VTBL_WRAPPER(16);
4169 DEFINE_VTBL_WRAPPER(20);
4170 DEFINE_VTBL_WRAPPER(24);
4171 DEFINE_VTBL_WRAPPER(28);
4172 DEFINE_VTBL_WRAPPER(32);
4173 DEFINE_VTBL_WRAPPER(36);
4174 DEFINE_VTBL_WRAPPER(40);
4175 DEFINE_VTBL_WRAPPER(44);
4176 DEFINE_VTBL_WRAPPER(48);
4177 DEFINE_VTBL_WRAPPER(52);
4178 DEFINE_VTBL_WRAPPER(56);
4180 #endif
4182 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
4183 void (__cdecl *MSVCRT_operator_delete)(void*);
4185 static void init_cxx_funcs(void)
4187 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
4189 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
4191 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
4192 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
4194 else
4196 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
4197 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
4201 static void init_io(void *base)
4203 filebuf *fb;
4205 #ifdef __x86_64__
4206 init_streambuf_rtti(base);
4207 init_filebuf_rtti(base);
4208 init_strstreambuf_rtti(base);
4209 init_stdiobuf_rtti(base);
4210 init_ios_rtti(base);
4211 init_ostream_rtti(base);
4212 init_ostream_withassign_rtti(base);
4213 init_istream_rtti(base);
4214 init_istream_withassign_rtti(base);
4215 init_iostream_rtti(base);
4216 #endif
4218 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4219 filebuf_fd_ctor(fb, 0);
4220 istream_withassign_sb_ctor(&cin.is, &fb->base, TRUE);
4221 } else
4222 istream_withassign_sb_ctor(&cin.is, NULL, TRUE);
4223 Iostream_init_ios_ctor(NULL, &cin.vbase, 0);
4225 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4226 filebuf_fd_ctor(fb, 1);
4227 ostream_withassign_sb_ctor(&cout.os, &fb->base, TRUE);
4228 } else
4229 ostream_withassign_sb_ctor(&cout.os, NULL, TRUE);
4230 Iostream_init_ios_ctor(NULL, &cout.vbase, -1);
4232 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4233 filebuf_fd_ctor(fb, 2);
4234 ostream_withassign_sb_ctor(&cerr.os, &fb->base, TRUE);
4235 } else
4236 ostream_withassign_sb_ctor(&cerr.os, NULL, TRUE);
4237 Iostream_init_ios_ctor(NULL, &cerr.vbase, 1);
4239 if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
4240 filebuf_fd_ctor(fb, 2);
4241 ostream_withassign_sb_ctor(&clog.os, &fb->base, TRUE);
4242 } else
4243 ostream_withassign_sb_ctor(&clog.os, NULL, TRUE);
4244 Iostream_init_ios_ctor(NULL, &clog.vbase, 0);
4247 static void free_io(void)
4249 /* destructors take care of deleting the buffers */
4250 istream_vbase_dtor(&cin.is);
4251 ostream_vbase_dtor(&cout.os);
4252 ostream_vbase_dtor(&cerr.os);
4253 ostream_vbase_dtor(&clog.os);
4256 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
4258 switch (reason)
4260 case DLL_WINE_PREATTACH:
4261 return FALSE; /* prefer native version */
4262 case DLL_PROCESS_ATTACH:
4263 init_cxx_funcs();
4264 init_exception(inst);
4265 init_io(inst);
4266 DisableThreadLibraryCalls( inst );
4267 break;
4268 case DLL_PROCESS_DETACH:
4269 if (reserved) break;
4270 free_io();
4271 break;
4273 return TRUE;