msvcirt: Fix ostream_print_char on 0 character.
[wine.git] / dlls / msvcirt / msvcirt.c
blob8d83fca7c94e66bc14310d468a2bef45831793e2
1 /*
2 * Copyright (C) 2007 Alexandre Julliard
3 * Copyright (C) 2015-2016 Iván Matellanes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <float.h>
24 #include <io.h>
25 #include <limits.h>
26 #include <share.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <sys/stat.h>
31 #include "msvcirt.h"
32 #include "windef.h"
33 #include "winbase.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
38 #define RESERVE_SIZE 512
39 #define STATEBUF_SIZE 8
41 void* (__cdecl *operator_new)(SIZE_T);
42 void (__cdecl *operator_delete)(void*);
44 /* ?sh_none@filebuf@@2HB */
45 const int filebuf_sh_none = 0x800;
46 /* ?sh_read@filebuf@@2HB */
47 const int filebuf_sh_read = 0xa00;
48 /* ?sh_write@filebuf@@2HB */
49 const int filebuf_sh_write = 0xc00;
50 /* ?openprot@filebuf@@2HB */
51 const int filebuf_openprot = 420;
52 /* ?binary@filebuf@@2HB */
53 const int filebuf_binary = _O_BINARY;
54 /* ?text@filebuf@@2HB */
55 const int filebuf_text = _O_TEXT;
57 /* ?adjustfield@ios@@2JB */
58 const LONG ios_adjustfield = FLAGS_left | FLAGS_right | FLAGS_internal;
59 /* ?basefield@ios@@2JB */
60 const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
61 /* ?floatfield@ios@@2JB */
62 const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
63 /* ?fLockcInit@ios@@0HA */
64 int ios_fLockcInit = 0;
65 /* ?sunk_with_stdio@ios@@0HA */
66 int ios_sunk_with_stdio = 0;
67 /* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
68 extern CRITICAL_SECTION ios_static_lock;
69 CRITICAL_SECTION_DEBUG ios_static_lock_debug =
71 0, 0, &ios_static_lock,
72 { &ios_static_lock_debug.ProcessLocksList, &ios_static_lock_debug.ProcessLocksList },
73 0, 0, { (DWORD_PTR)(__FILE__ ": ios_static_lock") }
75 CRITICAL_SECTION ios_static_lock = { &ios_static_lock_debug, -1, 0, 0, 0, 0 };
76 /* ?x_maxbit@ios@@0JA */
77 LONG ios_maxbit = 0x8000;
78 /* ?x_curindex@ios@@0HA */
79 int ios_curindex = -1;
80 /* ?x_statebuf@ios@@0PAJA */
81 LONG ios_statebuf[STATEBUF_SIZE] = {0};
83 /* class streambuf */
84 typedef struct {
85 const vtable_ptr *vtable;
86 int allocated;
87 int unbuffered;
88 int stored_char;
89 char *base;
90 char *ebuf;
91 char *pbase;
92 char *pptr;
93 char *epptr;
94 char *eback;
95 char *gptr;
96 char *egptr;
97 int do_lock;
98 CRITICAL_SECTION lock;
99 } streambuf;
101 void __thiscall streambuf_setb(streambuf*, char*, char*, int);
102 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
103 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
104 void __thiscall streambuf_setp(streambuf*, char*, char*);
106 /* class filebuf */
107 typedef struct {
108 streambuf base;
109 filedesc fd;
110 int close;
111 } filebuf;
113 filebuf* __thiscall filebuf_close(filebuf*);
115 /* class strstreambuf */
116 typedef struct {
117 streambuf base;
118 int dynamic;
119 int increase;
120 int unknown;
121 int constant;
122 allocFunction f_alloc;
123 freeFunction f_free;
124 } strstreambuf;
126 /* class stdiobuf */
127 typedef struct {
128 streambuf base;
129 FILE *file;
130 } stdiobuf;
132 /* class ios */
133 struct _ostream;
134 typedef struct {
135 const vtable_ptr *vtable;
136 streambuf *sb;
137 ios_io_state state;
138 int special[4];
139 int delbuf;
140 struct _ostream *tie;
141 ios_flags flags;
142 int precision;
143 char fill;
144 int width;
145 int do_lock;
146 CRITICAL_SECTION lock;
147 } ios;
149 ios* __thiscall ios_assign(ios*, const ios*);
150 int __thiscall ios_fail(const ios*);
151 void __cdecl ios_lock(ios*);
152 void __cdecl ios_lockc(void);
153 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
154 void __cdecl ios_unlock(ios*);
155 void __cdecl ios_unlockc(void);
157 /* class ostream */
158 typedef struct _ostream {
159 const int *vbtable;
160 int unknown;
161 } ostream;
163 /* class istream */
164 typedef struct {
165 const int *vbtable;
166 int extract_delim;
167 int count;
168 } istream;
170 /* class iostream */
171 typedef struct {
172 istream base1;
173 ostream base2;
174 } iostream;
176 /* ??_7streambuf@@6B@ */
177 extern const vtable_ptr streambuf_vtable;
178 /* ??_7filebuf@@6B@ */
179 extern const vtable_ptr filebuf_vtable;
180 /* ??_7strstreambuf@@6B@ */
181 extern const vtable_ptr strstreambuf_vtable;
182 /* ??_7stdiobuf@@6B@ */
183 extern const vtable_ptr stdiobuf_vtable;
184 /* ??_7ios@@6B@ */
185 extern const vtable_ptr ios_vtable;
186 /* ??_7ostream@@6B@ */
187 extern const vtable_ptr ostream_vtable;
188 /* ??_7ostream_withassign@@6B@ */
189 extern const vtable_ptr ostream_withassign_vtable;
190 /* ??_7ostrstream@@6B@ */
191 extern const vtable_ptr ostrstream_vtable;
192 /* ??_7ofstream@@6B@ */
193 extern const vtable_ptr ofstream_vtable;
194 /* ??_7istream@@6B@ */
195 extern const vtable_ptr istream_vtable;
196 /* ??_7istream_withassign@@6B@ */
197 extern const vtable_ptr istream_withassign_vtable;
198 /* ??_7istrstream@@6B@ */
199 extern const vtable_ptr istrstream_vtable;
200 /* ??_7ifstream@@6B@ */
201 extern const vtable_ptr ifstream_vtable;
202 /* ??_7iostream@@6B@ */
203 extern const vtable_ptr iostream_vtable;
204 /* ??_7strstream@@6B@ */
205 extern const vtable_ptr strstream_vtable;
206 /* ??_7stdiostream@@6B@ */
207 extern const vtable_ptr stdiostream_vtable;
208 /* ??_7fstream@@6B@ */
209 extern const vtable_ptr fstream_vtable;
211 __ASM_BLOCK_BEGIN(vtables)
212 __ASM_VTABLE(streambuf,
213 VTABLE_ADD_FUNC(streambuf_vector_dtor)
214 VTABLE_ADD_FUNC(streambuf_sync)
215 VTABLE_ADD_FUNC(streambuf_setbuf)
216 VTABLE_ADD_FUNC(streambuf_seekoff)
217 VTABLE_ADD_FUNC(streambuf_seekpos)
218 VTABLE_ADD_FUNC(streambuf_xsputn)
219 VTABLE_ADD_FUNC(streambuf_xsgetn)
220 VTABLE_ADD_FUNC(streambuf_overflow)
221 VTABLE_ADD_FUNC(streambuf_underflow)
222 VTABLE_ADD_FUNC(streambuf_pbackfail)
223 VTABLE_ADD_FUNC(streambuf_doallocate));
224 __ASM_VTABLE(filebuf,
225 VTABLE_ADD_FUNC(filebuf_vector_dtor)
226 VTABLE_ADD_FUNC(filebuf_sync)
227 VTABLE_ADD_FUNC(filebuf_setbuf)
228 VTABLE_ADD_FUNC(filebuf_seekoff)
229 VTABLE_ADD_FUNC(streambuf_seekpos)
230 VTABLE_ADD_FUNC(streambuf_xsputn)
231 VTABLE_ADD_FUNC(streambuf_xsgetn)
232 VTABLE_ADD_FUNC(filebuf_overflow)
233 VTABLE_ADD_FUNC(filebuf_underflow)
234 VTABLE_ADD_FUNC(streambuf_pbackfail)
235 VTABLE_ADD_FUNC(streambuf_doallocate));
236 __ASM_VTABLE(strstreambuf,
237 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
238 VTABLE_ADD_FUNC(strstreambuf_sync)
239 VTABLE_ADD_FUNC(strstreambuf_setbuf)
240 VTABLE_ADD_FUNC(strstreambuf_seekoff)
241 VTABLE_ADD_FUNC(streambuf_seekpos)
242 VTABLE_ADD_FUNC(streambuf_xsputn)
243 VTABLE_ADD_FUNC(streambuf_xsgetn)
244 VTABLE_ADD_FUNC(strstreambuf_overflow)
245 VTABLE_ADD_FUNC(strstreambuf_underflow)
246 VTABLE_ADD_FUNC(streambuf_pbackfail)
247 VTABLE_ADD_FUNC(strstreambuf_doallocate));
248 __ASM_VTABLE(stdiobuf,
249 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
250 VTABLE_ADD_FUNC(stdiobuf_sync)
251 VTABLE_ADD_FUNC(streambuf_setbuf)
252 VTABLE_ADD_FUNC(stdiobuf_seekoff)
253 VTABLE_ADD_FUNC(streambuf_seekpos)
254 VTABLE_ADD_FUNC(streambuf_xsputn)
255 VTABLE_ADD_FUNC(streambuf_xsgetn)
256 VTABLE_ADD_FUNC(stdiobuf_overflow)
257 VTABLE_ADD_FUNC(stdiobuf_underflow)
258 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
259 VTABLE_ADD_FUNC(streambuf_doallocate));
260 __ASM_VTABLE(ios,
261 VTABLE_ADD_FUNC(ios_vector_dtor));
262 __ASM_VTABLE(ostream,
263 VTABLE_ADD_FUNC(ostream_vector_dtor));
264 __ASM_VTABLE(ostream_withassign,
265 VTABLE_ADD_FUNC(ostream_vector_dtor));
266 __ASM_VTABLE(ostrstream,
267 VTABLE_ADD_FUNC(ostream_vector_dtor));
268 __ASM_VTABLE(ofstream,
269 VTABLE_ADD_FUNC(ostream_vector_dtor));
270 __ASM_VTABLE(istream,
271 VTABLE_ADD_FUNC(istream_vector_dtor));
272 __ASM_VTABLE(istream_withassign,
273 VTABLE_ADD_FUNC(istream_vector_dtor));
274 __ASM_VTABLE(istrstream,
275 VTABLE_ADD_FUNC(istream_vector_dtor));
276 __ASM_VTABLE(ifstream,
277 VTABLE_ADD_FUNC(istream_vector_dtor));
278 __ASM_VTABLE(iostream,
279 VTABLE_ADD_FUNC(iostream_vector_dtor));
280 __ASM_VTABLE(strstream,
281 VTABLE_ADD_FUNC(iostream_vector_dtor));
282 __ASM_VTABLE(stdiostream,
283 VTABLE_ADD_FUNC(iostream_vector_dtor));
284 __ASM_VTABLE(fstream,
285 VTABLE_ADD_FUNC(iostream_vector_dtor));
286 __ASM_BLOCK_END
288 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
289 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
291 /* ??_8ostream@@7B@ */
292 /* ??_8ostream_withassign@@7B@ */
293 /* ??_8ostrstream@@7B@ */
294 /* ??_8ofstream@@7B@ */
295 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
296 /* ??_8istream@@7B@ */
297 /* ??_8istream_withassign@@7B@ */
298 /* ??_8istrstream@@7B@ */
299 /* ??_8ifstream@@7B@ */
300 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
301 /* ??_8iostream@@7Bistream@@@ */
302 /* ??_8stdiostream@@7Bistream@@@ */
303 /* ??_8strstream@@7Bistream@@@ */
304 const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)};
305 /* ??_8iostream@@7Bostream@@@ */
306 /* ??_8stdiostream@@7Bostream@@@ */
307 /* ??_8strstream@@7Bostream@@@ */
308 const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)};
310 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
311 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
312 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
313 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
314 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
315 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
316 DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream),
317 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@")
318 DEFINE_RTTI_DATA2(ostrstream, sizeof(ostream),
319 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostrstream@@")
320 DEFINE_RTTI_DATA2(ofstream, sizeof(ostream),
321 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVofstream@@")
322 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
323 DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
324 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
325 DEFINE_RTTI_DATA2(istrstream, sizeof(istream),
326 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistrstream@@")
327 DEFINE_RTTI_DATA2(ifstream, sizeof(istream),
328 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVifstream@@")
329 DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
330 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
331 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
332 DEFINE_RTTI_DATA5(strstream, sizeof(iostream), &iostream_rtti_base_descriptor,
333 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
334 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstrstream@@")
335 DEFINE_RTTI_DATA5(stdiostream, sizeof(iostream), &iostream_rtti_base_descriptor,
336 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
337 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVstdiostream@@")
338 DEFINE_RTTI_DATA5(fstream, sizeof(iostream), &iostream_rtti_base_descriptor,
339 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
340 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVfstream@@")
342 /* ?cin@@3Vistream_withassign@@A */
343 struct {
344 istream is;
345 ios vbase;
346 } cin = { { 0 } };
348 /* ?cout@@3Vostream_withassign@@A */
349 /* ?cerr@@3Vostream_withassign@@A */
350 /* ?clog@@3Vostream_withassign@@A */
351 struct {
352 ostream os;
353 ios vbase;
354 } cout = { { 0 } }, cerr = { { 0 } }, MSVCP_clog = { { 0 } };
357 /* ??0streambuf@@IAE@PADH@Z */
358 /* ??0streambuf@@IEAA@PEADH@Z */
359 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
360 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
362 TRACE("(%p %p %d)\n", this, buffer, length);
363 this->vtable = &streambuf_vtable;
364 this->allocated = 0;
365 this->stored_char = EOF;
366 this->do_lock = -1;
367 this->base = NULL;
368 streambuf_setbuf(this, buffer, length);
369 streambuf_setg(this, NULL, NULL, NULL);
370 streambuf_setp(this, NULL, NULL);
371 InitializeCriticalSection(&this->lock);
372 return this;
375 /* ??0streambuf@@IAE@XZ */
376 /* ??0streambuf@@IEAA@XZ */
377 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
378 streambuf* __thiscall streambuf_ctor(streambuf *this)
380 streambuf_reserve_ctor(this, NULL, 0);
381 this->unbuffered = 0;
382 return this;
385 /* ??0streambuf@@QAE@ABV0@@Z */
386 /* ??0streambuf@@QEAA@AEBV0@@Z */
387 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
388 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
390 TRACE("(%p %p)\n", this, copy);
391 *this = *copy;
392 this->vtable = &streambuf_vtable;
393 return this;
396 /* ??1streambuf@@UAE@XZ */
397 /* ??1streambuf@@UEAA@XZ */
398 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
399 void __thiscall streambuf_dtor(streambuf *this)
401 TRACE("(%p)\n", this);
402 if (this->allocated)
403 operator_delete(this->base);
404 DeleteCriticalSection(&this->lock);
407 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
408 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
409 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
410 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
412 streambuf_dtor(this);
413 return streambuf_copy_ctor(this, rhs);
416 /* ??_Estreambuf@@UAEPAXI@Z */
417 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
418 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
419 streambuf*, (streambuf*, unsigned int), (this, flags))
420 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
422 TRACE("(%p %x)\n", this, flags);
423 if (flags & 2) {
424 /* we have an array, with the number of elements stored before the first object */
425 INT_PTR i, *ptr = (INT_PTR *)this-1;
427 for (i = *ptr-1; i >= 0; i--)
428 streambuf_dtor(this+i);
429 operator_delete(ptr);
430 } else {
431 streambuf_dtor(this);
432 if (flags & 1)
433 operator_delete(this);
435 return this;
438 /* ??_Gstreambuf@@UAEPAXI@Z */
439 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
440 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
442 TRACE("(%p %x)\n", this, flags);
443 streambuf_dtor(this);
444 if (flags & 1) operator_delete(this);
445 return this;
448 /* ?doallocate@streambuf@@MAEHXZ */
449 /* ?doallocate@streambuf@@MEAAHXZ */
450 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
451 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
452 int __thiscall streambuf_doallocate(streambuf *this)
454 char *reserve;
456 TRACE("(%p)\n", this);
457 reserve = operator_new(RESERVE_SIZE);
458 if (!reserve)
459 return EOF;
461 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
462 return 1;
465 /* ?allocate@streambuf@@IAEHXZ */
466 /* ?allocate@streambuf@@IEAAHXZ */
467 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
468 int __thiscall streambuf_allocate(streambuf *this)
470 TRACE("(%p)\n", this);
471 if (this->base != NULL || this->unbuffered)
472 return 0;
473 return call_streambuf_doallocate(this);
476 /* ?base@streambuf@@IBEPADXZ */
477 /* ?base@streambuf@@IEBAPEADXZ */
478 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
479 char* __thiscall streambuf_base(const streambuf *this)
481 TRACE("(%p)\n", this);
482 return this->base;
485 /* ?blen@streambuf@@IBEHXZ */
486 /* ?blen@streambuf@@IEBAHXZ */
487 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
488 int __thiscall streambuf_blen(const streambuf *this)
490 TRACE("(%p)\n", this);
491 return this->ebuf - this->base;
494 /* ?eback@streambuf@@IBEPADXZ */
495 /* ?eback@streambuf@@IEBAPEADXZ */
496 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
497 char* __thiscall streambuf_eback(const streambuf *this)
499 TRACE("(%p)\n", this);
500 return this->eback;
503 /* ?ebuf@streambuf@@IBEPADXZ */
504 /* ?ebuf@streambuf@@IEBAPEADXZ */
505 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
506 char* __thiscall streambuf_ebuf(const streambuf *this)
508 TRACE("(%p)\n", this);
509 return this->ebuf;
512 /* ?egptr@streambuf@@IBEPADXZ */
513 /* ?egptr@streambuf@@IEBAPEADXZ */
514 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
515 char* __thiscall streambuf_egptr(const streambuf *this)
517 TRACE("(%p)\n", this);
518 return this->egptr;
521 /* ?epptr@streambuf@@IBEPADXZ */
522 /* ?epptr@streambuf@@IEBAPEADXZ */
523 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
524 char* __thiscall streambuf_epptr(const streambuf *this)
526 TRACE("(%p)\n", this);
527 return this->epptr;
530 /* ?gptr@streambuf@@IBEPADXZ */
531 /* ?gptr@streambuf@@IEBAPEADXZ */
532 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
533 char* __thiscall streambuf_gptr(const streambuf *this)
535 TRACE("(%p)\n", this);
536 return this->gptr;
539 /* ?pbase@streambuf@@IBEPADXZ */
540 /* ?pbase@streambuf@@IEBAPEADXZ */
541 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
542 char* __thiscall streambuf_pbase(const streambuf *this)
544 TRACE("(%p)\n", this);
545 return this->pbase;
548 /* ?pptr@streambuf@@IBEPADXZ */
549 /* ?pptr@streambuf@@IEBAPEADXZ */
550 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
551 char* __thiscall streambuf_pptr(const streambuf *this)
553 TRACE("(%p)\n", this);
554 return this->pptr;
557 /* ?clrlock@streambuf@@QAEXXZ */
558 /* ?clrlock@streambuf@@QEAAXXZ */
559 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
560 void __thiscall streambuf_clrlock(streambuf *this)
562 TRACE("(%p)\n", this);
563 if (this->do_lock <= 0)
564 this->do_lock++;
567 /* ?lock@streambuf@@QAEXXZ */
568 /* ?lock@streambuf@@QEAAXXZ */
569 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
570 void __thiscall streambuf_lock(streambuf *this)
572 TRACE("(%p)\n", this);
573 if (this->do_lock < 0)
574 EnterCriticalSection(&this->lock);
577 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
578 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
579 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
580 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
582 TRACE("(%p)\n", this);
583 return &this->lock;
586 /* ?gbump@streambuf@@IAEXH@Z */
587 /* ?gbump@streambuf@@IEAAXH@Z */
588 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
589 void __thiscall streambuf_gbump(streambuf *this, int count)
591 TRACE("(%p %d)\n", this, count);
592 this->gptr += count;
595 /* ?pbump@streambuf@@IAEXH@Z */
596 /* ?pbump@streambuf@@IEAAXH@Z */
597 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
598 void __thiscall streambuf_pbump(streambuf *this, int count)
600 TRACE("(%p %d)\n", this, count);
601 this->pptr += count;
604 /* ?in_avail@streambuf@@QBEHXZ */
605 /* ?in_avail@streambuf@@QEBAHXZ */
606 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
607 int __thiscall streambuf_in_avail(const streambuf *this)
609 TRACE("(%p)\n", this);
610 return (this->egptr - this->gptr > 0) ? this->egptr - this->gptr : 0;
613 /* ?out_waiting@streambuf@@QBEHXZ */
614 /* ?out_waiting@streambuf@@QEBAHXZ */
615 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
616 int __thiscall streambuf_out_waiting(const streambuf *this)
618 TRACE("(%p)\n", this);
619 return (this->pptr - this->pbase > 0) ? this->pptr - this->pbase : 0;
622 /* Unexported */
623 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
624 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
625 int __thiscall streambuf_overflow(streambuf *this, int c)
627 ERR("overflow is not implemented in streambuf\n");
628 return EOF;
631 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
632 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
633 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
634 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
635 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
637 TRACE("(%p %ld %d %d)\n", this, offset, dir, mode);
638 return EOF;
641 /* ?seekpos@streambuf@@UAEJJH@Z */
642 /* ?seekpos@streambuf@@UEAAJJH@Z */
643 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
644 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
646 TRACE("(%p %ld %d)\n", this, pos, mode);
647 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
650 /* ?pbackfail@streambuf@@UAEHH@Z */
651 /* ?pbackfail@streambuf@@UEAAHH@Z */
652 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
653 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
654 int __thiscall streambuf_pbackfail(streambuf *this, int c)
656 TRACE("(%p %d)\n", this, c);
657 if (this->gptr > this->eback)
658 return *--this->gptr = c;
659 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
660 return EOF;
661 if (!this->unbuffered && this->egptr) {
662 /* 'c' should be the next character read */
663 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
664 *this->gptr = c;
666 return c;
669 /* ?setb@streambuf@@IAEXPAD0H@Z */
670 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
671 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
672 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
674 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
675 if (this->allocated)
676 operator_delete(this->base);
677 this->allocated = delete;
678 this->base = ba;
679 this->ebuf = eb;
682 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
683 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
684 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
685 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
687 TRACE("(%p %p %d)\n", this, buffer, length);
688 if (this->base != NULL)
689 return NULL;
691 if (buffer == NULL || !length) {
692 this->unbuffered = 1;
693 this->base = this->ebuf = NULL;
694 } else {
695 this->unbuffered = 0;
696 this->base = buffer;
697 this->ebuf = buffer + length;
699 return this;
702 /* ?setg@streambuf@@IAEXPAD00@Z */
703 /* ?setg@streambuf@@IEAAXPEAD00@Z */
704 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
705 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
707 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
708 this->eback = ek;
709 this->gptr = gp;
710 this->egptr = eg;
713 /* ?setlock@streambuf@@QAEXXZ */
714 /* ?setlock@streambuf@@QEAAXXZ */
715 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
716 void __thiscall streambuf_setlock(streambuf *this)
718 TRACE("(%p)\n", this);
719 this->do_lock--;
722 /* ?setp@streambuf@@IAEXPAD0@Z */
723 /* ?setp@streambuf@@IEAAXPEAD0@Z */
724 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
725 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
727 TRACE("(%p %p %p)\n", this, pb, ep);
728 this->pbase = this->pptr = pb;
729 this->epptr = ep;
732 /* ?sync@streambuf@@UAEHXZ */
733 /* ?sync@streambuf@@UEAAHXZ */
734 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
735 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
736 int __thiscall streambuf_sync(streambuf *this)
738 TRACE("(%p)\n", this);
739 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
742 /* ?unbuffered@streambuf@@IAEXH@Z */
743 /* ?unbuffered@streambuf@@IEAAXH@Z */
744 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
745 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
747 TRACE("(%p %d)\n", this, buf);
748 this->unbuffered = buf;
751 /* ?unbuffered@streambuf@@IBEHXZ */
752 /* ?unbuffered@streambuf@@IEBAHXZ */
753 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
754 int __thiscall streambuf_unbuffered_get(const streambuf *this)
756 TRACE("(%p)\n", this);
757 return this->unbuffered;
760 /* Unexported */
761 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
762 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
763 int __thiscall streambuf_underflow(streambuf *this)
765 ERR("underflow is not implemented in streambuf\n");
766 return EOF;
769 /* ?unlock@streambuf@@QAEXXZ */
770 /* ?unlock@streambuf@@QEAAXXZ */
771 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
772 void __thiscall streambuf_unlock(streambuf *this)
774 TRACE("(%p)\n", this);
775 if (this->do_lock < 0)
776 LeaveCriticalSection(&this->lock);
779 /* ?xsgetn@streambuf@@UAEHPADH@Z */
780 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
781 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
782 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
783 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
785 int copied = 0, chunk;
787 TRACE("(%p %p %d)\n", this, buffer, count);
789 if (this->unbuffered) {
790 if (this->stored_char == EOF)
791 this->stored_char = call_streambuf_underflow(this);
792 while (copied < count && this->stored_char != EOF) {
793 buffer[copied++] = this->stored_char;
794 this->stored_char = call_streambuf_underflow(this);
796 } else {
797 while (copied < count) {
798 if (call_streambuf_underflow(this) == EOF)
799 break;
800 chunk = this->egptr - this->gptr;
801 if (chunk > count - copied)
802 chunk = count - copied;
803 memcpy(buffer+copied, this->gptr, chunk);
804 this->gptr += chunk;
805 copied += chunk;
808 return copied;
811 /* ?xsputn@streambuf@@UAEHPBDH@Z */
812 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
813 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
814 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
815 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
817 int copied = 0, chunk;
819 TRACE("(%p %p %d)\n", this, data, length);
821 while (copied < length) {
822 if (this->unbuffered || this->pptr == this->epptr) {
823 if (call_streambuf_overflow(this, (unsigned char)data[copied]) == EOF)
824 break;
825 copied++;
826 } else {
827 chunk = this->epptr - this->pptr;
828 if (chunk > length - copied)
829 chunk = length - copied;
830 memcpy(this->pptr, data+copied, chunk);
831 this->pptr += chunk;
832 copied += chunk;
835 return copied;
838 /* ?sgetc@streambuf@@QAEHXZ */
839 /* ?sgetc@streambuf@@QEAAHXZ */
840 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
841 int __thiscall streambuf_sgetc(streambuf *this)
843 TRACE("(%p)\n", this);
844 if (this->unbuffered) {
845 if (this->stored_char == EOF)
846 this->stored_char = call_streambuf_underflow(this);
847 return this->stored_char;
848 } else
849 return call_streambuf_underflow(this);
852 /* ?sputc@streambuf@@QAEHH@Z */
853 /* ?sputc@streambuf@@QEAAHH@Z */
854 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
855 int __thiscall streambuf_sputc(streambuf *this, int ch)
857 TRACE("(%p %d)\n", this, ch);
858 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
861 /* ?sgetn@streambuf@@QAEHPADH@Z */
862 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
863 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
864 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
866 return call_streambuf_xsgetn(this, buffer, count);
869 /* ?sputn@streambuf@@QAEHPBDH@Z */
870 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
871 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
872 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
874 return call_streambuf_xsputn(this, data, length);
877 /* ?snextc@streambuf@@QAEHXZ */
878 /* ?snextc@streambuf@@QEAAHXZ */
879 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
880 int __thiscall streambuf_snextc(streambuf *this)
882 TRACE("(%p)\n", this);
883 if (this->unbuffered) {
884 if (this->stored_char == EOF)
885 call_streambuf_underflow(this);
886 return this->stored_char = call_streambuf_underflow(this);
887 } else {
888 if (this->gptr >= this->egptr)
889 call_streambuf_underflow(this);
890 this->gptr++;
891 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
895 /* ?sbumpc@streambuf@@QAEHXZ */
896 /* ?sbumpc@streambuf@@QEAAHXZ */
897 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
898 int __thiscall streambuf_sbumpc(streambuf *this)
900 int ret;
902 TRACE("(%p)\n", this);
904 if (this->unbuffered) {
905 ret = this->stored_char;
906 this->stored_char = EOF;
907 if (ret == EOF)
908 ret = call_streambuf_underflow(this);
909 } else {
910 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
911 this->gptr++;
913 return ret;
916 /* ?stossc@streambuf@@QAEXXZ */
917 /* ?stossc@streambuf@@QEAAXXZ */
918 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
919 void __thiscall streambuf_stossc(streambuf *this)
921 TRACE("(%p)\n", this);
922 if (this->unbuffered) {
923 if (this->stored_char == EOF)
924 call_streambuf_underflow(this);
925 else
926 this->stored_char = EOF;
927 } else {
928 if (this->gptr >= this->egptr)
929 call_streambuf_underflow(this);
930 if (this->gptr < this->egptr)
931 this->gptr++;
935 /* ?sputbackc@streambuf@@QAEHD@Z */
936 /* ?sputbackc@streambuf@@QEAAHD@Z */
937 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
938 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
940 TRACE("(%p %d)\n", this, ch);
941 return call_streambuf_pbackfail(this, ch);
944 /* ?dbp@streambuf@@QAEXXZ */
945 /* ?dbp@streambuf@@QEAAXXZ */
946 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
947 void __thiscall streambuf_dbp(streambuf *this)
949 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
950 if (this->unbuffered) {
951 printf("unbuffered\n");
952 } else {
953 printf("_fAlloc=%d\n", this->allocated);
954 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
955 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
956 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
960 /* ??0filebuf@@QAE@ABV0@@Z */
961 /* ??0filebuf@@QEAA@AEBV0@@Z */
962 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
963 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
965 TRACE("(%p %p)\n", this, copy);
966 *this = *copy;
967 this->base.vtable = &filebuf_vtable;
968 return this;
971 /* ??0filebuf@@QAE@HPADH@Z */
972 /* ??0filebuf@@QEAA@HPEADH@Z */
973 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
974 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
976 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
977 streambuf_reserve_ctor(&this->base, buffer, length);
978 this->base.vtable = &filebuf_vtable;
979 this->fd = fd;
980 this->close = 0;
981 return this;
984 /* ??0filebuf@@QAE@H@Z */
985 /* ??0filebuf@@QEAA@H@Z */
986 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
987 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
989 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
990 this->base.unbuffered = 0;
991 return this;
994 /* ??0filebuf@@QAE@XZ */
995 /* ??0filebuf@@QEAA@XZ */
996 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
997 filebuf* __thiscall filebuf_ctor(filebuf* this)
999 return filebuf_fd_ctor(this, -1);
1002 /* ??1filebuf@@UAE@XZ */
1003 /* ??1filebuf@@UEAA@XZ */
1004 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
1005 void __thiscall filebuf_dtor(filebuf* this)
1007 TRACE("(%p)\n", this);
1008 if (this->close)
1009 filebuf_close(this);
1010 streambuf_dtor(&this->base);
1013 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
1014 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
1015 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
1016 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
1018 filebuf_dtor(this);
1019 return filebuf_copy_ctor(this, rhs);
1022 /* ??_Efilebuf@@UAEPAXI@Z */
1023 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
1024 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
1026 TRACE("(%p %x)\n", this, flags);
1027 if (flags & 2) {
1028 /* we have an array, with the number of elements stored before the first object */
1029 INT_PTR i, *ptr = (INT_PTR *)this-1;
1031 for (i = *ptr-1; i >= 0; i--)
1032 filebuf_dtor(this+i);
1033 operator_delete(ptr);
1034 } else {
1035 filebuf_dtor(this);
1036 if (flags & 1)
1037 operator_delete(this);
1039 return this;
1042 /* ??_Gfilebuf@@UAEPAXI@Z */
1043 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
1044 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
1046 TRACE("(%p %x)\n", this, flags);
1047 filebuf_dtor(this);
1048 if (flags & 1) operator_delete(this);
1049 return this;
1052 /* ?attach@filebuf@@QAEPAV1@H@Z */
1053 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
1054 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
1055 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
1057 TRACE("(%p %d)\n", this, fd);
1058 if (this->fd != -1)
1059 return NULL;
1061 streambuf_lock(&this->base);
1062 this->fd = fd;
1063 streambuf_allocate(&this->base);
1064 streambuf_unlock(&this->base);
1065 return this;
1068 /* ?close@filebuf@@QAEPAV1@XZ */
1069 /* ?close@filebuf@@QEAAPEAV1@XZ */
1070 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
1071 filebuf* __thiscall filebuf_close(filebuf *this)
1073 filebuf *ret;
1075 TRACE("(%p)\n", this);
1076 if (this->fd == -1)
1077 return NULL;
1079 streambuf_lock(&this->base);
1080 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
1081 ret = NULL;
1082 } else {
1083 this->fd = -1;
1084 ret = this;
1086 streambuf_unlock(&this->base);
1087 return ret;
1090 /* ?fd@filebuf@@QBEHXZ */
1091 /* ?fd@filebuf@@QEBAHXZ */
1092 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
1093 filedesc __thiscall filebuf_fd(const filebuf *this)
1095 TRACE("(%p)\n", this);
1096 return this->fd;
1099 /* ?is_open@filebuf@@QBEHXZ */
1100 /* ?is_open@filebuf@@QEBAHXZ */
1101 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1102 int __thiscall filebuf_is_open(const filebuf *this)
1104 TRACE("(%p)\n", this);
1105 return this->fd != -1;
1108 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1109 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1110 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1111 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1113 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1114 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1115 int op_flags, sh_flags, fd;
1117 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1118 if (this->fd != -1)
1119 return NULL;
1121 /* mode */
1122 if (mode & (OPENMODE_app|OPENMODE_trunc))
1123 mode |= OPENMODE_out;
1124 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1125 if (op_flags < 0)
1126 return NULL;
1127 if (mode & OPENMODE_app)
1128 op_flags |= _O_APPEND;
1129 if ((mode & OPENMODE_trunc) ||
1130 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1131 op_flags |= _O_TRUNC;
1132 if (!(mode & OPENMODE_nocreate))
1133 op_flags |= _O_CREAT;
1134 if (mode & OPENMODE_noreplace)
1135 op_flags |= _O_EXCL;
1136 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1138 /* share protection */
1139 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1141 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1142 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1143 if (fd < 0)
1144 return NULL;
1146 streambuf_lock(&this->base);
1147 this->close = 1;
1148 this->fd = fd;
1149 if ((mode & OPENMODE_ate) &&
1150 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1151 _close(fd);
1152 this->fd = -1;
1154 streambuf_allocate(&this->base);
1155 streambuf_unlock(&this->base);
1156 return (this->fd == -1) ? NULL : this;
1159 /* ?overflow@filebuf@@UAEHH@Z */
1160 /* ?overflow@filebuf@@UEAAHH@Z */
1161 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1162 int __thiscall filebuf_overflow(filebuf *this, int c)
1164 TRACE("(%p %d)\n", this, c);
1165 if (call_streambuf_sync(&this->base) == EOF)
1166 return EOF;
1167 if (this->base.unbuffered)
1168 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1169 if (streambuf_allocate(&this->base) == EOF)
1170 return EOF;
1172 this->base.pbase = this->base.pptr = this->base.base;
1173 this->base.epptr = this->base.ebuf;
1174 if (c != EOF)
1175 *this->base.pptr++ = c;
1176 return 1;
1179 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1180 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1181 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1182 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1184 TRACE("(%p %ld %d %d)\n", this, offset, dir, mode);
1185 if (call_streambuf_sync(&this->base) == EOF)
1186 return EOF;
1187 return _lseek(this->fd, offset, dir);
1190 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1191 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1192 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1193 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1195 TRACE("(%p %p %d)\n", this, buffer, length);
1197 if (filebuf_is_open(this) && this->base.base != NULL)
1198 return NULL;
1200 streambuf_lock(&this->base);
1202 if (buffer == NULL || !length) {
1203 this->base.unbuffered = 1;
1204 } else {
1205 if (this->base.allocated) {
1206 operator_delete(this->base.base);
1207 this->base.allocated = 0;
1210 this->base.base = buffer;
1211 this->base.ebuf = buffer + length;
1214 streambuf_unlock(&this->base);
1216 return &this->base;
1219 /* ?setmode@filebuf@@QAEHH@Z */
1220 /* ?setmode@filebuf@@QEAAHH@Z */
1221 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1222 int __thiscall filebuf_setmode(filebuf *this, int mode)
1224 int ret;
1226 TRACE("(%p %d)\n", this, mode);
1227 if (mode != filebuf_text && mode != filebuf_binary)
1228 return -1;
1230 streambuf_lock(&this->base);
1231 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1232 streambuf_unlock(&this->base);
1233 return ret;
1236 /* ?sync@filebuf@@UAEHXZ */
1237 /* ?sync@filebuf@@UEAAHXZ */
1238 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1239 int __thiscall filebuf_sync(filebuf *this)
1241 int count, mode;
1242 char *ptr;
1243 LONG offset;
1245 TRACE("(%p)\n", this);
1246 if (this->fd == -1)
1247 return EOF;
1248 if (this->base.unbuffered)
1249 return 0;
1251 /* flush output buffer */
1252 if (this->base.pptr != NULL) {
1253 count = this->base.pptr - this->base.pbase;
1254 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1255 return EOF;
1257 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1258 /* flush input buffer */
1259 if (this->base.egptr != NULL) {
1260 offset = this->base.egptr - this->base.gptr;
1261 if (offset > 0) {
1262 mode = _setmode(this->fd, _O_TEXT);
1263 _setmode(this->fd, mode);
1264 if (mode & _O_TEXT) {
1265 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1266 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1267 if (*ptr == '\n')
1268 offset++;
1270 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1271 return EOF;
1274 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1275 return 0;
1278 /* ?underflow@filebuf@@UAEHXZ */
1279 /* ?underflow@filebuf@@UEAAHXZ */
1280 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1281 int __thiscall filebuf_underflow(filebuf *this)
1283 int buffer_size, read_bytes;
1284 char c;
1286 TRACE("(%p)\n", this);
1288 if (this->base.unbuffered)
1289 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1291 if (this->base.gptr >= this->base.egptr) {
1292 if (call_streambuf_sync(&this->base) == EOF)
1293 return EOF;
1294 buffer_size = this->base.ebuf - this->base.base;
1295 read_bytes = _read(this->fd, this->base.base, buffer_size);
1296 if (read_bytes <= 0)
1297 return EOF;
1298 this->base.eback = this->base.gptr = this->base.base;
1299 this->base.egptr = this->base.base + read_bytes;
1301 return (unsigned char) *this->base.gptr;
1304 /* ??0strstreambuf@@QAE@ABV0@@Z */
1305 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1306 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1307 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1309 TRACE("(%p %p)\n", this, copy);
1310 *this = *copy;
1311 this->base.vtable = &strstreambuf_vtable;
1312 return this;
1315 /* ??0strstreambuf@@QAE@H@Z */
1316 /* ??0strstreambuf@@QEAA@H@Z */
1317 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1318 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1320 TRACE("(%p %d)\n", this, length);
1321 streambuf_ctor(&this->base);
1322 this->base.vtable = &strstreambuf_vtable;
1323 this->dynamic = 1;
1324 this->increase = length;
1325 this->constant = 0;
1326 this->f_alloc = NULL;
1327 this->f_free = NULL;
1328 return this;
1331 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1332 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1333 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1334 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1336 TRACE("(%p %p %p)\n", this, falloc, ffree);
1337 strstreambuf_dynamic_ctor(this, 1);
1338 this->f_alloc = falloc;
1339 this->f_free = ffree;
1340 return this;
1343 /* ??0strstreambuf@@QAE@PADH0@Z */
1344 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1345 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1346 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1348 char *end_buffer;
1350 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1352 if (length > 0)
1353 end_buffer = buffer + length;
1354 else if (length == 0)
1355 end_buffer = buffer + strlen(buffer);
1356 else
1357 end_buffer = (char*) -1;
1359 streambuf_ctor(&this->base);
1360 streambuf_setb(&this->base, buffer, end_buffer, 0);
1361 if (put == NULL) {
1362 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1363 } else {
1364 streambuf_setg(&this->base, buffer, buffer, put);
1365 streambuf_setp(&this->base, put, end_buffer);
1367 this->base.vtable = &strstreambuf_vtable;
1368 this->dynamic = 0;
1369 this->constant = 1;
1370 return this;
1373 /* ??0strstreambuf@@QAE@PAEH0@Z */
1374 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1375 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1376 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1378 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1379 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1382 /* ??0strstreambuf@@QAE@XZ */
1383 /* ??0strstreambuf@@QEAA@XZ */
1384 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1385 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1387 TRACE("(%p)\n", this);
1388 return strstreambuf_dynamic_ctor(this, 1);
1391 /* ??1strstreambuf@@UAE@XZ */
1392 /* ??1strstreambuf@@UEAA@XZ */
1393 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1394 void __thiscall strstreambuf_dtor(strstreambuf *this)
1396 TRACE("(%p)\n", this);
1397 if (this->dynamic && this->base.base) {
1398 if (this->f_free)
1399 this->f_free(this->base.base);
1400 else
1401 operator_delete(this->base.base);
1403 streambuf_dtor(&this->base);
1406 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1407 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1408 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1409 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1411 strstreambuf_dtor(this);
1412 return strstreambuf_copy_ctor(this, rhs);
1415 /* ??_Estrstreambuf@@UAEPAXI@Z */
1416 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1417 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1419 TRACE("(%p %x)\n", this, flags);
1420 if (flags & 2) {
1421 /* we have an array, with the number of elements stored before the first object */
1422 INT_PTR i, *ptr = (INT_PTR *)this-1;
1424 for (i = *ptr-1; i >= 0; i--)
1425 strstreambuf_dtor(this+i);
1426 operator_delete(ptr);
1427 } else {
1428 strstreambuf_dtor(this);
1429 if (flags & 1)
1430 operator_delete(this);
1432 return this;
1435 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1436 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1437 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1439 TRACE("(%p %x)\n", this, flags);
1440 strstreambuf_dtor(this);
1441 if (flags & 1) operator_delete(this);
1442 return this;
1445 /* ?doallocate@strstreambuf@@MAEHXZ */
1446 /* ?doallocate@strstreambuf@@MEAAHXZ */
1447 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1448 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1450 char *prev_buffer = this->base.base, *new_buffer;
1451 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1453 TRACE("(%p)\n", this);
1455 /* calculate the size of the new buffer */
1456 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1457 /* get a new buffer */
1458 if (this->f_alloc)
1459 new_buffer = this->f_alloc(new_size);
1460 else
1461 new_buffer = operator_new(new_size);
1462 if (!new_buffer)
1463 return EOF;
1464 if (this->base.ebuf) {
1465 /* copy the contents and adjust the pointers */
1466 memcpy(new_buffer, this->base.base, prev_size);
1467 if (this->base.egptr) {
1468 this->base.eback += new_buffer - prev_buffer;
1469 this->base.gptr += new_buffer - prev_buffer;
1470 this->base.egptr += new_buffer - prev_buffer;
1472 if (this->base.epptr) {
1473 this->base.pbase += new_buffer - prev_buffer;
1474 this->base.pptr += new_buffer - prev_buffer;
1475 this->base.epptr += new_buffer - prev_buffer;
1477 /* free the old buffer */
1478 if (this->f_free)
1479 this->f_free(this->base.base);
1480 else
1481 operator_delete(this->base.base);
1483 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1484 return 1;
1487 /* ?freeze@strstreambuf@@QAEXH@Z */
1488 /* ?freeze@strstreambuf@@QEAAXH@Z */
1489 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1490 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1492 TRACE("(%p %d)\n", this, frozen);
1493 if (!this->constant)
1494 this->dynamic = !frozen;
1497 /* ?overflow@strstreambuf@@UAEHH@Z */
1498 /* ?overflow@strstreambuf@@UEAAHH@Z */
1499 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1500 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1502 TRACE("(%p %d)\n", this, c);
1503 if (this->base.pptr >= this->base.epptr) {
1504 /* increase the buffer size if it's dynamic */
1505 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1506 return EOF;
1507 if (!this->base.epptr)
1508 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1509 this->base.epptr = this->base.ebuf;
1511 if (c != EOF)
1512 *this->base.pptr++ = c;
1513 return 1;
1516 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1517 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1518 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1519 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1521 char *base[3];
1523 TRACE("(%p %ld %d %d)\n", this, offset, dir, mode);
1525 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1526 return EOF;
1527 /* read buffer */
1528 if (mode & OPENMODE_in) {
1529 call_streambuf_underflow(&this->base);
1530 base[SEEKDIR_beg] = this->base.eback;
1531 base[SEEKDIR_cur] = this->base.gptr;
1532 base[SEEKDIR_end] = this->base.egptr;
1533 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1534 return EOF;
1535 this->base.gptr = base[dir] + offset;
1537 /* write buffer */
1538 if (mode & OPENMODE_out) {
1539 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1540 return EOF;
1541 base[SEEKDIR_beg] = this->base.pbase;
1542 base[SEEKDIR_cur] = this->base.pptr;
1543 base[SEEKDIR_end] = this->base.epptr;
1544 if (base[dir] + offset < this->base.pbase)
1545 return EOF;
1546 if (base[dir] + offset > this->base.epptr) {
1547 /* make room if the buffer is dynamic */
1548 if (!this->dynamic)
1549 return EOF;
1550 this->increase = offset;
1551 if (call_streambuf_doallocate(&this->base) == EOF)
1552 return EOF;
1554 this->base.pptr = base[dir] + offset;
1555 return this->base.pptr - base[SEEKDIR_beg];
1557 return this->base.gptr - base[SEEKDIR_beg];
1560 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1561 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1562 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1563 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1565 TRACE("(%p %p %d)\n", this, buffer, length);
1566 if (length)
1567 this->increase = length;
1568 return &this->base;
1571 /* ?str@strstreambuf@@QAEPADXZ */
1572 /* ?str@strstreambuf@@QEAAPEADXZ */
1573 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1574 char* __thiscall strstreambuf_str(strstreambuf *this)
1576 TRACE("(%p)\n", this);
1577 strstreambuf_freeze(this, 1);
1578 return this->base.base;
1581 /* ?sync@strstreambuf@@UAEHXZ */
1582 /* ?sync@strstreambuf@@UEAAHXZ */
1583 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1584 int __thiscall strstreambuf_sync(strstreambuf *this)
1586 TRACE("(%p)\n", this);
1587 return 0;
1590 /* ?underflow@strstreambuf@@UAEHXZ */
1591 /* ?underflow@strstreambuf@@UEAAHXZ */
1592 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1593 int __thiscall strstreambuf_underflow(strstreambuf *this)
1595 TRACE("(%p)\n", this);
1596 if (this->base.gptr < this->base.egptr)
1597 return (unsigned char) *this->base.gptr;
1598 /* extend the get area to include the characters written */
1599 if (this->base.egptr < this->base.pptr) {
1600 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1601 this->base.eback = this->base.base;
1602 this->base.egptr = this->base.pptr;
1604 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1607 /* ??0stdiobuf@@QAE@ABV0@@Z */
1608 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1609 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1610 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1612 TRACE("(%p %p)\n", this, copy);
1613 *this = *copy;
1614 this->base.vtable = &stdiobuf_vtable;
1615 return this;
1618 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1619 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1620 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1621 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1623 TRACE("(%p %p)\n", this, file);
1624 streambuf_reserve_ctor(&this->base, NULL, 0);
1625 this->base.vtable = &stdiobuf_vtable;
1626 this->file = file;
1627 return this;
1630 /* ??1stdiobuf@@UAE@XZ */
1631 /* ??1stdiobuf@@UEAA@XZ */
1632 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1633 void __thiscall stdiobuf_dtor(stdiobuf *this)
1635 TRACE("(%p)\n", this);
1636 call_streambuf_sync(&this->base);
1637 streambuf_dtor(&this->base);
1640 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1641 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1642 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1643 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1645 stdiobuf_dtor(this);
1646 return stdiobuf_copy_ctor(this, rhs);
1649 /* ??_Estdiobuf@@UAEPAXI@Z */
1650 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1651 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1653 TRACE("(%p %x)\n", this, flags);
1654 if (flags & 2) {
1655 /* we have an array, with the number of elements stored before the first object */
1656 INT_PTR i, *ptr = (INT_PTR *)this-1;
1658 for (i = *ptr-1; i >= 0; i--)
1659 stdiobuf_dtor(this+i);
1660 operator_delete(ptr);
1661 } else {
1662 stdiobuf_dtor(this);
1663 if (flags & 1)
1664 operator_delete(this);
1666 return this;
1669 /* ??_Gstdiobuf@@UAEPAXI@Z */
1670 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1671 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1673 TRACE("(%p %x)\n", this, flags);
1674 stdiobuf_dtor(this);
1675 if (flags & 1) operator_delete(this);
1676 return this;
1679 /* ?overflow@stdiobuf@@UAEHH@Z */
1680 /* ?overflow@stdiobuf@@UEAAHH@Z */
1681 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1682 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1684 TRACE("(%p %d)\n", this, c);
1685 if (this->base.unbuffered)
1686 return (c == EOF) ? 1 : fputc(c, this->file);
1687 if (streambuf_allocate(&this->base) == EOF)
1688 return EOF;
1690 if (!this->base.epptr) {
1691 /* set the put area to the second half of the buffer */
1692 streambuf_setp(&this->base,
1693 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1694 } else if (this->base.pptr > this->base.pbase) {
1695 /* flush the put area */
1696 int count = this->base.pptr - this->base.pbase;
1697 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1698 return EOF;
1699 this->base.pptr = this->base.pbase;
1701 if (c != EOF) {
1702 if (this->base.pbase >= this->base.epptr)
1703 return fputc(c, this->file);
1704 *this->base.pptr++ = c;
1706 return 1;
1709 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1710 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1711 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1712 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1714 TRACE("(%p %d)\n", this, c);
1715 return streambuf_pbackfail(&this->base, c);
1718 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1719 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1720 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1721 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1723 TRACE("(%p %ld %d %d)\n", this, offset, dir, mode);
1724 call_streambuf_overflow(&this->base, EOF);
1725 if (fseek(this->file, offset, dir))
1726 return EOF;
1727 return ftell(this->file);
1730 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1731 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1732 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1733 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1735 char *reserve;
1736 int buffer_size = read_size + write_size;
1738 TRACE("(%p %d %d)\n", this, read_size, write_size);
1739 if (read_size < 0 || write_size < 0)
1740 return 0;
1741 if (!buffer_size) {
1742 this->base.unbuffered = 1;
1743 return 0;
1745 /* get a new buffer */
1746 reserve = operator_new(buffer_size);
1747 if (!reserve)
1748 return 0;
1749 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1750 this->base.unbuffered = 0;
1751 /* set the get/put areas */
1752 if (read_size > 0)
1753 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1754 else
1755 streambuf_setg(&this->base, NULL, NULL, NULL);
1756 if (write_size > 0)
1757 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1758 else
1759 streambuf_setp(&this->base, NULL, NULL);
1760 return 1;
1763 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1764 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1765 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1766 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1768 TRACE("(%p)\n", this);
1769 return this->file;
1772 /* ?sync@stdiobuf@@UAEHXZ */
1773 /* ?sync@stdiobuf@@UEAAHXZ */
1774 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1775 int __thiscall stdiobuf_sync(stdiobuf *this)
1777 TRACE("(%p)\n", this);
1778 if (this->base.unbuffered)
1779 return 0;
1780 /* flush the put area */
1781 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1782 return EOF;
1783 /* flush the get area */
1784 if (this->base.gptr < this->base.egptr) {
1785 char *ptr;
1786 int fd, mode, offset = this->base.egptr - this->base.gptr;
1787 if ((fd = fileno(this->file)) < 0)
1788 return EOF;
1789 mode = _setmode(fd, _O_TEXT);
1790 _setmode(fd, mode);
1791 if (mode & _O_TEXT) {
1792 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1793 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1794 if (*ptr == '\n')
1795 offset++;
1797 if (fseek(this->file, -offset, SEEK_CUR))
1798 return EOF;
1799 this->base.gptr = this->base.egptr;
1801 return 0;
1804 /* ?underflow@stdiobuf@@UAEHXZ */
1805 /* ?underflow@stdiobuf@@UEAAHXZ */
1806 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1807 int __thiscall stdiobuf_underflow(stdiobuf *this)
1809 TRACE("(%p)\n", this);
1810 if (!this->file)
1811 return EOF;
1812 if (this->base.unbuffered)
1813 return fgetc(this->file);
1814 if (streambuf_allocate(&this->base) == EOF)
1815 return EOF;
1817 if (!this->base.egptr) {
1818 /* set the get area to the first half of the buffer */
1819 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1820 streambuf_setg(&this->base, this->base.base, middle, middle);
1822 if (this->base.gptr >= this->base.egptr) {
1823 /* read characters from the file */
1824 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1825 if (!this->base.eback ||
1826 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1827 return EOF;
1828 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1829 this->base.gptr = this->base.egptr - read_bytes;
1831 return (unsigned char) *this->base.gptr++;
1834 /* ??0ios@@IAE@ABV0@@Z */
1835 /* ??0ios@@IEAA@AEBV0@@Z */
1836 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1837 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1839 TRACE("(%p %p)\n", this, copy);
1840 ios_fLockcInit++;
1841 this->vtable = &ios_vtable;
1842 this->sb = NULL;
1843 this->delbuf = 0;
1844 this->do_lock = -1;
1845 InitializeCriticalSection(&this->lock);
1846 return ios_assign(this, copy);
1849 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1850 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1851 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1852 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1854 TRACE("(%p %p)\n", this, sb);
1855 ios_fLockcInit++;
1856 this->vtable = &ios_vtable;
1857 this->sb = sb;
1858 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1859 this->special[0] = this->special[1] = 0;
1860 this->delbuf = 0;
1861 this->tie = NULL;
1862 this->flags = 0;
1863 this->precision = 6;
1864 this->fill = ' ';
1865 this->width = 0;
1866 this->do_lock = -1;
1867 InitializeCriticalSection(&this->lock);
1868 return this;
1871 /* ??0ios@@IAE@XZ */
1872 /* ??0ios@@IEAA@XZ */
1873 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1874 ios* __thiscall ios_ctor(ios *this)
1876 return ios_sb_ctor(this, NULL);
1879 /* ??1ios@@UAE@XZ */
1880 /* ??1ios@@UEAA@XZ */
1881 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1882 void __thiscall ios_dtor(ios *this)
1884 TRACE("(%p)\n", this);
1885 ios_fLockcInit--;
1886 if (this->delbuf && this->sb)
1887 call_streambuf_vector_dtor(this->sb, 1);
1888 this->sb = NULL;
1889 this->state = IOSTATE_badbit;
1890 DeleteCriticalSection(&this->lock);
1893 /* ??4ios@@IAEAAV0@ABV0@@Z */
1894 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1895 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1896 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1898 TRACE("(%p %p)\n", this, rhs);
1899 this->state = rhs->state;
1900 if (!this->sb)
1901 this->state |= IOSTATE_badbit;
1902 this->tie = rhs->tie;
1903 this->flags = rhs->flags;
1904 this->precision = (char) rhs->precision;
1905 this->fill = rhs->fill;
1906 this->width = (char) rhs->width;
1907 return this;
1910 /* ??7ios@@QBEHXZ */
1911 /* ??7ios@@QEBAHXZ */
1912 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1913 int __thiscall ios_op_not(const ios *this)
1915 TRACE("(%p)\n", this);
1916 return ios_fail(this);
1919 /* ??Bios@@QBEPAXXZ */
1920 /* ??Bios@@QEBAPEAXXZ */
1921 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1922 void* __thiscall ios_op_void(const ios *this)
1924 TRACE("(%p)\n", this);
1925 return ios_fail(this) ? NULL : (void*)this;
1928 /* ??_Eios@@UAEPAXI@Z */
1929 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1930 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1932 TRACE("(%p %x)\n", this, flags);
1933 if (flags & 2) {
1934 /* we have an array, with the number of elements stored before the first object */
1935 INT_PTR i, *ptr = (INT_PTR *)this-1;
1937 for (i = *ptr-1; i >= 0; i--)
1938 ios_dtor(this+i);
1939 operator_delete(ptr);
1940 } else {
1941 ios_dtor(this);
1942 if (flags & 1)
1943 operator_delete(this);
1945 return this;
1948 /* ??_Gios@@UAEPAXI@Z */
1949 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1950 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1952 TRACE("(%p %x)\n", this, flags);
1953 ios_dtor(this);
1954 if (flags & 1) operator_delete(this);
1955 return this;
1958 /* ?bad@ios@@QBEHXZ */
1959 /* ?bad@ios@@QEBAHXZ */
1960 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1961 int __thiscall ios_bad(const ios *this)
1963 TRACE("(%p)\n", this);
1964 return (this->state & IOSTATE_badbit);
1967 /* ?bitalloc@ios@@SAJXZ */
1968 LONG __cdecl ios_bitalloc(void)
1970 TRACE("()\n");
1971 ios_lockc();
1972 ios_maxbit <<= 1;
1973 ios_unlockc();
1974 return ios_maxbit;
1977 /* ?clear@ios@@QAEXH@Z */
1978 /* ?clear@ios@@QEAAXH@Z */
1979 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1980 void __thiscall ios_clear(ios *this, int state)
1982 TRACE("(%p %d)\n", this, state);
1983 ios_lock(this);
1984 this->state = state;
1985 ios_unlock(this);
1988 /* ?clrlock@ios@@QAAXXZ */
1989 /* ?clrlock@ios@@QEAAXXZ */
1990 void __cdecl ios_clrlock(ios *this)
1992 TRACE("(%p)\n", this);
1993 if (this->do_lock <= 0)
1994 this->do_lock++;
1995 if (this->sb)
1996 streambuf_clrlock(this->sb);
1999 /* ?delbuf@ios@@QAEXH@Z */
2000 /* ?delbuf@ios@@QEAAXH@Z */
2001 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
2002 void __thiscall ios_delbuf_set(ios *this, int delete)
2004 TRACE("(%p %d)\n", this, delete);
2005 this->delbuf = delete;
2008 /* ?delbuf@ios@@QBEHXZ */
2009 /* ?delbuf@ios@@QEBAHXZ */
2010 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
2011 int __thiscall ios_delbuf_get(const ios *this)
2013 TRACE("(%p)\n", this);
2014 return this->delbuf;
2017 /* ?dec@@YAAAVios@@AAV1@@Z */
2018 /* ?dec@@YAAEAVios@@AEAV1@@Z */
2019 ios* __cdecl ios_dec(ios *this)
2021 TRACE("(%p)\n", this);
2022 ios_setf_mask(this, FLAGS_dec, ios_basefield);
2023 return this;
2026 /* ?eof@ios@@QBEHXZ */
2027 /* ?eof@ios@@QEBAHXZ */
2028 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
2029 int __thiscall ios_eof(const ios *this)
2031 TRACE("(%p)\n", this);
2032 return (this->state & IOSTATE_eofbit);
2035 /* ?fail@ios@@QBEHXZ */
2036 /* ?fail@ios@@QEBAHXZ */
2037 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
2038 int __thiscall ios_fail(const ios *this)
2040 TRACE("(%p)\n", this);
2041 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
2044 /* ?fill@ios@@QAEDD@Z */
2045 /* ?fill@ios@@QEAADD@Z */
2046 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
2047 char __thiscall ios_fill_set(ios *this, char fill)
2049 char prev = this->fill;
2051 TRACE("(%p %d)\n", this, fill);
2053 this->fill = fill;
2054 return prev;
2057 /* ?fill@ios@@QBEDXZ */
2058 /* ?fill@ios@@QEBADXZ */
2059 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
2060 char __thiscall ios_fill_get(const ios *this)
2062 TRACE("(%p)\n", this);
2063 return this->fill;
2066 /* ?flags@ios@@QAEJJ@Z */
2067 /* ?flags@ios@@QEAAJJ@Z */
2068 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
2069 LONG __thiscall ios_flags_set(ios *this, LONG flags)
2071 LONG prev = this->flags;
2073 TRACE("(%p %lx)\n", this, flags);
2075 this->flags = flags;
2076 return prev;
2079 /* ?flags@ios@@QBEJXZ */
2080 /* ?flags@ios@@QEBAJXZ */
2081 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
2082 LONG __thiscall ios_flags_get(const ios *this)
2084 TRACE("(%p)\n", this);
2085 return this->flags;
2088 /* ?good@ios@@QBEHXZ */
2089 /* ?good@ios@@QEBAHXZ */
2090 DEFINE_THISCALL_WRAPPER(ios_good, 4)
2091 int __thiscall ios_good(const ios *this)
2093 TRACE("(%p)\n", this);
2094 return this->state == IOSTATE_goodbit;
2097 /* ?hex@@YAAAVios@@AAV1@@Z */
2098 /* ?hex@@YAAEAVios@@AEAV1@@Z */
2099 ios* __cdecl ios_hex(ios *this)
2101 TRACE("(%p)\n", this);
2102 ios_setf_mask(this, FLAGS_hex, ios_basefield);
2103 return this;
2106 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
2107 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
2108 DEFINE_THISCALL_WRAPPER(ios_init, 8)
2109 void __thiscall ios_init(ios *this, streambuf *sb)
2111 TRACE("(%p %p)\n", this, sb);
2112 if (this->delbuf && this->sb)
2113 call_streambuf_vector_dtor(this->sb, 1);
2114 this->sb = sb;
2115 if (sb == NULL)
2116 this->state |= IOSTATE_badbit;
2117 else
2118 this->state &= ~IOSTATE_badbit;
2121 /* ?iword@ios@@QBEAAJH@Z */
2122 /* ?iword@ios@@QEBAAEAJH@Z */
2123 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2124 LONG* __thiscall ios_iword(const ios *this, int index)
2126 TRACE("(%p %d)\n", this, index);
2127 return &ios_statebuf[index];
2130 /* ?lock@ios@@QAAXXZ */
2131 /* ?lock@ios@@QEAAXXZ */
2132 void __cdecl ios_lock(ios *this)
2134 TRACE("(%p)\n", this);
2135 if (this->do_lock < 0)
2136 EnterCriticalSection(&this->lock);
2139 /* ?lockbuf@ios@@QAAXXZ */
2140 /* ?lockbuf@ios@@QEAAXXZ */
2141 void __cdecl ios_lockbuf(ios *this)
2143 TRACE("(%p)\n", this);
2144 streambuf_lock(this->sb);
2147 /* ?lockc@ios@@KAXXZ */
2148 void __cdecl ios_lockc(void)
2150 TRACE("()\n");
2151 EnterCriticalSection(&ios_static_lock);
2154 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2155 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2156 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2157 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2159 TRACE("(%p)\n", this);
2160 return &this->lock;
2163 /* ?oct@@YAAAVios@@AAV1@@Z */
2164 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2165 ios* __cdecl ios_oct(ios *this)
2167 TRACE("(%p)\n", this);
2168 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2169 return this;
2172 /* ?precision@ios@@QAEHH@Z */
2173 /* ?precision@ios@@QEAAHH@Z */
2174 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2175 int __thiscall ios_precision_set(ios *this, int prec)
2177 int prev = this->precision;
2179 TRACE("(%p %d)\n", this, prec);
2181 this->precision = prec;
2182 return prev;
2185 /* ?precision@ios@@QBEHXZ */
2186 /* ?precision@ios@@QEBAHXZ */
2187 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2188 int __thiscall ios_precision_get(const ios *this)
2190 TRACE("(%p)\n", this);
2191 return this->precision;
2194 /* ?pword@ios@@QBEAAPAXH@Z */
2195 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2196 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2197 void** __thiscall ios_pword(const ios *this, int index)
2199 TRACE("(%p %d)\n", this, index);
2200 return (void**)&ios_statebuf[index];
2203 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2204 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2205 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2206 streambuf* __thiscall ios_rdbuf(const ios *this)
2208 TRACE("(%p)\n", this);
2209 return this->sb;
2212 /* ?rdstate@ios@@QBEHXZ */
2213 /* ?rdstate@ios@@QEBAHXZ */
2214 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2215 int __thiscall ios_rdstate(const ios *this)
2217 TRACE("(%p)\n", this);
2218 return this->state;
2221 /* ?setf@ios@@QAEJJ@Z */
2222 /* ?setf@ios@@QEAAJJ@Z */
2223 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2224 LONG __thiscall ios_setf(ios *this, LONG flags)
2226 LONG prev = this->flags;
2228 TRACE("(%p %lx)\n", this, flags);
2230 ios_lock(this);
2231 this->flags |= flags;
2232 ios_unlock(this);
2233 return prev;
2236 /* ?setf@ios@@QAEJJJ@Z */
2237 /* ?setf@ios@@QEAAJJJ@Z */
2238 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2239 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2241 LONG prev = this->flags;
2243 TRACE("(%p %lx %lx)\n", this, flags, mask);
2245 ios_lock(this);
2246 this->flags = (this->flags & (~mask)) | (flags & mask);
2247 ios_unlock(this);
2248 return prev;
2251 /* ?setlock@ios@@QAAXXZ */
2252 /* ?setlock@ios@@QEAAXXZ */
2253 void __cdecl ios_setlock(ios *this)
2255 TRACE("(%p)\n", this);
2256 this->do_lock--;
2257 if (this->sb)
2258 streambuf_setlock(this->sb);
2261 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2262 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2263 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2264 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2266 ostream *prev = this->tie;
2268 TRACE("(%p %p)\n", this, ostr);
2270 this->tie = ostr;
2271 return prev;
2274 /* ?tie@ios@@QBEPAVostream@@XZ */
2275 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2276 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2277 ostream* __thiscall ios_tie_get(const ios *this)
2279 TRACE("(%p)\n", this);
2280 return this->tie;
2283 /* ?unlock@ios@@QAAXXZ */
2284 /* ?unlock@ios@@QEAAXXZ */
2285 void __cdecl ios_unlock(ios *this)
2287 TRACE("(%p)\n", this);
2288 if (this->do_lock < 0)
2289 LeaveCriticalSection(&this->lock);
2292 /* ?unlockbuf@ios@@QAAXXZ */
2293 /* ?unlockbuf@ios@@QEAAXXZ */
2294 void __cdecl ios_unlockbuf(ios *this)
2296 TRACE("(%p)\n", this);
2297 streambuf_unlock(this->sb);
2300 /* ?unlockc@ios@@KAXXZ */
2301 void __cdecl ios_unlockc(void)
2303 TRACE("()\n");
2304 LeaveCriticalSection(&ios_static_lock);
2307 /* ?unsetf@ios@@QAEJJ@Z */
2308 /* ?unsetf@ios@@QEAAJJ@Z */
2309 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2310 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2312 LONG prev = this->flags;
2314 TRACE("(%p %lx)\n", this, flags);
2316 ios_lock(this);
2317 this->flags &= ~flags;
2318 ios_unlock(this);
2319 return prev;
2322 /* ?width@ios@@QAEHH@Z */
2323 /* ?width@ios@@QEAAHH@Z */
2324 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2325 int __thiscall ios_width_set(ios *this, int width)
2327 int prev = this->width;
2329 TRACE("(%p %d)\n", this, width);
2331 this->width = width;
2332 return prev;
2335 /* ?width@ios@@QBEHXZ */
2336 /* ?width@ios@@QEBAHXZ */
2337 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2338 int __thiscall ios_width_get(const ios *this)
2340 TRACE("(%p)\n", this);
2341 return this->width;
2344 /* ?xalloc@ios@@SAHXZ */
2345 int __cdecl ios_xalloc(void)
2347 int ret;
2349 TRACE("()\n");
2351 ios_lockc();
2352 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2353 ios_unlockc();
2354 return ret;
2357 static inline ios* ostream_get_ios(const ostream *this)
2359 return (ios*)((char*)this + this->vbtable[1]);
2362 static inline ios* ostream_to_ios(const ostream *this)
2364 return (ios*)((char*)this + ostream_vbtable[1]);
2367 static inline ostream* ios_to_ostream(const ios *base)
2369 return (ostream*)((char*)base - ostream_vbtable[1]);
2372 /* ??0ostream@@IAE@XZ */
2373 /* ??0ostream@@IEAA@XZ */
2374 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2375 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2377 ios *base;
2379 TRACE("(%p %d)\n", this, virt_init);
2381 if (virt_init) {
2382 this->vbtable = ostream_vbtable;
2383 base = ostream_get_ios(this);
2384 ios_ctor(base);
2385 } else
2386 base = ostream_get_ios(this);
2387 base->vtable = &ostream_vtable;
2388 this->unknown = 0;
2389 return this;
2392 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2393 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2394 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2395 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2397 TRACE("(%p %p %d)\n", this, sb, virt_init);
2398 ostream_ctor(this, virt_init);
2399 ios_init(ostream_get_ios(this), sb);
2400 return this;
2403 /* ??0ostream@@IAE@ABV0@@Z */
2404 /* ??0ostream@@IEAA@AEBV0@@Z */
2405 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2406 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2408 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2411 /* ??1ostream@@UAE@XZ */
2412 /* ??1ostream@@UEAA@XZ */
2413 /* ??1ostream_withassign@@UAE@XZ */
2414 /* ??1ostream_withassign@@UEAA@XZ */
2415 /* ??1ostrstream@@UAE@XZ */
2416 /* ??1ostrstream@@UEAA@XZ */
2417 /* ??1ofstream@@UAE@XZ */
2418 /* ??1ofstream@@UEAA@XZ */
2419 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2420 void __thiscall ostream_dtor(ios *base)
2422 ostream *this = ios_to_ostream(base);
2424 TRACE("(%p)\n", this);
2427 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2428 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2429 /* ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z */
2430 /* ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z */
2431 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2432 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2434 ios *base = ostream_get_ios(this);
2436 TRACE("(%p %p)\n", this, sb);
2438 ios_init(base, sb);
2439 base->state &= IOSTATE_badbit;
2440 base->delbuf = 0;
2441 base->tie = NULL;
2442 base->flags = 0;
2443 base->precision = 6;
2444 base->fill = ' ';
2445 base->width = 0;
2446 return this;
2449 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2450 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2451 /* ??4ostream_withassign@@QAEAAV0@ABV0@@Z */
2452 /* ??4ostream_withassign@@QEAAAEAV0@AEBV0@@Z */
2453 /* ??4ostream_withassign@@QAEAAVostream@@ABV1@@Z */
2454 /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */
2455 /* ??4ostrstream@@QAEAAV0@ABV0@@Z */
2456 /* ??4ostrstream@@QEAAAEAV0@AEBV0@@Z */
2457 /* ??4ofstream@@QAEAAV0@ABV0@@Z */
2458 /* ??4ofstream@@QEAAAEAV0@AEBV0@@Z */
2459 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2460 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2462 return ostream_assign_sb(this, ostream_get_ios(rhs)->sb);
2465 /* ??_Dostream@@QAEXXZ */
2466 /* ??_Dostream@@QEAAXXZ */
2467 /* ??_Dostream_withassign@@QAEXXZ */
2468 /* ??_Dostream_withassign@@QEAAXXZ */
2469 /* ??_Dostrstream@@QAEXXZ */
2470 /* ??_Dostrstream@@QEAAXXZ */
2471 /* ??_Dofstream@@QAEXXZ */
2472 /* ??_Dofstream@@QEAAXXZ */
2473 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2474 void __thiscall ostream_vbase_dtor(ostream *this)
2476 ios *base = ostream_to_ios(this);
2478 TRACE("(%p)\n", this);
2480 ostream_dtor(base);
2481 ios_dtor(base);
2484 /* ??_Eostream@@UAEPAXI@Z */
2485 /* ??_Eostream_withassign@@UAEPAXI@Z */
2486 /* ??_Eostrstream@@UAEPAXI@Z */
2487 /* ??_Eofstream@@UAEPAXI@Z */
2488 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2489 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2491 ostream *this = ios_to_ostream(base);
2493 TRACE("(%p %x)\n", this, flags);
2495 if (flags & 2) {
2496 /* we have an array, with the number of elements stored before the first object */
2497 INT_PTR i, *ptr = (INT_PTR *)this-1;
2499 for (i = *ptr-1; i >= 0; i--)
2500 ostream_vbase_dtor(this+i);
2501 operator_delete(ptr);
2502 } else {
2503 ostream_vbase_dtor(this);
2504 if (flags & 1)
2505 operator_delete(this);
2507 return this;
2510 /* ??_Gostream@@UAEPAXI@Z */
2511 /* ??_Gostream_withassign@@UAEPAXI@Z */
2512 /* ??_Gostrstream@@UAEPAXI@Z */
2513 /* ??_Gofstream@@UAEPAXI@Z */
2514 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2515 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2517 ostream *this = ios_to_ostream(base);
2519 TRACE("(%p %x)\n", this, flags);
2521 ostream_vbase_dtor(this);
2522 if (flags & 1) operator_delete(this);
2523 return this;
2526 /* ?flush@ostream@@QAEAAV1@XZ */
2527 /* ?flush@ostream@@QEAAAEAV1@XZ */
2528 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2529 ostream* __thiscall ostream_flush(ostream *this)
2531 ios *base = ostream_get_ios(this);
2533 TRACE("(%p)\n", this);
2535 ios_lockbuf(base);
2536 if (call_streambuf_sync(base->sb) == EOF)
2537 ios_clear(base, base->state | IOSTATE_failbit);
2538 ios_unlockbuf(base);
2539 return this;
2542 /* ?opfx@ostream@@QAEHXZ */
2543 /* ?opfx@ostream@@QEAAHXZ */
2544 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2545 int __thiscall ostream_opfx(ostream *this)
2547 ios *base = ostream_get_ios(this);
2549 TRACE("(%p)\n", this);
2551 if (!ios_good(base)) {
2552 ios_clear(base, base->state | IOSTATE_failbit);
2553 return 0;
2555 ios_lock(base);
2556 ios_lockbuf(base);
2557 if (base->tie)
2558 ostream_flush(base->tie);
2559 return 1;
2562 /* ?osfx@ostream@@QAEXXZ */
2563 /* ?osfx@ostream@@QEAAXXZ */
2564 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2565 void __thiscall ostream_osfx(ostream *this)
2567 ios *base = ostream_get_ios(this);
2569 TRACE("(%p)\n", this);
2571 ios_unlockbuf(base);
2572 ios_width_set(base, 0);
2573 if (base->flags & FLAGS_unitbuf)
2574 ostream_flush(this);
2575 if (base->flags & FLAGS_stdio) {
2576 fflush(stdout);
2577 fflush(stderr);
2579 ios_unlock(base);
2582 /* ?put@ostream@@QAEAAV1@C@Z */
2583 /* ?put@ostream@@QEAAAEAV1@C@Z */
2584 /* ?put@ostream@@QAEAAV1@D@Z */
2585 /* ?put@ostream@@QEAAAEAV1@D@Z */
2586 /* ?put@ostream@@QAEAAV1@E@Z */
2587 /* ?put@ostream@@QEAAAEAV1@E@Z */
2588 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2589 ostream* __thiscall ostream_put(ostream *this, char c)
2591 ios *base = ostream_get_ios(this);
2593 TRACE("(%p %c)\n", this, c);
2595 if (ostream_opfx(this)) {
2596 if (streambuf_sputc(base->sb, c) == EOF)
2597 base->state = IOSTATE_badbit | IOSTATE_failbit;
2598 ostream_osfx(this);
2600 return this;
2603 /* ?seekp@ostream@@QAEAAV1@J@Z */
2604 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2605 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2606 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2608 ios *base = ostream_get_ios(this);
2610 TRACE("(%p %ld)\n", this, pos);
2612 ios_lockbuf(base);
2613 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2614 ios_clear(base, base->state | IOSTATE_failbit);
2615 ios_unlockbuf(base);
2616 return this;
2619 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2620 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2621 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2622 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2624 ios *base = ostream_get_ios(this);
2626 TRACE("(%p %ld %d)\n", this, off, dir);
2628 ios_lockbuf(base);
2629 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2630 ios_clear(base, base->state | IOSTATE_failbit);
2631 ios_unlockbuf(base);
2632 return this;
2635 /* ?tellp@ostream@@QAEJXZ */
2636 /* ?tellp@ostream@@QEAAJXZ */
2637 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2638 streampos __thiscall ostream_tellp(ostream *this)
2640 ios *base = ostream_get_ios(this);
2641 streampos pos;
2643 TRACE("(%p)\n", this);
2645 ios_lockbuf(base);
2646 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2647 ios_clear(base, base->state | IOSTATE_failbit);
2648 ios_unlockbuf(base);
2649 return pos;
2652 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2653 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2654 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2655 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2656 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2657 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2658 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2659 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2661 ios *base = ostream_get_ios(this);
2663 TRACE("(%p %p %d)\n", this, str, count);
2665 if (ostream_opfx(this)) {
2666 if (streambuf_sputn(base->sb, str, count) != count)
2667 base->state = IOSTATE_badbit | IOSTATE_failbit;
2668 ostream_osfx(this);
2670 return this;
2673 static ostream* ostream_writepad_len(ostream *this, const char *str1, const char *str2, int len2)
2675 ios *base = ostream_get_ios(this);
2676 int len1 = strlen(str1), i;
2678 TRACE("(%p %p %p %d)\n", this, str1, str2, len2);
2680 /* left of the padding */
2681 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2682 if (streambuf_sputn(base->sb, str1, len1) != len1)
2683 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2684 if (!(base->flags & FLAGS_internal))
2685 if (streambuf_sputn(base->sb, str2, len2) != len2)
2686 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2688 /* add padding to fill the width */
2689 for (i = len1 + len2; i < base->width; i++)
2690 if (streambuf_sputc(base->sb, base->fill) == EOF)
2691 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2692 /* right of the padding */
2693 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2694 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2695 if (streambuf_sputn(base->sb, str1, len1) != len1)
2696 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2697 if (streambuf_sputn(base->sb, str2, len2) != len2)
2698 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2700 return this;
2703 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2704 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2705 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2706 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2708 return ostream_writepad_len(this, str1, str2, strlen(str2));
2711 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2713 ios *base = ostream_get_ios(ostr);
2714 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2716 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2718 if (ostream_opfx(ostr)) {
2719 if (base->flags & FLAGS_hex) {
2720 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2721 if (base->flags & FLAGS_showbase) {
2722 prefix_str[0] = '0';
2723 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2725 } else if (base->flags & FLAGS_oct) {
2726 sprintf_fmt[1] = 'o';
2727 if (base->flags & FLAGS_showbase)
2728 prefix_str[0] = '0';
2729 } else { /* FLAGS_dec */
2730 if (unsig)
2731 sprintf_fmt[1] = 'u';
2732 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2733 prefix_str[0] = '+';
2736 if (shrt) {
2737 sprintf_fmt[2] = sprintf_fmt[1];
2738 sprintf_fmt[1] = 'h';
2741 if (sprintf(number_str, sprintf_fmt, n) > 0)
2742 ostream_writepad(ostr, prefix_str, number_str);
2743 else
2744 base->state |= IOSTATE_failbit;
2745 ostream_osfx(ostr);
2747 return ostr;
2750 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2752 ios *base = ostream_get_ios(ostr);
2753 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2754 int prec, max_prec = dbl ? 15 : 6;
2755 int str_length = 1; /* null end char */
2757 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2759 if (ostream_opfx(ostr)) {
2760 if ((base->flags & FLAGS_showpos) && d > 0) {
2761 prefix_str[0] = '+';
2762 str_length++; /* plus sign */
2764 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2765 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2766 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2767 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2768 if (base->flags & FLAGS_showpoint) {
2769 sprintf_fmt[4] = sprintf_fmt[3];
2770 sprintf_fmt[3] = sprintf_fmt[2];
2771 sprintf_fmt[2] = sprintf_fmt[1];
2772 sprintf_fmt[1] = '#';
2775 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2776 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2777 if (str_length > 24) {
2778 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2779 ostream_writepad(ostr, "", "");
2780 } else {
2781 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2782 ostream_writepad(ostr, prefix_str, number_str);
2783 else
2784 base->state |= IOSTATE_failbit;
2786 ostream_osfx(ostr);
2788 return ostr;
2791 /* ??6ostream@@QAEAAV0@C@Z */
2792 /* ??6ostream@@QEAAAEAV0@C@Z */
2793 /* ??6ostream@@QAEAAV0@D@Z */
2794 /* ??6ostream@@QEAAAEAV0@D@Z */
2795 /* ??6ostream@@QAEAAV0@E@Z */
2796 /* ??6ostream@@QEAAAEAV0@E@Z */
2797 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2798 ostream* __thiscall ostream_print_char(ostream *this, char c)
2800 TRACE("(%p %d)\n", this, c);
2802 if (ostream_opfx(this)) {
2803 ostream_writepad_len(this, "", &c, 1);
2804 ostream_osfx(this);
2806 return this;
2809 /* ??6ostream@@QAEAAV0@PBC@Z */
2810 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2811 /* ??6ostream@@QAEAAV0@PBD@Z */
2812 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2813 /* ??6ostream@@QAEAAV0@PBE@Z */
2814 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2815 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2816 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2818 TRACE("(%p %s)\n", this, str);
2819 if (ostream_opfx(this)) {
2820 ostream_writepad(this, "", str);
2821 ostream_osfx(this);
2823 return this;
2826 /* ??6ostream@@QAEAAV0@F@Z */
2827 /* ??6ostream@@QEAAAEAV0@F@Z */
2828 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2829 ostream* __thiscall ostream_print_short(ostream *this, short n)
2831 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2834 /* ??6ostream@@QAEAAV0@G@Z */
2835 /* ??6ostream@@QEAAAEAV0@G@Z */
2836 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2837 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2839 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2842 /* ??6ostream@@QAEAAV0@H@Z */
2843 /* ??6ostream@@QEAAAEAV0@H@Z */
2844 /* ??6ostream@@QAEAAV0@J@Z */
2845 /* ??6ostream@@QEAAAEAV0@J@Z */
2846 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2847 ostream* __thiscall ostream_print_int(ostream *this, int n)
2849 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2852 /* ??6ostream@@QAEAAV0@I@Z */
2853 /* ??6ostream@@QEAAAEAV0@I@Z */
2854 /* ??6ostream@@QAEAAV0@K@Z */
2855 /* ??6ostream@@QEAAAEAV0@K@Z */
2856 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2857 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2859 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2862 /* ??6ostream@@QAEAAV0@M@Z */
2863 /* ??6ostream@@QEAAAEAV0@M@Z */
2864 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2865 ostream* __thiscall ostream_print_float(ostream *this, float f)
2867 return ostream_internal_print_float(this, f, FALSE);
2870 /* ??6ostream@@QAEAAV0@N@Z */
2871 /* ??6ostream@@QEAAAEAV0@N@Z */
2872 /* ??6ostream@@QAEAAV0@O@Z */
2873 /* ??6ostream@@QEAAAEAV0@O@Z */
2874 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2875 ostream* __thiscall ostream_print_double(ostream *this, double d)
2877 return ostream_internal_print_float(this, d, TRUE);
2880 /* ??6ostream@@QAEAAV0@PBX@Z */
2881 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2882 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2883 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2885 ios *base = ostream_get_ios(this);
2886 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2888 TRACE("(%p %p)\n", this, ptr);
2890 if (ostream_opfx(this)) {
2891 if (ptr && base->flags & FLAGS_uppercase)
2892 prefix_str[1] = 'X';
2894 if (sprintf(pointer_str, "%p", ptr) > 0)
2895 ostream_writepad(this, prefix_str, pointer_str);
2896 else
2897 base->state |= IOSTATE_failbit;
2898 ostream_osfx(this);
2900 return this;
2903 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2904 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2905 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2906 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2908 ios *base = ostream_get_ios(this);
2909 int c;
2911 TRACE("(%p %p)\n", this, sb);
2913 if (ostream_opfx(this)) {
2914 while ((c = streambuf_sbumpc(sb)) != EOF) {
2915 if (streambuf_sputc(base->sb, c) == EOF) {
2916 base->state |= IOSTATE_failbit;
2917 break;
2920 ostream_osfx(this);
2922 return this;
2925 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2926 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2927 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2928 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2930 TRACE("(%p %p)\n", this, func);
2931 return func(this);
2934 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2935 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2936 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2937 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2939 TRACE("(%p %p)\n", this, func);
2940 func(ostream_get_ios(this));
2941 return this;
2944 /* ?endl@@YAAAVostream@@AAV1@@Z */
2945 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2946 ostream* __cdecl ostream_endl(ostream *this)
2948 TRACE("(%p)\n", this);
2949 ostream_put(this, '\n');
2950 return ostream_flush(this);
2953 /* ?ends@@YAAAVostream@@AAV1@@Z */
2954 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2955 ostream* __cdecl ostream_ends(ostream *this)
2957 TRACE("(%p)\n", this);
2958 return ostream_put(this, 0);
2961 /* ?flush@@YAAAVostream@@AAV1@@Z */
2962 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2963 ostream* __cdecl ostream_flush_manip(ostream *this)
2965 TRACE("(%p)\n", this);
2966 return ostream_flush(this);
2969 /* ??0ostream_withassign@@QAE@ABV0@@Z */
2970 /* ??0ostream_withassign@@QEAA@AEBV0@@Z */
2971 DEFINE_THISCALL_WRAPPER(ostream_withassign_copy_ctor, 12)
2972 ostream* __thiscall ostream_withassign_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2974 ios *base, *base_copy;
2976 TRACE("(%p %p %d)\n", this, copy, virt_init);
2978 base_copy = ostream_get_ios(copy);
2979 if (virt_init) {
2980 this->vbtable = ostream_vbtable;
2981 base = ostream_get_ios(this);
2982 ios_copy_ctor(base, base_copy);
2983 } else
2984 base = ostream_get_ios(this);
2985 ios_init(base, base_copy->sb);
2986 base->vtable = &ostream_withassign_vtable;
2987 this->unknown = 0;
2988 return this;
2991 /* ??0ostream_withassign@@QAE@PAVstreambuf@@@Z */
2992 /* ??0ostream_withassign@@QEAA@PEAVstreambuf@@@Z */
2993 DEFINE_THISCALL_WRAPPER(ostream_withassign_sb_ctor, 12)
2994 ostream* __thiscall ostream_withassign_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2996 ios *base;
2998 TRACE("(%p %p %d)\n", this, sb, virt_init);
3000 ostream_sb_ctor(this, sb, virt_init);
3001 base = ostream_get_ios(this);
3002 base->vtable = &ostream_withassign_vtable;
3003 return this;
3006 /* ??0ostream_withassign@@QAE@XZ */
3007 /* ??0ostream_withassign@@QEAA@XZ */
3008 DEFINE_THISCALL_WRAPPER(ostream_withassign_ctor, 8)
3009 ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init)
3011 ios *base;
3013 TRACE("(%p %d)\n", this, virt_init);
3015 ostream_ctor(this, virt_init);
3016 base = ostream_get_ios(this);
3017 base->vtable = &ostream_withassign_vtable;
3018 return this;
3021 static ostream* ostrstream_internal_sb_ctor(ostream *this, strstreambuf *ssb, BOOL virt_init)
3023 ios *base;
3025 if (ssb)
3026 ostream_sb_ctor(this, &ssb->base, virt_init);
3027 else
3028 ostream_ctor(this, virt_init);
3029 base = ostream_get_ios(this);
3030 base->vtable = &ostrstream_vtable;
3031 base->delbuf = 1;
3032 return this;
3035 /* ??0ostrstream@@QAE@ABV0@@Z */
3036 /* ??0ostrstream@@QEAA@AEBV0@@Z */
3037 DEFINE_THISCALL_WRAPPER(ostrstream_copy_ctor, 12)
3038 ostream* __thiscall ostrstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
3040 TRACE("(%p %p %d)\n", this, copy, virt_init);
3041 ostream_withassign_copy_ctor(this, copy, virt_init);
3042 ostream_get_ios(this)->vtable = &ostrstream_vtable;
3043 return this;
3046 /* ??0ostrstream@@QAE@PADHH@Z */
3047 /* ??0ostrstream@@QEAA@PEADHH@Z */
3048 DEFINE_THISCALL_WRAPPER(ostrstream_buffer_ctor, 20)
3049 ostream* __thiscall ostrstream_buffer_ctor(ostream *this, char *buffer, int length, int mode, BOOL virt_init)
3051 strstreambuf *ssb = operator_new(sizeof(strstreambuf));
3053 TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init);
3055 if (!ssb) {
3056 FIXME("out of memory\n");
3057 return NULL;
3060 strstreambuf_buffer_ctor(ssb, buffer, length, buffer);
3061 if (mode & (OPENMODE_app|OPENMODE_ate))
3062 ssb->base.pptr = buffer + strlen(buffer);
3064 return ostrstream_internal_sb_ctor(this, ssb, virt_init);
3067 /* ??0ostrstream@@QAE@XZ */
3068 /* ??0ostrstream@@QEAA@XZ */
3069 DEFINE_THISCALL_WRAPPER(ostrstream_ctor, 8)
3070 ostream* __thiscall ostrstream_ctor(ostream *this, BOOL virt_init)
3072 strstreambuf *ssb = operator_new(sizeof(strstreambuf));
3074 TRACE("(%p %d)\n", this, virt_init);
3076 if (!ssb) {
3077 FIXME("out of memory\n");
3078 return NULL;
3081 strstreambuf_ctor(ssb);
3083 return ostrstream_internal_sb_ctor(this, ssb, virt_init);
3086 /* ?pcount@ostrstream@@QBEHXZ */
3087 /* ?pcount@ostrstream@@QEBAHXZ */
3088 DEFINE_THISCALL_WRAPPER(ostrstream_pcount, 4)
3089 int __thiscall ostrstream_pcount(const ostream *this)
3091 return streambuf_out_waiting(ostream_get_ios(this)->sb);
3094 /* ?rdbuf@ostrstream@@QBEPAVstrstreambuf@@XZ */
3095 /* ?rdbuf@ostrstream@@QEBAPEAVstrstreambuf@@XZ */
3096 DEFINE_THISCALL_WRAPPER(ostrstream_rdbuf, 4)
3097 strstreambuf* __thiscall ostrstream_rdbuf(const ostream *this)
3099 return (strstreambuf*) ostream_get_ios(this)->sb;
3102 /* ?str@ostrstream@@QAEPADXZ */
3103 /* ?str@ostrstream@@QEAAPEADXZ */
3104 DEFINE_THISCALL_WRAPPER(ostrstream_str, 4)
3105 char* __thiscall ostrstream_str(ostream *this)
3107 return strstreambuf_str(ostrstream_rdbuf(this));
3110 /* ??0ofstream@@QAE@ABV0@@Z */
3111 /* ??0ofstream@@QEAA@AEBV0@@Z */
3112 DEFINE_THISCALL_WRAPPER(ofstream_copy_ctor, 12)
3113 ostream* __thiscall ofstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
3115 TRACE("(%p %p %d)\n", this, copy, virt_init);
3116 ostream_withassign_copy_ctor(this, copy, virt_init);
3117 ostream_get_ios(this)->vtable = &ofstream_vtable;
3118 return this;
3121 /* ??0ofstream@@QAE@HPADH@Z */
3122 /* ??0ofstream@@QEAA@HPEADH@Z */
3123 DEFINE_THISCALL_WRAPPER(ofstream_buffer_ctor, 20)
3124 ostream* __thiscall ofstream_buffer_ctor(ostream *this, filedesc fd, char *buffer, int length, BOOL virt_init)
3126 ios *base;
3127 filebuf *fb = operator_new(sizeof(filebuf));
3129 TRACE("(%p %d %p %d %d)\n", this, fd, buffer, length, virt_init);
3131 if (!fb) {
3132 FIXME("out of memory\n");
3133 return NULL;
3136 filebuf_fd_reserve_ctor(fb, fd, buffer, length);
3137 ostream_sb_ctor(this, &fb->base, virt_init);
3139 base = ostream_get_ios(this);
3140 base->vtable = &ofstream_vtable;
3141 base->delbuf = 1;
3143 return this;
3146 /* ??0ofstream@@QAE@H@Z */
3147 /* ??0ofstream@@QEAA@H@Z */
3148 DEFINE_THISCALL_WRAPPER(ofstream_fd_ctor, 12)
3149 ostream* __thiscall ofstream_fd_ctor(ostream *this, filedesc fd, BOOL virt_init)
3151 ios *base;
3152 filebuf *fb = operator_new(sizeof(filebuf));
3154 TRACE("(%p %d %d)\n", this, fd, virt_init);
3156 if (!fb) {
3157 FIXME("out of memory\n");
3158 return NULL;
3161 filebuf_fd_ctor(fb, fd);
3162 ostream_sb_ctor(this, &fb->base, virt_init);
3164 base = ostream_get_ios(this);
3165 base->vtable = &ofstream_vtable;
3166 base->delbuf = 1;
3168 return this;
3171 /* ??0ofstream@@QAE@PBDHH@Z */
3172 /* ??0ofstream@@QEAA@PEBDHH@Z */
3173 DEFINE_THISCALL_WRAPPER(ofstream_open_ctor, 20)
3174 ostream* __thiscall ofstream_open_ctor(ostream *this, const char *name, int mode, int protection, BOOL virt_init)
3176 ios *base;
3177 filebuf *fb = operator_new(sizeof(filebuf));
3179 TRACE("(%p %s %d %d %d)\n", this, name, mode, protection, virt_init);
3181 if (!fb) {
3182 FIXME("out of memory\n");
3183 return NULL;
3186 filebuf_ctor(fb);
3187 ostream_sb_ctor(this, &fb->base, virt_init);
3189 base = ostream_get_ios(this);
3190 base->vtable = &ofstream_vtable;
3191 base->delbuf = 1;
3193 if (filebuf_open(fb, name, mode|OPENMODE_out, protection) == NULL)
3194 base->state |= IOSTATE_failbit;
3195 return this;
3198 /* ??0ofstream@@QAE@XZ */
3199 /* ??0ofstream@@QEAA@XZ */
3200 DEFINE_THISCALL_WRAPPER(ofstream_ctor, 8)
3201 ostream* __thiscall ofstream_ctor(ostream *this, BOOL virt_init)
3203 return ofstream_fd_ctor(this, -1, virt_init);
3206 /* ?rdbuf@ofstream@@QBEPAVfilebuf@@XZ */
3207 /* ?rdbuf@ofstream@@QEBAPEAVfilebuf@@XZ */
3208 DEFINE_THISCALL_WRAPPER(ofstream_rdbuf, 4)
3209 filebuf* __thiscall ofstream_rdbuf(const ostream *this)
3211 TRACE("(%p)\n", this);
3212 return (filebuf*) ostream_get_ios(this)->sb;
3215 /* ?fd@ofstream@@QBEHXZ */
3216 /* ?fd@ofstream@@QEBAHXZ */
3217 DEFINE_THISCALL_WRAPPER(ofstream_fd, 4)
3218 filedesc __thiscall ofstream_fd(ostream *this)
3220 TRACE("(%p)\n", this);
3221 return filebuf_fd(ofstream_rdbuf(this));
3224 /* ?attach@ofstream@@QAEXH@Z */
3225 /* ?attach@ofstream@@QEAAXH@Z */
3226 DEFINE_THISCALL_WRAPPER(ofstream_attach, 8)
3227 void __thiscall ofstream_attach(ostream *this, filedesc fd)
3229 ios *base = ostream_get_ios(this);
3230 TRACE("(%p %d)\n", this, fd);
3231 if (filebuf_attach(ofstream_rdbuf(this), fd) == NULL)
3232 ios_clear(base, base->state | IOSTATE_failbit);
3235 /* ?close@ofstream@@QAEXXZ */
3236 /* ?close@ofstream@@QEAAXXZ */
3237 DEFINE_THISCALL_WRAPPER(ofstream_close, 4)
3238 void __thiscall ofstream_close(ostream *this)
3240 ios *base = ostream_get_ios(this);
3241 TRACE("(%p)\n", this);
3242 if (filebuf_close(ofstream_rdbuf(this)) == NULL)
3243 ios_clear(base, base->state | IOSTATE_failbit);
3244 else
3245 ios_clear(base, IOSTATE_goodbit);
3248 /* ?is_open@ofstream@@QBEHXZ */
3249 /* ?is_open@ofstream@@QEBAHXZ */
3250 DEFINE_THISCALL_WRAPPER(ofstream_is_open, 4)
3251 int __thiscall ofstream_is_open(const ostream *this)
3253 TRACE("(%p)\n", this);
3254 return filebuf_is_open(ofstream_rdbuf(this));
3257 /* ?open@ofstream@@QAEXPBDHH@Z */
3258 /* ?open@ofstream@@QEAAXPEBDHH@Z */
3259 DEFINE_THISCALL_WRAPPER(ofstream_open, 16)
3260 void __thiscall ofstream_open(ostream *this, const char *name, ios_open_mode mode, int protection)
3262 ios *base = ostream_get_ios(this);
3263 TRACE("(%p %s %d %d)\n", this, name, mode, protection);
3264 if (filebuf_open(ofstream_rdbuf(this), name, mode|OPENMODE_out, protection) == NULL)
3265 ios_clear(base, base->state | IOSTATE_failbit);
3268 /* ?setbuf@ofstream@@QAEPAVstreambuf@@PADH@Z */
3269 /* ?setbuf@ofstream@@QEAAPEAVstreambuf@@PEADH@Z */
3270 DEFINE_THISCALL_WRAPPER(ofstream_setbuf, 12)
3271 streambuf* __thiscall ofstream_setbuf(ostream *this, char *buffer, int length)
3273 ios *base = ostream_get_ios(this);
3274 filebuf* fb = ofstream_rdbuf(this);
3276 TRACE("(%p %p %d)\n", this, buffer, length);
3278 if (filebuf_is_open(fb)) {
3279 ios_clear(base, base->state | IOSTATE_failbit);
3280 return NULL;
3283 return filebuf_setbuf(fb, buffer, length);
3286 /* ?setmode@ofstream@@QAEHH@Z */
3287 /* ?setmode@ofstream@@QEAAHH@Z */
3288 DEFINE_THISCALL_WRAPPER(ofstream_setmode, 8)
3289 int __thiscall ofstream_setmode(ostream *this, int mode)
3291 TRACE("(%p %d)\n", this, mode);
3292 return filebuf_setmode(ofstream_rdbuf(this), mode);
3295 static inline ios* istream_get_ios(const istream *this)
3297 return (ios*)((char*)this + this->vbtable[1]);
3300 static inline ios* istream_to_ios(const istream *this)
3302 return (ios*)((char*)this + istream_vbtable[1]);
3305 static inline istream* ios_to_istream(const ios *base)
3307 return (istream*)((char*)base - istream_vbtable[1]);
3310 /* ??0istream@@IAE@XZ */
3311 /* ??0istream@@IEAA@XZ */
3312 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
3313 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
3315 ios *base;
3317 TRACE("(%p %d)\n", this, virt_init);
3319 if (virt_init) {
3320 this->vbtable = istream_vbtable;
3321 base = istream_get_ios(this);
3322 ios_ctor(base);
3323 } else
3324 base = istream_get_ios(this);
3325 base->vtable = &istream_vtable;
3326 base->flags |= FLAGS_skipws;
3327 this->extract_delim = 0;
3328 this->count = 0;
3329 return this;
3332 /* ??0istream@@QAE@PAVstreambuf@@@Z */
3333 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
3334 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
3335 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
3337 TRACE("(%p %p %d)\n", this, sb, virt_init);
3338 istream_ctor(this, virt_init);
3339 ios_init(istream_get_ios(this), sb);
3340 return this;
3343 /* ??0istream@@IAE@ABV0@@Z */
3344 /* ??0istream@@IEAA@AEBV0@@Z */
3345 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
3346 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3348 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
3351 /* ??1istream@@UAE@XZ */
3352 /* ??1istream@@UEAA@XZ */
3353 /* ??1istream_withassign@@UAE@XZ */
3354 /* ??1istream_withassign@@UEAA@XZ */
3355 /* ??1istrstream@@UAE@XZ */
3356 /* ??1istrstream@@UEAA@XZ */
3357 /* ??1ifstream@@UAE@XZ */
3358 /* ??1ifstream@@UEAA@XZ */
3359 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
3360 void __thiscall istream_dtor(ios *base)
3362 istream *this = ios_to_istream(base);
3364 TRACE("(%p)\n", this);
3367 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
3368 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3369 /* ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z */
3370 /* ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z */
3371 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
3372 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
3374 ios *base = istream_get_ios(this);
3376 TRACE("(%p %p)\n", this, sb);
3378 ios_init(base, sb);
3379 base->state &= IOSTATE_badbit;
3380 base->delbuf = 0;
3381 base->tie = NULL;
3382 base->flags = FLAGS_skipws;
3383 base->precision = 6;
3384 base->fill = ' ';
3385 base->width = 0;
3386 this->count = 0;
3387 return this;
3390 /* ??4istream@@IAEAAV0@ABV0@@Z */
3391 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
3392 /* ??4istream_withassign@@QAEAAV0@ABV0@@Z */
3393 /* ??4istream_withassign@@QEAAAEAV0@AEBV0@@Z */
3394 /* ??4istream_withassign@@QAEAAVistream@@ABV1@@Z */
3395 /* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */
3396 /* ??4istrstream@@QAEAAV0@ABV0@@Z */
3397 /* ??4istrstream@@QEAAAEAV0@AEBV0@@Z */
3398 /* ??4ifstream@@QAEAAV0@ABV0@@Z */
3399 /* ??4ifstream@@QEAAAEAV0@AEBV0@@Z */
3400 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
3401 istream* __thiscall istream_assign(istream *this, const istream *rhs)
3403 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
3406 /* ??_Distream@@QAEXXZ */
3407 /* ??_Distream@@QEAAXXZ */
3408 /* ??_Distream_withassign@@QAEXXZ */
3409 /* ??_Distream_withassign@@QEAAXXZ */
3410 /* ??_Distrstream@@QAEXXZ */
3411 /* ??_Distrstream@@QEAAXXZ */
3412 /* ??_Difstream@@QAEXXZ */
3413 /* ??_Difstream@@QEAAXXZ */
3414 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
3415 void __thiscall istream_vbase_dtor(istream *this)
3417 ios *base = istream_to_ios(this);
3419 TRACE("(%p)\n", this);
3421 istream_dtor(base);
3422 ios_dtor(base);
3425 /* ??_Eistream@@UAEPAXI@Z */
3426 /* ??_Eistream_withassign@@UAEPAXI@Z */
3427 /* ??_Eistrstream@@UAEPAXI@Z */
3428 /* ??_Eifstream@@UAEPAXI@Z */
3429 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
3430 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
3432 istream *this = ios_to_istream(base);
3434 TRACE("(%p %x)\n", this, flags);
3436 if (flags & 2) {
3437 /* we have an array, with the number of elements stored before the first object */
3438 INT_PTR i, *ptr = (INT_PTR *)this-1;
3440 for (i = *ptr-1; i >= 0; i--)
3441 istream_vbase_dtor(this+i);
3442 operator_delete(ptr);
3443 } else {
3444 istream_vbase_dtor(this);
3445 if (flags & 1)
3446 operator_delete(this);
3448 return this;
3451 /* ??_Gistream@@UAEPAXI@Z */
3452 /* ??_Gistream_withassign@@UAEPAXI@Z */
3453 /* ??_Gistrstream@@UAEPAXI@Z */
3454 /* ??_Gifstream@@UAEPAXI@Z */
3455 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
3456 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
3458 istream *this = ios_to_istream(base);
3460 TRACE("(%p %x)\n", this, flags);
3462 istream_vbase_dtor(this);
3463 if (flags & 1) operator_delete(this);
3464 return this;
3467 /* ?eatwhite@istream@@QAEXXZ */
3468 /* ?eatwhite@istream@@QEAAXXZ */
3469 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3470 void __thiscall istream_eatwhite(istream *this)
3472 ios *base = istream_get_ios(this);
3473 int c;
3475 TRACE("(%p)\n", this);
3477 ios_lockbuf(base);
3478 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3479 ios_unlockbuf(base);
3480 if (c == EOF)
3481 ios_clear(base, base->state | IOSTATE_eofbit);
3484 /* ?gcount@istream@@QBEHXZ */
3485 /* ?gcount@istream@@QEBAHXZ */
3486 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3487 int __thiscall istream_gcount(const istream *this)
3489 TRACE("(%p)\n", this);
3490 return this->count;
3493 /* ?ipfx@istream@@QAEHH@Z */
3494 /* ?ipfx@istream@@QEAAHH@Z */
3495 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3496 int __thiscall istream_ipfx(istream *this, int need)
3498 ios *base = istream_get_ios(this);
3500 TRACE("(%p %d)\n", this, need);
3502 if (need)
3503 this->count = 0;
3504 if (!ios_good(base)) {
3505 ios_clear(base, base->state | IOSTATE_failbit);
3506 return 0;
3508 ios_lock(base);
3509 ios_lockbuf(base);
3510 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3511 ostream_flush(base->tie);
3512 if ((base->flags & FLAGS_skipws) && !need) {
3513 istream_eatwhite(this);
3514 if (base->state & IOSTATE_eofbit) {
3515 base->state |= IOSTATE_failbit;
3516 ios_unlockbuf(base);
3517 ios_unlock(base);
3518 return 0;
3521 return 1;
3524 /* ?isfx@istream@@QAEXXZ */
3525 /* ?isfx@istream@@QEAAXXZ */
3526 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3527 void __thiscall istream_isfx(istream *this)
3529 ios *base = istream_get_ios(this);
3531 TRACE("(%p)\n", this);
3533 ios_unlockbuf(base);
3534 ios_unlock(base);
3537 /* ?get@istream@@IAEAAV1@PADHH@Z */
3538 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3539 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3540 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3542 ios *base = istream_get_ios(this);
3543 int ch, i = 0;
3545 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3547 if (istream_ipfx(this, 1)) {
3548 while (i < count - 1) {
3549 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3550 base->state |= IOSTATE_eofbit;
3551 if (!i) /* tried to read, but not a single character was obtained */
3552 base->state |= IOSTATE_failbit;
3553 break;
3555 if (ch == delim) {
3556 if (this->extract_delim) { /* discard the delimiter */
3557 streambuf_stossc(base->sb);
3558 this->count++;
3560 break;
3562 if (str)
3563 str[i] = ch;
3564 streambuf_stossc(base->sb);
3565 i++;
3567 this->count += i;
3568 istream_isfx(this);
3570 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3571 str[i] = 0;
3572 this->extract_delim = 0;
3573 return this;
3576 /* ?get@istream@@QAEAAV1@PACHD@Z */
3577 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3578 /* ?get@istream@@QAEAAV1@PADHD@Z */
3579 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3580 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3581 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3582 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3583 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3585 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3588 static int istream_internal_get_char(istream *this, char *ch)
3590 ios *base = istream_get_ios(this);
3591 int ret = EOF;
3593 TRACE("(%p %p)\n", this, ch);
3595 if (istream_ipfx(this, 1)) {
3596 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3597 this->count = 1;
3598 } else {
3599 base->state |= IOSTATE_eofbit;
3600 if (ch)
3601 base->state |= IOSTATE_failbit;
3603 if (ch)
3604 *ch = ret;
3605 istream_isfx(this);
3607 return ret;
3610 /* ?get@istream@@QAEAAV1@AAC@Z */
3611 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3612 /* ?get@istream@@QAEAAV1@AAD@Z */
3613 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3614 /* ?get@istream@@QAEAAV1@AAE@Z */
3615 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3616 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3617 istream* __thiscall istream_get_char(istream *this, char *ch)
3619 istream_internal_get_char(this, ch);
3620 return this;
3623 /* ?get@istream@@QAEHXZ */
3624 /* ?get@istream@@QEAAHXZ */
3625 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3626 int __thiscall istream_get(istream *this)
3628 return istream_internal_get_char(this, NULL);
3631 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3632 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3633 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3634 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3636 ios *base = istream_get_ios(this);
3637 int ch;
3639 TRACE("(%p %p %c)\n", this, sb, delim);
3641 if (istream_ipfx(this, 1)) {
3642 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3643 if (ch == EOF) {
3644 base->state |= IOSTATE_eofbit;
3645 break;
3647 if (streambuf_sputc(sb, ch) == EOF)
3648 base->state |= IOSTATE_failbit;
3649 this->count++;
3651 istream_isfx(this);
3653 return this;
3656 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3657 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3658 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3659 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3660 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3661 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3662 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3663 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3665 ios *base = istream_get_ios(this);
3667 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3669 ios_lock(base);
3670 this->extract_delim++;
3671 istream_get_str_delim(this, str, count, (unsigned char) delim);
3672 ios_unlock(base);
3673 return this;
3676 /* ?ignore@istream@@QAEAAV1@HH@Z */
3677 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3678 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3679 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3681 ios *base = istream_get_ios(this);
3683 TRACE("(%p %d %d)\n", this, count, delim);
3685 ios_lock(base);
3686 this->extract_delim++;
3687 istream_get_str_delim(this, NULL, count + 1, delim);
3688 ios_unlock(base);
3689 return this;
3692 /* ?peek@istream@@QAEHXZ */
3693 /* ?peek@istream@@QEAAHXZ */
3694 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3695 int __thiscall istream_peek(istream *this)
3697 ios *base = istream_get_ios(this);
3698 int ret = EOF;
3700 TRACE("(%p)\n", this);
3702 if (istream_ipfx(this, 1)) {
3703 ret = streambuf_sgetc(base->sb);
3704 istream_isfx(this);
3706 return ret;
3709 /* ?putback@istream@@QAEAAV1@D@Z */
3710 /* ?putback@istream@@QEAAAEAV1@D@Z */
3711 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3712 istream* __thiscall istream_putback(istream *this, char ch)
3714 ios *base = istream_get_ios(this);
3716 TRACE("(%p %c)\n", this, ch);
3718 if (ios_good(base)) {
3719 ios_lockbuf(base);
3720 if (streambuf_sputbackc(base->sb, ch) == EOF)
3721 ios_clear(base, base->state | IOSTATE_failbit);
3722 ios_unlockbuf(base);
3724 return this;
3727 /* ?read@istream@@QAEAAV1@PACH@Z */
3728 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3729 /* ?read@istream@@QAEAAV1@PADH@Z */
3730 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3731 /* ?read@istream@@QAEAAV1@PAEH@Z */
3732 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3733 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3734 istream* __thiscall istream_read(istream *this, char *str, int count)
3736 ios *base = istream_get_ios(this);
3738 TRACE("(%p %p %d)\n", this, str, count);
3740 if (istream_ipfx(this, 1)) {
3741 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3742 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3743 istream_isfx(this);
3745 return this;
3748 /* ?seekg@istream@@QAEAAV1@J@Z */
3749 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3750 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3751 istream* __thiscall istream_seekg(istream *this, streampos pos)
3753 ios *base = istream_get_ios(this);
3755 TRACE("(%p %ld)\n", this, pos);
3757 ios_lockbuf(base);
3758 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3759 ios_clear(base, base->state | IOSTATE_failbit);
3760 ios_unlockbuf(base);
3761 return this;
3764 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3765 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3766 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3767 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3769 ios *base = istream_get_ios(this);
3771 TRACE("(%p %ld %d)\n", this, off, dir);
3773 ios_lockbuf(base);
3774 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3775 ios_clear(base, base->state | IOSTATE_failbit);
3776 ios_unlockbuf(base);
3777 return this;
3780 /* ?sync@istream@@QAEHXZ */
3781 /* ?sync@istream@@QEAAHXZ */
3782 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3783 int __thiscall istream_sync(istream *this)
3785 ios *base = istream_get_ios(this);
3786 int ret;
3788 TRACE("(%p)\n", this);
3790 ios_lockbuf(base);
3791 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3792 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3793 ios_unlockbuf(base);
3794 return ret;
3797 /* ?tellg@istream@@QAEJXZ */
3798 /* ?tellg@istream@@QEAAJXZ */
3799 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3800 streampos __thiscall istream_tellg(istream *this)
3802 ios *base = istream_get_ios(this);
3803 streampos pos;
3805 TRACE("(%p)\n", this);
3807 ios_lockbuf(base);
3808 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3809 ios_clear(base, base->state | IOSTATE_failbit);
3810 ios_unlockbuf(base);
3811 return pos;
3814 static int getint_is_valid_digit(char ch, int base)
3816 if (base == 8) return (ch >= '0' && ch <= '7');
3817 if (base == 16) return isxdigit(ch);
3818 return isdigit(ch);
3821 /* ?getint@istream@@AAEHPAD@Z */
3822 /* ?getint@istream@@AEAAHPEAD@Z */
3823 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3824 int __thiscall istream_getint(istream *this, char *str)
3826 ios *base = istream_get_ios(this);
3827 int ch, num_base = 0, i = 0;
3828 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3830 TRACE("(%p %p)\n", this, str);
3832 if (istream_ipfx(this, 0)) {
3833 num_base = (base->flags & FLAGS_dec) ? 10 :
3834 (base->flags & FLAGS_hex) ? 16 :
3835 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3836 /* scan valid characters, up to 15 (hard limit on Windows) */
3837 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3838 if ((ch == '+' || ch == '-') && scan_sign) {
3839 /* no additional sign allowed */
3840 scan_sign = FALSE;
3841 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3842 /* only hex digits can (and must) follow */
3843 scan_x = valid_integer = FALSE;
3844 num_base = 16;
3845 } else if (ch == '0' && scan_prefix) {
3846 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3847 scan_sign = scan_prefix = FALSE;
3848 scan_x = !num_base || num_base == 16;
3849 valid_integer = TRUE;
3850 if (!num_base)
3851 num_base = 8;
3852 } else if (getint_is_valid_digit(ch, num_base)) {
3853 /* only digits in the corresponding base can follow */
3854 scan_sign = scan_prefix = scan_x = FALSE;
3855 valid_integer = TRUE;
3856 } else {
3857 /* unexpected character, stop scanning */
3858 if (!valid_integer) {
3859 /* the result is not a valid integer */
3860 base->state |= IOSTATE_failbit;
3861 /* put any extracted character back into the stream */
3862 while (i > 0)
3863 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3864 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3865 } else if (ch == EOF) {
3866 base->state |= IOSTATE_eofbit;
3867 if (scan_x && !(base->flags & ios_basefield)) {
3868 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3869 num_base = 0;
3872 break;
3874 str[i++] = ch;
3876 /* append a null terminator */
3877 str[i] = 0;
3878 istream_isfx(this);
3880 return num_base;
3883 /* ?getdouble@istream@@AAEHPADH@Z */
3884 /* ?getdouble@istream@@AEAAHPEADH@Z */
3885 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3886 int __thiscall istream_getdouble(istream *this, char *str, int count)
3888 ios *base = istream_get_ios(this);
3889 int ch, i = 0;
3890 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3891 valid_mantissa = FALSE, valid_exponent = FALSE;
3893 TRACE("(%p %p %d)\n", this, str, count);
3895 if (istream_ipfx(this, 0)) {
3896 if (!count) {
3897 /* can't output anything */
3898 base->state |= IOSTATE_failbit;
3899 i = -1;
3900 } else {
3901 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3902 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3903 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3904 if ((ch == '+' || ch == '-') && scan_sign) {
3905 /* no additional sign allowed */
3906 scan_sign = FALSE;
3907 } else if (ch == '.' && scan_dot) {
3908 /* no sign or additional dot allowed */
3909 scan_sign = scan_dot = FALSE;
3910 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3911 /* sign is allowed again but not dots or exponents */
3912 scan_sign = TRUE;
3913 scan_dot = scan_exp = FALSE;
3914 } else if (isdigit(ch)) {
3915 if (scan_exp)
3916 valid_mantissa = TRUE;
3917 else
3918 valid_exponent = TRUE;
3919 /* no sign allowed after a digit */
3920 scan_sign = FALSE;
3921 } else {
3922 /* unexpected character, stop scanning */
3923 /* check whether the result is a valid double */
3924 if (!scan_exp && !valid_exponent) {
3925 /* put the last character back into the stream, usually the 'e' or 'E' */
3926 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3927 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3928 } else if (ch == EOF)
3929 base->state |= IOSTATE_eofbit;
3930 if (!valid_mantissa)
3931 base->state |= IOSTATE_failbit;
3932 break;
3934 str[i++] = ch;
3936 /* check if character limit has been reached */
3937 if (i == count) {
3938 base->state |= IOSTATE_failbit;
3939 i--;
3941 /* append a null terminator */
3942 str[i] = 0;
3944 istream_isfx(this);
3946 return i;
3949 /* ??5istream@@QAEAAV0@AAC@Z */
3950 /* ??5istream@@QEAAAEAV0@AEAC@Z */
3951 /* ??5istream@@QAEAAV0@AAD@Z */
3952 /* ??5istream@@QEAAAEAV0@AEAD@Z */
3953 /* ??5istream@@QAEAAV0@AAE@Z */
3954 /* ??5istream@@QEAAAEAV0@AEAE@Z */
3955 DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
3956 istream* __thiscall istream_read_char(istream *this, char *ch)
3958 ios *base = istream_get_ios(this);
3959 int ret;
3961 TRACE("(%p %p)\n", this, ch);
3963 if (istream_ipfx(this, 0)) {
3964 if ((ret = streambuf_sbumpc(base->sb)) == EOF)
3965 base->state |= IOSTATE_eofbit | IOSTATE_failbit;
3966 else
3967 *ch = ret;
3968 istream_isfx(this);
3970 return this;
3973 /* ??5istream@@QAEAAV0@PAC@Z */
3974 /* ??5istream@@QEAAAEAV0@PEAC@Z */
3975 /* ??5istream@@QAEAAV0@PAD@Z */
3976 /* ??5istream@@QEAAAEAV0@PEAD@Z */
3977 /* ??5istream@@QAEAAV0@PAE@Z */
3978 /* ??5istream@@QEAAAEAV0@PEAE@Z */
3979 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
3980 istream* __thiscall istream_read_str(istream *this, char *str)
3982 ios *base = istream_get_ios(this);
3983 int ch, count = 0;
3985 TRACE("(%p %p)\n", this, str);
3987 if (istream_ipfx(this, 0)) {
3988 if (str) {
3989 for (ch = streambuf_sgetc(base->sb);
3990 count < (unsigned int) base->width - 1 && !isspace(ch);
3991 ch = streambuf_snextc(base->sb)) {
3992 if (ch == EOF) {
3993 base->state |= IOSTATE_eofbit;
3994 break;
3996 str[count++] = ch;
3999 if (!count) /* nothing to output */
4000 base->state |= IOSTATE_failbit;
4001 else /* append a null terminator */
4002 str[count] = 0;
4003 base->width = 0;
4004 istream_isfx(this);
4006 return this;
4009 static LONG istream_internal_read_integer(istream *this, LONG min_value, LONG max_value, BOOL set_flag)
4011 ios *base = istream_get_ios(this);
4012 char buffer[16];
4013 int num_base;
4014 LONG ret;
4016 TRACE("(%p %ld %ld %d)\n", this, min_value, max_value, set_flag);
4018 num_base = istream_getint(this, buffer);
4019 errno = 0;
4020 ret = strtol(buffer, NULL, num_base);
4021 /* check for overflow and whether the value fits in the output var */
4022 if (set_flag && errno == ERANGE) {
4023 base->state |= IOSTATE_failbit;
4024 } else if (ret > max_value) {
4025 base->state |= IOSTATE_failbit;
4026 ret = max_value;
4027 } else if (ret < min_value) {
4028 base->state |= IOSTATE_failbit;
4029 ret = min_value;
4031 return ret;
4034 static ULONG istream_internal_read_unsigned_integer(istream *this, LONG min_value, ULONG max_value)
4036 ios *base = istream_get_ios(this);
4037 char buffer[16];
4038 int num_base;
4039 ULONG ret;
4041 TRACE("(%p %ld %lu)\n", this, min_value, max_value);
4043 num_base = istream_getint(this, buffer);
4044 errno = 0;
4045 ret = strtoul(buffer, NULL, num_base);
4046 /* check for overflow and whether the value fits in the output var */
4047 if ((ret == ULONG_MAX && errno == ERANGE) ||
4048 (ret > max_value && ret < (ULONG) min_value)) {
4049 base->state |= IOSTATE_failbit;
4050 ret = max_value;
4052 return ret;
4055 /* ??5istream@@QAEAAV0@AAF@Z */
4056 /* ??5istream@@QEAAAEAV0@AEAF@Z */
4057 DEFINE_THISCALL_WRAPPER(istream_read_short, 8)
4058 istream* __thiscall istream_read_short(istream *this, short *p)
4060 if (istream_ipfx(this, 0)) {
4061 *p = istream_internal_read_integer(this, SHRT_MIN, SHRT_MAX, FALSE);
4062 istream_isfx(this);
4064 return this;
4067 /* ??5istream@@QAEAAV0@AAG@Z */
4068 /* ??5istream@@QEAAAEAV0@AEAG@Z */
4069 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_short, 8)
4070 istream* __thiscall istream_read_unsigned_short(istream *this, unsigned short *p)
4072 if (istream_ipfx(this, 0)) {
4073 *p = istream_internal_read_unsigned_integer(this, SHRT_MIN, USHRT_MAX);
4074 istream_isfx(this);
4076 return this;
4079 /* ??5istream@@QAEAAV0@AAH@Z */
4080 /* ??5istream@@QEAAAEAV0@AEAH@Z */
4081 DEFINE_THISCALL_WRAPPER(istream_read_int, 8)
4082 istream* __thiscall istream_read_int(istream *this, int *p)
4084 if (istream_ipfx(this, 0)) {
4085 *p = istream_internal_read_integer(this, INT_MIN, INT_MAX, FALSE);
4086 istream_isfx(this);
4088 return this;
4091 /* ??5istream@@QAEAAV0@AAI@Z */
4092 /* ??5istream@@QEAAAEAV0@AEAI@Z */
4093 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_int, 8)
4094 istream* __thiscall istream_read_unsigned_int(istream *this, unsigned int *p)
4096 if (istream_ipfx(this, 0)) {
4097 *p = istream_internal_read_unsigned_integer(this, INT_MIN, UINT_MAX);
4098 istream_isfx(this);
4100 return this;
4103 /* ??5istream@@QAEAAV0@AAJ@Z */
4104 /* ??5istream@@QEAAAEAV0@AEAJ@Z */
4105 DEFINE_THISCALL_WRAPPER(istream_read_long, 8)
4106 istream* __thiscall istream_read_long(istream *this, LONG *p)
4108 if (istream_ipfx(this, 0)) {
4109 *p = istream_internal_read_integer(this, LONG_MIN, LONG_MAX, TRUE);
4110 istream_isfx(this);
4112 return this;
4115 /* ??5istream@@QAEAAV0@AAK@Z */
4116 /* ??5istream@@QEAAAEAV0@AEAK@Z */
4117 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_long, 8)
4118 istream* __thiscall istream_read_unsigned_long(istream *this, ULONG *p)
4120 if (istream_ipfx(this, 0)) {
4121 *p = istream_internal_read_unsigned_integer(this, LONG_MIN, ULONG_MAX);
4122 istream_isfx(this);
4124 return this;
4127 static BOOL istream_internal_read_float(istream *this, int max_chars, double *out)
4129 char buffer[32];
4130 BOOL read = FALSE;
4132 TRACE("(%p %d %p)\n", this, max_chars, out);
4134 if (istream_ipfx(this, 0)) {
4135 /* character count is limited on Windows */
4136 if (istream_getdouble(this, buffer, max_chars) > 0) {
4137 *out = strtod(buffer, NULL);
4138 read = TRUE;
4140 istream_isfx(this);
4142 return read;
4145 /* ??5istream@@QAEAAV0@AAM@Z */
4146 /* ??5istream@@QEAAAEAV0@AEAM@Z */
4147 DEFINE_THISCALL_WRAPPER(istream_read_float, 8)
4148 istream* __thiscall istream_read_float(istream *this, float *f)
4150 double tmp;
4151 if (istream_internal_read_float(this, 20, &tmp)) {
4152 /* check whether the value fits in the output var */
4153 if (tmp > FLT_MAX)
4154 tmp = FLT_MAX;
4155 else if (tmp < -FLT_MAX)
4156 tmp = -FLT_MAX;
4157 else if (tmp > 0 && tmp < FLT_MIN)
4158 tmp = FLT_MIN;
4159 else if (tmp < 0 && tmp > -FLT_MIN)
4160 tmp = -FLT_MIN;
4161 *f = tmp;
4163 return this;
4166 /* ??5istream@@QAEAAV0@AAN@Z */
4167 /* ??5istream@@QEAAAEAV0@AEAN@Z */
4168 DEFINE_THISCALL_WRAPPER(istream_read_double, 8)
4169 istream* __thiscall istream_read_double(istream *this, double *d)
4171 istream_internal_read_float(this, 28, d);
4172 return this;
4175 /* ??5istream@@QAEAAV0@AAO@Z */
4176 /* ??5istream@@QEAAAEAV0@AEAO@Z */
4177 DEFINE_THISCALL_WRAPPER(istream_read_long_double, 8)
4178 istream* __thiscall istream_read_long_double(istream *this, double *ld)
4180 istream_internal_read_float(this, 32, ld);
4181 return this;
4184 /* ??5istream@@QAEAAV0@PAVstreambuf@@@Z */
4185 /* ??5istream@@QEAAAEAV0@PEAVstreambuf@@@Z */
4186 DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
4187 istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
4189 ios *base = istream_get_ios(this);
4190 int ch;
4192 TRACE("(%p %p)\n", this, sb);
4194 if (istream_ipfx(this, 0)) {
4195 while ((ch = streambuf_sbumpc(base->sb)) != EOF)
4196 if (streambuf_sputc(sb, ch) == EOF)
4197 base->state |= IOSTATE_failbit;
4198 istream_isfx(this);
4200 return this;
4203 /* ??5istream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
4204 /* ??5istream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
4205 DEFINE_THISCALL_WRAPPER(istream_read_manip, 8)
4206 istream* __thiscall istream_read_manip(istream *this, istream* (__cdecl *func)(istream*))
4208 TRACE("(%p %p)\n", this, func);
4209 return func(this);
4212 /* ??5istream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
4213 /* ??5istream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
4214 DEFINE_THISCALL_WRAPPER(istream_read_ios_manip, 8)
4215 istream* __thiscall istream_read_ios_manip(istream *this, ios* (__cdecl *func)(ios*))
4217 TRACE("(%p %p)\n", this, func);
4218 func(istream_get_ios(this));
4219 return this;
4222 /* ?ws@@YAAAVistream@@AAV1@@Z */
4223 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
4224 istream* __cdecl istream_ws(istream *this)
4226 TRACE("(%p)\n", this);
4227 istream_eatwhite(this);
4228 return this;
4231 /* ??0istream_withassign@@QAE@ABV0@@Z */
4232 /* ??0istream_withassign@@QEAA@AEBV0@@Z */
4233 DEFINE_THISCALL_WRAPPER(istream_withassign_copy_ctor, 12)
4234 istream* __thiscall istream_withassign_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
4236 ios *base, *base_copy;
4238 TRACE("(%p %p %d)\n", this, copy, virt_init);
4240 base_copy = istream_get_ios(copy);
4241 if (virt_init) {
4242 this->vbtable = istream_vbtable;
4243 base = istream_get_ios(this);
4244 ios_copy_ctor(base, base_copy);
4245 } else
4246 base = istream_get_ios(this);
4247 ios_init(base, base_copy->sb);
4248 base->vtable = &istream_withassign_vtable;
4249 base->flags |= FLAGS_skipws;
4250 this->extract_delim = 0;
4251 this->count = 0;
4252 return this;
4255 /* ??0istream_withassign@@QAE@PAVstreambuf@@@Z */
4256 /* ??0istream_withassign@@QEAA@PEAVstreambuf@@@Z */
4257 DEFINE_THISCALL_WRAPPER(istream_withassign_sb_ctor, 12)
4258 istream* __thiscall istream_withassign_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
4260 ios *base;
4262 TRACE("(%p %p %d)\n", this, sb, virt_init);
4264 istream_sb_ctor(this, sb, virt_init);
4265 base = istream_get_ios(this);
4266 base->vtable = &istream_withassign_vtable;
4267 return this;
4270 /* ??0istream_withassign@@QAE@XZ */
4271 /* ??0istream_withassign@@QEAA@XZ */
4272 DEFINE_THISCALL_WRAPPER(istream_withassign_ctor, 8)
4273 istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init)
4275 ios *base;
4277 TRACE("(%p %d)\n", this, virt_init);
4279 istream_ctor(this, virt_init);
4280 base = istream_get_ios(this);
4281 base->vtable = &istream_withassign_vtable;
4282 return this;
4285 /* ??0istrstream@@QAE@ABV0@@Z */
4286 /* ??0istrstream@@QEAA@AEBV0@@Z */
4287 DEFINE_THISCALL_WRAPPER(istrstream_copy_ctor, 12)
4288 istream* __thiscall istrstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
4290 TRACE("(%p %p %d)\n", this, copy, virt_init);
4291 istream_withassign_copy_ctor(this, copy, virt_init);
4292 istream_get_ios(this)->vtable = &istrstream_vtable;
4293 return this;
4296 /* ??0istrstream@@QAE@PADH@Z */
4297 /* ??0istrstream@@QEAA@PEADH@Z */
4298 DEFINE_THISCALL_WRAPPER(istrstream_buffer_ctor, 16)
4299 istream* __thiscall istrstream_buffer_ctor(istream *this, char *buffer, int length, BOOL virt_init)
4301 ios *base;
4302 strstreambuf *ssb = operator_new(sizeof(strstreambuf));
4304 TRACE("(%p %p %d %d)\n", this, buffer, length, virt_init);
4306 if (!ssb) {
4307 FIXME("out of memory\n");
4308 return NULL;
4311 strstreambuf_buffer_ctor(ssb, buffer, length, NULL);
4312 istream_sb_ctor(this, &ssb->base, virt_init);
4314 base = istream_get_ios(this);
4315 base->vtable = &istrstream_vtable;
4316 base->delbuf = 1;
4317 return this;
4320 /* ??0istrstream@@QAE@PAD@Z */
4321 /* ??0istrstream@@QEAA@PEAD@Z */
4322 DEFINE_THISCALL_WRAPPER(istrstream_str_ctor, 12)
4323 istream* __thiscall istrstream_str_ctor(istream *this, char *str, BOOL virt_init)
4325 return istrstream_buffer_ctor(this, str, 0, virt_init);
4328 /* ?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ */
4329 /* ?rdbuf@istrstream@@QEBAPEAVstrstreambuf@@XZ */
4330 DEFINE_THISCALL_WRAPPER(istrstream_rdbuf, 4)
4331 strstreambuf* __thiscall istrstream_rdbuf(const istream *this)
4333 return (strstreambuf*) istream_get_ios(this)->sb;
4336 /* ?str@istrstream@@QAEPADXZ */
4337 /* ?str@istrstream@@QEAAPEADXZ */
4338 DEFINE_THISCALL_WRAPPER(istrstream_str, 4)
4339 char* __thiscall istrstream_str(istream *this)
4341 return strstreambuf_str(istrstream_rdbuf(this));
4344 /* ??0ifstream@@QAE@ABV0@@Z */
4345 /* ??0ifstream@@QEAA@AEBV0@@Z */
4346 DEFINE_THISCALL_WRAPPER(ifstream_copy_ctor, 12)
4347 istream* __thiscall ifstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
4349 TRACE("(%p %p %d)\n", this, copy, virt_init);
4350 istream_withassign_copy_ctor(this, copy, virt_init);
4351 istream_get_ios(this)->vtable = &ifstream_vtable;
4352 return this;
4355 /* ??0ifstream@@QAE@HPADH@Z */
4356 /* ??0ifstream@@QEAA@HPEADH@Z */
4357 DEFINE_THISCALL_WRAPPER(ifstream_buffer_ctor, 20)
4358 istream* __thiscall ifstream_buffer_ctor(istream *this, filedesc fd, char *buffer, int length, BOOL virt_init)
4360 ios *base;
4361 filebuf *fb = operator_new(sizeof(filebuf));
4363 TRACE("(%p %d %p %d %d)\n", this, fd, buffer, length, virt_init);
4365 if (!fb) {
4366 FIXME("out of memory\n");
4367 return NULL;
4370 filebuf_fd_reserve_ctor(fb, fd, buffer, length);
4371 istream_sb_ctor(this, &fb->base, virt_init);
4373 base = istream_get_ios(this);
4374 base->vtable = &ifstream_vtable;
4375 base->delbuf = 1;
4377 return this;
4380 /* ??0ifstream@@QAE@H@Z */
4381 /* ??0ifstream@@QEAA@H@Z */
4382 DEFINE_THISCALL_WRAPPER(ifstream_fd_ctor, 12)
4383 istream* __thiscall ifstream_fd_ctor(istream *this, filedesc fd, BOOL virt_init)
4385 ios *base;
4386 filebuf *fb = operator_new(sizeof(filebuf));
4388 TRACE("(%p %d %d)\n", this, fd, virt_init);
4390 if (!fb) {
4391 FIXME("out of memory\n");
4392 return NULL;
4395 filebuf_fd_ctor(fb, fd);
4396 istream_sb_ctor(this, &fb->base, virt_init);
4398 base = istream_get_ios(this);
4399 base->vtable = &ifstream_vtable;
4400 base->delbuf = 1;
4402 return this;
4405 /* ??0ifstream@@QAE@PBDHH@Z */
4406 /* ??0ifstream@@QEAA@PEBDHH@Z */
4407 DEFINE_THISCALL_WRAPPER(ifstream_open_ctor, 20)
4408 istream* __thiscall ifstream_open_ctor(istream *this, const char *name, ios_open_mode mode, int protection, BOOL virt_init)
4410 ios *base;
4411 filebuf *fb = operator_new(sizeof(filebuf));
4413 TRACE("(%p %s %d %d %d)\n", this, name, mode, protection, virt_init);
4415 if (!fb) {
4416 FIXME("out of memory\n");
4417 return NULL;
4420 filebuf_ctor(fb);
4421 istream_sb_ctor(this, &fb->base, virt_init);
4423 base = istream_get_ios(this);
4424 base->vtable = &ifstream_vtable;
4425 base->delbuf = 1;
4427 if (filebuf_open(fb, name, mode|OPENMODE_in, protection) == NULL)
4428 base->state |= IOSTATE_failbit;
4429 return this;
4432 /* ??0ifstream@@QAE@XZ */
4433 /* ??0ifstream@@QEAA@XZ */
4434 DEFINE_THISCALL_WRAPPER(ifstream_ctor, 8)
4435 istream* __thiscall ifstream_ctor(istream *this, BOOL virt_init)
4437 return ifstream_fd_ctor(this, -1, virt_init);
4440 /* ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ */
4441 /* ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ */
4442 DEFINE_THISCALL_WRAPPER(ifstream_rdbuf, 4)
4443 filebuf* __thiscall ifstream_rdbuf(const istream *this)
4445 TRACE("(%p)\n", this);
4446 return (filebuf*) istream_get_ios(this)->sb;
4449 /* ?fd@ifstream@@QBEHXZ */
4450 /* ?fd@ifstream@@QEBAHXZ */
4451 DEFINE_THISCALL_WRAPPER(ifstream_fd, 4)
4452 filedesc __thiscall ifstream_fd(istream *this)
4454 TRACE("(%p)\n", this);
4455 return filebuf_fd(ifstream_rdbuf(this));
4458 /* ?attach@ifstream@@QAEXH@Z */
4459 /* ?attach@ifstream@@QEAAXH@Z */
4460 DEFINE_THISCALL_WRAPPER(ifstream_attach, 8)
4461 void __thiscall ifstream_attach(istream *this, filedesc fd)
4463 ios *base = istream_get_ios(this);
4464 TRACE("(%p %d)\n", this, fd);
4465 if (filebuf_attach(ifstream_rdbuf(this), fd) == NULL)
4466 ios_clear(base, base->state | IOSTATE_failbit);
4469 /* ?close@ifstream@@QAEXXZ */
4470 /* ?close@ifstream@@QEAAXXZ */
4471 DEFINE_THISCALL_WRAPPER(ifstream_close, 4)
4472 void __thiscall ifstream_close(istream *this)
4474 ios *base = istream_get_ios(this);
4475 TRACE("(%p)\n", this);
4476 if (filebuf_close(ifstream_rdbuf(this)) == NULL)
4477 ios_clear(base, base->state | IOSTATE_failbit);
4478 else
4479 ios_clear(base, IOSTATE_goodbit);
4482 /* ?is_open@ifstream@@QBEHXZ */
4483 /* ?is_open@ifstream@@QEBAHXZ */
4484 DEFINE_THISCALL_WRAPPER(ifstream_is_open, 4)
4485 int __thiscall ifstream_is_open(const istream *this)
4487 TRACE("(%p)\n", this);
4488 return filebuf_is_open(ifstream_rdbuf(this));
4491 /* ?open@ifstream@@QAEXPBDHH@Z */
4492 /* ?open@ifstream@@QEAAXPEBDHH@Z */
4493 DEFINE_THISCALL_WRAPPER(ifstream_open, 16)
4494 void __thiscall ifstream_open(istream *this, const char *name, ios_open_mode mode, int protection)
4496 ios *base = istream_get_ios(this);
4497 TRACE("(%p %s %d %d)\n", this, name, mode, protection);
4498 if (filebuf_open(ifstream_rdbuf(this), name, mode|OPENMODE_in, protection) == NULL)
4499 ios_clear(base, base->state | IOSTATE_failbit);
4502 /* ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z */
4503 /* ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z */
4504 DEFINE_THISCALL_WRAPPER(ifstream_setbuf, 12)
4505 streambuf* __thiscall ifstream_setbuf(istream *this, char *buffer, int length)
4507 ios *base = istream_get_ios(this);
4508 filebuf* fb = ifstream_rdbuf(this);
4510 TRACE("(%p %p %d)\n", this, buffer, length);
4512 if (filebuf_is_open(fb)) {
4513 ios_clear(base, base->state | IOSTATE_failbit);
4514 return NULL;
4517 return filebuf_setbuf(fb, buffer, length);
4520 /* ?setmode@ifstream@@QAEHH@Z */
4521 /* ?setmode@ifstream@@QEAAHH@Z */
4522 DEFINE_THISCALL_WRAPPER(ifstream_setmode, 8)
4523 int __thiscall ifstream_setmode(istream *this, int mode)
4525 TRACE("(%p %d)\n", this, mode);
4526 return filebuf_setmode(ifstream_rdbuf(this), mode);
4529 static inline ios* iostream_to_ios(const iostream *this)
4531 return (ios*)((char*)this + iostream_vbtable_istream[1]);
4534 static inline iostream* ios_to_iostream(const ios *base)
4536 return (iostream*)((char*)base - iostream_vbtable_istream[1]);
4539 /* ??0iostream@@IAE@XZ */
4540 /* ??0iostream@@IEAA@XZ */
4541 DEFINE_THISCALL_WRAPPER(iostream_ctor, 8)
4542 iostream* __thiscall iostream_ctor(iostream *this, BOOL virt_init)
4544 ios *base;
4546 TRACE("(%p %d)\n", this, virt_init);
4548 if (virt_init) {
4549 this->base1.vbtable = iostream_vbtable_istream;
4550 this->base2.vbtable = iostream_vbtable_ostream;
4551 base = istream_get_ios(&this->base1);
4552 ios_ctor(base);
4553 } else
4554 base = istream_get_ios(&this->base1);
4555 istream_ctor(&this->base1, FALSE);
4556 ostream_ctor(&this->base2, FALSE);
4557 base->vtable = &iostream_vtable;
4558 return this;
4561 /* ??0iostream@@QAE@PAVstreambuf@@@Z */
4562 /* ??0iostream@@QEAA@PEAVstreambuf@@@Z */
4563 DEFINE_THISCALL_WRAPPER(iostream_sb_ctor, 12)
4564 iostream* __thiscall iostream_sb_ctor(iostream *this, streambuf *sb, BOOL virt_init)
4566 TRACE("(%p %p %d)\n", this, sb, virt_init);
4567 iostream_ctor(this, virt_init);
4568 ios_init(istream_get_ios(&this->base1), sb);
4569 return this;
4572 /* ??0iostream@@IAE@ABV0@@Z */
4573 /* ??0iostream@@IEAA@AEBV0@@Z */
4574 DEFINE_THISCALL_WRAPPER(iostream_copy_ctor, 12)
4575 iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4577 return iostream_sb_ctor(this, istream_get_ios(&copy->base1)->sb, virt_init);
4580 /* ??1iostream@@UAE@XZ */
4581 /* ??1iostream@@UEAA@XZ */
4582 /* ??1stdiostream@@UAE@XZ */
4583 /* ??1stdiostream@@UEAA@XZ */
4584 /* ??1strstream@@UAE@XZ */
4585 /* ??1strstream@@UEAA@XZ */
4586 /* ??1fstream@@UAE@XZ */
4587 /* ??1fstream@@UEAA@XZ */
4588 DEFINE_THISCALL_WRAPPER(iostream_dtor, 4)
4589 void __thiscall iostream_dtor(ios *base)
4591 iostream *this = ios_to_iostream(base);
4593 TRACE("(%p)\n", this);
4595 ostream_dtor(ostream_to_ios(&this->base2));
4596 istream_dtor(istream_to_ios(&this->base1));
4599 /* ??4iostream@@IAEAAV0@PAVstreambuf@@@Z */
4600 /* ??4iostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
4601 DEFINE_THISCALL_WRAPPER(iostream_assign_sb, 8)
4602 iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb)
4604 TRACE("(%p %p)\n", this, sb);
4605 this->base1.count = 0;
4606 ostream_assign_sb(&this->base2, sb);
4607 return this;
4610 /* ??4iostream@@IAEAAV0@AAV0@@Z */
4611 /* ??4iostream@@IEAAAEAV0@AEAV0@@Z */
4612 /* ??4stdiostream@@QAEAAV0@AAV0@@Z */
4613 /* ??4stdiostream@@QEAAAEAV0@AEAV0@@Z */
4614 /* ??4strstream@@QAEAAV0@ABV0@@Z */
4615 /* ??4strstream@@QEAAAEAV0@AEBV0@@Z */
4616 DEFINE_THISCALL_WRAPPER(iostream_assign, 8)
4617 iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs)
4619 return iostream_assign_sb(this, istream_get_ios(&rhs->base1)->sb);
4622 /* ??_Diostream@@QAEXXZ */
4623 /* ??_Diostream@@QEAAXXZ */
4624 /* ??_Dstdiostream@@QAEXXZ */
4625 /* ??_Dstdiostream@@QEAAXXZ */
4626 /* ??_Dstrstream@@QAEXXZ */
4627 /* ??_Dstrstream@@QEAAXXZ */
4628 DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4)
4629 void __thiscall iostream_vbase_dtor(iostream *this)
4631 ios *base = iostream_to_ios(this);
4633 TRACE("(%p)\n", this);
4635 iostream_dtor(base);
4636 ios_dtor(base);
4639 /* ??_Eiostream@@UAEPAXI@Z */
4640 /* ??_Estdiostream@@UAEPAXI@Z */
4641 /* ??_Estrstream@@UAEPAXI@Z */
4642 DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8)
4643 iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags)
4645 iostream *this = ios_to_iostream(base);
4647 TRACE("(%p %x)\n", this, flags);
4649 if (flags & 2) {
4650 /* we have an array, with the number of elements stored before the first object */
4651 INT_PTR i, *ptr = (INT_PTR *)this-1;
4653 for (i = *ptr-1; i >= 0; i--)
4654 iostream_vbase_dtor(this+i);
4655 operator_delete(ptr);
4656 } else {
4657 iostream_vbase_dtor(this);
4658 if (flags & 1)
4659 operator_delete(this);
4661 return this;
4664 /* ??_Giostream@@UAEPAXI@Z */
4665 /* ??_Gstdiostream@@UAEPAXI@Z */
4666 /* ??_Gstrstream@@UAEPAXI@Z */
4667 DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8)
4668 iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags)
4670 iostream *this = ios_to_iostream(base);
4672 TRACE("(%p %x)\n", this, flags);
4674 iostream_vbase_dtor(this);
4675 if (flags & 1) operator_delete(this);
4676 return this;
4679 static iostream* iostream_internal_copy_ctor(iostream *this, const iostream *copy, const vtable_ptr *vtbl, BOOL virt_init)
4681 ios *base, *base_copy = istream_get_ios(&copy->base1);
4683 if (virt_init) {
4684 this->base1.vbtable = iostream_vbtable_istream;
4685 this->base2.vbtable = iostream_vbtable_ostream;
4686 base = istream_get_ios(&this->base1);
4687 ios_copy_ctor(base, base_copy);
4688 } else
4689 base = istream_get_ios(&this->base1);
4690 ios_init(base, base_copy->sb);
4691 istream_ctor(&this->base1, FALSE);
4692 ostream_ctor(&this->base2, FALSE);
4693 base->vtable = vtbl;
4694 return this;
4697 static iostream* iostream_internal_sb_ctor(iostream *this, streambuf *sb, const vtable_ptr *vtbl, BOOL virt_init)
4699 ios *base;
4701 iostream_ctor(this, virt_init);
4702 base = istream_get_ios(&this->base1);
4703 if (sb)
4704 ios_init(base, sb);
4705 base->vtable = vtbl;
4706 base->delbuf = 1;
4707 return this;
4710 /* ??0strstream@@QAE@ABV0@@Z */
4711 /* ??0strstream@@QEAA@AEBV0@@Z */
4712 DEFINE_THISCALL_WRAPPER(strstream_copy_ctor, 12)
4713 iostream* __thiscall strstream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4715 TRACE("(%p %p %d)\n", this, copy, virt_init);
4716 return iostream_internal_copy_ctor(this, copy, &strstream_vtable, virt_init);
4719 /* ??0strstream@@QAE@PADHH@Z */
4720 /* ??0strstream@@QEAA@PEADHH@Z */
4721 DEFINE_THISCALL_WRAPPER(strstream_buffer_ctor, 20)
4722 iostream* __thiscall strstream_buffer_ctor(iostream *this, char *buffer, int length, int mode, BOOL virt_init)
4724 strstreambuf *ssb = operator_new(sizeof(strstreambuf));
4726 TRACE("(%p %p %d %d %d)\n", this, buffer, length, mode, virt_init);
4728 if (!ssb) {
4729 FIXME("out of memory\n");
4730 return NULL;
4733 strstreambuf_buffer_ctor(ssb, buffer, length, buffer);
4735 if ((mode & OPENMODE_out) && (mode & (OPENMODE_app|OPENMODE_ate)))
4736 ssb->base.pptr = buffer + strlen(buffer);
4738 return iostream_internal_sb_ctor(this, &ssb->base, &strstream_vtable, virt_init);
4741 /* ??0strstream@@QAE@XZ */
4742 /* ??0strstream@@QEAA@XZ */
4743 DEFINE_THISCALL_WRAPPER(strstream_ctor, 8)
4744 iostream* __thiscall strstream_ctor(iostream *this, BOOL virt_init)
4746 strstreambuf *ssb = operator_new(sizeof(strstreambuf));
4748 TRACE("(%p %d)\n", this, virt_init);
4750 if (!ssb) {
4751 FIXME("out of memory\n");
4752 return NULL;
4755 strstreambuf_ctor(ssb);
4757 return iostream_internal_sb_ctor(this, &ssb->base, &strstream_vtable, virt_init);
4760 /* ?pcount@strstream@@QBEHXZ */
4761 /* ?pcount@strstream@@QEBAHXZ */
4762 DEFINE_THISCALL_WRAPPER(strstream_pcount, 4)
4763 int __thiscall strstream_pcount(const iostream *this)
4765 return streambuf_out_waiting(istream_get_ios(&this->base1)->sb);
4768 /* ?rdbuf@strstream@@QBEPAVstrstreambuf@@XZ */
4769 /* ?rdbuf@strstream@@QEBAPEAVstrstreambuf@@XZ */
4770 DEFINE_THISCALL_WRAPPER(strstream_rdbuf, 4)
4771 strstreambuf* __thiscall strstream_rdbuf(const iostream *this)
4773 return (strstreambuf*) istream_get_ios(&this->base1)->sb;
4776 /* ?str@strstream@@QAEPADXZ */
4777 /* ?str@strstream@@QEAAPEADXZ */
4778 DEFINE_THISCALL_WRAPPER(strstream_str, 4)
4779 char* __thiscall strstream_str(iostream *this)
4781 return strstreambuf_str(strstream_rdbuf(this));
4784 /* ??0stdiostream@@QAE@ABV0@@Z */
4785 /* ??0stdiostream@@QEAA@AEBV0@@Z */
4786 DEFINE_THISCALL_WRAPPER(stdiostream_copy_ctor, 12)
4787 iostream* __thiscall stdiostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4789 TRACE("(%p %p %d)\n", this, copy, virt_init);
4790 return iostream_internal_copy_ctor(this, copy, &stdiostream_vtable, virt_init);
4793 /* ??0stdiostream@@QAE@PAU_iobuf@@@Z */
4794 /* ??0stdiostream@@QEAA@PEAU_iobuf@@@Z */
4795 DEFINE_THISCALL_WRAPPER(stdiostream_file_ctor, 12)
4796 iostream* __thiscall stdiostream_file_ctor(iostream *this, FILE *file, BOOL virt_init)
4798 stdiobuf *stb = operator_new(sizeof(stdiobuf));
4800 TRACE("(%p %p %d)\n", this, file, virt_init);
4802 if (!stb) {
4803 FIXME("out of memory\n");
4804 return NULL;
4807 stdiobuf_file_ctor(stb, file);
4809 return iostream_internal_sb_ctor(this, &stb->base, &stdiostream_vtable, virt_init);
4812 /* ?rdbuf@stdiostream@@QBEPAVstdiobuf@@XZ */
4813 /* ?rdbuf@stdiostream@@QEBAPEAVstdiobuf@@XZ */
4814 DEFINE_THISCALL_WRAPPER(stdiostream_rdbuf, 4)
4815 stdiobuf* __thiscall stdiostream_rdbuf(const iostream *this)
4817 return (stdiobuf*) istream_get_ios(&this->base1)->sb;
4820 /* ??0fstream@@QAE@ABV0@@Z */
4821 /* ??0fstream@@QEAA@AEBV0@@Z */
4822 DEFINE_THISCALL_WRAPPER(fstream_copy_ctor, 12)
4823 iostream* __thiscall fstream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
4825 TRACE("(%p %p %d)\n", this, copy, virt_init);
4826 iostream_internal_copy_ctor(this, copy, &fstream_vtable, virt_init);
4827 return this;
4830 /* ??0fstream@@QAE@HPADH@Z */
4831 /* ??0fstream@@QEAA@HPEADH@Z */
4832 DEFINE_THISCALL_WRAPPER(fstream_buffer_ctor, 20)
4833 iostream* __thiscall fstream_buffer_ctor(iostream *this, filedesc fd, char *buffer, int length, BOOL virt_init)
4835 ios *base;
4836 filebuf *fb = operator_new(sizeof(filebuf));
4838 TRACE("(%p %d %p %d %d)\n", this, fd, buffer, length, virt_init);
4840 if (!fb) {
4841 FIXME("out of memory\n");
4842 return NULL;
4845 filebuf_fd_reserve_ctor(fb, fd, buffer, length);
4847 iostream_internal_sb_ctor(this, &fb->base, &fstream_vtable, virt_init);
4849 base = istream_get_ios(&this->base1);
4850 base->delbuf = 1;
4852 return this;
4855 /* ??0fstream@@QAE@H@Z */
4856 /* ??0fstream@@QEAA@H@Z */
4857 DEFINE_THISCALL_WRAPPER(fstream_fd_ctor, 12)
4858 iostream* __thiscall fstream_fd_ctor(iostream *this, filedesc fd, BOOL virt_init)
4860 ios *base;
4861 filebuf *fb = operator_new(sizeof(filebuf));
4863 TRACE("(%p %d %d)\n", this, fd, virt_init);
4865 if (!fb) {
4866 FIXME("out of memory\n");
4867 return NULL;
4870 filebuf_fd_ctor(fb, fd);
4872 iostream_internal_sb_ctor(this, &fb->base, &fstream_vtable, virt_init);
4874 base = istream_get_ios(&this->base1);
4875 base->delbuf = 1;
4877 return this;
4880 /* ??0fstream@@QAE@PBDHH@Z */
4881 /* ??0fstream@@QEAA@PEBDHH@Z */
4882 DEFINE_THISCALL_WRAPPER(fstream_open_ctor, 20)
4883 iostream* __thiscall fstream_open_ctor(iostream *this, const char *name, ios_open_mode mode, int protection, BOOL virt_init)
4885 ios *base;
4886 filebuf *fb = operator_new(sizeof(filebuf));
4888 TRACE("(%p %s %d %d %d)\n", this, name, mode, protection, virt_init);
4890 if (!fb) {
4891 FIXME("out of memory\n");
4892 return NULL;
4895 filebuf_ctor(fb);
4897 iostream_internal_sb_ctor(this, &fb->base, &fstream_vtable, virt_init);
4899 base = istream_get_ios(&this->base1);
4900 base->delbuf = 1;
4902 if (filebuf_open(fb, name, mode, protection) == NULL)
4903 base->state |= IOSTATE_failbit;
4904 return this;
4907 /* ??0fstream@@QAE@XZ */
4908 /* ??0fstream@@QEAA@XZ */
4909 DEFINE_THISCALL_WRAPPER(fstream_ctor, 8)
4910 iostream* __thiscall fstream_ctor(iostream *this, BOOL virt_init)
4912 return fstream_fd_ctor(this, -1, virt_init);
4915 /* ?rdbuf@fstream@@QBEPAVfilebuf@@XZ */
4916 /* ?rdbuf@fstream@@QEBAPEAVfilebuf@@XZ */
4917 DEFINE_THISCALL_WRAPPER(fstream_rdbuf, 4)
4918 filebuf* __thiscall fstream_rdbuf(const iostream *this)
4920 TRACE("(%p)\n", this);
4921 return (filebuf*) istream_get_ios(&this->base1)->sb;
4924 /* ?fd@fstream@@QBEHXZ */
4925 /* ?fd@fstream@@QEBAHXZ */
4926 DEFINE_THISCALL_WRAPPER(fstream_fd, 4)
4927 filedesc __thiscall fstream_fd(iostream *this)
4929 TRACE("(%p)\n", this);
4930 return filebuf_fd(fstream_rdbuf(this));
4933 /* ?attach@fstream@@QAEXH@Z */
4934 /* ?attach@fstream@@QEAAXH@Z */
4935 DEFINE_THISCALL_WRAPPER(fstream_attach, 8)
4936 void __thiscall fstream_attach(iostream *this, filedesc fd)
4938 ios *base = istream_get_ios(&this->base1);
4939 TRACE("(%p %d)\n", this, fd);
4940 if (filebuf_attach(fstream_rdbuf(this), fd) == NULL)
4941 ios_clear(base, base->state | IOSTATE_failbit);
4944 /* ?close@fstream@@QAEXXZ */
4945 /* ?close@fstream@@QEAAXXZ */
4946 DEFINE_THISCALL_WRAPPER(fstream_close, 4)
4947 void __thiscall fstream_close(iostream *this)
4949 ios *base = istream_get_ios(&this->base1);
4950 TRACE("(%p)\n", this);
4951 if (filebuf_close(fstream_rdbuf(this)) == NULL)
4952 ios_clear(base, base->state | IOSTATE_failbit);
4953 else
4954 ios_clear(base, IOSTATE_goodbit);
4957 /* ?is_open@fstream@@QBEHXZ */
4958 /* ?is_open@fstream@@QEBAHXZ */
4959 DEFINE_THISCALL_WRAPPER(fstream_is_open, 4)
4960 int __thiscall fstream_is_open(const iostream *this)
4962 TRACE("(%p)\n", this);
4963 return filebuf_is_open(fstream_rdbuf(this));
4966 /* ?open@fstream@@QAEXPBDHH@Z */
4967 /* ?open@fstream@@QEAAXPEBDHH@Z */
4968 DEFINE_THISCALL_WRAPPER(fstream_open, 16)
4969 void __thiscall fstream_open(iostream *this, const char *name, ios_open_mode mode, int protection)
4971 ios *base = istream_get_ios(&this->base1);
4972 TRACE("(%p %s %d %d)\n", this, name, mode, protection);
4973 if (filebuf_open(fstream_rdbuf(this), name, mode|OPENMODE_out, protection) == NULL)
4974 ios_clear(base, base->state | IOSTATE_failbit);
4977 /* ?setbuf@fstream@@QAEPAVstreambuf@@PADH@Z */
4978 /* ?setbuf@fstream@@QEAAPEAVstreambuf@@PEADH@Z */
4979 DEFINE_THISCALL_WRAPPER(fstream_setbuf, 12)
4980 streambuf* __thiscall fstream_setbuf(iostream *this, char *buffer, int length)
4982 ios *base = istream_get_ios(&this->base1);
4983 filebuf* fb = fstream_rdbuf(this);
4985 TRACE("(%p %p %d)\n", this, buffer, length);
4987 if (filebuf_is_open(fb)) {
4988 ios_clear(base, base->state | IOSTATE_failbit);
4989 return NULL;
4992 return filebuf_setbuf(fb, buffer, length);
4995 /* ?setmode@fstream@@QAEHH@Z */
4996 /* ?setmode@fstream@@QEAAHH@Z */
4997 DEFINE_THISCALL_WRAPPER(fstream_setmode, 8)
4998 int __thiscall fstream_setmode(iostream *this, int mode)
5000 TRACE("(%p %d)\n", this, mode);
5001 return filebuf_setmode(fstream_rdbuf(this), mode);
5004 /* ??0Iostream_init@@QAE@AAVios@@H@Z */
5005 /* ??0Iostream_init@@QEAA@AEAVios@@H@Z */
5006 DEFINE_THISCALL_WRAPPER(Iostream_init_ios_ctor, 12)
5007 void* __thiscall Iostream_init_ios_ctor(void *this, ios *obj, int n)
5009 TRACE("(%p %p %d)\n", this, obj, n);
5010 obj->delbuf = 1;
5011 if (n >= 0) {
5012 obj->tie = &cout.os;
5013 if (n > 0)
5014 ios_setf(obj, FLAGS_unitbuf);
5016 return this;
5019 /* ??0Iostream_init@@QAE@XZ */
5020 /* ??0Iostream_init@@QEAA@XZ */
5021 DEFINE_THISCALL_WRAPPER(Iostream_init_ctor, 4)
5022 void* __thiscall Iostream_init_ctor(void *this)
5024 TRACE("(%p)\n", this);
5025 return this;
5028 /* ??1Iostream_init@@QAE@XZ */
5029 /* ??1Iostream_init@@QEAA@XZ */
5030 DEFINE_THISCALL_WRAPPER(Iostream_init_dtor, 4)
5031 void __thiscall Iostream_init_dtor(void *this)
5033 TRACE("(%p)\n", this);
5036 /* ??4Iostream_init@@QAEAAV0@ABV0@@Z */
5037 /* ??4Iostream_init@@QEAAAEAV0@AEBV0@@Z */
5038 DEFINE_THISCALL_WRAPPER(Iostream_init_assign, 8)
5039 void* __thiscall Iostream_init_assign(void *this, const void *rhs)
5041 TRACE("(%p %p)\n", this, rhs);
5042 return this;
5045 /* ?sync_with_stdio@ios@@SAXXZ */
5046 void __cdecl ios_sync_with_stdio(void)
5048 if (!ios_sunk_with_stdio) {
5049 stdiobuf *new_buf;
5051 TRACE("()\n");
5053 /* run at most once */
5054 ios_sunk_with_stdio++;
5056 /* calls to [io]stream_assign_sb automatically destroy the old buffers */
5057 if ((new_buf = operator_new(sizeof(stdiobuf)))) {
5058 stdiobuf_file_ctor(new_buf, stdin);
5059 istream_assign_sb(&cin.is, &new_buf->base);
5060 } else
5061 istream_assign_sb(&cin.is, NULL);
5062 cin.vbase.delbuf = 1;
5063 ios_setf(&cin.vbase, FLAGS_stdio);
5065 if ((new_buf = operator_new(sizeof(stdiobuf)))) {
5066 stdiobuf_file_ctor(new_buf, stdout);
5067 stdiobuf_setrwbuf(new_buf, 0, 80);
5068 ostream_assign_sb(&cout.os, &new_buf->base);
5069 } else
5070 ostream_assign_sb(&cout.os, NULL);
5071 cout.vbase.delbuf = 1;
5072 ios_setf(&cout.vbase, FLAGS_unitbuf | FLAGS_stdio);
5074 if ((new_buf = operator_new(sizeof(stdiobuf)))) {
5075 stdiobuf_file_ctor(new_buf, stderr);
5076 stdiobuf_setrwbuf(new_buf, 0, 80);
5077 ostream_assign_sb(&cerr.os, &new_buf->base);
5078 } else
5079 ostream_assign_sb(&cerr.os, NULL);
5080 cerr.vbase.delbuf = 1;
5081 ios_setf(&cerr.vbase, FLAGS_unitbuf | FLAGS_stdio);
5083 if ((new_buf = operator_new(sizeof(stdiobuf)))) {
5084 stdiobuf_file_ctor(new_buf, stderr);
5085 stdiobuf_setrwbuf(new_buf, 0, 512);
5086 ostream_assign_sb(&MSVCP_clog.os, &new_buf->base);
5087 } else
5088 ostream_assign_sb(&MSVCP_clog.os, NULL);
5089 MSVCP_clog.vbase.delbuf = 1;
5090 ios_setf(&MSVCP_clog.vbase, FLAGS_stdio);
5095 #ifdef __ASM_USE_THISCALL_WRAPPER
5097 #define DEFINE_VTBL_WRAPPER(off) \
5098 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
5099 "popl %eax\n\t" \
5100 "popl %ecx\n\t" \
5101 "pushl %eax\n\t" \
5102 "movl 0(%ecx), %eax\n\t" \
5103 "jmp *" #off "(%eax)\n\t")
5105 DEFINE_VTBL_WRAPPER(0);
5106 DEFINE_VTBL_WRAPPER(4);
5107 DEFINE_VTBL_WRAPPER(8);
5108 DEFINE_VTBL_WRAPPER(12);
5109 DEFINE_VTBL_WRAPPER(16);
5110 DEFINE_VTBL_WRAPPER(20);
5111 DEFINE_VTBL_WRAPPER(24);
5112 DEFINE_VTBL_WRAPPER(28);
5113 DEFINE_VTBL_WRAPPER(32);
5114 DEFINE_VTBL_WRAPPER(36);
5115 DEFINE_VTBL_WRAPPER(40);
5116 DEFINE_VTBL_WRAPPER(44);
5117 DEFINE_VTBL_WRAPPER(48);
5118 DEFINE_VTBL_WRAPPER(52);
5119 DEFINE_VTBL_WRAPPER(56);
5121 #endif
5123 void __cdecl _mtlock(CRITICAL_SECTION *crit)
5125 TRACE("(%p)\n", crit);
5126 EnterCriticalSection(crit);
5129 void __cdecl _mtunlock(CRITICAL_SECTION *crit)
5131 TRACE("(%p)\n", crit);
5132 LeaveCriticalSection(crit);
5135 static void init_cxx_funcs(void)
5137 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
5139 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
5141 operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
5142 operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
5144 else
5146 operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
5147 operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
5151 static void init_io(void *base)
5153 filebuf *fb;
5155 #ifdef __x86_64__
5156 init_streambuf_rtti(base);
5157 init_filebuf_rtti(base);
5158 init_strstreambuf_rtti(base);
5159 init_stdiobuf_rtti(base);
5160 init_ios_rtti(base);
5161 init_ostream_rtti(base);
5162 init_ostream_withassign_rtti(base);
5163 init_ostrstream_rtti(base);
5164 init_ofstream_rtti(base);
5165 init_istream_rtti(base);
5166 init_istream_withassign_rtti(base);
5167 init_istrstream_rtti(base);
5168 init_ifstream_rtti(base);
5169 init_iostream_rtti(base);
5170 init_strstream_rtti(base);
5171 init_stdiostream_rtti(base);
5172 init_fstream_rtti(base);
5173 #endif
5175 if ((fb = operator_new(sizeof(filebuf)))) {
5176 filebuf_fd_ctor(fb, 0);
5177 istream_withassign_sb_ctor(&cin.is, &fb->base, TRUE);
5178 } else
5179 istream_withassign_sb_ctor(&cin.is, NULL, TRUE);
5180 Iostream_init_ios_ctor(NULL, &cin.vbase, 0);
5182 if ((fb = operator_new(sizeof(filebuf)))) {
5183 filebuf_fd_ctor(fb, 1);
5184 ostream_withassign_sb_ctor(&cout.os, &fb->base, TRUE);
5185 } else
5186 ostream_withassign_sb_ctor(&cout.os, NULL, TRUE);
5187 Iostream_init_ios_ctor(NULL, &cout.vbase, -1);
5189 if ((fb = operator_new(sizeof(filebuf)))) {
5190 filebuf_fd_ctor(fb, 2);
5191 ostream_withassign_sb_ctor(&cerr.os, &fb->base, TRUE);
5192 } else
5193 ostream_withassign_sb_ctor(&cerr.os, NULL, TRUE);
5194 Iostream_init_ios_ctor(NULL, &cerr.vbase, 1);
5196 if ((fb = operator_new(sizeof(filebuf)))) {
5197 filebuf_fd_ctor(fb, 2);
5198 ostream_withassign_sb_ctor(&MSVCP_clog.os, &fb->base, TRUE);
5199 } else
5200 ostream_withassign_sb_ctor(&MSVCP_clog.os, NULL, TRUE);
5201 Iostream_init_ios_ctor(NULL, &MSVCP_clog.vbase, 0);
5204 static void free_io(void)
5206 /* destructors take care of deleting the buffers */
5207 istream_vbase_dtor(&cin.is);
5208 ostream_vbase_dtor(&cout.os);
5209 ostream_vbase_dtor(&cerr.os);
5210 ostream_vbase_dtor(&MSVCP_clog.os);
5213 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
5215 switch (reason)
5217 case DLL_PROCESS_ATTACH:
5218 init_cxx_funcs();
5219 init_exception(inst);
5220 init_io(inst);
5221 DisableThreadLibraryCalls( inst );
5222 break;
5223 case DLL_PROCESS_DETACH:
5224 if (reserved) break;
5225 free_io();
5226 break;
5228 return TRUE;