msvcirt: Implement iostream constructors/destructors.
[wine.git] / dlls / msvcirt / msvcirt.c
blob305eb9d2ae4e97e2180ec42d9c6b365fe9941475
1 /*
2 * Copyright (C) 2007 Alexandre Julliard
3 * Copyright (C) 2015-2016 Iván Matellanes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <float.h>
25 #include <io.h>
26 #include <limits.h>
27 #include <share.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <sys/stat.h>
32 #include "msvcirt.h"
33 #include "windef.h"
34 #include "winbase.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
39 #define RESERVE_SIZE 512
40 #define STATEBUF_SIZE 8
42 /* ?sh_none@filebuf@@2HB */
43 const int filebuf_sh_none = 0x800;
44 /* ?sh_read@filebuf@@2HB */
45 const int filebuf_sh_read = 0xa00;
46 /* ?sh_write@filebuf@@2HB */
47 const int filebuf_sh_write = 0xc00;
48 /* ?openprot@filebuf@@2HB */
49 const int filebuf_openprot = 420;
50 /* ?binary@filebuf@@2HB */
51 const int filebuf_binary = _O_BINARY;
52 /* ?text@filebuf@@2HB */
53 const int filebuf_text = _O_TEXT;
55 /* ?adjustfield@ios@@2JB */
56 const LONG ios_adjustfield = FLAGS_left | FLAGS_right | FLAGS_internal;
57 /* ?basefield@ios@@2JB */
58 const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
59 /* ?floatfield@ios@@2JB */
60 const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
61 /* ?fLockcInit@ios@@0HA */
62 /* FIXME: should be initialized to 0 and increased on construction of cin, cout, cerr and clog */
63 int ios_fLockcInit = 4;
64 /* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
65 extern CRITICAL_SECTION ios_static_lock;
66 CRITICAL_SECTION_DEBUG ios_static_lock_debug =
68 0, 0, &ios_static_lock,
69 { &ios_static_lock_debug.ProcessLocksList, &ios_static_lock_debug.ProcessLocksList },
70 0, 0, { (DWORD_PTR)(__FILE__ ": ios_static_lock") }
72 CRITICAL_SECTION ios_static_lock = { &ios_static_lock_debug, -1, 0, 0, 0, 0 };
73 /* ?x_maxbit@ios@@0JA */
74 LONG ios_maxbit = 0x8000;
75 /* ?x_curindex@ios@@0HA */
76 int ios_curindex = -1;
77 /* ?x_statebuf@ios@@0PAJA */
78 LONG ios_statebuf[STATEBUF_SIZE] = {0};
80 /* class streambuf */
81 typedef struct {
82 const vtable_ptr *vtable;
83 int allocated;
84 int unbuffered;
85 int stored_char;
86 char *base;
87 char *ebuf;
88 char *pbase;
89 char *pptr;
90 char *epptr;
91 char *eback;
92 char *gptr;
93 char *egptr;
94 int do_lock;
95 CRITICAL_SECTION lock;
96 } streambuf;
98 void __thiscall streambuf_setb(streambuf*, char*, char*, int);
99 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
100 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
101 void __thiscall streambuf_setp(streambuf*, char*, char*);
103 /* class filebuf */
104 typedef struct {
105 streambuf base;
106 filedesc fd;
107 int close;
108 } filebuf;
110 filebuf* __thiscall filebuf_close(filebuf*);
112 /* class strstreambuf */
113 typedef struct {
114 streambuf base;
115 int dynamic;
116 int increase;
117 int unknown;
118 int constant;
119 allocFunction f_alloc;
120 freeFunction f_free;
121 } strstreambuf;
123 /* class stdiobuf */
124 typedef struct {
125 streambuf base;
126 FILE *file;
127 } stdiobuf;
129 /* class ios */
130 struct _ostream;
131 typedef struct {
132 const vtable_ptr *vtable;
133 streambuf *sb;
134 ios_io_state state;
135 int special[4];
136 int delbuf;
137 struct _ostream *tie;
138 ios_flags flags;
139 int precision;
140 char fill;
141 int width;
142 int do_lock;
143 CRITICAL_SECTION lock;
144 } ios;
146 ios* __thiscall ios_assign(ios*, const ios*);
147 int __thiscall ios_fail(const ios*);
148 void __cdecl ios_lock(ios*);
149 void __cdecl ios_lockc(void);
150 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
151 void __cdecl ios_unlock(ios*);
152 void __cdecl ios_unlockc(void);
154 /* class ostream */
155 typedef struct _ostream {
156 const int *vbtable;
157 int unknown;
158 } ostream;
160 /* class istream */
161 typedef struct {
162 const int *vbtable;
163 int extract_delim;
164 int count;
165 } istream;
167 /* class iostream */
168 typedef struct {
169 istream base1;
170 ostream base2;
171 } iostream;
173 /* ??_7streambuf@@6B@ */
174 extern const vtable_ptr MSVCP_streambuf_vtable;
175 /* ??_7filebuf@@6B@ */
176 extern const vtable_ptr MSVCP_filebuf_vtable;
177 /* ??_7strstreambuf@@6B@ */
178 extern const vtable_ptr MSVCP_strstreambuf_vtable;
179 /* ??_7stdiobuf@@6B@ */
180 extern const vtable_ptr MSVCP_stdiobuf_vtable;
181 /* ??_7ios@@6B@ */
182 extern const vtable_ptr MSVCP_ios_vtable;
183 /* ??_7ostream@@6B@ */
184 extern const vtable_ptr MSVCP_ostream_vtable;
185 /* ??_7ostream_withassign@@6B@ */
186 extern const vtable_ptr MSVCP_ostream_withassign_vtable;
187 /* ??_7istream@@6B@ */
188 extern const vtable_ptr MSVCP_istream_vtable;
189 /* ??_7istream_withassign@@6B@ */
190 extern const vtable_ptr MSVCP_istream_withassign_vtable;
191 /* ??_7iostream@@6B@ */
192 extern const vtable_ptr MSVCP_iostream_vtable;
194 #ifndef __GNUC__
195 void __asm_dummy_vtables(void) {
196 #endif
197 __ASM_VTABLE(streambuf,
198 VTABLE_ADD_FUNC(streambuf_vector_dtor)
199 VTABLE_ADD_FUNC(streambuf_sync)
200 VTABLE_ADD_FUNC(streambuf_setbuf)
201 VTABLE_ADD_FUNC(streambuf_seekoff)
202 VTABLE_ADD_FUNC(streambuf_seekpos)
203 VTABLE_ADD_FUNC(streambuf_xsputn)
204 VTABLE_ADD_FUNC(streambuf_xsgetn)
205 VTABLE_ADD_FUNC(streambuf_overflow)
206 VTABLE_ADD_FUNC(streambuf_underflow)
207 VTABLE_ADD_FUNC(streambuf_pbackfail)
208 VTABLE_ADD_FUNC(streambuf_doallocate));
209 __ASM_VTABLE(filebuf,
210 VTABLE_ADD_FUNC(filebuf_vector_dtor)
211 VTABLE_ADD_FUNC(filebuf_sync)
212 VTABLE_ADD_FUNC(filebuf_setbuf)
213 VTABLE_ADD_FUNC(filebuf_seekoff)
214 VTABLE_ADD_FUNC(streambuf_seekpos)
215 VTABLE_ADD_FUNC(streambuf_xsputn)
216 VTABLE_ADD_FUNC(streambuf_xsgetn)
217 VTABLE_ADD_FUNC(filebuf_overflow)
218 VTABLE_ADD_FUNC(filebuf_underflow)
219 VTABLE_ADD_FUNC(streambuf_pbackfail)
220 VTABLE_ADD_FUNC(streambuf_doallocate));
221 __ASM_VTABLE(strstreambuf,
222 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
223 VTABLE_ADD_FUNC(strstreambuf_sync)
224 VTABLE_ADD_FUNC(strstreambuf_setbuf)
225 VTABLE_ADD_FUNC(strstreambuf_seekoff)
226 VTABLE_ADD_FUNC(streambuf_seekpos)
227 VTABLE_ADD_FUNC(streambuf_xsputn)
228 VTABLE_ADD_FUNC(streambuf_xsgetn)
229 VTABLE_ADD_FUNC(strstreambuf_overflow)
230 VTABLE_ADD_FUNC(strstreambuf_underflow)
231 VTABLE_ADD_FUNC(streambuf_pbackfail)
232 VTABLE_ADD_FUNC(strstreambuf_doallocate));
233 __ASM_VTABLE(stdiobuf,
234 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
235 VTABLE_ADD_FUNC(stdiobuf_sync)
236 VTABLE_ADD_FUNC(streambuf_setbuf)
237 VTABLE_ADD_FUNC(stdiobuf_seekoff)
238 VTABLE_ADD_FUNC(streambuf_seekpos)
239 VTABLE_ADD_FUNC(streambuf_xsputn)
240 VTABLE_ADD_FUNC(streambuf_xsgetn)
241 VTABLE_ADD_FUNC(stdiobuf_overflow)
242 VTABLE_ADD_FUNC(stdiobuf_underflow)
243 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
244 VTABLE_ADD_FUNC(streambuf_doallocate));
245 __ASM_VTABLE(ios,
246 VTABLE_ADD_FUNC(ios_vector_dtor));
247 __ASM_VTABLE(ostream,
248 VTABLE_ADD_FUNC(ostream_vector_dtor));
249 __ASM_VTABLE(ostream_withassign,
250 VTABLE_ADD_FUNC(ostream_vector_dtor));
251 __ASM_VTABLE(istream,
252 VTABLE_ADD_FUNC(istream_vector_dtor));
253 __ASM_VTABLE(istream_withassign,
254 VTABLE_ADD_FUNC(istream_vector_dtor));
255 __ASM_VTABLE(iostream,
256 VTABLE_ADD_FUNC(iostream_vector_dtor));
257 #ifndef __GNUC__
259 #endif
261 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
262 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
264 /* ??_8ostream@@7B@ */
265 /* ??_8ostream_withassign@@7B@ */
266 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
267 /* ??_8istream@@7B@ */
268 /* ??_8istream_withassign@@7B@ */
269 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
270 /* ??_8iostream@@7Bistream@@@ */
271 const int iostream_vbtable_istream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base1), ios)};
272 /* ??_8iostream@@7Bostream@@@ */
273 const int iostream_vbtable_ostream[] = {0, VBTABLE_ENTRY(iostream, FIELD_OFFSET(iostream, base2), ios)};
275 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
276 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
277 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
278 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
279 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
280 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
281 DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream),
282 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@")
283 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
284 DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
285 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
286 DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
287 &istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
288 &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
290 /* ??0streambuf@@IAE@PADH@Z */
291 /* ??0streambuf@@IEAA@PEADH@Z */
292 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
293 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
295 TRACE("(%p %p %d)\n", this, buffer, length);
296 this->vtable = &MSVCP_streambuf_vtable;
297 this->allocated = 0;
298 this->stored_char = EOF;
299 this->do_lock = -1;
300 this->base = NULL;
301 streambuf_setbuf(this, buffer, length);
302 streambuf_setg(this, NULL, NULL, NULL);
303 streambuf_setp(this, NULL, NULL);
304 InitializeCriticalSection(&this->lock);
305 return this;
308 /* ??0streambuf@@IAE@XZ */
309 /* ??0streambuf@@IEAA@XZ */
310 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
311 streambuf* __thiscall streambuf_ctor(streambuf *this)
313 streambuf_reserve_ctor(this, NULL, 0);
314 this->unbuffered = 0;
315 return this;
318 /* ??0streambuf@@QAE@ABV0@@Z */
319 /* ??0streambuf@@QEAA@AEBV0@@Z */
320 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
321 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
323 TRACE("(%p %p)\n", this, copy);
324 *this = *copy;
325 this->vtable = &MSVCP_streambuf_vtable;
326 return this;
329 /* ??1streambuf@@UAE@XZ */
330 /* ??1streambuf@@UEAA@XZ */
331 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
332 void __thiscall streambuf_dtor(streambuf *this)
334 TRACE("(%p)\n", this);
335 if (this->allocated)
336 MSVCRT_operator_delete(this->base);
337 DeleteCriticalSection(&this->lock);
340 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
341 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
342 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
343 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
345 streambuf_dtor(this);
346 return streambuf_copy_ctor(this, rhs);
349 /* ??_Estreambuf@@UAEPAXI@Z */
350 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
351 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
352 streambuf*, (streambuf*, unsigned int), (this, flags))
353 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
355 TRACE("(%p %x)\n", this, flags);
356 if (flags & 2) {
357 /* we have an array, with the number of elements stored before the first object */
358 INT_PTR i, *ptr = (INT_PTR *)this-1;
360 for (i = *ptr-1; i >= 0; i--)
361 streambuf_dtor(this+i);
362 MSVCRT_operator_delete(ptr);
363 } else {
364 streambuf_dtor(this);
365 if (flags & 1)
366 MSVCRT_operator_delete(this);
368 return this;
371 /* ??_Gstreambuf@@UAEPAXI@Z */
372 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
373 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
375 TRACE("(%p %x)\n", this, flags);
376 streambuf_dtor(this);
377 if (flags & 1) MSVCRT_operator_delete(this);
378 return this;
381 /* ?doallocate@streambuf@@MAEHXZ */
382 /* ?doallocate@streambuf@@MEAAHXZ */
383 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
384 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
385 int __thiscall streambuf_doallocate(streambuf *this)
387 char *reserve;
389 TRACE("(%p)\n", this);
390 reserve = MSVCRT_operator_new(RESERVE_SIZE);
391 if (!reserve)
392 return EOF;
394 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
395 return 1;
398 /* ?allocate@streambuf@@IAEHXZ */
399 /* ?allocate@streambuf@@IEAAHXZ */
400 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
401 int __thiscall streambuf_allocate(streambuf *this)
403 TRACE("(%p)\n", this);
404 if (this->base != NULL || this->unbuffered)
405 return 0;
406 return call_streambuf_doallocate(this);
409 /* ?base@streambuf@@IBEPADXZ */
410 /* ?base@streambuf@@IEBAPEADXZ */
411 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
412 char* __thiscall streambuf_base(const streambuf *this)
414 TRACE("(%p)\n", this);
415 return this->base;
418 /* ?blen@streambuf@@IBEHXZ */
419 /* ?blen@streambuf@@IEBAHXZ */
420 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
421 int __thiscall streambuf_blen(const streambuf *this)
423 TRACE("(%p)\n", this);
424 return this->ebuf - this->base;
427 /* ?eback@streambuf@@IBEPADXZ */
428 /* ?eback@streambuf@@IEBAPEADXZ */
429 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
430 char* __thiscall streambuf_eback(const streambuf *this)
432 TRACE("(%p)\n", this);
433 return this->eback;
436 /* ?ebuf@streambuf@@IBEPADXZ */
437 /* ?ebuf@streambuf@@IEBAPEADXZ */
438 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
439 char* __thiscall streambuf_ebuf(const streambuf *this)
441 TRACE("(%p)\n", this);
442 return this->ebuf;
445 /* ?egptr@streambuf@@IBEPADXZ */
446 /* ?egptr@streambuf@@IEBAPEADXZ */
447 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
448 char* __thiscall streambuf_egptr(const streambuf *this)
450 TRACE("(%p)\n", this);
451 return this->egptr;
454 /* ?epptr@streambuf@@IBEPADXZ */
455 /* ?epptr@streambuf@@IEBAPEADXZ */
456 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
457 char* __thiscall streambuf_epptr(const streambuf *this)
459 TRACE("(%p)\n", this);
460 return this->epptr;
463 /* ?gptr@streambuf@@IBEPADXZ */
464 /* ?gptr@streambuf@@IEBAPEADXZ */
465 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
466 char* __thiscall streambuf_gptr(const streambuf *this)
468 TRACE("(%p)\n", this);
469 return this->gptr;
472 /* ?pbase@streambuf@@IBEPADXZ */
473 /* ?pbase@streambuf@@IEBAPEADXZ */
474 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
475 char* __thiscall streambuf_pbase(const streambuf *this)
477 TRACE("(%p)\n", this);
478 return this->pbase;
481 /* ?pptr@streambuf@@IBEPADXZ */
482 /* ?pptr@streambuf@@IEBAPEADXZ */
483 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
484 char* __thiscall streambuf_pptr(const streambuf *this)
486 TRACE("(%p)\n", this);
487 return this->pptr;
490 /* ?clrlock@streambuf@@QAEXXZ */
491 /* ?clrlock@streambuf@@QEAAXXZ */
492 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
493 void __thiscall streambuf_clrlock(streambuf *this)
495 TRACE("(%p)\n", this);
496 if (this->do_lock <= 0)
497 this->do_lock++;
500 /* ?lock@streambuf@@QAEXXZ */
501 /* ?lock@streambuf@@QEAAXXZ */
502 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
503 void __thiscall streambuf_lock(streambuf *this)
505 TRACE("(%p)\n", this);
506 if (this->do_lock < 0)
507 EnterCriticalSection(&this->lock);
510 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
511 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
512 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
513 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
515 TRACE("(%p)\n", this);
516 return &this->lock;
519 /* ?gbump@streambuf@@IAEXH@Z */
520 /* ?gbump@streambuf@@IEAAXH@Z */
521 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
522 void __thiscall streambuf_gbump(streambuf *this, int count)
524 TRACE("(%p %d)\n", this, count);
525 this->gptr += count;
528 /* ?pbump@streambuf@@IAEXH@Z */
529 /* ?pbump@streambuf@@IEAAXH@Z */
530 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
531 void __thiscall streambuf_pbump(streambuf *this, int count)
533 TRACE("(%p %d)\n", this, count);
534 this->pptr += count;
537 /* ?in_avail@streambuf@@QBEHXZ */
538 /* ?in_avail@streambuf@@QEBAHXZ */
539 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
540 int __thiscall streambuf_in_avail(const streambuf *this)
542 TRACE("(%p)\n", this);
543 return this->egptr - this->gptr;
546 /* ?out_waiting@streambuf@@QBEHXZ */
547 /* ?out_waiting@streambuf@@QEBAHXZ */
548 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
549 int __thiscall streambuf_out_waiting(const streambuf *this)
551 TRACE("(%p)\n", this);
552 return this->pptr - this->pbase;
555 /* Unexported */
556 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
557 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
558 int __thiscall streambuf_overflow(streambuf *this, int c)
560 ERR("overflow is not implemented in streambuf\n");
561 return EOF;
564 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
565 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
566 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
567 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
568 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
570 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
571 return EOF;
574 /* ?seekpos@streambuf@@UAEJJH@Z */
575 /* ?seekpos@streambuf@@UEAAJJH@Z */
576 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
577 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
579 TRACE("(%p %d %d)\n", this, pos, mode);
580 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
583 /* ?pbackfail@streambuf@@UAEHH@Z */
584 /* ?pbackfail@streambuf@@UEAAHH@Z */
585 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
586 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
587 int __thiscall streambuf_pbackfail(streambuf *this, int c)
589 TRACE("(%p %d)\n", this, c);
590 if (this->gptr > this->eback)
591 return *--this->gptr = c;
592 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
593 return EOF;
594 if (!this->unbuffered && this->egptr) {
595 /* 'c' should be the next character read */
596 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
597 *this->gptr = c;
599 return c;
602 /* ?setb@streambuf@@IAEXPAD0H@Z */
603 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
604 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
605 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
607 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
608 if (this->allocated)
609 MSVCRT_operator_delete(this->base);
610 this->allocated = delete;
611 this->base = ba;
612 this->ebuf = eb;
615 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
616 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
617 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
618 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
620 TRACE("(%p %p %d)\n", this, buffer, length);
621 if (this->base != NULL)
622 return NULL;
624 if (buffer == NULL || !length) {
625 this->unbuffered = 1;
626 this->base = this->ebuf = NULL;
627 } else {
628 this->unbuffered = 0;
629 this->base = buffer;
630 this->ebuf = buffer + length;
632 return this;
635 /* ?setg@streambuf@@IAEXPAD00@Z */
636 /* ?setg@streambuf@@IEAAXPEAD00@Z */
637 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
638 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
640 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
641 this->eback = ek;
642 this->gptr = gp;
643 this->egptr = eg;
646 /* ?setlock@streambuf@@QAEXXZ */
647 /* ?setlock@streambuf@@QEAAXXZ */
648 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
649 void __thiscall streambuf_setlock(streambuf *this)
651 TRACE("(%p)\n", this);
652 this->do_lock--;
655 /* ?setp@streambuf@@IAEXPAD0@Z */
656 /* ?setp@streambuf@@IEAAXPEAD0@Z */
657 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
658 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
660 TRACE("(%p %p %p)\n", this, pb, ep);
661 this->pbase = this->pptr = pb;
662 this->epptr = ep;
665 /* ?sync@streambuf@@UAEHXZ */
666 /* ?sync@streambuf@@UEAAHXZ */
667 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
668 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
669 int __thiscall streambuf_sync(streambuf *this)
671 TRACE("(%p)\n", this);
672 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
675 /* ?unbuffered@streambuf@@IAEXH@Z */
676 /* ?unbuffered@streambuf@@IEAAXH@Z */
677 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
678 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
680 TRACE("(%p %d)\n", this, buf);
681 this->unbuffered = buf;
684 /* ?unbuffered@streambuf@@IBEHXZ */
685 /* ?unbuffered@streambuf@@IEBAHXZ */
686 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
687 int __thiscall streambuf_unbuffered_get(const streambuf *this)
689 TRACE("(%p)\n", this);
690 return this->unbuffered;
693 /* Unexported */
694 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
695 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
696 int __thiscall streambuf_underflow(streambuf *this)
698 ERR("underflow is not implemented in streambuf\n");
699 return EOF;
702 /* ?unlock@streambuf@@QAEXXZ */
703 /* ?unlock@streambuf@@QEAAXXZ */
704 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
705 void __thiscall streambuf_unlock(streambuf *this)
707 TRACE("(%p)\n", this);
708 if (this->do_lock < 0)
709 LeaveCriticalSection(&this->lock);
712 /* ?xsgetn@streambuf@@UAEHPADH@Z */
713 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
714 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
715 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
716 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
718 int copied = 0, chunk;
720 TRACE("(%p %p %d)\n", this, buffer, count);
722 if (this->unbuffered) {
723 if (this->stored_char == EOF)
724 this->stored_char = call_streambuf_underflow(this);
725 while (copied < count && this->stored_char != EOF) {
726 buffer[copied++] = this->stored_char;
727 this->stored_char = call_streambuf_underflow(this);
729 } else {
730 while (copied < count) {
731 if (call_streambuf_underflow(this) == EOF)
732 break;
733 chunk = this->egptr - this->gptr;
734 if (chunk > count - copied)
735 chunk = count - copied;
736 memcpy(buffer+copied, this->gptr, chunk);
737 this->gptr += chunk;
738 copied += chunk;
741 return copied;
744 /* ?xsputn@streambuf@@UAEHPBDH@Z */
745 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
746 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
747 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
748 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
750 int copied = 0, chunk;
752 TRACE("(%p %p %d)\n", this, data, length);
754 while (copied < length) {
755 if (this->unbuffered || this->pptr == this->epptr) {
756 if (call_streambuf_overflow(this, data[copied]) == EOF)
757 break;
758 copied++;
759 } else {
760 chunk = this->epptr - this->pptr;
761 if (chunk > length - copied)
762 chunk = length - copied;
763 memcpy(this->pptr, data+copied, chunk);
764 this->pptr += chunk;
765 copied += chunk;
768 return copied;
771 /* ?sgetc@streambuf@@QAEHXZ */
772 /* ?sgetc@streambuf@@QEAAHXZ */
773 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
774 int __thiscall streambuf_sgetc(streambuf *this)
776 TRACE("(%p)\n", this);
777 if (this->unbuffered) {
778 if (this->stored_char == EOF)
779 this->stored_char = call_streambuf_underflow(this);
780 return this->stored_char;
781 } else
782 return call_streambuf_underflow(this);
785 /* ?sputc@streambuf@@QAEHH@Z */
786 /* ?sputc@streambuf@@QEAAHH@Z */
787 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
788 int __thiscall streambuf_sputc(streambuf *this, int ch)
790 TRACE("(%p %d)\n", this, ch);
791 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
794 /* ?sgetn@streambuf@@QAEHPADH@Z */
795 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
796 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
797 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
799 return call_streambuf_xsgetn(this, buffer, count);
802 /* ?sputn@streambuf@@QAEHPBDH@Z */
803 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
804 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
805 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
807 return call_streambuf_xsputn(this, data, length);
810 /* ?snextc@streambuf@@QAEHXZ */
811 /* ?snextc@streambuf@@QEAAHXZ */
812 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
813 int __thiscall streambuf_snextc(streambuf *this)
815 TRACE("(%p)\n", this);
816 if (this->unbuffered) {
817 if (this->stored_char == EOF)
818 call_streambuf_underflow(this);
819 return this->stored_char = call_streambuf_underflow(this);
820 } else {
821 if (this->gptr >= this->egptr)
822 call_streambuf_underflow(this);
823 this->gptr++;
824 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
828 /* ?sbumpc@streambuf@@QAEHXZ */
829 /* ?sbumpc@streambuf@@QEAAHXZ */
830 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
831 int __thiscall streambuf_sbumpc(streambuf *this)
833 int ret;
835 TRACE("(%p)\n", this);
837 if (this->unbuffered) {
838 ret = this->stored_char;
839 this->stored_char = EOF;
840 if (ret == EOF)
841 ret = call_streambuf_underflow(this);
842 } else {
843 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
844 this->gptr++;
846 return ret;
849 /* ?stossc@streambuf@@QAEXXZ */
850 /* ?stossc@streambuf@@QEAAXXZ */
851 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
852 void __thiscall streambuf_stossc(streambuf *this)
854 TRACE("(%p)\n", this);
855 if (this->unbuffered) {
856 if (this->stored_char == EOF)
857 call_streambuf_underflow(this);
858 else
859 this->stored_char = EOF;
860 } else {
861 if (this->gptr >= this->egptr)
862 call_streambuf_underflow(this);
863 if (this->gptr < this->egptr)
864 this->gptr++;
868 /* ?sputbackc@streambuf@@QAEHD@Z */
869 /* ?sputbackc@streambuf@@QEAAHD@Z */
870 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
871 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
873 TRACE("(%p %d)\n", this, ch);
874 return call_streambuf_pbackfail(this, ch);
877 /* ?dbp@streambuf@@QAEXXZ */
878 /* ?dbp@streambuf@@QEAAXXZ */
879 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
880 void __thiscall streambuf_dbp(streambuf *this)
882 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
883 if (this->unbuffered) {
884 printf("unbuffered\n");
885 } else {
886 printf("_fAlloc=%d\n", this->allocated);
887 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
888 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
889 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
893 /* ??0filebuf@@QAE@ABV0@@Z */
894 /* ??0filebuf@@QEAA@AEBV0@@Z */
895 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
896 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
898 TRACE("(%p %p)\n", this, copy);
899 *this = *copy;
900 this->base.vtable = &MSVCP_filebuf_vtable;
901 return this;
904 /* ??0filebuf@@QAE@HPADH@Z */
905 /* ??0filebuf@@QEAA@HPEADH@Z */
906 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
907 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
909 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
910 streambuf_reserve_ctor(&this->base, buffer, length);
911 this->base.vtable = &MSVCP_filebuf_vtable;
912 this->fd = fd;
913 this->close = 0;
914 return this;
917 /* ??0filebuf@@QAE@H@Z */
918 /* ??0filebuf@@QEAA@H@Z */
919 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
920 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
922 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
923 this->base.unbuffered = 0;
924 return this;
927 /* ??0filebuf@@QAE@XZ */
928 /* ??0filebuf@@QEAA@XZ */
929 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
930 filebuf* __thiscall filebuf_ctor(filebuf* this)
932 return filebuf_fd_ctor(this, -1);
935 /* ??1filebuf@@UAE@XZ */
936 /* ??1filebuf@@UEAA@XZ */
937 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
938 void __thiscall filebuf_dtor(filebuf* this)
940 TRACE("(%p)\n", this);
941 if (this->close)
942 filebuf_close(this);
943 streambuf_dtor(&this->base);
946 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
947 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
948 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
949 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
951 filebuf_dtor(this);
952 return filebuf_copy_ctor(this, rhs);
955 /* ??_Efilebuf@@UAEPAXI@Z */
956 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
957 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
959 TRACE("(%p %x)\n", this, flags);
960 if (flags & 2) {
961 /* we have an array, with the number of elements stored before the first object */
962 INT_PTR i, *ptr = (INT_PTR *)this-1;
964 for (i = *ptr-1; i >= 0; i--)
965 filebuf_dtor(this+i);
966 MSVCRT_operator_delete(ptr);
967 } else {
968 filebuf_dtor(this);
969 if (flags & 1)
970 MSVCRT_operator_delete(this);
972 return this;
975 /* ??_Gfilebuf@@UAEPAXI@Z */
976 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
977 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
979 TRACE("(%p %x)\n", this, flags);
980 filebuf_dtor(this);
981 if (flags & 1) MSVCRT_operator_delete(this);
982 return this;
985 /* ?attach@filebuf@@QAEPAV1@H@Z */
986 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
987 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
988 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
990 TRACE("(%p %d)\n", this, fd);
991 if (this->fd != -1)
992 return NULL;
994 streambuf_lock(&this->base);
995 this->fd = fd;
996 streambuf_allocate(&this->base);
997 streambuf_unlock(&this->base);
998 return this;
1001 /* ?close@filebuf@@QAEPAV1@XZ */
1002 /* ?close@filebuf@@QEAAPEAV1@XZ */
1003 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
1004 filebuf* __thiscall filebuf_close(filebuf *this)
1006 filebuf *ret;
1008 TRACE("(%p)\n", this);
1009 if (this->fd == -1)
1010 return NULL;
1012 streambuf_lock(&this->base);
1013 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
1014 ret = NULL;
1015 } else {
1016 this->fd = -1;
1017 ret = this;
1019 streambuf_unlock(&this->base);
1020 return ret;
1023 /* ?fd@filebuf@@QBEHXZ */
1024 /* ?fd@filebuf@@QEBAHXZ */
1025 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
1026 filedesc __thiscall filebuf_fd(const filebuf *this)
1028 TRACE("(%p)\n", this);
1029 return this->fd;
1032 /* ?is_open@filebuf@@QBEHXZ */
1033 /* ?is_open@filebuf@@QEBAHXZ */
1034 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1035 int __thiscall filebuf_is_open(const filebuf *this)
1037 TRACE("(%p)\n", this);
1038 return this->fd != -1;
1041 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1042 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1043 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1044 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1046 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1047 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1048 int op_flags, sh_flags, fd;
1050 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1051 if (this->fd != -1)
1052 return NULL;
1054 /* mode */
1055 if (mode & (OPENMODE_app|OPENMODE_trunc))
1056 mode |= OPENMODE_out;
1057 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1058 if (op_flags < 0)
1059 return NULL;
1060 if (mode & OPENMODE_app)
1061 op_flags |= _O_APPEND;
1062 if ((mode & OPENMODE_trunc) ||
1063 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1064 op_flags |= _O_TRUNC;
1065 if (!(mode & OPENMODE_nocreate))
1066 op_flags |= _O_CREAT;
1067 if (mode & OPENMODE_noreplace)
1068 op_flags |= _O_EXCL;
1069 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1071 /* share protection */
1072 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1074 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1075 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1076 if (fd < 0)
1077 return NULL;
1079 streambuf_lock(&this->base);
1080 this->close = 1;
1081 this->fd = fd;
1082 if ((mode & OPENMODE_ate) &&
1083 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1084 _close(fd);
1085 this->fd = -1;
1087 streambuf_allocate(&this->base);
1088 streambuf_unlock(&this->base);
1089 return (this->fd == -1) ? NULL : this;
1092 /* ?overflow@filebuf@@UAEHH@Z */
1093 /* ?overflow@filebuf@@UEAAHH@Z */
1094 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1095 int __thiscall filebuf_overflow(filebuf *this, int c)
1097 TRACE("(%p %d)\n", this, c);
1098 if (call_streambuf_sync(&this->base) == EOF)
1099 return EOF;
1100 if (this->base.unbuffered)
1101 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1102 if (streambuf_allocate(&this->base) == EOF)
1103 return EOF;
1105 this->base.pbase = this->base.pptr = this->base.base;
1106 this->base.epptr = this->base.ebuf;
1107 if (c != EOF)
1108 *this->base.pptr++ = c;
1109 return 1;
1112 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1113 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1114 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1115 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1117 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1118 if (call_streambuf_sync(&this->base) == EOF)
1119 return EOF;
1120 return _lseek(this->fd, offset, dir);
1123 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1124 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1125 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1126 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1128 streambuf *ret;
1130 TRACE("(%p %p %d)\n", this, buffer, length);
1131 if (this->base.base != NULL)
1132 return NULL;
1134 streambuf_lock(&this->base);
1135 ret = streambuf_setbuf(&this->base, buffer, length);
1136 streambuf_unlock(&this->base);
1137 return ret;
1140 /* ?setmode@filebuf@@QAEHH@Z */
1141 /* ?setmode@filebuf@@QEAAHH@Z */
1142 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1143 int __thiscall filebuf_setmode(filebuf *this, int mode)
1145 int ret;
1147 TRACE("(%p %d)\n", this, mode);
1148 if (mode != filebuf_text && mode != filebuf_binary)
1149 return -1;
1151 streambuf_lock(&this->base);
1152 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1153 streambuf_unlock(&this->base);
1154 return ret;
1157 /* ?sync@filebuf@@UAEHXZ */
1158 /* ?sync@filebuf@@UEAAHXZ */
1159 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1160 int __thiscall filebuf_sync(filebuf *this)
1162 int count, mode;
1163 char *ptr;
1164 LONG offset;
1166 TRACE("(%p)\n", this);
1167 if (this->fd == -1)
1168 return EOF;
1169 if (this->base.unbuffered)
1170 return 0;
1172 /* flush output buffer */
1173 if (this->base.pptr != NULL) {
1174 count = this->base.pptr - this->base.pbase;
1175 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1176 return EOF;
1178 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1179 /* flush input buffer */
1180 if (this->base.egptr != NULL) {
1181 offset = this->base.egptr - this->base.gptr;
1182 if (offset > 0) {
1183 mode = _setmode(this->fd, _O_TEXT);
1184 _setmode(this->fd, mode);
1185 if (mode & _O_TEXT) {
1186 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1187 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1188 if (*ptr == '\n')
1189 offset++;
1191 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1192 return EOF;
1195 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1196 return 0;
1199 /* ?underflow@filebuf@@UAEHXZ */
1200 /* ?underflow@filebuf@@UEAAHXZ */
1201 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1202 int __thiscall filebuf_underflow(filebuf *this)
1204 int buffer_size, read_bytes;
1205 char c;
1207 TRACE("(%p)\n", this);
1209 if (this->base.unbuffered)
1210 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1212 if (this->base.gptr >= this->base.egptr) {
1213 if (call_streambuf_sync(&this->base) == EOF)
1214 return EOF;
1215 buffer_size = this->base.ebuf - this->base.base;
1216 read_bytes = _read(this->fd, this->base.base, buffer_size);
1217 if (read_bytes <= 0)
1218 return EOF;
1219 this->base.eback = this->base.gptr = this->base.base;
1220 this->base.egptr = this->base.base + read_bytes;
1222 return (unsigned char) *this->base.gptr;
1225 /* ??0strstreambuf@@QAE@ABV0@@Z */
1226 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1227 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1228 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1230 TRACE("(%p %p)\n", this, copy);
1231 *this = *copy;
1232 this->base.vtable = &MSVCP_strstreambuf_vtable;
1233 return this;
1236 /* ??0strstreambuf@@QAE@H@Z */
1237 /* ??0strstreambuf@@QEAA@H@Z */
1238 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1239 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1241 TRACE("(%p %d)\n", this, length);
1242 streambuf_ctor(&this->base);
1243 this->base.vtable = &MSVCP_strstreambuf_vtable;
1244 this->dynamic = 1;
1245 this->increase = length;
1246 this->constant = 0;
1247 this->f_alloc = NULL;
1248 this->f_free = NULL;
1249 return this;
1252 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1253 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1254 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1255 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1257 TRACE("(%p %p %p)\n", this, falloc, ffree);
1258 strstreambuf_dynamic_ctor(this, 1);
1259 this->f_alloc = falloc;
1260 this->f_free = ffree;
1261 return this;
1264 /* ??0strstreambuf@@QAE@PADH0@Z */
1265 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1266 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1267 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1269 char *end_buffer;
1271 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1273 if (length > 0)
1274 end_buffer = buffer + length;
1275 else if (length == 0)
1276 end_buffer = buffer + strlen(buffer);
1277 else
1278 end_buffer = (char*) -1;
1280 streambuf_ctor(&this->base);
1281 streambuf_setb(&this->base, buffer, end_buffer, 0);
1282 if (put == NULL) {
1283 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1284 } else {
1285 streambuf_setg(&this->base, buffer, buffer, put);
1286 streambuf_setp(&this->base, put, end_buffer);
1288 this->base.vtable = &MSVCP_strstreambuf_vtable;
1289 this->dynamic = 0;
1290 this->constant = 1;
1291 return this;
1294 /* ??0strstreambuf@@QAE@PAEH0@Z */
1295 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1296 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1297 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1299 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1300 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1303 /* ??0strstreambuf@@QAE@XZ */
1304 /* ??0strstreambuf@@QEAA@XZ */
1305 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1306 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1308 TRACE("(%p)\n", this);
1309 return strstreambuf_dynamic_ctor(this, 1);
1312 /* ??1strstreambuf@@UAE@XZ */
1313 /* ??1strstreambuf@@UEAA@XZ */
1314 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1315 void __thiscall strstreambuf_dtor(strstreambuf *this)
1317 TRACE("(%p)\n", this);
1318 if (this->dynamic && this->base.base) {
1319 if (this->f_free)
1320 this->f_free(this->base.base);
1321 else
1322 MSVCRT_operator_delete(this->base.base);
1324 streambuf_dtor(&this->base);
1327 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1328 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1329 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1330 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1332 strstreambuf_dtor(this);
1333 return strstreambuf_copy_ctor(this, rhs);
1336 /* ??_Estrstreambuf@@UAEPAXI@Z */
1337 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1338 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1340 TRACE("(%p %x)\n", this, flags);
1341 if (flags & 2) {
1342 /* we have an array, with the number of elements stored before the first object */
1343 INT_PTR i, *ptr = (INT_PTR *)this-1;
1345 for (i = *ptr-1; i >= 0; i--)
1346 strstreambuf_dtor(this+i);
1347 MSVCRT_operator_delete(ptr);
1348 } else {
1349 strstreambuf_dtor(this);
1350 if (flags & 1)
1351 MSVCRT_operator_delete(this);
1353 return this;
1356 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1357 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1358 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1360 TRACE("(%p %x)\n", this, flags);
1361 strstreambuf_dtor(this);
1362 if (flags & 1) MSVCRT_operator_delete(this);
1363 return this;
1366 /* ?doallocate@strstreambuf@@MAEHXZ */
1367 /* ?doallocate@strstreambuf@@MEAAHXZ */
1368 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1369 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1371 char *prev_buffer = this->base.base, *new_buffer;
1372 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1374 TRACE("(%p)\n", this);
1376 /* calculate the size of the new buffer */
1377 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1378 /* get a new buffer */
1379 if (this->f_alloc)
1380 new_buffer = this->f_alloc(new_size);
1381 else
1382 new_buffer = MSVCRT_operator_new(new_size);
1383 if (!new_buffer)
1384 return EOF;
1385 if (this->base.ebuf) {
1386 /* copy the contents and adjust the pointers */
1387 memcpy(new_buffer, this->base.base, prev_size);
1388 if (this->base.egptr) {
1389 this->base.eback += new_buffer - prev_buffer;
1390 this->base.gptr += new_buffer - prev_buffer;
1391 this->base.egptr += new_buffer - prev_buffer;
1393 if (this->base.epptr) {
1394 this->base.pbase += new_buffer - prev_buffer;
1395 this->base.pptr += new_buffer - prev_buffer;
1396 this->base.epptr += new_buffer - prev_buffer;
1398 /* free the old buffer */
1399 if (this->f_free)
1400 this->f_free(this->base.base);
1401 else
1402 MSVCRT_operator_delete(this->base.base);
1404 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1405 return 1;
1408 /* ?freeze@strstreambuf@@QAEXH@Z */
1409 /* ?freeze@strstreambuf@@QEAAXH@Z */
1410 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1411 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1413 TRACE("(%p %d)\n", this, frozen);
1414 if (!this->constant)
1415 this->dynamic = !frozen;
1418 /* ?overflow@strstreambuf@@UAEHH@Z */
1419 /* ?overflow@strstreambuf@@UEAAHH@Z */
1420 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1421 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1423 TRACE("(%p %d)\n", this, c);
1424 if (this->base.pptr >= this->base.epptr) {
1425 /* increase the buffer size if it's dynamic */
1426 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1427 return EOF;
1428 if (!this->base.epptr)
1429 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1430 this->base.epptr = this->base.ebuf;
1432 if (c != EOF)
1433 *this->base.pptr++ = c;
1434 return 1;
1437 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1438 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1439 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1440 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1442 char *base[3];
1444 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1446 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1447 return EOF;
1448 /* read buffer */
1449 if (mode & OPENMODE_in) {
1450 call_streambuf_underflow(&this->base);
1451 base[SEEKDIR_beg] = this->base.eback;
1452 base[SEEKDIR_cur] = this->base.gptr;
1453 base[SEEKDIR_end] = this->base.egptr;
1454 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1455 return EOF;
1456 this->base.gptr = base[dir] + offset;
1458 /* write buffer */
1459 if (mode & OPENMODE_out) {
1460 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1461 return EOF;
1462 base[SEEKDIR_beg] = this->base.pbase;
1463 base[SEEKDIR_cur] = this->base.pptr;
1464 base[SEEKDIR_end] = this->base.epptr;
1465 if (base[dir] + offset < this->base.pbase)
1466 return EOF;
1467 if (base[dir] + offset > this->base.epptr) {
1468 /* make room if the buffer is dynamic */
1469 if (!this->dynamic)
1470 return EOF;
1471 this->increase = offset;
1472 if (call_streambuf_doallocate(&this->base) == EOF)
1473 return EOF;
1475 this->base.pptr = base[dir] + offset;
1476 return this->base.pptr - base[SEEKDIR_beg];
1478 return this->base.gptr - base[SEEKDIR_beg];
1481 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1482 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1483 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1484 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1486 TRACE("(%p %p %d)\n", this, buffer, length);
1487 if (length)
1488 this->increase = length;
1489 return &this->base;
1492 /* ?str@strstreambuf@@QAEPADXZ */
1493 /* ?str@strstreambuf@@QEAAPEADXZ */
1494 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1495 char* __thiscall strstreambuf_str(strstreambuf *this)
1497 TRACE("(%p)\n", this);
1498 strstreambuf_freeze(this, 1);
1499 return this->base.base;
1502 /* ?sync@strstreambuf@@UAEHXZ */
1503 /* ?sync@strstreambuf@@UEAAHXZ */
1504 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1505 int __thiscall strstreambuf_sync(strstreambuf *this)
1507 TRACE("(%p)\n", this);
1508 return 0;
1511 /* ?underflow@strstreambuf@@UAEHXZ */
1512 /* ?underflow@strstreambuf@@UEAAHXZ */
1513 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1514 int __thiscall strstreambuf_underflow(strstreambuf *this)
1516 TRACE("(%p)\n", this);
1517 if (this->base.gptr < this->base.egptr)
1518 return (unsigned char) *this->base.gptr;
1519 /* extend the get area to include the characters written */
1520 if (this->base.egptr < this->base.pptr) {
1521 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1522 this->base.eback = this->base.base;
1523 this->base.egptr = this->base.pptr;
1525 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1528 /* ??0stdiobuf@@QAE@ABV0@@Z */
1529 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1530 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1531 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1533 TRACE("(%p %p)\n", this, copy);
1534 *this = *copy;
1535 this->base.vtable = &MSVCP_stdiobuf_vtable;
1536 return this;
1539 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1540 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1541 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1542 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1544 TRACE("(%p %p)\n", this, file);
1545 streambuf_reserve_ctor(&this->base, NULL, 0);
1546 this->base.vtable = &MSVCP_stdiobuf_vtable;
1547 this->file = file;
1548 return this;
1551 /* ??1stdiobuf@@UAE@XZ */
1552 /* ??1stdiobuf@@UEAA@XZ */
1553 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1554 void __thiscall stdiobuf_dtor(stdiobuf *this)
1556 TRACE("(%p)\n", this);
1557 call_streambuf_sync(&this->base);
1558 streambuf_dtor(&this->base);
1561 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1562 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1563 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1564 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1566 stdiobuf_dtor(this);
1567 return stdiobuf_copy_ctor(this, rhs);
1570 /* ??_Estdiobuf@@UAEPAXI@Z */
1571 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1572 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1574 TRACE("(%p %x)\n", this, flags);
1575 if (flags & 2) {
1576 /* we have an array, with the number of elements stored before the first object */
1577 INT_PTR i, *ptr = (INT_PTR *)this-1;
1579 for (i = *ptr-1; i >= 0; i--)
1580 stdiobuf_dtor(this+i);
1581 MSVCRT_operator_delete(ptr);
1582 } else {
1583 stdiobuf_dtor(this);
1584 if (flags & 1)
1585 MSVCRT_operator_delete(this);
1587 return this;
1590 /* ??_Gstdiobuf@@UAEPAXI@Z */
1591 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1592 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1594 TRACE("(%p %x)\n", this, flags);
1595 stdiobuf_dtor(this);
1596 if (flags & 1) MSVCRT_operator_delete(this);
1597 return this;
1600 /* ?overflow@stdiobuf@@UAEHH@Z */
1601 /* ?overflow@stdiobuf@@UEAAHH@Z */
1602 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1603 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1605 TRACE("(%p %d)\n", this, c);
1606 if (this->base.unbuffered)
1607 return (c == EOF) ? 1 : fputc(c, this->file);
1608 if (streambuf_allocate(&this->base) == EOF)
1609 return EOF;
1611 if (!this->base.epptr) {
1612 /* set the put area to the second half of the buffer */
1613 streambuf_setp(&this->base,
1614 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1615 } else if (this->base.pptr > this->base.pbase) {
1616 /* flush the put area */
1617 int count = this->base.pptr - this->base.pbase;
1618 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1619 return EOF;
1620 this->base.pptr = this->base.pbase;
1622 if (c != EOF) {
1623 if (this->base.pbase >= this->base.epptr)
1624 return fputc(c, this->file);
1625 *this->base.pptr++ = c;
1627 return 1;
1630 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1631 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1632 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1633 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1635 TRACE("(%p %d)\n", this, c);
1636 return streambuf_pbackfail(&this->base, c);
1639 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1640 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1641 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1642 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1644 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1645 call_streambuf_overflow(&this->base, EOF);
1646 if (fseek(this->file, offset, dir))
1647 return EOF;
1648 return ftell(this->file);
1651 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1652 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1653 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1654 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1656 char *reserve;
1657 int buffer_size = read_size + write_size;
1659 TRACE("(%p %d %d)\n", this, read_size, write_size);
1660 if (read_size < 0 || write_size < 0)
1661 return 0;
1662 if (!buffer_size) {
1663 this->base.unbuffered = 1;
1664 return 0;
1666 /* get a new buffer */
1667 reserve = MSVCRT_operator_new(buffer_size);
1668 if (!reserve)
1669 return 0;
1670 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1671 this->base.unbuffered = 0;
1672 /* set the get/put areas */
1673 if (read_size > 0)
1674 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1675 else
1676 streambuf_setg(&this->base, NULL, NULL, NULL);
1677 if (write_size > 0)
1678 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1679 else
1680 streambuf_setp(&this->base, NULL, NULL);
1681 return 1;
1684 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1685 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1686 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1687 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1689 TRACE("(%p)\n", this);
1690 return this->file;
1693 /* ?sync@stdiobuf@@UAEHXZ */
1694 /* ?sync@stdiobuf@@UEAAHXZ */
1695 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1696 int __thiscall stdiobuf_sync(stdiobuf *this)
1698 TRACE("(%p)\n", this);
1699 if (this->base.unbuffered)
1700 return 0;
1701 /* flush the put area */
1702 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1703 return EOF;
1704 /* flush the get area */
1705 if (this->base.gptr < this->base.egptr) {
1706 char *ptr;
1707 int fd, mode, offset = this->base.egptr - this->base.gptr;
1708 if ((fd = fileno(this->file)) < 0)
1709 return EOF;
1710 mode = _setmode(fd, _O_TEXT);
1711 _setmode(fd, mode);
1712 if (mode & _O_TEXT) {
1713 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1714 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1715 if (*ptr == '\n')
1716 offset++;
1718 if (fseek(this->file, -offset, SEEK_CUR))
1719 return EOF;
1720 this->base.gptr = this->base.egptr;
1722 return 0;
1725 /* ?underflow@stdiobuf@@UAEHXZ */
1726 /* ?underflow@stdiobuf@@UEAAHXZ */
1727 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1728 int __thiscall stdiobuf_underflow(stdiobuf *this)
1730 TRACE("(%p)\n", this);
1731 if (!this->file)
1732 return EOF;
1733 if (this->base.unbuffered)
1734 return fgetc(this->file);
1735 if (streambuf_allocate(&this->base) == EOF)
1736 return EOF;
1738 if (!this->base.egptr) {
1739 /* set the get area to the first half of the buffer */
1740 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1741 streambuf_setg(&this->base, this->base.base, middle, middle);
1743 if (this->base.gptr >= this->base.egptr) {
1744 /* read characters from the file */
1745 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1746 if (!this->base.eback ||
1747 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1748 return EOF;
1749 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1750 this->base.gptr = this->base.egptr - read_bytes;
1752 return (unsigned char) *this->base.gptr++;
1755 /* ??0ios@@IAE@ABV0@@Z */
1756 /* ??0ios@@IEAA@AEBV0@@Z */
1757 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1758 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1760 TRACE("(%p %p)\n", this, copy);
1761 ios_fLockcInit++;
1762 this->vtable = &MSVCP_ios_vtable;
1763 this->sb = NULL;
1764 this->delbuf = 0;
1765 this->do_lock = -1;
1766 InitializeCriticalSection(&this->lock);
1767 return ios_assign(this, copy);
1770 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1771 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1772 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1773 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1775 TRACE("(%p %p)\n", this, sb);
1776 ios_fLockcInit++;
1777 this->vtable = &MSVCP_ios_vtable;
1778 this->sb = sb;
1779 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1780 this->special[0] = this->special[1] = 0;
1781 this->delbuf = 0;
1782 this->tie = NULL;
1783 this->flags = 0;
1784 this->precision = 6;
1785 this->fill = ' ';
1786 this->width = 0;
1787 this->do_lock = -1;
1788 InitializeCriticalSection(&this->lock);
1789 return this;
1792 /* ??0ios@@IAE@XZ */
1793 /* ??0ios@@IEAA@XZ */
1794 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1795 ios* __thiscall ios_ctor(ios *this)
1797 return ios_sb_ctor(this, NULL);
1800 /* ??1ios@@UAE@XZ */
1801 /* ??1ios@@UEAA@XZ */
1802 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1803 void __thiscall ios_dtor(ios *this)
1805 TRACE("(%p)\n", this);
1806 ios_fLockcInit--;
1807 if (this->delbuf && this->sb)
1808 call_streambuf_vector_dtor(this->sb, 1);
1809 this->sb = NULL;
1810 this->state = IOSTATE_badbit;
1811 DeleteCriticalSection(&this->lock);
1814 /* ??4ios@@IAEAAV0@ABV0@@Z */
1815 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1816 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1817 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1819 TRACE("(%p %p)\n", this, rhs);
1820 this->state = rhs->state;
1821 if (!this->sb)
1822 this->state |= IOSTATE_badbit;
1823 this->tie = rhs->tie;
1824 this->flags = rhs->flags;
1825 this->precision = (char) rhs->precision;
1826 this->fill = rhs->fill;
1827 this->width = (char) rhs->width;
1828 return this;
1831 /* ??7ios@@QBEHXZ */
1832 /* ??7ios@@QEBAHXZ */
1833 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1834 int __thiscall ios_op_not(const ios *this)
1836 TRACE("(%p)\n", this);
1837 return ios_fail(this);
1840 /* ??Bios@@QBEPAXXZ */
1841 /* ??Bios@@QEBAPEAXXZ */
1842 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1843 void* __thiscall ios_op_void(const ios *this)
1845 TRACE("(%p)\n", this);
1846 return ios_fail(this) ? NULL : (void*)this;
1849 /* ??_Eios@@UAEPAXI@Z */
1850 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1851 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1853 TRACE("(%p %x)\n", this, flags);
1854 if (flags & 2) {
1855 /* we have an array, with the number of elements stored before the first object */
1856 INT_PTR i, *ptr = (INT_PTR *)this-1;
1858 for (i = *ptr-1; i >= 0; i--)
1859 ios_dtor(this+i);
1860 MSVCRT_operator_delete(ptr);
1861 } else {
1862 ios_dtor(this);
1863 if (flags & 1)
1864 MSVCRT_operator_delete(this);
1866 return this;
1869 /* ??_Gios@@UAEPAXI@Z */
1870 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1871 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1873 TRACE("(%p %x)\n", this, flags);
1874 ios_dtor(this);
1875 if (flags & 1) MSVCRT_operator_delete(this);
1876 return this;
1879 /* ?bad@ios@@QBEHXZ */
1880 /* ?bad@ios@@QEBAHXZ */
1881 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1882 int __thiscall ios_bad(const ios *this)
1884 TRACE("(%p)\n", this);
1885 return (this->state & IOSTATE_badbit);
1888 /* ?bitalloc@ios@@SAJXZ */
1889 LONG __cdecl ios_bitalloc(void)
1891 TRACE("()\n");
1892 ios_lockc();
1893 ios_maxbit <<= 1;
1894 ios_unlockc();
1895 return ios_maxbit;
1898 /* ?clear@ios@@QAEXH@Z */
1899 /* ?clear@ios@@QEAAXH@Z */
1900 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1901 void __thiscall ios_clear(ios *this, int state)
1903 TRACE("(%p %d)\n", this, state);
1904 ios_lock(this);
1905 this->state = state;
1906 ios_unlock(this);
1909 /* ?clrlock@ios@@QAAXXZ */
1910 /* ?clrlock@ios@@QEAAXXZ */
1911 void __cdecl ios_clrlock(ios *this)
1913 TRACE("(%p)\n", this);
1914 if (this->do_lock <= 0)
1915 this->do_lock++;
1916 if (this->sb)
1917 streambuf_clrlock(this->sb);
1920 /* ?delbuf@ios@@QAEXH@Z */
1921 /* ?delbuf@ios@@QEAAXH@Z */
1922 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1923 void __thiscall ios_delbuf_set(ios *this, int delete)
1925 TRACE("(%p %d)\n", this, delete);
1926 this->delbuf = delete;
1929 /* ?delbuf@ios@@QBEHXZ */
1930 /* ?delbuf@ios@@QEBAHXZ */
1931 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1932 int __thiscall ios_delbuf_get(const ios *this)
1934 TRACE("(%p)\n", this);
1935 return this->delbuf;
1938 /* ?dec@@YAAAVios@@AAV1@@Z */
1939 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1940 ios* __cdecl ios_dec(ios *this)
1942 TRACE("(%p)\n", this);
1943 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1944 return this;
1947 /* ?eof@ios@@QBEHXZ */
1948 /* ?eof@ios@@QEBAHXZ */
1949 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1950 int __thiscall ios_eof(const ios *this)
1952 TRACE("(%p)\n", this);
1953 return (this->state & IOSTATE_eofbit);
1956 /* ?fail@ios@@QBEHXZ */
1957 /* ?fail@ios@@QEBAHXZ */
1958 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1959 int __thiscall ios_fail(const ios *this)
1961 TRACE("(%p)\n", this);
1962 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1965 /* ?fill@ios@@QAEDD@Z */
1966 /* ?fill@ios@@QEAADD@Z */
1967 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1968 char __thiscall ios_fill_set(ios *this, char fill)
1970 char prev = this->fill;
1972 TRACE("(%p %d)\n", this, fill);
1974 this->fill = fill;
1975 return prev;
1978 /* ?fill@ios@@QBEDXZ */
1979 /* ?fill@ios@@QEBADXZ */
1980 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1981 char __thiscall ios_fill_get(const ios *this)
1983 TRACE("(%p)\n", this);
1984 return this->fill;
1987 /* ?flags@ios@@QAEJJ@Z */
1988 /* ?flags@ios@@QEAAJJ@Z */
1989 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
1990 LONG __thiscall ios_flags_set(ios *this, LONG flags)
1992 LONG prev = this->flags;
1994 TRACE("(%p %x)\n", this, flags);
1996 this->flags = flags;
1997 return prev;
2000 /* ?flags@ios@@QBEJXZ */
2001 /* ?flags@ios@@QEBAJXZ */
2002 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
2003 LONG __thiscall ios_flags_get(const ios *this)
2005 TRACE("(%p)\n", this);
2006 return this->flags;
2009 /* ?good@ios@@QBEHXZ */
2010 /* ?good@ios@@QEBAHXZ */
2011 DEFINE_THISCALL_WRAPPER(ios_good, 4)
2012 int __thiscall ios_good(const ios *this)
2014 TRACE("(%p)\n", this);
2015 return this->state == IOSTATE_goodbit;
2018 /* ?hex@@YAAAVios@@AAV1@@Z */
2019 /* ?hex@@YAAEAVios@@AEAV1@@Z */
2020 ios* __cdecl ios_hex(ios *this)
2022 TRACE("(%p)\n", this);
2023 ios_setf_mask(this, FLAGS_hex, ios_basefield);
2024 return this;
2027 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
2028 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
2029 DEFINE_THISCALL_WRAPPER(ios_init, 8)
2030 void __thiscall ios_init(ios *this, streambuf *sb)
2032 TRACE("(%p %p)\n", this, sb);
2033 if (this->delbuf && this->sb)
2034 call_streambuf_vector_dtor(this->sb, 1);
2035 this->sb = sb;
2036 if (sb == NULL)
2037 this->state |= IOSTATE_badbit;
2038 else
2039 this->state &= ~IOSTATE_badbit;
2042 /* ?iword@ios@@QBEAAJH@Z */
2043 /* ?iword@ios@@QEBAAEAJH@Z */
2044 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2045 LONG* __thiscall ios_iword(const ios *this, int index)
2047 TRACE("(%p %d)\n", this, index);
2048 return &ios_statebuf[index];
2051 /* ?lock@ios@@QAAXXZ */
2052 /* ?lock@ios@@QEAAXXZ */
2053 void __cdecl ios_lock(ios *this)
2055 TRACE("(%p)\n", this);
2056 if (this->do_lock < 0)
2057 EnterCriticalSection(&this->lock);
2060 /* ?lockbuf@ios@@QAAXXZ */
2061 /* ?lockbuf@ios@@QEAAXXZ */
2062 void __cdecl ios_lockbuf(ios *this)
2064 TRACE("(%p)\n", this);
2065 streambuf_lock(this->sb);
2068 /* ?lockc@ios@@KAXXZ */
2069 void __cdecl ios_lockc(void)
2071 TRACE("()\n");
2072 EnterCriticalSection(&ios_static_lock);
2075 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2076 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2077 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2078 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2080 TRACE("(%p)\n", this);
2081 return &this->lock;
2084 /* ?oct@@YAAAVios@@AAV1@@Z */
2085 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2086 ios* __cdecl ios_oct(ios *this)
2088 TRACE("(%p)\n", this);
2089 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2090 return this;
2093 /* ?precision@ios@@QAEHH@Z */
2094 /* ?precision@ios@@QEAAHH@Z */
2095 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2096 int __thiscall ios_precision_set(ios *this, int prec)
2098 int prev = this->precision;
2100 TRACE("(%p %d)\n", this, prec);
2102 this->precision = prec;
2103 return prev;
2106 /* ?precision@ios@@QBEHXZ */
2107 /* ?precision@ios@@QEBAHXZ */
2108 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2109 int __thiscall ios_precision_get(const ios *this)
2111 TRACE("(%p)\n", this);
2112 return this->precision;
2115 /* ?pword@ios@@QBEAAPAXH@Z */
2116 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2117 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2118 void** __thiscall ios_pword(const ios *this, int index)
2120 TRACE("(%p %d)\n", this, index);
2121 return (void**)&ios_statebuf[index];
2124 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2125 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2126 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2127 streambuf* __thiscall ios_rdbuf(const ios *this)
2129 TRACE("(%p)\n", this);
2130 return this->sb;
2133 /* ?rdstate@ios@@QBEHXZ */
2134 /* ?rdstate@ios@@QEBAHXZ */
2135 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2136 int __thiscall ios_rdstate(const ios *this)
2138 TRACE("(%p)\n", this);
2139 return this->state;
2142 /* ?setf@ios@@QAEJJ@Z */
2143 /* ?setf@ios@@QEAAJJ@Z */
2144 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2145 LONG __thiscall ios_setf(ios *this, LONG flags)
2147 LONG prev = this->flags;
2149 TRACE("(%p %x)\n", this, flags);
2151 ios_lock(this);
2152 this->flags |= flags;
2153 ios_unlock(this);
2154 return prev;
2157 /* ?setf@ios@@QAEJJJ@Z */
2158 /* ?setf@ios@@QEAAJJJ@Z */
2159 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2160 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2162 LONG prev = this->flags;
2164 TRACE("(%p %x %x)\n", this, flags, mask);
2166 ios_lock(this);
2167 this->flags = (this->flags & (~mask)) | (flags & mask);
2168 ios_unlock(this);
2169 return prev;
2172 /* ?setlock@ios@@QAAXXZ */
2173 /* ?setlock@ios@@QEAAXXZ */
2174 void __cdecl ios_setlock(ios *this)
2176 TRACE("(%p)\n", this);
2177 this->do_lock--;
2178 if (this->sb)
2179 streambuf_setlock(this->sb);
2182 /* ?sync_with_stdio@ios@@SAXXZ */
2183 void __cdecl ios_sync_with_stdio(void)
2185 FIXME("() stub\n");
2188 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2189 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2190 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2191 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2193 ostream *prev = this->tie;
2195 TRACE("(%p %p)\n", this, ostr);
2197 this->tie = ostr;
2198 return prev;
2201 /* ?tie@ios@@QBEPAVostream@@XZ */
2202 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2203 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2204 ostream* __thiscall ios_tie_get(const ios *this)
2206 TRACE("(%p)\n", this);
2207 return this->tie;
2210 /* ?unlock@ios@@QAAXXZ */
2211 /* ?unlock@ios@@QEAAXXZ */
2212 void __cdecl ios_unlock(ios *this)
2214 TRACE("(%p)\n", this);
2215 if (this->do_lock < 0)
2216 LeaveCriticalSection(&this->lock);
2219 /* ?unlockbuf@ios@@QAAXXZ */
2220 /* ?unlockbuf@ios@@QEAAXXZ */
2221 void __cdecl ios_unlockbuf(ios *this)
2223 TRACE("(%p)\n", this);
2224 streambuf_unlock(this->sb);
2227 /* ?unlockc@ios@@KAXXZ */
2228 void __cdecl ios_unlockc(void)
2230 TRACE("()\n");
2231 LeaveCriticalSection(&ios_static_lock);
2234 /* ?unsetf@ios@@QAEJJ@Z */
2235 /* ?unsetf@ios@@QEAAJJ@Z */
2236 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2237 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2239 LONG prev = this->flags;
2241 TRACE("(%p %x)\n", this, flags);
2243 ios_lock(this);
2244 this->flags &= ~flags;
2245 ios_unlock(this);
2246 return prev;
2249 /* ?width@ios@@QAEHH@Z */
2250 /* ?width@ios@@QEAAHH@Z */
2251 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2252 int __thiscall ios_width_set(ios *this, int width)
2254 int prev = this->width;
2256 TRACE("(%p %d)\n", this, width);
2258 this->width = width;
2259 return prev;
2262 /* ?width@ios@@QBEHXZ */
2263 /* ?width@ios@@QEBAHXZ */
2264 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2265 int __thiscall ios_width_get(const ios *this)
2267 TRACE("(%p)\n", this);
2268 return this->width;
2271 /* ?xalloc@ios@@SAHXZ */
2272 int __cdecl ios_xalloc(void)
2274 int ret;
2276 TRACE("()\n");
2278 ios_lockc();
2279 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2280 ios_unlockc();
2281 return ret;
2284 static inline ios* ostream_get_ios(const ostream *this)
2286 return (ios*)((char*)this + this->vbtable[1]);
2289 static inline ios* ostream_to_ios(const ostream *this)
2291 return (ios*)((char*)this + ostream_vbtable[1]);
2294 static inline ostream* ios_to_ostream(const ios *base)
2296 return (ostream*)((char*)base - ostream_vbtable[1]);
2299 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2300 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2301 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2302 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2304 ios *base;
2306 TRACE("(%p %p %d)\n", this, sb, virt_init);
2308 if (virt_init) {
2309 this->vbtable = ostream_vbtable;
2310 base = ostream_get_ios(this);
2311 ios_sb_ctor(base, sb);
2312 } else {
2313 base = ostream_get_ios(this);
2314 ios_init(base, sb);
2316 base->vtable = &MSVCP_ostream_vtable;
2317 this->unknown = 0;
2318 return this;
2321 /* ??0ostream@@IAE@ABV0@@Z */
2322 /* ??0ostream@@IEAA@AEBV0@@Z */
2323 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2324 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2326 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2329 /* ??0ostream@@IAE@XZ */
2330 /* ??0ostream@@IEAA@XZ */
2331 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2332 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2334 ios *base;
2336 TRACE("(%p %d)\n", this, virt_init);
2338 if (virt_init) {
2339 this->vbtable = ostream_vbtable;
2340 base = ostream_get_ios(this);
2341 ios_ctor(base);
2342 } else
2343 base = ostream_get_ios(this);
2344 base->vtable = &MSVCP_ostream_vtable;
2345 this->unknown = 0;
2346 return this;
2349 /* ??1ostream@@UAE@XZ */
2350 /* ??1ostream@@UEAA@XZ */
2351 /* ??1ostream_withassign@@UAE@XZ */
2352 /* ??1ostream_withassign@@UEAA@XZ */
2353 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2354 void __thiscall ostream_dtor(ios *base)
2356 ostream *this = ios_to_ostream(base);
2358 TRACE("(%p)\n", this);
2361 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2362 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2363 /* ??4ostream_withassign@@QAEAAVostream@@PAVstreambuf@@@Z */
2364 /* ??4ostream_withassign@@QEAAAEAVostream@@PEAVstreambuf@@@Z */
2365 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2366 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2368 ios *base = ostream_get_ios(this);
2370 TRACE("(%p %p)\n", this, sb);
2372 ios_init(base, sb);
2373 base->state &= IOSTATE_badbit;
2374 base->delbuf = 0;
2375 base->tie = NULL;
2376 base->flags = 0;
2377 base->precision = 6;
2378 base->fill = ' ';
2379 base->width = 0;
2380 return this;
2383 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2384 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2385 /* ??4ostream_withassign@@QAEAAV0@ABV0@@Z */
2386 /* ??4ostream_withassign@@QEAAAEAV0@AEBV0@@Z */
2387 /* ??4ostream_withassign@@QAEAAVostream@@ABV1@@Z */
2388 /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */
2389 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2390 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2392 ios *base_rhs = ostream_get_ios(rhs);
2394 TRACE("(%p %p)\n", this, rhs);
2396 return ostream_assign_sb(this, base_rhs->sb);
2399 /* ??_Dostream@@QAEXXZ */
2400 /* ??_Dostream@@QEAAXXZ */
2401 /* ??_Dostream_withassign@@QAEXXZ */
2402 /* ??_Dostream_withassign@@QEAAXXZ */
2403 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2404 void __thiscall ostream_vbase_dtor(ostream *this)
2406 ios *base = ostream_to_ios(this);
2408 TRACE("(%p)\n", this);
2410 ostream_dtor(base);
2411 ios_dtor(base);
2414 /* ??_Eostream@@UAEPAXI@Z */
2415 /* ??_Eostream_withassign@@UAEPAXI@Z */
2416 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2417 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2419 ostream *this = ios_to_ostream(base);
2421 TRACE("(%p %x)\n", this, flags);
2423 if (flags & 2) {
2424 /* we have an array, with the number of elements stored before the first object */
2425 INT_PTR i, *ptr = (INT_PTR *)this-1;
2427 for (i = *ptr-1; i >= 0; i--)
2428 ostream_vbase_dtor(this+i);
2429 MSVCRT_operator_delete(ptr);
2430 } else {
2431 ostream_vbase_dtor(this);
2432 if (flags & 1)
2433 MSVCRT_operator_delete(this);
2435 return this;
2438 /* ??_Gostream@@UAEPAXI@Z */
2439 /* ??_Gostream_withassign@@UAEPAXI@Z */
2440 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2441 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2443 ostream *this = ios_to_ostream(base);
2445 TRACE("(%p %x)\n", this, flags);
2447 ostream_vbase_dtor(this);
2448 if (flags & 1) MSVCRT_operator_delete(this);
2449 return this;
2452 /* ?flush@ostream@@QAEAAV1@XZ */
2453 /* ?flush@ostream@@QEAAAEAV1@XZ */
2454 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2455 ostream* __thiscall ostream_flush(ostream *this)
2457 ios *base = ostream_get_ios(this);
2459 TRACE("(%p)\n", this);
2461 ios_lockbuf(base);
2462 if (call_streambuf_sync(base->sb) == EOF)
2463 ios_clear(base, base->state | IOSTATE_failbit);
2464 ios_unlockbuf(base);
2465 return this;
2468 /* ?opfx@ostream@@QAEHXZ */
2469 /* ?opfx@ostream@@QEAAHXZ */
2470 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2471 int __thiscall ostream_opfx(ostream *this)
2473 ios *base = ostream_get_ios(this);
2475 TRACE("(%p)\n", this);
2477 if (!ios_good(base)) {
2478 ios_clear(base, base->state | IOSTATE_failbit);
2479 return 0;
2481 ios_lock(base);
2482 ios_lockbuf(base);
2483 if (base->tie)
2484 ostream_flush(base->tie);
2485 return 1;
2488 /* ?osfx@ostream@@QAEXXZ */
2489 /* ?osfx@ostream@@QEAAXXZ */
2490 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2491 void __thiscall ostream_osfx(ostream *this)
2493 ios *base = ostream_get_ios(this);
2495 TRACE("(%p)\n", this);
2497 ios_unlockbuf(base);
2498 ios_width_set(base, 0);
2499 if (base->flags & FLAGS_unitbuf)
2500 ostream_flush(this);
2501 if (base->flags & FLAGS_stdio) {
2502 fflush(stdout);
2503 fflush(stderr);
2505 ios_unlock(base);
2508 /* ?put@ostream@@QAEAAV1@C@Z */
2509 /* ?put@ostream@@QEAAAEAV1@C@Z */
2510 /* ?put@ostream@@QAEAAV1@D@Z */
2511 /* ?put@ostream@@QEAAAEAV1@D@Z */
2512 /* ?put@ostream@@QAEAAV1@E@Z */
2513 /* ?put@ostream@@QEAAAEAV1@E@Z */
2514 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2515 ostream* __thiscall ostream_put(ostream *this, char c)
2517 ios *base = ostream_get_ios(this);
2519 TRACE("(%p %c)\n", this, c);
2521 if (ostream_opfx(this)) {
2522 if (streambuf_sputc(base->sb, c) == EOF)
2523 base->state = IOSTATE_badbit | IOSTATE_failbit;
2524 ostream_osfx(this);
2526 return this;
2529 /* ?seekp@ostream@@QAEAAV1@J@Z */
2530 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2531 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2532 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2534 ios *base = ostream_get_ios(this);
2536 TRACE("(%p %d)\n", this, pos);
2538 ios_lockbuf(base);
2539 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2540 ios_clear(base, base->state | IOSTATE_failbit);
2541 ios_unlockbuf(base);
2542 return this;
2545 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2546 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2547 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2548 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2550 ios *base = ostream_get_ios(this);
2552 TRACE("(%p %d %d)\n", this, off, dir);
2554 ios_lockbuf(base);
2555 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2556 ios_clear(base, base->state | IOSTATE_failbit);
2557 ios_unlockbuf(base);
2558 return this;
2561 /* ?tellp@ostream@@QAEJXZ */
2562 /* ?tellp@ostream@@QEAAJXZ */
2563 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2564 streampos __thiscall ostream_tellp(ostream *this)
2566 ios *base = ostream_get_ios(this);
2567 streampos pos;
2569 TRACE("(%p)\n", this);
2571 ios_lockbuf(base);
2572 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2573 ios_clear(base, base->state | IOSTATE_failbit);
2574 ios_unlockbuf(base);
2575 return pos;
2578 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2579 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2580 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2581 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2582 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2583 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2584 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2585 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2587 ios *base = ostream_get_ios(this);
2589 TRACE("(%p %p %d)\n", this, str, count);
2591 if (ostream_opfx(this)) {
2592 if (streambuf_sputn(base->sb, str, count) != count)
2593 base->state = IOSTATE_badbit | IOSTATE_failbit;
2594 ostream_osfx(this);
2596 return this;
2599 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2600 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2601 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2602 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2604 ios *base = ostream_get_ios(this);
2605 int len1 = strlen(str1), len2 = strlen(str2), i;
2607 TRACE("(%p %p %p)\n", this, str1, str2);
2609 /* left of the padding */
2610 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2611 if (streambuf_sputn(base->sb, str1, len1) != len1)
2612 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2613 if (!(base->flags & FLAGS_internal))
2614 if (streambuf_sputn(base->sb, str2, len2) != len2)
2615 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2617 /* add padding to fill the width */
2618 for (i = len1 + len2; i < base->width; i++)
2619 if (streambuf_sputc(base->sb, base->fill) == EOF)
2620 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2621 /* right of the padding */
2622 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2623 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2624 if (streambuf_sputn(base->sb, str1, len1) != len1)
2625 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2626 if (streambuf_sputn(base->sb, str2, len2) != len2)
2627 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2629 return this;
2632 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2634 ios *base = ostream_get_ios(ostr);
2635 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2637 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2639 if (ostream_opfx(ostr)) {
2640 if (base->flags & FLAGS_hex) {
2641 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2642 if (base->flags & FLAGS_showbase) {
2643 prefix_str[0] = '0';
2644 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2646 } else if (base->flags & FLAGS_oct) {
2647 sprintf_fmt[1] = 'o';
2648 if (base->flags & FLAGS_showbase)
2649 prefix_str[0] = '0';
2650 } else { /* FLAGS_dec */
2651 if (unsig)
2652 sprintf_fmt[1] = 'u';
2653 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2654 prefix_str[0] = '+';
2657 if (shrt) {
2658 sprintf_fmt[2] = sprintf_fmt[1];
2659 sprintf_fmt[1] = 'h';
2662 if (sprintf(number_str, sprintf_fmt, n) > 0)
2663 ostream_writepad(ostr, prefix_str, number_str);
2664 else
2665 base->state |= IOSTATE_failbit;
2666 ostream_osfx(ostr);
2668 return ostr;
2671 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2673 ios *base = ostream_get_ios(ostr);
2674 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2675 int prec, max_prec = dbl ? 15 : 6;
2676 int str_length = 1; /* null end char */
2678 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2680 if (ostream_opfx(ostr)) {
2681 if ((base->flags & FLAGS_showpos) && d > 0) {
2682 prefix_str[0] = '+';
2683 str_length++; /* plus sign */
2685 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2686 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2687 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2688 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2689 if (base->flags & FLAGS_showpoint) {
2690 sprintf_fmt[4] = sprintf_fmt[3];
2691 sprintf_fmt[3] = sprintf_fmt[2];
2692 sprintf_fmt[2] = sprintf_fmt[1];
2693 sprintf_fmt[1] = '#';
2696 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2697 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2698 if (str_length > 24) {
2699 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2700 ostream_writepad(ostr, "", "");
2701 } else {
2702 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2703 ostream_writepad(ostr, prefix_str, number_str);
2704 else
2705 base->state |= IOSTATE_failbit;
2707 ostream_osfx(ostr);
2709 return ostr;
2712 /* ??6ostream@@QAEAAV0@C@Z */
2713 /* ??6ostream@@QEAAAEAV0@C@Z */
2714 /* ??6ostream@@QAEAAV0@D@Z */
2715 /* ??6ostream@@QEAAAEAV0@D@Z */
2716 /* ??6ostream@@QAEAAV0@E@Z */
2717 /* ??6ostream@@QEAAAEAV0@E@Z */
2718 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2719 ostream* __thiscall ostream_print_char(ostream *this, char c)
2721 const char c_str[2] = {c, 0};
2723 TRACE("(%p %c)\n", this, c);
2725 if (ostream_opfx(this)) {
2726 ostream_writepad(this, "", c_str);
2727 ostream_osfx(this);
2729 return this;
2732 /* ??6ostream@@QAEAAV0@PBC@Z */
2733 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2734 /* ??6ostream@@QAEAAV0@PBD@Z */
2735 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2736 /* ??6ostream@@QAEAAV0@PBE@Z */
2737 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2738 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2739 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2741 TRACE("(%p %s)\n", this, str);
2742 if (ostream_opfx(this)) {
2743 ostream_writepad(this, "", str);
2744 ostream_osfx(this);
2746 return this;
2749 /* ??6ostream@@QAEAAV0@F@Z */
2750 /* ??6ostream@@QEAAAEAV0@F@Z */
2751 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2752 ostream* __thiscall ostream_print_short(ostream *this, short n)
2754 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2757 /* ??6ostream@@QAEAAV0@G@Z */
2758 /* ??6ostream@@QEAAAEAV0@G@Z */
2759 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2760 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2762 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2765 /* ??6ostream@@QAEAAV0@H@Z */
2766 /* ??6ostream@@QEAAAEAV0@H@Z */
2767 /* ??6ostream@@QAEAAV0@J@Z */
2768 /* ??6ostream@@QEAAAEAV0@J@Z */
2769 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2770 ostream* __thiscall ostream_print_int(ostream *this, int n)
2772 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2775 /* ??6ostream@@QAEAAV0@I@Z */
2776 /* ??6ostream@@QEAAAEAV0@I@Z */
2777 /* ??6ostream@@QAEAAV0@K@Z */
2778 /* ??6ostream@@QEAAAEAV0@K@Z */
2779 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2780 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2782 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2785 /* ??6ostream@@QAEAAV0@M@Z */
2786 /* ??6ostream@@QEAAAEAV0@M@Z */
2787 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2788 ostream* __thiscall ostream_print_float(ostream *this, float f)
2790 return ostream_internal_print_float(this, f, FALSE);
2793 /* ??6ostream@@QAEAAV0@N@Z */
2794 /* ??6ostream@@QEAAAEAV0@N@Z */
2795 /* ??6ostream@@QAEAAV0@O@Z */
2796 /* ??6ostream@@QEAAAEAV0@O@Z */
2797 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2798 ostream* __thiscall ostream_print_double(ostream *this, double d)
2800 return ostream_internal_print_float(this, d, TRUE);
2803 /* ??6ostream@@QAEAAV0@PBX@Z */
2804 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2805 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2806 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2808 ios *base = ostream_get_ios(this);
2809 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2811 TRACE("(%p %p)\n", this, ptr);
2813 if (ostream_opfx(this)) {
2814 if (ptr && base->flags & FLAGS_uppercase)
2815 prefix_str[1] = 'X';
2817 if (sprintf(pointer_str, "%p", ptr) > 0)
2818 ostream_writepad(this, prefix_str, pointer_str);
2819 else
2820 base->state |= IOSTATE_failbit;
2821 ostream_osfx(this);
2823 return this;
2826 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2827 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2828 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2829 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2831 ios *base = ostream_get_ios(this);
2832 int c;
2834 TRACE("(%p %p)\n", this, sb);
2836 if (ostream_opfx(this)) {
2837 while ((c = streambuf_sbumpc(sb)) != EOF) {
2838 if (streambuf_sputc(base->sb, c) == EOF) {
2839 base->state |= IOSTATE_failbit;
2840 break;
2843 ostream_osfx(this);
2845 return this;
2848 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2849 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2850 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2851 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2853 TRACE("(%p %p)\n", this, func);
2854 return func(this);
2857 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2858 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2859 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2860 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2862 TRACE("(%p %p)\n", this, func);
2863 func(ostream_get_ios(this));
2864 return this;
2867 /* ?endl@@YAAAVostream@@AAV1@@Z */
2868 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2869 ostream* __cdecl ostream_endl(ostream *this)
2871 TRACE("(%p)\n", this);
2872 ostream_put(this, '\n');
2873 return ostream_flush(this);
2876 /* ?ends@@YAAAVostream@@AAV1@@Z */
2877 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2878 ostream* __cdecl ostream_ends(ostream *this)
2880 TRACE("(%p)\n", this);
2881 return ostream_put(this, 0);
2884 /* ?flush@@YAAAVostream@@AAV1@@Z */
2885 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2886 ostream* __cdecl ostream_flush_manip(ostream *this)
2888 TRACE("(%p)\n", this);
2889 return ostream_flush(this);
2892 /* ??0ostream_withassign@@QAE@ABV0@@Z */
2893 /* ??0ostream_withassign@@QEAA@AEBV0@@Z */
2894 DEFINE_THISCALL_WRAPPER(ostream_withassign_copy_ctor, 12)
2895 ostream* __thiscall ostream_withassign_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2897 ios *base, *base_copy;
2899 TRACE("(%p %p %d)\n", this, copy, virt_init);
2901 base_copy = ostream_get_ios(copy);
2902 if (virt_init) {
2903 this->vbtable = ostream_vbtable;
2904 base = ostream_get_ios(this);
2905 ios_copy_ctor(base, base_copy);
2906 } else
2907 base = ostream_get_ios(this);
2908 ios_init(base, base_copy->sb);
2909 base->vtable = &MSVCP_ostream_withassign_vtable;
2910 this->unknown = 0;
2911 return this;
2914 /* ??0ostream_withassign@@QAE@PAVstreambuf@@@Z */
2915 /* ??0ostream_withassign@@QEAA@PEAVstreambuf@@@Z */
2916 DEFINE_THISCALL_WRAPPER(ostream_withassign_sb_ctor, 12)
2917 ostream* __thiscall ostream_withassign_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2919 ios *base;
2921 TRACE("(%p %p %d)\n", this, sb, virt_init);
2923 ostream_sb_ctor(this, sb, virt_init);
2924 base = ostream_get_ios(this);
2925 base->vtable = &MSVCP_ostream_withassign_vtable;
2926 return this;
2929 /* ??0ostream_withassign@@QAE@XZ */
2930 /* ??0ostream_withassign@@QEAA@XZ */
2931 DEFINE_THISCALL_WRAPPER(ostream_withassign_ctor, 8)
2932 ostream* __thiscall ostream_withassign_ctor(ostream *this, BOOL virt_init)
2934 ios *base;
2936 TRACE("(%p %d)\n", this, virt_init);
2938 ostream_ctor(this, virt_init);
2939 base = ostream_get_ios(this);
2940 base->vtable = &MSVCP_ostream_withassign_vtable;
2941 return this;
2944 static inline ios* istream_get_ios(const istream *this)
2946 return (ios*)((char*)this + this->vbtable[1]);
2949 static inline ios* istream_to_ios(const istream *this)
2951 return (ios*)((char*)this + istream_vbtable[1]);
2954 static inline istream* ios_to_istream(const ios *base)
2956 return (istream*)((char*)base - istream_vbtable[1]);
2959 /* ??0istream@@QAE@PAVstreambuf@@@Z */
2960 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
2961 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
2962 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
2964 ios *base;
2966 TRACE("(%p %p %d)\n", this, sb, virt_init);
2968 if (virt_init) {
2969 this->vbtable = istream_vbtable;
2970 base = istream_get_ios(this);
2971 ios_sb_ctor(base, sb);
2972 } else {
2973 base = istream_get_ios(this);
2974 ios_init(base, sb);
2976 base->vtable = &MSVCP_istream_vtable;
2977 base->flags |= FLAGS_skipws;
2978 this->extract_delim = 0;
2979 this->count = 0;
2980 return this;
2983 /* ??0istream@@IAE@ABV0@@Z */
2984 /* ??0istream@@IEAA@AEBV0@@Z */
2985 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
2986 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
2988 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
2991 /* ??0istream@@IAE@XZ */
2992 /* ??0istream@@IEAA@XZ */
2993 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
2994 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
2996 ios *base;
2998 TRACE("(%p %d)\n", this, virt_init);
3000 if (virt_init) {
3001 this->vbtable = istream_vbtable;
3002 base = istream_get_ios(this);
3003 ios_ctor(base);
3004 } else
3005 base = istream_get_ios(this);
3006 base->vtable = &MSVCP_istream_vtable;
3007 base->flags |= FLAGS_skipws;
3008 this->extract_delim = 0;
3009 this->count = 0;
3010 return this;
3013 /* ??1istream@@UAE@XZ */
3014 /* ??1istream@@UEAA@XZ */
3015 /* ??1istream_withassign@@UAE@XZ */
3016 /* ??1istream_withassign@@UEAA@XZ */
3017 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
3018 void __thiscall istream_dtor(ios *base)
3020 istream *this = ios_to_istream(base);
3022 TRACE("(%p)\n", this);
3025 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
3026 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3027 /* ??4istream_withassign@@QAEAAVistream@@PAVstreambuf@@@Z */
3028 /* ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z */
3029 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
3030 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
3032 ios *base = istream_get_ios(this);
3034 TRACE("(%p %p)\n", this, sb);
3036 ios_init(base, sb);
3037 base->state &= IOSTATE_badbit;
3038 base->delbuf = 0;
3039 base->tie = NULL;
3040 base->flags = FLAGS_skipws;
3041 base->precision = 6;
3042 base->fill = ' ';
3043 base->width = 0;
3044 this->count = 0;
3045 return this;
3048 /* ??4istream@@IAEAAV0@ABV0@@Z */
3049 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
3050 /* ??4istream_withassign@@QAEAAV0@ABV0@@Z */
3051 /* ??4istream_withassign@@QEAAAEAV0@AEBV0@@Z */
3052 /* ??4istream_withassign@@QAEAAVistream@@ABV1@@Z */
3053 /* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */
3054 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
3055 istream* __thiscall istream_assign(istream *this, const istream *rhs)
3057 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
3060 /* ??_Distream@@QAEXXZ */
3061 /* ??_Distream@@QEAAXXZ */
3062 /* ??_Distream_withassign@@QAEXXZ */
3063 /* ??_Distream_withassign@@QEAAXXZ */
3064 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
3065 void __thiscall istream_vbase_dtor(istream *this)
3067 ios *base = istream_to_ios(this);
3069 TRACE("(%p)\n", this);
3071 istream_dtor(base);
3072 ios_dtor(base);
3075 /* ??_Eistream@@UAEPAXI@Z */
3076 /* ??_Eistream_withassign@@UAEPAXI@Z */
3077 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
3078 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
3080 istream *this = ios_to_istream(base);
3082 TRACE("(%p %x)\n", this, flags);
3084 if (flags & 2) {
3085 /* we have an array, with the number of elements stored before the first object */
3086 INT_PTR i, *ptr = (INT_PTR *)this-1;
3088 for (i = *ptr-1; i >= 0; i--)
3089 istream_vbase_dtor(this+i);
3090 MSVCRT_operator_delete(ptr);
3091 } else {
3092 istream_vbase_dtor(this);
3093 if (flags & 1)
3094 MSVCRT_operator_delete(this);
3096 return this;
3099 /* ??_Gistream@@UAEPAXI@Z */
3100 /* ??_Gistream_withassign@@UAEPAXI@Z */
3101 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
3102 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
3104 istream *this = ios_to_istream(base);
3106 TRACE("(%p %x)\n", this, flags);
3108 istream_vbase_dtor(this);
3109 if (flags & 1) MSVCRT_operator_delete(this);
3110 return this;
3113 /* ?eatwhite@istream@@QAEXXZ */
3114 /* ?eatwhite@istream@@QEAAXXZ */
3115 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3116 void __thiscall istream_eatwhite(istream *this)
3118 ios *base = istream_get_ios(this);
3119 int c;
3121 TRACE("(%p)\n", this);
3123 ios_lockbuf(base);
3124 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3125 ios_unlockbuf(base);
3126 if (c == EOF)
3127 ios_clear(base, base->state | IOSTATE_eofbit);
3130 /* ?gcount@istream@@QBEHXZ */
3131 /* ?gcount@istream@@QEBAHXZ */
3132 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3133 int __thiscall istream_gcount(const istream *this)
3135 TRACE("(%p)\n", this);
3136 return this->count;
3139 /* ?ipfx@istream@@QAEHH@Z */
3140 /* ?ipfx@istream@@QEAAHH@Z */
3141 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3142 int __thiscall istream_ipfx(istream *this, int need)
3144 ios *base = istream_get_ios(this);
3146 TRACE("(%p %d)\n", this, need);
3148 if (need)
3149 this->count = 0;
3150 if (!ios_good(base)) {
3151 ios_clear(base, base->state | IOSTATE_failbit);
3152 return 0;
3154 ios_lock(base);
3155 ios_lockbuf(base);
3156 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3157 ostream_flush(base->tie);
3158 if ((base->flags & FLAGS_skipws) && !need) {
3159 istream_eatwhite(this);
3160 if (base->state & IOSTATE_eofbit) {
3161 base->state |= IOSTATE_failbit;
3162 ios_unlockbuf(base);
3163 ios_unlock(base);
3164 return 0;
3167 return 1;
3170 /* ?isfx@istream@@QAEXXZ */
3171 /* ?isfx@istream@@QEAAXXZ */
3172 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3173 void __thiscall istream_isfx(istream *this)
3175 ios *base = istream_get_ios(this);
3177 TRACE("(%p)\n", this);
3179 ios_unlockbuf(base);
3180 ios_unlock(base);
3183 /* ?get@istream@@IAEAAV1@PADHH@Z */
3184 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3185 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3186 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3188 ios *base = istream_get_ios(this);
3189 int ch, i = 0;
3191 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3193 if (istream_ipfx(this, 1)) {
3194 while (i < count - 1) {
3195 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3196 base->state |= IOSTATE_eofbit;
3197 if (!i) /* tried to read, but not a single character was obtained */
3198 base->state |= IOSTATE_failbit;
3199 break;
3201 if (ch == delim) {
3202 if (this->extract_delim) { /* discard the delimiter */
3203 streambuf_stossc(base->sb);
3204 this->count++;
3206 break;
3208 if (str)
3209 str[i] = ch;
3210 streambuf_stossc(base->sb);
3211 i++;
3213 this->count += i;
3214 istream_isfx(this);
3216 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3217 str[i] = 0;
3218 this->extract_delim = 0;
3219 return this;
3222 /* ?get@istream@@QAEAAV1@PACHD@Z */
3223 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3224 /* ?get@istream@@QAEAAV1@PADHD@Z */
3225 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3226 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3227 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3228 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3229 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3231 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3234 static int istream_internal_get_char(istream *this, char *ch)
3236 ios *base = istream_get_ios(this);
3237 int ret = EOF;
3239 TRACE("(%p %p)\n", this, ch);
3241 if (istream_ipfx(this, 1)) {
3242 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3243 this->count = 1;
3244 } else {
3245 base->state |= IOSTATE_eofbit;
3246 if (ch)
3247 base->state |= IOSTATE_failbit;
3249 if (ch)
3250 *ch = ret;
3251 istream_isfx(this);
3253 return ret;
3256 /* ?get@istream@@QAEAAV1@AAC@Z */
3257 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3258 /* ?get@istream@@QAEAAV1@AAD@Z */
3259 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3260 /* ?get@istream@@QAEAAV1@AAE@Z */
3261 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3262 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3263 istream* __thiscall istream_get_char(istream *this, char *ch)
3265 istream_internal_get_char(this, ch);
3266 return this;
3269 /* ?get@istream@@QAEHXZ */
3270 /* ?get@istream@@QEAAHXZ */
3271 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3272 int __thiscall istream_get(istream *this)
3274 return istream_internal_get_char(this, NULL);
3277 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3278 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3279 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3280 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3282 ios *base = istream_get_ios(this);
3283 int ch;
3285 TRACE("(%p %p %c)\n", this, sb, delim);
3287 if (istream_ipfx(this, 1)) {
3288 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3289 if (ch == EOF) {
3290 base->state |= IOSTATE_eofbit;
3291 break;
3293 if (streambuf_sputc(sb, ch) == EOF)
3294 base->state |= IOSTATE_failbit;
3295 this->count++;
3297 istream_isfx(this);
3299 return this;
3302 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3303 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3304 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3305 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3306 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3307 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3308 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3309 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3311 ios *base = istream_get_ios(this);
3313 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3315 ios_lock(base);
3316 this->extract_delim++;
3317 istream_get_str_delim(this, str, count, (unsigned char) delim);
3318 ios_unlock(base);
3319 return this;
3322 /* ?ignore@istream@@QAEAAV1@HH@Z */
3323 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3324 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3325 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3327 ios *base = istream_get_ios(this);
3329 TRACE("(%p %d %d)\n", this, count, delim);
3331 ios_lock(base);
3332 this->extract_delim++;
3333 istream_get_str_delim(this, NULL, count + 1, delim);
3334 ios_unlock(base);
3335 return this;
3338 /* ?peek@istream@@QAEHXZ */
3339 /* ?peek@istream@@QEAAHXZ */
3340 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3341 int __thiscall istream_peek(istream *this)
3343 ios *base = istream_get_ios(this);
3344 int ret = EOF;
3346 TRACE("(%p)\n", this);
3348 if (istream_ipfx(this, 1)) {
3349 ret = streambuf_sgetc(base->sb);
3350 istream_isfx(this);
3352 return ret;
3355 /* ?putback@istream@@QAEAAV1@D@Z */
3356 /* ?putback@istream@@QEAAAEAV1@D@Z */
3357 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3358 istream* __thiscall istream_putback(istream *this, char ch)
3360 ios *base = istream_get_ios(this);
3362 TRACE("(%p %c)\n", this, ch);
3364 if (ios_good(base)) {
3365 ios_lockbuf(base);
3366 if (streambuf_sputbackc(base->sb, ch) == EOF)
3367 ios_clear(base, base->state | IOSTATE_failbit);
3368 ios_unlockbuf(base);
3370 return this;
3373 /* ?read@istream@@QAEAAV1@PACH@Z */
3374 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3375 /* ?read@istream@@QAEAAV1@PADH@Z */
3376 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3377 /* ?read@istream@@QAEAAV1@PAEH@Z */
3378 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3379 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3380 istream* __thiscall istream_read(istream *this, char *str, int count)
3382 ios *base = istream_get_ios(this);
3384 TRACE("(%p %p %d)\n", this, str, count);
3386 if (istream_ipfx(this, 1)) {
3387 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3388 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3389 istream_isfx(this);
3391 return this;
3394 /* ?seekg@istream@@QAEAAV1@J@Z */
3395 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3396 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3397 istream* __thiscall istream_seekg(istream *this, streampos pos)
3399 ios *base = istream_get_ios(this);
3401 TRACE("(%p %d)\n", this, pos);
3403 ios_lockbuf(base);
3404 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3405 ios_clear(base, base->state | IOSTATE_failbit);
3406 ios_unlockbuf(base);
3407 return this;
3410 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3411 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3412 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3413 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3415 ios *base = istream_get_ios(this);
3417 TRACE("(%p %d %d)\n", this, off, dir);
3419 ios_lockbuf(base);
3420 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3421 ios_clear(base, base->state | IOSTATE_failbit);
3422 ios_unlockbuf(base);
3423 return this;
3426 /* ?sync@istream@@QAEHXZ */
3427 /* ?sync@istream@@QEAAHXZ */
3428 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3429 int __thiscall istream_sync(istream *this)
3431 ios *base = istream_get_ios(this);
3432 int ret;
3434 TRACE("(%p)\n", this);
3436 ios_lockbuf(base);
3437 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3438 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3439 ios_unlockbuf(base);
3440 return ret;
3443 /* ?tellg@istream@@QAEJXZ */
3444 /* ?tellg@istream@@QEAAJXZ */
3445 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3446 streampos __thiscall istream_tellg(istream *this)
3448 ios *base = istream_get_ios(this);
3449 streampos pos;
3451 TRACE("(%p)\n", this);
3453 ios_lockbuf(base);
3454 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3455 ios_clear(base, base->state | IOSTATE_failbit);
3456 ios_unlockbuf(base);
3457 return pos;
3460 static int getint_is_valid_digit(char ch, int base)
3462 if (base == 8) return (ch >= '0' && ch <= '7');
3463 if (base == 16) return isxdigit(ch);
3464 return isdigit(ch);
3467 /* ?getint@istream@@AAEHPAD@Z */
3468 /* ?getint@istream@@AEAAHPEAD@Z */
3469 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3470 int __thiscall istream_getint(istream *this, char *str)
3472 ios *base = istream_get_ios(this);
3473 int ch, num_base = 0, i = 0;
3474 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3476 TRACE("(%p %p)\n", this, str);
3478 if (istream_ipfx(this, 0)) {
3479 num_base = (base->flags & FLAGS_dec) ? 10 :
3480 (base->flags & FLAGS_hex) ? 16 :
3481 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3482 /* scan valid characters, up to 15 (hard limit on Windows) */
3483 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3484 if ((ch == '+' || ch == '-') && scan_sign) {
3485 /* no additional sign allowed */
3486 scan_sign = FALSE;
3487 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3488 /* only hex digits can (and must) follow */
3489 scan_x = valid_integer = FALSE;
3490 num_base = 16;
3491 } else if (ch == '0' && scan_prefix) {
3492 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3493 scan_sign = scan_prefix = FALSE;
3494 scan_x = !num_base || num_base == 16;
3495 valid_integer = TRUE;
3496 if (!num_base)
3497 num_base = 8;
3498 } else if (getint_is_valid_digit(ch, num_base)) {
3499 /* only digits in the corresponding base can follow */
3500 scan_sign = scan_prefix = scan_x = FALSE;
3501 valid_integer = TRUE;
3502 } else {
3503 /* unexpected character, stop scanning */
3504 if (!valid_integer) {
3505 /* the result is not a valid integer */
3506 base->state |= IOSTATE_failbit;
3507 /* put any extracted character back into the stream */
3508 while (i > 0)
3509 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3510 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3511 } else if (ch == EOF) {
3512 base->state |= IOSTATE_eofbit;
3513 if (scan_x && !(base->flags & ios_basefield)) {
3514 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3515 num_base = 0;
3518 break;
3520 str[i++] = ch;
3522 /* append a null terminator */
3523 str[i] = 0;
3524 istream_isfx(this);
3526 return num_base;
3529 /* ?getdouble@istream@@AAEHPADH@Z */
3530 /* ?getdouble@istream@@AEAAHPEADH@Z */
3531 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3532 int __thiscall istream_getdouble(istream *this, char *str, int count)
3534 ios *base = istream_get_ios(this);
3535 int ch, i = 0;
3536 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3537 valid_mantissa = FALSE, valid_exponent = FALSE;
3539 TRACE("(%p %p %d)\n", this, str, count);
3541 if (istream_ipfx(this, 0)) {
3542 if (!count) {
3543 /* can't output anything */
3544 base->state |= IOSTATE_failbit;
3545 i = -1;
3546 } else {
3547 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3548 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3549 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3550 if ((ch == '+' || ch == '-') && scan_sign) {
3551 /* no additional sign allowed */
3552 scan_sign = FALSE;
3553 } else if (ch == '.' && scan_dot) {
3554 /* no sign or additional dot allowed */
3555 scan_sign = scan_dot = FALSE;
3556 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3557 /* sign is allowed again but not dots or exponents */
3558 scan_sign = TRUE;
3559 scan_dot = scan_exp = FALSE;
3560 } else if (isdigit(ch)) {
3561 if (scan_exp)
3562 valid_mantissa = TRUE;
3563 else
3564 valid_exponent = TRUE;
3565 /* no sign allowed after a digit */
3566 scan_sign = FALSE;
3567 } else {
3568 /* unexpected character, stop scanning */
3569 /* check whether the result is a valid double */
3570 if (!scan_exp && !valid_exponent) {
3571 /* put the last character back into the stream, usually the 'e' or 'E' */
3572 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3573 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3574 } else if (ch == EOF)
3575 base->state |= IOSTATE_eofbit;
3576 if (!valid_mantissa)
3577 base->state |= IOSTATE_failbit;
3578 break;
3580 str[i++] = ch;
3582 /* check if character limit has been reached */
3583 if (i == count) {
3584 base->state |= IOSTATE_failbit;
3585 i--;
3587 /* append a null terminator */
3588 str[i] = 0;
3590 istream_isfx(this);
3592 return i;
3595 /* ??5istream@@QAEAAV0@AAC@Z */
3596 /* ??5istream@@QEAAAEAV0@AEAC@Z */
3597 /* ??5istream@@QAEAAV0@AAD@Z */
3598 /* ??5istream@@QEAAAEAV0@AEAD@Z */
3599 /* ??5istream@@QAEAAV0@AAE@Z */
3600 /* ??5istream@@QEAAAEAV0@AEAE@Z */
3601 DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
3602 istream* __thiscall istream_read_char(istream *this, char *ch)
3604 ios *base = istream_get_ios(this);
3605 int ret;
3607 TRACE("(%p %p)\n", this, ch);
3609 if (istream_ipfx(this, 0)) {
3610 if ((ret = streambuf_sbumpc(base->sb)) == EOF)
3611 base->state |= IOSTATE_eofbit | IOSTATE_failbit;
3612 else
3613 *ch = ret;
3614 istream_isfx(this);
3616 return this;
3619 /* ??5istream@@QAEAAV0@PAC@Z */
3620 /* ??5istream@@QEAAAEAV0@PEAC@Z */
3621 /* ??5istream@@QAEAAV0@PAD@Z */
3622 /* ??5istream@@QEAAAEAV0@PEAD@Z */
3623 /* ??5istream@@QAEAAV0@PAE@Z */
3624 /* ??5istream@@QEAAAEAV0@PEAE@Z */
3625 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
3626 istream* __thiscall istream_read_str(istream *this, char *str)
3628 ios *base = istream_get_ios(this);
3629 int ch, count = 0;
3631 TRACE("(%p %p)\n", this, str);
3633 if (istream_ipfx(this, 0)) {
3634 if (str) {
3635 for (ch = streambuf_sgetc(base->sb);
3636 count < (unsigned int) base->width - 1 && !isspace(ch);
3637 ch = streambuf_snextc(base->sb)) {
3638 if (ch == EOF) {
3639 base->state |= IOSTATE_eofbit;
3640 break;
3642 str[count++] = ch;
3645 if (!count) /* nothing to output */
3646 base->state |= IOSTATE_failbit;
3647 else /* append a null terminator */
3648 str[count] = 0;
3649 base->width = 0;
3650 istream_isfx(this);
3652 return this;
3655 static LONG istream_internal_read_integer(istream *this, LONG min_value, LONG max_value, BOOL set_flag)
3657 ios *base = istream_get_ios(this);
3658 char buffer[16];
3659 int num_base;
3660 LONG ret;
3662 TRACE("(%p %d %d %d)\n", this, min_value, max_value, set_flag);
3664 num_base = istream_getint(this, buffer);
3665 errno = 0;
3666 ret = strtol(buffer, NULL, num_base);
3667 /* check for overflow and whether the value fits in the output var */
3668 if (set_flag && errno == ERANGE) {
3669 base->state |= IOSTATE_failbit;
3670 } else if (ret > max_value) {
3671 base->state |= IOSTATE_failbit;
3672 ret = max_value;
3673 } else if (ret < min_value) {
3674 base->state |= IOSTATE_failbit;
3675 ret = min_value;
3677 return ret;
3680 static ULONG istream_internal_read_unsigned_integer(istream *this, LONG min_value, ULONG max_value)
3682 ios *base = istream_get_ios(this);
3683 char buffer[16];
3684 int num_base;
3685 ULONG ret;
3687 TRACE("(%p %d %u)\n", this, min_value, max_value);
3689 num_base = istream_getint(this, buffer);
3690 errno = 0;
3691 ret = strtoul(buffer, NULL, num_base);
3692 /* check for overflow and whether the value fits in the output var */
3693 if ((ret == ULONG_MAX && errno == ERANGE) ||
3694 (ret > max_value && ret < (ULONG) min_value)) {
3695 base->state |= IOSTATE_failbit;
3696 ret = max_value;
3698 return ret;
3701 /* ??5istream@@QAEAAV0@AAF@Z */
3702 /* ??5istream@@QEAAAEAV0@AEAF@Z */
3703 DEFINE_THISCALL_WRAPPER(istream_read_short, 8)
3704 istream* __thiscall istream_read_short(istream *this, short *p)
3706 if (istream_ipfx(this, 0)) {
3707 *p = istream_internal_read_integer(this, SHRT_MIN, SHRT_MAX, FALSE);
3708 istream_isfx(this);
3710 return this;
3713 /* ??5istream@@QAEAAV0@AAG@Z */
3714 /* ??5istream@@QEAAAEAV0@AEAG@Z */
3715 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_short, 8)
3716 istream* __thiscall istream_read_unsigned_short(istream *this, unsigned short *p)
3718 if (istream_ipfx(this, 0)) {
3719 *p = istream_internal_read_unsigned_integer(this, SHRT_MIN, USHRT_MAX);
3720 istream_isfx(this);
3722 return this;
3725 /* ??5istream@@QAEAAV0@AAH@Z */
3726 /* ??5istream@@QEAAAEAV0@AEAH@Z */
3727 DEFINE_THISCALL_WRAPPER(istream_read_int, 8)
3728 istream* __thiscall istream_read_int(istream *this, int *p)
3730 if (istream_ipfx(this, 0)) {
3731 *p = istream_internal_read_integer(this, INT_MIN, INT_MAX, FALSE);
3732 istream_isfx(this);
3734 return this;
3737 /* ??5istream@@QAEAAV0@AAI@Z */
3738 /* ??5istream@@QEAAAEAV0@AEAI@Z */
3739 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_int, 8)
3740 istream* __thiscall istream_read_unsigned_int(istream *this, unsigned int *p)
3742 if (istream_ipfx(this, 0)) {
3743 *p = istream_internal_read_unsigned_integer(this, INT_MIN, UINT_MAX);
3744 istream_isfx(this);
3746 return this;
3749 /* ??5istream@@QAEAAV0@AAJ@Z */
3750 /* ??5istream@@QEAAAEAV0@AEAJ@Z */
3751 DEFINE_THISCALL_WRAPPER(istream_read_long, 8)
3752 istream* __thiscall istream_read_long(istream *this, LONG *p)
3754 if (istream_ipfx(this, 0)) {
3755 *p = istream_internal_read_integer(this, LONG_MIN, LONG_MAX, TRUE);
3756 istream_isfx(this);
3758 return this;
3761 /* ??5istream@@QAEAAV0@AAK@Z */
3762 /* ??5istream@@QEAAAEAV0@AEAK@Z */
3763 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_long, 8)
3764 istream* __thiscall istream_read_unsigned_long(istream *this, ULONG *p)
3766 if (istream_ipfx(this, 0)) {
3767 *p = istream_internal_read_unsigned_integer(this, LONG_MIN, ULONG_MAX);
3768 istream_isfx(this);
3770 return this;
3773 static BOOL istream_internal_read_float(istream *this, int max_chars, double *out)
3775 char buffer[32];
3776 BOOL read = FALSE;
3778 TRACE("(%p %d %p)\n", this, max_chars, out);
3780 if (istream_ipfx(this, 0)) {
3781 /* character count is limited on Windows */
3782 if (istream_getdouble(this, buffer, max_chars) > 0) {
3783 *out = strtod(buffer, NULL);
3784 read = TRUE;
3786 istream_isfx(this);
3788 return read;
3791 /* ??5istream@@QAEAAV0@AAM@Z */
3792 /* ??5istream@@QEAAAEAV0@AEAM@Z */
3793 DEFINE_THISCALL_WRAPPER(istream_read_float, 8)
3794 istream* __thiscall istream_read_float(istream *this, float *f)
3796 double tmp;
3797 if (istream_internal_read_float(this, 20, &tmp)) {
3798 /* check whether the value fits in the output var */
3799 if (tmp > FLT_MAX)
3800 tmp = FLT_MAX;
3801 else if (tmp < -FLT_MAX)
3802 tmp = -FLT_MAX;
3803 else if (tmp > 0 && tmp < FLT_MIN)
3804 tmp = FLT_MIN;
3805 else if (tmp < 0 && tmp > -FLT_MIN)
3806 tmp = -FLT_MIN;
3807 *f = tmp;
3809 return this;
3812 /* ??5istream@@QAEAAV0@AAN@Z */
3813 /* ??5istream@@QEAAAEAV0@AEAN@Z */
3814 DEFINE_THISCALL_WRAPPER(istream_read_double, 8)
3815 istream* __thiscall istream_read_double(istream *this, double *d)
3817 istream_internal_read_float(this, 28, d);
3818 return this;
3821 /* ??5istream@@QAEAAV0@AAO@Z */
3822 /* ??5istream@@QEAAAEAV0@AEAO@Z */
3823 DEFINE_THISCALL_WRAPPER(istream_read_long_double, 8)
3824 istream* __thiscall istream_read_long_double(istream *this, double *ld)
3826 istream_internal_read_float(this, 32, ld);
3827 return this;
3830 /* ??5istream@@QAEAAV0@PAVstreambuf@@@Z */
3831 /* ??5istream@@QEAAAEAV0@PEAVstreambuf@@@Z */
3832 DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
3833 istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
3835 ios *base = istream_get_ios(this);
3836 int ch;
3838 TRACE("(%p %p)\n", this, sb);
3840 if (istream_ipfx(this, 0)) {
3841 while ((ch = streambuf_sbumpc(base->sb)) != EOF)
3842 if (streambuf_sputc(sb, ch) == EOF)
3843 base->state |= IOSTATE_failbit;
3844 istream_isfx(this);
3846 return this;
3849 /* ??5istream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
3850 /* ??5istream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
3851 DEFINE_THISCALL_WRAPPER(istream_read_manip, 8)
3852 istream* __thiscall istream_read_manip(istream *this, istream* (__cdecl *func)(istream*))
3854 TRACE("(%p %p)\n", this, func);
3855 return func(this);
3858 /* ??5istream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
3859 /* ??5istream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
3860 DEFINE_THISCALL_WRAPPER(istream_read_ios_manip, 8)
3861 istream* __thiscall istream_read_ios_manip(istream *this, ios* (__cdecl *func)(ios*))
3863 TRACE("(%p %p)\n", this, func);
3864 func(istream_get_ios(this));
3865 return this;
3868 /* ?ws@@YAAAVistream@@AAV1@@Z */
3869 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
3870 istream* __cdecl istream_ws(istream *this)
3872 TRACE("(%p)\n", this);
3873 istream_eatwhite(this);
3874 return this;
3877 /* ??0istream_withassign@@QAE@ABV0@@Z */
3878 /* ??0istream_withassign@@QEAA@AEBV0@@Z */
3879 DEFINE_THISCALL_WRAPPER(istream_withassign_copy_ctor, 12)
3880 istream* __thiscall istream_withassign_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
3882 ios *base, *base_copy;
3884 TRACE("(%p %p %d)\n", this, copy, virt_init);
3886 base_copy = istream_get_ios(copy);
3887 if (virt_init) {
3888 this->vbtable = istream_vbtable;
3889 base = istream_get_ios(this);
3890 ios_copy_ctor(base, base_copy);
3891 } else
3892 base = istream_get_ios(this);
3893 ios_init(base, base_copy->sb);
3894 base->vtable = &MSVCP_istream_withassign_vtable;
3895 base->flags |= FLAGS_skipws;
3896 this->extract_delim = 0;
3897 this->count = 0;
3898 return this;
3901 /* ??0istream_withassign@@QAE@PAVstreambuf@@@Z */
3902 /* ??0istream_withassign@@QEAA@PEAVstreambuf@@@Z */
3903 DEFINE_THISCALL_WRAPPER(istream_withassign_sb_ctor, 12)
3904 istream* __thiscall istream_withassign_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
3906 ios *base;
3908 TRACE("(%p %p %d)\n", this, sb, virt_init);
3910 istream_sb_ctor(this, sb, virt_init);
3911 base = istream_get_ios(this);
3912 base->vtable = &MSVCP_istream_withassign_vtable;
3913 return this;
3916 /* ??0istream_withassign@@QAE@XZ */
3917 /* ??0istream_withassign@@QEAA@XZ */
3918 DEFINE_THISCALL_WRAPPER(istream_withassign_ctor, 8)
3919 istream* __thiscall istream_withassign_ctor(istream *this, BOOL virt_init)
3921 ios *base;
3923 TRACE("(%p %d)\n", this, virt_init);
3925 istream_ctor(this, virt_init);
3926 base = istream_get_ios(this);
3927 base->vtable = &MSVCP_istream_withassign_vtable;
3928 return this;
3931 static inline ios* iostream_to_ios(const iostream *this)
3933 return (ios*)((char*)this + iostream_vbtable_istream[1]);
3936 static inline iostream* ios_to_iostream(const ios *base)
3938 return (iostream*)((char*)base - iostream_vbtable_istream[1]);
3941 /* ??0iostream@@IAE@XZ */
3942 /* ??0iostream@@IEAA@XZ */
3943 DEFINE_THISCALL_WRAPPER(iostream_ctor, 8)
3944 iostream* __thiscall iostream_ctor(iostream *this, BOOL virt_init)
3946 ios *base;
3948 TRACE("(%p %d)\n", this, virt_init);
3950 if (virt_init) {
3951 this->base1.vbtable = iostream_vbtable_istream;
3952 this->base2.vbtable = iostream_vbtable_ostream;
3953 base = istream_get_ios(&this->base1);
3954 ios_ctor(base);
3955 } else
3956 base = istream_get_ios(&this->base1);
3957 istream_ctor(&this->base1, FALSE);
3958 ostream_ctor(&this->base2, FALSE);
3959 base->vtable = &MSVCP_iostream_vtable;
3960 return this;
3963 /* ??0iostream@@QAE@PAVstreambuf@@@Z */
3964 /* ??0iostream@@QEAA@PEAVstreambuf@@@Z */
3965 DEFINE_THISCALL_WRAPPER(iostream_sb_ctor, 12)
3966 iostream* __thiscall iostream_sb_ctor(iostream *this, streambuf *sb, BOOL virt_init)
3968 TRACE("(%p %p %d)\n", this, sb, virt_init);
3969 iostream_ctor(this, virt_init);
3970 ios_init(istream_get_ios(&this->base1), sb);
3971 return this;
3974 /* ??0iostream@@IAE@ABV0@@Z */
3975 /* ??0iostream@@IEAA@AEBV0@@Z */
3976 DEFINE_THISCALL_WRAPPER(iostream_copy_ctor, 12)
3977 iostream* __thiscall iostream_copy_ctor(iostream *this, const iostream *copy, BOOL virt_init)
3979 return iostream_sb_ctor(this, istream_get_ios(&copy->base1)->sb, virt_init);
3982 /* ??1iostream@@UAE@XZ */
3983 /* ??1iostream@@UEAA@XZ */
3984 DEFINE_THISCALL_WRAPPER(iostream_dtor, 4)
3985 void __thiscall iostream_dtor(ios *base)
3987 iostream *this = ios_to_iostream(base);
3989 TRACE("(%p)\n", this);
3991 ostream_dtor(ostream_to_ios(&this->base2));
3992 istream_dtor(istream_to_ios(&this->base1));
3995 /* ??4iostream@@IAEAAV0@PAVstreambuf@@@Z */
3996 /* ??4iostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
3997 DEFINE_THISCALL_WRAPPER(iostream_assign_sb, 8)
3998 iostream* __thiscall iostream_assign_sb(iostream *this, streambuf *sb)
4000 FIXME("(%p %p) stub\n", this, sb);
4001 return this;
4004 /* ??4iostream@@IAEAAV0@AAV0@@Z */
4005 /* ??4iostream@@IEAAAEAV0@AEAV0@@Z */
4006 DEFINE_THISCALL_WRAPPER(iostream_assign, 8)
4007 iostream* __thiscall iostream_assign(iostream *this, const iostream *rhs)
4009 FIXME("(%p %p) stub\n", this, rhs);
4010 return this;
4013 /* ??_Diostream@@QAEXXZ */
4014 /* ??_Diostream@@QEAAXXZ */
4015 DEFINE_THISCALL_WRAPPER(iostream_vbase_dtor, 4)
4016 void __thiscall iostream_vbase_dtor(iostream *this)
4018 ios *base = iostream_to_ios(this);
4020 TRACE("(%p)\n", this);
4022 iostream_dtor(base);
4023 ios_dtor(base);
4026 /* ??_Eiostream@@UAEPAXI@Z */
4027 DEFINE_THISCALL_WRAPPER(iostream_vector_dtor, 8)
4028 iostream* __thiscall iostream_vector_dtor(ios *base, unsigned int flags)
4030 iostream *this = ios_to_iostream(base);
4032 TRACE("(%p %x)\n", this, flags);
4034 if (flags & 2) {
4035 /* we have an array, with the number of elements stored before the first object */
4036 INT_PTR i, *ptr = (INT_PTR *)this-1;
4038 for (i = *ptr-1; i >= 0; i--)
4039 iostream_vbase_dtor(this+i);
4040 MSVCRT_operator_delete(ptr);
4041 } else {
4042 iostream_vbase_dtor(this);
4043 if (flags & 1)
4044 MSVCRT_operator_delete(this);
4046 return this;
4049 /* ??_Giostream@@UAEPAXI@Z */
4050 DEFINE_THISCALL_WRAPPER(iostream_scalar_dtor, 8)
4051 iostream* __thiscall iostream_scalar_dtor(ios *base, unsigned int flags)
4053 iostream *this = ios_to_iostream(base);
4055 TRACE("(%p %x)\n", this, flags);
4057 iostream_vbase_dtor(this);
4058 if (flags & 1) MSVCRT_operator_delete(this);
4059 return this;
4062 /******************************************************************
4063 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
4065 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
4066 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
4068 FIXME("(%p %x) stub\n", this, virt_init);
4069 return this;
4072 /******************************************************************
4073 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
4075 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
4076 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
4078 FIXME("(%p) stub\n", base);
4081 #ifdef __i386__
4083 #define DEFINE_VTBL_WRAPPER(off) \
4084 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
4085 "popl %eax\n\t" \
4086 "popl %ecx\n\t" \
4087 "pushl %eax\n\t" \
4088 "movl 0(%ecx), %eax\n\t" \
4089 "jmp *" #off "(%eax)\n\t")
4091 DEFINE_VTBL_WRAPPER(0);
4092 DEFINE_VTBL_WRAPPER(4);
4093 DEFINE_VTBL_WRAPPER(8);
4094 DEFINE_VTBL_WRAPPER(12);
4095 DEFINE_VTBL_WRAPPER(16);
4096 DEFINE_VTBL_WRAPPER(20);
4097 DEFINE_VTBL_WRAPPER(24);
4098 DEFINE_VTBL_WRAPPER(28);
4099 DEFINE_VTBL_WRAPPER(32);
4100 DEFINE_VTBL_WRAPPER(36);
4101 DEFINE_VTBL_WRAPPER(40);
4102 DEFINE_VTBL_WRAPPER(44);
4103 DEFINE_VTBL_WRAPPER(48);
4104 DEFINE_VTBL_WRAPPER(52);
4105 DEFINE_VTBL_WRAPPER(56);
4107 #endif
4109 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
4110 void (__cdecl *MSVCRT_operator_delete)(void*);
4112 static void init_cxx_funcs(void)
4114 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
4116 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
4118 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
4119 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
4121 else
4123 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
4124 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
4128 static void init_io(void *base)
4130 #ifdef __x86_64__
4131 init_streambuf_rtti(base);
4132 init_filebuf_rtti(base);
4133 init_strstreambuf_rtti(base);
4134 init_stdiobuf_rtti(base);
4135 init_ios_rtti(base);
4136 init_ostream_rtti(base);
4137 init_ostream_withassign_rtti(base);
4138 init_istream_rtti(base);
4139 init_istream_withassign_rtti(base);
4140 init_iostream_rtti(base);
4141 #endif
4144 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
4146 switch (reason)
4148 case DLL_WINE_PREATTACH:
4149 return FALSE; /* prefer native version */
4150 case DLL_PROCESS_ATTACH:
4151 init_cxx_funcs();
4152 init_exception(inst);
4153 init_io(inst);
4154 DisableThreadLibraryCalls( inst );
4155 break;
4157 return TRUE;