Release 1.9.16.
[wine.git] / dlls / msvcirt / msvcirt.c
blob9a0a05b69245ff64f8b0410b3dbcfe38d53d7563
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 /* ??_7streambuf@@6B@ */
168 extern const vtable_ptr MSVCP_streambuf_vtable;
169 /* ??_7filebuf@@6B@ */
170 extern const vtable_ptr MSVCP_filebuf_vtable;
171 /* ??_7strstreambuf@@6B@ */
172 extern const vtable_ptr MSVCP_strstreambuf_vtable;
173 /* ??_7stdiobuf@@6B@ */
174 extern const vtable_ptr MSVCP_stdiobuf_vtable;
175 /* ??_7ios@@6B@ */
176 extern const vtable_ptr MSVCP_ios_vtable;
177 /* ??_7ostream@@6B@ */
178 extern const vtable_ptr MSVCP_ostream_vtable;
179 /* ??_7istream@@6B@ */
180 extern const vtable_ptr MSVCP_istream_vtable;
182 #ifndef __GNUC__
183 void __asm_dummy_vtables(void) {
184 #endif
185 __ASM_VTABLE(streambuf,
186 VTABLE_ADD_FUNC(streambuf_vector_dtor)
187 VTABLE_ADD_FUNC(streambuf_sync)
188 VTABLE_ADD_FUNC(streambuf_setbuf)
189 VTABLE_ADD_FUNC(streambuf_seekoff)
190 VTABLE_ADD_FUNC(streambuf_seekpos)
191 VTABLE_ADD_FUNC(streambuf_xsputn)
192 VTABLE_ADD_FUNC(streambuf_xsgetn)
193 VTABLE_ADD_FUNC(streambuf_overflow)
194 VTABLE_ADD_FUNC(streambuf_underflow)
195 VTABLE_ADD_FUNC(streambuf_pbackfail)
196 VTABLE_ADD_FUNC(streambuf_doallocate));
197 __ASM_VTABLE(filebuf,
198 VTABLE_ADD_FUNC(filebuf_vector_dtor)
199 VTABLE_ADD_FUNC(filebuf_sync)
200 VTABLE_ADD_FUNC(filebuf_setbuf)
201 VTABLE_ADD_FUNC(filebuf_seekoff)
202 VTABLE_ADD_FUNC(streambuf_seekpos)
203 VTABLE_ADD_FUNC(streambuf_xsputn)
204 VTABLE_ADD_FUNC(streambuf_xsgetn)
205 VTABLE_ADD_FUNC(filebuf_overflow)
206 VTABLE_ADD_FUNC(filebuf_underflow)
207 VTABLE_ADD_FUNC(streambuf_pbackfail)
208 VTABLE_ADD_FUNC(streambuf_doallocate));
209 __ASM_VTABLE(strstreambuf,
210 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
211 VTABLE_ADD_FUNC(strstreambuf_sync)
212 VTABLE_ADD_FUNC(strstreambuf_setbuf)
213 VTABLE_ADD_FUNC(strstreambuf_seekoff)
214 VTABLE_ADD_FUNC(streambuf_seekpos)
215 VTABLE_ADD_FUNC(streambuf_xsputn)
216 VTABLE_ADD_FUNC(streambuf_xsgetn)
217 VTABLE_ADD_FUNC(strstreambuf_overflow)
218 VTABLE_ADD_FUNC(strstreambuf_underflow)
219 VTABLE_ADD_FUNC(streambuf_pbackfail)
220 VTABLE_ADD_FUNC(strstreambuf_doallocate));
221 __ASM_VTABLE(stdiobuf,
222 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
223 VTABLE_ADD_FUNC(stdiobuf_sync)
224 VTABLE_ADD_FUNC(streambuf_setbuf)
225 VTABLE_ADD_FUNC(stdiobuf_seekoff)
226 VTABLE_ADD_FUNC(streambuf_seekpos)
227 VTABLE_ADD_FUNC(streambuf_xsputn)
228 VTABLE_ADD_FUNC(streambuf_xsgetn)
229 VTABLE_ADD_FUNC(stdiobuf_overflow)
230 VTABLE_ADD_FUNC(stdiobuf_underflow)
231 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
232 VTABLE_ADD_FUNC(streambuf_doallocate));
233 __ASM_VTABLE(ios,
234 VTABLE_ADD_FUNC(ios_vector_dtor));
235 __ASM_VTABLE(ostream,
236 VTABLE_ADD_FUNC(ostream_vector_dtor));
237 __ASM_VTABLE(istream,
238 VTABLE_ADD_FUNC(istream_vector_dtor));
239 #ifndef __GNUC__
241 #endif
243 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
244 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
246 /* ??_8ostream@@7B@ */
247 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
248 /* ??_8istream@@7B@ */
249 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
251 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
252 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
253 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
254 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
255 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
256 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
257 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
259 /* ??0streambuf@@IAE@PADH@Z */
260 /* ??0streambuf@@IEAA@PEADH@Z */
261 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
262 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
264 TRACE("(%p %p %d)\n", this, buffer, length);
265 this->vtable = &MSVCP_streambuf_vtable;
266 this->allocated = 0;
267 this->stored_char = EOF;
268 this->do_lock = -1;
269 this->base = NULL;
270 streambuf_setbuf(this, buffer, length);
271 streambuf_setg(this, NULL, NULL, NULL);
272 streambuf_setp(this, NULL, NULL);
273 InitializeCriticalSection(&this->lock);
274 return this;
277 /* ??0streambuf@@IAE@XZ */
278 /* ??0streambuf@@IEAA@XZ */
279 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
280 streambuf* __thiscall streambuf_ctor(streambuf *this)
282 streambuf_reserve_ctor(this, NULL, 0);
283 this->unbuffered = 0;
284 return this;
287 /* ??0streambuf@@QAE@ABV0@@Z */
288 /* ??0streambuf@@QEAA@AEBV0@@Z */
289 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
290 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
292 TRACE("(%p %p)\n", this, copy);
293 *this = *copy;
294 this->vtable = &MSVCP_streambuf_vtable;
295 return this;
298 /* ??1streambuf@@UAE@XZ */
299 /* ??1streambuf@@UEAA@XZ */
300 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
301 void __thiscall streambuf_dtor(streambuf *this)
303 TRACE("(%p)\n", this);
304 if (this->allocated)
305 MSVCRT_operator_delete(this->base);
306 DeleteCriticalSection(&this->lock);
309 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
310 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
311 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
312 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
314 streambuf_dtor(this);
315 return streambuf_copy_ctor(this, rhs);
318 /* ??_Estreambuf@@UAEPAXI@Z */
319 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
320 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
321 streambuf*, (streambuf*, unsigned int), (this, flags))
322 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
324 TRACE("(%p %x)\n", this, flags);
325 if (flags & 2) {
326 /* we have an array, with the number of elements stored before the first object */
327 INT_PTR i, *ptr = (INT_PTR *)this-1;
329 for (i = *ptr-1; i >= 0; i--)
330 streambuf_dtor(this+i);
331 MSVCRT_operator_delete(ptr);
332 } else {
333 streambuf_dtor(this);
334 if (flags & 1)
335 MSVCRT_operator_delete(this);
337 return this;
340 /* ??_Gstreambuf@@UAEPAXI@Z */
341 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
342 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
344 TRACE("(%p %x)\n", this, flags);
345 streambuf_dtor(this);
346 if (flags & 1) MSVCRT_operator_delete(this);
347 return this;
350 /* ?doallocate@streambuf@@MAEHXZ */
351 /* ?doallocate@streambuf@@MEAAHXZ */
352 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
353 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
354 int __thiscall streambuf_doallocate(streambuf *this)
356 char *reserve;
358 TRACE("(%p)\n", this);
359 reserve = MSVCRT_operator_new(RESERVE_SIZE);
360 if (!reserve)
361 return EOF;
363 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
364 return 1;
367 /* ?allocate@streambuf@@IAEHXZ */
368 /* ?allocate@streambuf@@IEAAHXZ */
369 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
370 int __thiscall streambuf_allocate(streambuf *this)
372 TRACE("(%p)\n", this);
373 if (this->base != NULL || this->unbuffered)
374 return 0;
375 return call_streambuf_doallocate(this);
378 /* ?base@streambuf@@IBEPADXZ */
379 /* ?base@streambuf@@IEBAPEADXZ */
380 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
381 char* __thiscall streambuf_base(const streambuf *this)
383 TRACE("(%p)\n", this);
384 return this->base;
387 /* ?blen@streambuf@@IBEHXZ */
388 /* ?blen@streambuf@@IEBAHXZ */
389 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
390 int __thiscall streambuf_blen(const streambuf *this)
392 TRACE("(%p)\n", this);
393 return this->ebuf - this->base;
396 /* ?eback@streambuf@@IBEPADXZ */
397 /* ?eback@streambuf@@IEBAPEADXZ */
398 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
399 char* __thiscall streambuf_eback(const streambuf *this)
401 TRACE("(%p)\n", this);
402 return this->eback;
405 /* ?ebuf@streambuf@@IBEPADXZ */
406 /* ?ebuf@streambuf@@IEBAPEADXZ */
407 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
408 char* __thiscall streambuf_ebuf(const streambuf *this)
410 TRACE("(%p)\n", this);
411 return this->ebuf;
414 /* ?egptr@streambuf@@IBEPADXZ */
415 /* ?egptr@streambuf@@IEBAPEADXZ */
416 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
417 char* __thiscall streambuf_egptr(const streambuf *this)
419 TRACE("(%p)\n", this);
420 return this->egptr;
423 /* ?epptr@streambuf@@IBEPADXZ */
424 /* ?epptr@streambuf@@IEBAPEADXZ */
425 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
426 char* __thiscall streambuf_epptr(const streambuf *this)
428 TRACE("(%p)\n", this);
429 return this->epptr;
432 /* ?gptr@streambuf@@IBEPADXZ */
433 /* ?gptr@streambuf@@IEBAPEADXZ */
434 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
435 char* __thiscall streambuf_gptr(const streambuf *this)
437 TRACE("(%p)\n", this);
438 return this->gptr;
441 /* ?pbase@streambuf@@IBEPADXZ */
442 /* ?pbase@streambuf@@IEBAPEADXZ */
443 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
444 char* __thiscall streambuf_pbase(const streambuf *this)
446 TRACE("(%p)\n", this);
447 return this->pbase;
450 /* ?pptr@streambuf@@IBEPADXZ */
451 /* ?pptr@streambuf@@IEBAPEADXZ */
452 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
453 char* __thiscall streambuf_pptr(const streambuf *this)
455 TRACE("(%p)\n", this);
456 return this->pptr;
459 /* ?clrlock@streambuf@@QAEXXZ */
460 /* ?clrlock@streambuf@@QEAAXXZ */
461 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
462 void __thiscall streambuf_clrlock(streambuf *this)
464 TRACE("(%p)\n", this);
465 if (this->do_lock <= 0)
466 this->do_lock++;
469 /* ?lock@streambuf@@QAEXXZ */
470 /* ?lock@streambuf@@QEAAXXZ */
471 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
472 void __thiscall streambuf_lock(streambuf *this)
474 TRACE("(%p)\n", this);
475 if (this->do_lock < 0)
476 EnterCriticalSection(&this->lock);
479 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
480 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
481 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
482 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
484 TRACE("(%p)\n", this);
485 return &this->lock;
488 /* ?gbump@streambuf@@IAEXH@Z */
489 /* ?gbump@streambuf@@IEAAXH@Z */
490 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
491 void __thiscall streambuf_gbump(streambuf *this, int count)
493 TRACE("(%p %d)\n", this, count);
494 this->gptr += count;
497 /* ?pbump@streambuf@@IAEXH@Z */
498 /* ?pbump@streambuf@@IEAAXH@Z */
499 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
500 void __thiscall streambuf_pbump(streambuf *this, int count)
502 TRACE("(%p %d)\n", this, count);
503 this->pptr += count;
506 /* ?in_avail@streambuf@@QBEHXZ */
507 /* ?in_avail@streambuf@@QEBAHXZ */
508 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
509 int __thiscall streambuf_in_avail(const streambuf *this)
511 TRACE("(%p)\n", this);
512 return this->egptr - this->gptr;
515 /* ?out_waiting@streambuf@@QBEHXZ */
516 /* ?out_waiting@streambuf@@QEBAHXZ */
517 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
518 int __thiscall streambuf_out_waiting(const streambuf *this)
520 TRACE("(%p)\n", this);
521 return this->pptr - this->pbase;
524 /* Unexported */
525 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
526 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
527 int __thiscall streambuf_overflow(streambuf *this, int c)
529 ERR("overflow is not implemented in streambuf\n");
530 return EOF;
533 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
534 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
535 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
536 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
537 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
539 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
540 return EOF;
543 /* ?seekpos@streambuf@@UAEJJH@Z */
544 /* ?seekpos@streambuf@@UEAAJJH@Z */
545 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
546 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
548 TRACE("(%p %d %d)\n", this, pos, mode);
549 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
552 /* ?pbackfail@streambuf@@UAEHH@Z */
553 /* ?pbackfail@streambuf@@UEAAHH@Z */
554 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
555 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
556 int __thiscall streambuf_pbackfail(streambuf *this, int c)
558 TRACE("(%p %d)\n", this, c);
559 if (this->gptr > this->eback)
560 return *--this->gptr = c;
561 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
562 return EOF;
563 if (!this->unbuffered && this->egptr) {
564 /* 'c' should be the next character read */
565 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
566 *this->gptr = c;
568 return c;
571 /* ?setb@streambuf@@IAEXPAD0H@Z */
572 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
573 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
574 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
576 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
577 if (this->allocated)
578 MSVCRT_operator_delete(this->base);
579 this->allocated = delete;
580 this->base = ba;
581 this->ebuf = eb;
584 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
585 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
586 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
587 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
589 TRACE("(%p %p %d)\n", this, buffer, length);
590 if (this->base != NULL)
591 return NULL;
593 if (buffer == NULL || !length) {
594 this->unbuffered = 1;
595 this->base = this->ebuf = NULL;
596 } else {
597 this->unbuffered = 0;
598 this->base = buffer;
599 this->ebuf = buffer + length;
601 return this;
604 /* ?setg@streambuf@@IAEXPAD00@Z */
605 /* ?setg@streambuf@@IEAAXPEAD00@Z */
606 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
607 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
609 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
610 this->eback = ek;
611 this->gptr = gp;
612 this->egptr = eg;
615 /* ?setlock@streambuf@@QAEXXZ */
616 /* ?setlock@streambuf@@QEAAXXZ */
617 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
618 void __thiscall streambuf_setlock(streambuf *this)
620 TRACE("(%p)\n", this);
621 this->do_lock--;
624 /* ?setp@streambuf@@IAEXPAD0@Z */
625 /* ?setp@streambuf@@IEAAXPEAD0@Z */
626 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
627 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
629 TRACE("(%p %p %p)\n", this, pb, ep);
630 this->pbase = this->pptr = pb;
631 this->epptr = ep;
634 /* ?sync@streambuf@@UAEHXZ */
635 /* ?sync@streambuf@@UEAAHXZ */
636 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
637 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
638 int __thiscall streambuf_sync(streambuf *this)
640 TRACE("(%p)\n", this);
641 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
644 /* ?unbuffered@streambuf@@IAEXH@Z */
645 /* ?unbuffered@streambuf@@IEAAXH@Z */
646 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
647 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
649 TRACE("(%p %d)\n", this, buf);
650 this->unbuffered = buf;
653 /* ?unbuffered@streambuf@@IBEHXZ */
654 /* ?unbuffered@streambuf@@IEBAHXZ */
655 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
656 int __thiscall streambuf_unbuffered_get(const streambuf *this)
658 TRACE("(%p)\n", this);
659 return this->unbuffered;
662 /* Unexported */
663 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
664 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
665 int __thiscall streambuf_underflow(streambuf *this)
667 ERR("underflow is not implemented in streambuf\n");
668 return EOF;
671 /* ?unlock@streambuf@@QAEXXZ */
672 /* ?unlock@streambuf@@QEAAXXZ */
673 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
674 void __thiscall streambuf_unlock(streambuf *this)
676 TRACE("(%p)\n", this);
677 if (this->do_lock < 0)
678 LeaveCriticalSection(&this->lock);
681 /* ?xsgetn@streambuf@@UAEHPADH@Z */
682 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
683 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
684 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
685 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
687 int copied = 0, chunk;
689 TRACE("(%p %p %d)\n", this, buffer, count);
691 if (this->unbuffered) {
692 if (this->stored_char == EOF)
693 this->stored_char = call_streambuf_underflow(this);
694 while (copied < count && this->stored_char != EOF) {
695 buffer[copied++] = this->stored_char;
696 this->stored_char = call_streambuf_underflow(this);
698 } else {
699 while (copied < count) {
700 if (call_streambuf_underflow(this) == EOF)
701 break;
702 chunk = this->egptr - this->gptr;
703 if (chunk > count - copied)
704 chunk = count - copied;
705 memcpy(buffer+copied, this->gptr, chunk);
706 this->gptr += chunk;
707 copied += chunk;
710 return copied;
713 /* ?xsputn@streambuf@@UAEHPBDH@Z */
714 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
715 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
716 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
717 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
719 int copied = 0, chunk;
721 TRACE("(%p %p %d)\n", this, data, length);
723 while (copied < length) {
724 if (this->unbuffered || this->pptr == this->epptr) {
725 if (call_streambuf_overflow(this, data[copied]) == EOF)
726 break;
727 copied++;
728 } else {
729 chunk = this->epptr - this->pptr;
730 if (chunk > length - copied)
731 chunk = length - copied;
732 memcpy(this->pptr, data+copied, chunk);
733 this->pptr += chunk;
734 copied += chunk;
737 return copied;
740 /* ?sgetc@streambuf@@QAEHXZ */
741 /* ?sgetc@streambuf@@QEAAHXZ */
742 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
743 int __thiscall streambuf_sgetc(streambuf *this)
745 TRACE("(%p)\n", this);
746 if (this->unbuffered) {
747 if (this->stored_char == EOF)
748 this->stored_char = call_streambuf_underflow(this);
749 return this->stored_char;
750 } else
751 return call_streambuf_underflow(this);
754 /* ?sputc@streambuf@@QAEHH@Z */
755 /* ?sputc@streambuf@@QEAAHH@Z */
756 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
757 int __thiscall streambuf_sputc(streambuf *this, int ch)
759 TRACE("(%p %d)\n", this, ch);
760 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
763 /* ?sgetn@streambuf@@QAEHPADH@Z */
764 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
765 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
766 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
768 return call_streambuf_xsgetn(this, buffer, count);
771 /* ?sputn@streambuf@@QAEHPBDH@Z */
772 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
773 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
774 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
776 return call_streambuf_xsputn(this, data, length);
779 /* ?snextc@streambuf@@QAEHXZ */
780 /* ?snextc@streambuf@@QEAAHXZ */
781 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
782 int __thiscall streambuf_snextc(streambuf *this)
784 TRACE("(%p)\n", this);
785 if (this->unbuffered) {
786 if (this->stored_char == EOF)
787 call_streambuf_underflow(this);
788 return this->stored_char = call_streambuf_underflow(this);
789 } else {
790 if (this->gptr >= this->egptr)
791 call_streambuf_underflow(this);
792 this->gptr++;
793 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
797 /* ?sbumpc@streambuf@@QAEHXZ */
798 /* ?sbumpc@streambuf@@QEAAHXZ */
799 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
800 int __thiscall streambuf_sbumpc(streambuf *this)
802 int ret;
804 TRACE("(%p)\n", this);
806 if (this->unbuffered) {
807 ret = this->stored_char;
808 this->stored_char = EOF;
809 if (ret == EOF)
810 ret = call_streambuf_underflow(this);
811 } else {
812 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
813 this->gptr++;
815 return ret;
818 /* ?stossc@streambuf@@QAEXXZ */
819 /* ?stossc@streambuf@@QEAAXXZ */
820 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
821 void __thiscall streambuf_stossc(streambuf *this)
823 TRACE("(%p)\n", this);
824 if (this->unbuffered) {
825 if (this->stored_char == EOF)
826 call_streambuf_underflow(this);
827 else
828 this->stored_char = EOF;
829 } else {
830 if (this->gptr >= this->egptr)
831 call_streambuf_underflow(this);
832 if (this->gptr < this->egptr)
833 this->gptr++;
837 /* ?sputbackc@streambuf@@QAEHD@Z */
838 /* ?sputbackc@streambuf@@QEAAHD@Z */
839 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
840 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
842 TRACE("(%p %d)\n", this, ch);
843 return call_streambuf_pbackfail(this, ch);
846 /* ?dbp@streambuf@@QAEXXZ */
847 /* ?dbp@streambuf@@QEAAXXZ */
848 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
849 void __thiscall streambuf_dbp(streambuf *this)
851 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
852 if (this->unbuffered) {
853 printf("unbuffered\n");
854 } else {
855 printf("_fAlloc=%d\n", this->allocated);
856 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
857 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
858 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
862 /* ??0filebuf@@QAE@ABV0@@Z */
863 /* ??0filebuf@@QEAA@AEBV0@@Z */
864 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
865 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
867 TRACE("(%p %p)\n", this, copy);
868 *this = *copy;
869 this->base.vtable = &MSVCP_filebuf_vtable;
870 return this;
873 /* ??0filebuf@@QAE@HPADH@Z */
874 /* ??0filebuf@@QEAA@HPEADH@Z */
875 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
876 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
878 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
879 streambuf_reserve_ctor(&this->base, buffer, length);
880 this->base.vtable = &MSVCP_filebuf_vtable;
881 this->fd = fd;
882 this->close = 0;
883 return this;
886 /* ??0filebuf@@QAE@H@Z */
887 /* ??0filebuf@@QEAA@H@Z */
888 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
889 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
891 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
892 this->base.unbuffered = 0;
893 return this;
896 /* ??0filebuf@@QAE@XZ */
897 /* ??0filebuf@@QEAA@XZ */
898 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
899 filebuf* __thiscall filebuf_ctor(filebuf* this)
901 return filebuf_fd_ctor(this, -1);
904 /* ??1filebuf@@UAE@XZ */
905 /* ??1filebuf@@UEAA@XZ */
906 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
907 void __thiscall filebuf_dtor(filebuf* this)
909 TRACE("(%p)\n", this);
910 if (this->close)
911 filebuf_close(this);
912 streambuf_dtor(&this->base);
915 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
916 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
917 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
918 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
920 filebuf_dtor(this);
921 return filebuf_copy_ctor(this, rhs);
924 /* ??_Efilebuf@@UAEPAXI@Z */
925 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
926 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
928 TRACE("(%p %x)\n", this, flags);
929 if (flags & 2) {
930 /* we have an array, with the number of elements stored before the first object */
931 INT_PTR i, *ptr = (INT_PTR *)this-1;
933 for (i = *ptr-1; i >= 0; i--)
934 filebuf_dtor(this+i);
935 MSVCRT_operator_delete(ptr);
936 } else {
937 filebuf_dtor(this);
938 if (flags & 1)
939 MSVCRT_operator_delete(this);
941 return this;
944 /* ??_Gfilebuf@@UAEPAXI@Z */
945 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
946 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
948 TRACE("(%p %x)\n", this, flags);
949 filebuf_dtor(this);
950 if (flags & 1) MSVCRT_operator_delete(this);
951 return this;
954 /* ?attach@filebuf@@QAEPAV1@H@Z */
955 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
956 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
957 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
959 TRACE("(%p %d)\n", this, fd);
960 if (this->fd != -1)
961 return NULL;
963 streambuf_lock(&this->base);
964 this->fd = fd;
965 streambuf_allocate(&this->base);
966 streambuf_unlock(&this->base);
967 return this;
970 /* ?close@filebuf@@QAEPAV1@XZ */
971 /* ?close@filebuf@@QEAAPEAV1@XZ */
972 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
973 filebuf* __thiscall filebuf_close(filebuf *this)
975 filebuf *ret;
977 TRACE("(%p)\n", this);
978 if (this->fd == -1)
979 return NULL;
981 streambuf_lock(&this->base);
982 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
983 ret = NULL;
984 } else {
985 this->fd = -1;
986 ret = this;
988 streambuf_unlock(&this->base);
989 return ret;
992 /* ?fd@filebuf@@QBEHXZ */
993 /* ?fd@filebuf@@QEBAHXZ */
994 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
995 filedesc __thiscall filebuf_fd(const filebuf *this)
997 TRACE("(%p)\n", this);
998 return this->fd;
1001 /* ?is_open@filebuf@@QBEHXZ */
1002 /* ?is_open@filebuf@@QEBAHXZ */
1003 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1004 int __thiscall filebuf_is_open(const filebuf *this)
1006 TRACE("(%p)\n", this);
1007 return this->fd != -1;
1010 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1011 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1012 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1013 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1015 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1016 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1017 int op_flags, sh_flags, fd;
1019 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1020 if (this->fd != -1)
1021 return NULL;
1023 /* mode */
1024 if (mode & (OPENMODE_app|OPENMODE_trunc))
1025 mode |= OPENMODE_out;
1026 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1027 if (op_flags < 0)
1028 return NULL;
1029 if (mode & OPENMODE_app)
1030 op_flags |= _O_APPEND;
1031 if ((mode & OPENMODE_trunc) ||
1032 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1033 op_flags |= _O_TRUNC;
1034 if (!(mode & OPENMODE_nocreate))
1035 op_flags |= _O_CREAT;
1036 if (mode & OPENMODE_noreplace)
1037 op_flags |= _O_EXCL;
1038 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1040 /* share protection */
1041 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1043 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1044 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1045 if (fd < 0)
1046 return NULL;
1048 streambuf_lock(&this->base);
1049 this->close = 1;
1050 this->fd = fd;
1051 if ((mode & OPENMODE_ate) &&
1052 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1053 _close(fd);
1054 this->fd = -1;
1056 streambuf_allocate(&this->base);
1057 streambuf_unlock(&this->base);
1058 return (this->fd == -1) ? NULL : this;
1061 /* ?overflow@filebuf@@UAEHH@Z */
1062 /* ?overflow@filebuf@@UEAAHH@Z */
1063 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1064 int __thiscall filebuf_overflow(filebuf *this, int c)
1066 TRACE("(%p %d)\n", this, c);
1067 if (call_streambuf_sync(&this->base) == EOF)
1068 return EOF;
1069 if (this->base.unbuffered)
1070 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1071 if (streambuf_allocate(&this->base) == EOF)
1072 return EOF;
1074 this->base.pbase = this->base.pptr = this->base.base;
1075 this->base.epptr = this->base.ebuf;
1076 if (c != EOF)
1077 *this->base.pptr++ = c;
1078 return 1;
1081 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1082 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1083 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1084 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1086 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1087 if (call_streambuf_sync(&this->base) == EOF)
1088 return EOF;
1089 return _lseek(this->fd, offset, dir);
1092 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1093 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1094 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1095 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1097 streambuf *ret;
1099 TRACE("(%p %p %d)\n", this, buffer, length);
1100 if (this->base.base != NULL)
1101 return NULL;
1103 streambuf_lock(&this->base);
1104 ret = streambuf_setbuf(&this->base, buffer, length);
1105 streambuf_unlock(&this->base);
1106 return ret;
1109 /* ?setmode@filebuf@@QAEHH@Z */
1110 /* ?setmode@filebuf@@QEAAHH@Z */
1111 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1112 int __thiscall filebuf_setmode(filebuf *this, int mode)
1114 int ret;
1116 TRACE("(%p %d)\n", this, mode);
1117 if (mode != filebuf_text && mode != filebuf_binary)
1118 return -1;
1120 streambuf_lock(&this->base);
1121 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1122 streambuf_unlock(&this->base);
1123 return ret;
1126 /* ?sync@filebuf@@UAEHXZ */
1127 /* ?sync@filebuf@@UEAAHXZ */
1128 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1129 int __thiscall filebuf_sync(filebuf *this)
1131 int count, mode;
1132 char *ptr;
1133 LONG offset;
1135 TRACE("(%p)\n", this);
1136 if (this->fd == -1)
1137 return EOF;
1138 if (this->base.unbuffered)
1139 return 0;
1141 /* flush output buffer */
1142 if (this->base.pptr != NULL) {
1143 count = this->base.pptr - this->base.pbase;
1144 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1145 return EOF;
1147 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1148 /* flush input buffer */
1149 if (this->base.egptr != NULL) {
1150 offset = this->base.egptr - this->base.gptr;
1151 if (offset > 0) {
1152 mode = _setmode(this->fd, _O_TEXT);
1153 _setmode(this->fd, mode);
1154 if (mode & _O_TEXT) {
1155 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1156 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1157 if (*ptr == '\n')
1158 offset++;
1160 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1161 return EOF;
1164 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1165 return 0;
1168 /* ?underflow@filebuf@@UAEHXZ */
1169 /* ?underflow@filebuf@@UEAAHXZ */
1170 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1171 int __thiscall filebuf_underflow(filebuf *this)
1173 int buffer_size, read_bytes;
1174 char c;
1176 TRACE("(%p)\n", this);
1178 if (this->base.unbuffered)
1179 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1181 if (this->base.gptr >= this->base.egptr) {
1182 if (call_streambuf_sync(&this->base) == EOF)
1183 return EOF;
1184 buffer_size = this->base.ebuf - this->base.base;
1185 read_bytes = _read(this->fd, this->base.base, buffer_size);
1186 if (read_bytes <= 0)
1187 return EOF;
1188 this->base.eback = this->base.gptr = this->base.base;
1189 this->base.egptr = this->base.base + read_bytes;
1191 return (unsigned char) *this->base.gptr;
1194 /* ??0strstreambuf@@QAE@ABV0@@Z */
1195 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1196 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1197 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1199 TRACE("(%p %p)\n", this, copy);
1200 *this = *copy;
1201 this->base.vtable = &MSVCP_strstreambuf_vtable;
1202 return this;
1205 /* ??0strstreambuf@@QAE@H@Z */
1206 /* ??0strstreambuf@@QEAA@H@Z */
1207 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1208 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1210 TRACE("(%p %d)\n", this, length);
1211 streambuf_ctor(&this->base);
1212 this->base.vtable = &MSVCP_strstreambuf_vtable;
1213 this->dynamic = 1;
1214 this->increase = length;
1215 this->constant = 0;
1216 this->f_alloc = NULL;
1217 this->f_free = NULL;
1218 return this;
1221 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1222 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1223 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1224 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1226 TRACE("(%p %p %p)\n", this, falloc, ffree);
1227 strstreambuf_dynamic_ctor(this, 1);
1228 this->f_alloc = falloc;
1229 this->f_free = ffree;
1230 return this;
1233 /* ??0strstreambuf@@QAE@PADH0@Z */
1234 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1235 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1236 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1238 char *end_buffer;
1240 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1242 if (length > 0)
1243 end_buffer = buffer + length;
1244 else if (length == 0)
1245 end_buffer = buffer + strlen(buffer);
1246 else
1247 end_buffer = (char*) -1;
1249 streambuf_ctor(&this->base);
1250 streambuf_setb(&this->base, buffer, end_buffer, 0);
1251 if (put == NULL) {
1252 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1253 } else {
1254 streambuf_setg(&this->base, buffer, buffer, put);
1255 streambuf_setp(&this->base, put, end_buffer);
1257 this->base.vtable = &MSVCP_strstreambuf_vtable;
1258 this->dynamic = 0;
1259 this->constant = 1;
1260 return this;
1263 /* ??0strstreambuf@@QAE@PAEH0@Z */
1264 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1265 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1266 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1268 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1269 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1272 /* ??0strstreambuf@@QAE@XZ */
1273 /* ??0strstreambuf@@QEAA@XZ */
1274 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1275 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1277 TRACE("(%p)\n", this);
1278 return strstreambuf_dynamic_ctor(this, 1);
1281 /* ??1strstreambuf@@UAE@XZ */
1282 /* ??1strstreambuf@@UEAA@XZ */
1283 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1284 void __thiscall strstreambuf_dtor(strstreambuf *this)
1286 TRACE("(%p)\n", this);
1287 if (this->dynamic && this->base.base) {
1288 if (this->f_free)
1289 this->f_free(this->base.base);
1290 else
1291 MSVCRT_operator_delete(this->base.base);
1293 streambuf_dtor(&this->base);
1296 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1297 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1298 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1299 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1301 strstreambuf_dtor(this);
1302 return strstreambuf_copy_ctor(this, rhs);
1305 /* ??_Estrstreambuf@@UAEPAXI@Z */
1306 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1307 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1309 TRACE("(%p %x)\n", this, flags);
1310 if (flags & 2) {
1311 /* we have an array, with the number of elements stored before the first object */
1312 INT_PTR i, *ptr = (INT_PTR *)this-1;
1314 for (i = *ptr-1; i >= 0; i--)
1315 strstreambuf_dtor(this+i);
1316 MSVCRT_operator_delete(ptr);
1317 } else {
1318 strstreambuf_dtor(this);
1319 if (flags & 1)
1320 MSVCRT_operator_delete(this);
1322 return this;
1325 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1326 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1327 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1329 TRACE("(%p %x)\n", this, flags);
1330 strstreambuf_dtor(this);
1331 if (flags & 1) MSVCRT_operator_delete(this);
1332 return this;
1335 /* ?doallocate@strstreambuf@@MAEHXZ */
1336 /* ?doallocate@strstreambuf@@MEAAHXZ */
1337 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1338 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1340 char *prev_buffer = this->base.base, *new_buffer;
1341 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1343 TRACE("(%p)\n", this);
1345 /* calculate the size of the new buffer */
1346 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1347 /* get a new buffer */
1348 if (this->f_alloc)
1349 new_buffer = this->f_alloc(new_size);
1350 else
1351 new_buffer = MSVCRT_operator_new(new_size);
1352 if (!new_buffer)
1353 return EOF;
1354 if (this->base.ebuf) {
1355 /* copy the contents and adjust the pointers */
1356 memcpy(new_buffer, this->base.base, prev_size);
1357 if (this->base.egptr) {
1358 this->base.eback += new_buffer - prev_buffer;
1359 this->base.gptr += new_buffer - prev_buffer;
1360 this->base.egptr += new_buffer - prev_buffer;
1362 if (this->base.epptr) {
1363 this->base.pbase += new_buffer - prev_buffer;
1364 this->base.pptr += new_buffer - prev_buffer;
1365 this->base.epptr += new_buffer - prev_buffer;
1367 /* free the old buffer */
1368 if (this->f_free)
1369 this->f_free(this->base.base);
1370 else
1371 MSVCRT_operator_delete(this->base.base);
1373 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1374 return 1;
1377 /* ?freeze@strstreambuf@@QAEXH@Z */
1378 /* ?freeze@strstreambuf@@QEAAXH@Z */
1379 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1380 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1382 TRACE("(%p %d)\n", this, frozen);
1383 if (!this->constant)
1384 this->dynamic = !frozen;
1387 /* ?overflow@strstreambuf@@UAEHH@Z */
1388 /* ?overflow@strstreambuf@@UEAAHH@Z */
1389 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1390 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1392 TRACE("(%p %d)\n", this, c);
1393 if (this->base.pptr >= this->base.epptr) {
1394 /* increase the buffer size if it's dynamic */
1395 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1396 return EOF;
1397 if (!this->base.epptr)
1398 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1399 this->base.epptr = this->base.ebuf;
1401 if (c != EOF)
1402 *this->base.pptr++ = c;
1403 return 1;
1406 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1407 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1408 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1409 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1411 char *base[3];
1413 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1415 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1416 return EOF;
1417 /* read buffer */
1418 if (mode & OPENMODE_in) {
1419 call_streambuf_underflow(&this->base);
1420 base[SEEKDIR_beg] = this->base.eback;
1421 base[SEEKDIR_cur] = this->base.gptr;
1422 base[SEEKDIR_end] = this->base.egptr;
1423 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1424 return EOF;
1425 this->base.gptr = base[dir] + offset;
1427 /* write buffer */
1428 if (mode & OPENMODE_out) {
1429 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1430 return EOF;
1431 base[SEEKDIR_beg] = this->base.pbase;
1432 base[SEEKDIR_cur] = this->base.pptr;
1433 base[SEEKDIR_end] = this->base.epptr;
1434 if (base[dir] + offset < this->base.pbase)
1435 return EOF;
1436 if (base[dir] + offset > this->base.epptr) {
1437 /* make room if the buffer is dynamic */
1438 if (!this->dynamic)
1439 return EOF;
1440 this->increase = offset;
1441 if (call_streambuf_doallocate(&this->base) == EOF)
1442 return EOF;
1444 this->base.pptr = base[dir] + offset;
1445 return this->base.pptr - base[SEEKDIR_beg];
1447 return this->base.gptr - base[SEEKDIR_beg];
1450 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1451 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1452 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1453 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1455 TRACE("(%p %p %d)\n", this, buffer, length);
1456 if (length)
1457 this->increase = length;
1458 return &this->base;
1461 /* ?str@strstreambuf@@QAEPADXZ */
1462 /* ?str@strstreambuf@@QEAAPEADXZ */
1463 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1464 char* __thiscall strstreambuf_str(strstreambuf *this)
1466 TRACE("(%p)\n", this);
1467 strstreambuf_freeze(this, 1);
1468 return this->base.base;
1471 /* ?sync@strstreambuf@@UAEHXZ */
1472 /* ?sync@strstreambuf@@UEAAHXZ */
1473 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1474 int __thiscall strstreambuf_sync(strstreambuf *this)
1476 TRACE("(%p)\n", this);
1477 return 0;
1480 /* ?underflow@strstreambuf@@UAEHXZ */
1481 /* ?underflow@strstreambuf@@UEAAHXZ */
1482 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1483 int __thiscall strstreambuf_underflow(strstreambuf *this)
1485 TRACE("(%p)\n", this);
1486 if (this->base.gptr < this->base.egptr)
1487 return (unsigned char) *this->base.gptr;
1488 /* extend the get area to include the characters written */
1489 if (this->base.egptr < this->base.pptr) {
1490 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1491 this->base.eback = this->base.base;
1492 this->base.egptr = this->base.pptr;
1494 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1497 /* ??0stdiobuf@@QAE@ABV0@@Z */
1498 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1499 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1500 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1502 TRACE("(%p %p)\n", this, copy);
1503 *this = *copy;
1504 this->base.vtable = &MSVCP_stdiobuf_vtable;
1505 return this;
1508 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1509 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1510 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1511 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1513 TRACE("(%p %p)\n", this, file);
1514 streambuf_reserve_ctor(&this->base, NULL, 0);
1515 this->base.vtable = &MSVCP_stdiobuf_vtable;
1516 this->file = file;
1517 return this;
1520 /* ??1stdiobuf@@UAE@XZ */
1521 /* ??1stdiobuf@@UEAA@XZ */
1522 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1523 void __thiscall stdiobuf_dtor(stdiobuf *this)
1525 TRACE("(%p)\n", this);
1526 call_streambuf_sync(&this->base);
1527 streambuf_dtor(&this->base);
1530 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1531 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1532 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1533 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1535 stdiobuf_dtor(this);
1536 return stdiobuf_copy_ctor(this, rhs);
1539 /* ??_Estdiobuf@@UAEPAXI@Z */
1540 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1541 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1543 TRACE("(%p %x)\n", this, flags);
1544 if (flags & 2) {
1545 /* we have an array, with the number of elements stored before the first object */
1546 INT_PTR i, *ptr = (INT_PTR *)this-1;
1548 for (i = *ptr-1; i >= 0; i--)
1549 stdiobuf_dtor(this+i);
1550 MSVCRT_operator_delete(ptr);
1551 } else {
1552 stdiobuf_dtor(this);
1553 if (flags & 1)
1554 MSVCRT_operator_delete(this);
1556 return this;
1559 /* ??_Gstdiobuf@@UAEPAXI@Z */
1560 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1561 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1563 TRACE("(%p %x)\n", this, flags);
1564 stdiobuf_dtor(this);
1565 if (flags & 1) MSVCRT_operator_delete(this);
1566 return this;
1569 /* ?overflow@stdiobuf@@UAEHH@Z */
1570 /* ?overflow@stdiobuf@@UEAAHH@Z */
1571 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1572 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1574 TRACE("(%p %d)\n", this, c);
1575 if (this->base.unbuffered)
1576 return (c == EOF) ? 1 : fputc(c, this->file);
1577 if (streambuf_allocate(&this->base) == EOF)
1578 return EOF;
1580 if (!this->base.epptr) {
1581 /* set the put area to the second half of the buffer */
1582 streambuf_setp(&this->base,
1583 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1584 } else if (this->base.pptr > this->base.pbase) {
1585 /* flush the put area */
1586 int count = this->base.pptr - this->base.pbase;
1587 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1588 return EOF;
1589 this->base.pptr = this->base.pbase;
1591 if (c != EOF) {
1592 if (this->base.pbase >= this->base.epptr)
1593 return fputc(c, this->file);
1594 *this->base.pptr++ = c;
1596 return 1;
1599 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1600 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1601 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1602 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1604 TRACE("(%p %d)\n", this, c);
1605 return streambuf_pbackfail(&this->base, c);
1608 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1609 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1610 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1611 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1613 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1614 call_streambuf_overflow(&this->base, EOF);
1615 if (fseek(this->file, offset, dir))
1616 return EOF;
1617 return ftell(this->file);
1620 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1621 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1622 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1623 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1625 char *reserve;
1626 int buffer_size = read_size + write_size;
1628 TRACE("(%p %d %d)\n", this, read_size, write_size);
1629 if (read_size < 0 || write_size < 0)
1630 return 0;
1631 if (!buffer_size) {
1632 this->base.unbuffered = 1;
1633 return 0;
1635 /* get a new buffer */
1636 reserve = MSVCRT_operator_new(buffer_size);
1637 if (!reserve)
1638 return 0;
1639 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1640 this->base.unbuffered = 0;
1641 /* set the get/put areas */
1642 if (read_size > 0)
1643 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1644 else
1645 streambuf_setg(&this->base, NULL, NULL, NULL);
1646 if (write_size > 0)
1647 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1648 else
1649 streambuf_setp(&this->base, NULL, NULL);
1650 return 1;
1653 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1654 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1655 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1656 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1658 TRACE("(%p)\n", this);
1659 return this->file;
1662 /* ?sync@stdiobuf@@UAEHXZ */
1663 /* ?sync@stdiobuf@@UEAAHXZ */
1664 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1665 int __thiscall stdiobuf_sync(stdiobuf *this)
1667 TRACE("(%p)\n", this);
1668 if (this->base.unbuffered)
1669 return 0;
1670 /* flush the put area */
1671 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1672 return EOF;
1673 /* flush the get area */
1674 if (this->base.gptr < this->base.egptr) {
1675 char *ptr;
1676 int fd, mode, offset = this->base.egptr - this->base.gptr;
1677 if ((fd = fileno(this->file)) < 0)
1678 return EOF;
1679 mode = _setmode(fd, _O_TEXT);
1680 _setmode(fd, mode);
1681 if (mode & _O_TEXT) {
1682 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1683 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1684 if (*ptr == '\n')
1685 offset++;
1687 if (fseek(this->file, -offset, SEEK_CUR))
1688 return EOF;
1689 this->base.gptr = this->base.egptr;
1691 return 0;
1694 /* ?underflow@stdiobuf@@UAEHXZ */
1695 /* ?underflow@stdiobuf@@UEAAHXZ */
1696 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1697 int __thiscall stdiobuf_underflow(stdiobuf *this)
1699 TRACE("(%p)\n", this);
1700 if (!this->file)
1701 return EOF;
1702 if (this->base.unbuffered)
1703 return fgetc(this->file);
1704 if (streambuf_allocate(&this->base) == EOF)
1705 return EOF;
1707 if (!this->base.egptr) {
1708 /* set the get area to the first half of the buffer */
1709 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1710 streambuf_setg(&this->base, this->base.base, middle, middle);
1712 if (this->base.gptr >= this->base.egptr) {
1713 /* read characters from the file */
1714 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1715 if (!this->base.eback ||
1716 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1717 return EOF;
1718 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1719 this->base.gptr = this->base.egptr - read_bytes;
1721 return (unsigned char) *this->base.gptr++;
1724 /* ??0ios@@IAE@ABV0@@Z */
1725 /* ??0ios@@IEAA@AEBV0@@Z */
1726 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1727 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1729 TRACE("(%p %p)\n", this, copy);
1730 ios_fLockcInit++;
1731 this->vtable = &MSVCP_ios_vtable;
1732 this->sb = NULL;
1733 this->delbuf = 0;
1734 InitializeCriticalSection(&this->lock);
1735 return ios_assign(this, copy);
1738 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1739 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1740 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1741 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1743 TRACE("(%p %p)\n", this, sb);
1744 ios_fLockcInit++;
1745 this->vtable = &MSVCP_ios_vtable;
1746 this->sb = sb;
1747 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1748 this->special[0] = this->special[1] = 0;
1749 this->delbuf = 0;
1750 this->tie = NULL;
1751 this->flags = 0;
1752 this->precision = 6;
1753 this->fill = ' ';
1754 this->width = 0;
1755 this->do_lock = -1;
1756 InitializeCriticalSection(&this->lock);
1757 return this;
1760 /* ??0ios@@IAE@XZ */
1761 /* ??0ios@@IEAA@XZ */
1762 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1763 ios* __thiscall ios_ctor(ios *this)
1765 return ios_sb_ctor(this, NULL);
1768 /* ??1ios@@UAE@XZ */
1769 /* ??1ios@@UEAA@XZ */
1770 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1771 void __thiscall ios_dtor(ios *this)
1773 TRACE("(%p)\n", this);
1774 ios_fLockcInit--;
1775 if (this->delbuf && this->sb)
1776 call_streambuf_vector_dtor(this->sb, 1);
1777 this->sb = NULL;
1778 this->state = IOSTATE_badbit;
1779 DeleteCriticalSection(&this->lock);
1782 /* ??4ios@@IAEAAV0@ABV0@@Z */
1783 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1784 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1785 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1787 TRACE("(%p %p)\n", this, rhs);
1788 this->state = rhs->state;
1789 if (!this->sb)
1790 this->state |= IOSTATE_badbit;
1791 this->tie = rhs->tie;
1792 this->flags = rhs->flags;
1793 this->precision = (char) rhs->precision;
1794 this->fill = rhs->fill;
1795 this->width = (char) rhs->width;
1796 return this;
1799 /* ??7ios@@QBEHXZ */
1800 /* ??7ios@@QEBAHXZ */
1801 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1802 int __thiscall ios_op_not(const ios *this)
1804 TRACE("(%p)\n", this);
1805 return ios_fail(this);
1808 /* ??Bios@@QBEPAXXZ */
1809 /* ??Bios@@QEBAPEAXXZ */
1810 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1811 void* __thiscall ios_op_void(const ios *this)
1813 TRACE("(%p)\n", this);
1814 return ios_fail(this) ? NULL : (void*)this;
1817 /* ??_Eios@@UAEPAXI@Z */
1818 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1819 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1821 TRACE("(%p %x)\n", this, flags);
1822 if (flags & 2) {
1823 /* we have an array, with the number of elements stored before the first object */
1824 INT_PTR i, *ptr = (INT_PTR *)this-1;
1826 for (i = *ptr-1; i >= 0; i--)
1827 ios_dtor(this+i);
1828 MSVCRT_operator_delete(ptr);
1829 } else {
1830 ios_dtor(this);
1831 if (flags & 1)
1832 MSVCRT_operator_delete(this);
1834 return this;
1837 /* ??_Gios@@UAEPAXI@Z */
1838 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1839 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1841 TRACE("(%p %x)\n", this, flags);
1842 ios_dtor(this);
1843 if (flags & 1) MSVCRT_operator_delete(this);
1844 return this;
1847 /* ?bad@ios@@QBEHXZ */
1848 /* ?bad@ios@@QEBAHXZ */
1849 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1850 int __thiscall ios_bad(const ios *this)
1852 TRACE("(%p)\n", this);
1853 return (this->state & IOSTATE_badbit);
1856 /* ?bitalloc@ios@@SAJXZ */
1857 LONG __cdecl ios_bitalloc(void)
1859 TRACE("()\n");
1860 ios_lockc();
1861 ios_maxbit <<= 1;
1862 ios_unlockc();
1863 return ios_maxbit;
1866 /* ?clear@ios@@QAEXH@Z */
1867 /* ?clear@ios@@QEAAXH@Z */
1868 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1869 void __thiscall ios_clear(ios *this, int state)
1871 TRACE("(%p %d)\n", this, state);
1872 ios_lock(this);
1873 this->state = state;
1874 ios_unlock(this);
1877 /* ?clrlock@ios@@QAAXXZ */
1878 /* ?clrlock@ios@@QEAAXXZ */
1879 void __cdecl ios_clrlock(ios *this)
1881 TRACE("(%p)\n", this);
1882 if (this->do_lock <= 0)
1883 this->do_lock++;
1884 if (this->sb)
1885 streambuf_clrlock(this->sb);
1888 /* ?delbuf@ios@@QAEXH@Z */
1889 /* ?delbuf@ios@@QEAAXH@Z */
1890 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1891 void __thiscall ios_delbuf_set(ios *this, int delete)
1893 TRACE("(%p %d)\n", this, delete);
1894 this->delbuf = delete;
1897 /* ?delbuf@ios@@QBEHXZ */
1898 /* ?delbuf@ios@@QEBAHXZ */
1899 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1900 int __thiscall ios_delbuf_get(const ios *this)
1902 TRACE("(%p)\n", this);
1903 return this->delbuf;
1906 /* ?dec@@YAAAVios@@AAV1@@Z */
1907 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1908 ios* __cdecl ios_dec(ios *this)
1910 TRACE("(%p)\n", this);
1911 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1912 return this;
1915 /* ?eof@ios@@QBEHXZ */
1916 /* ?eof@ios@@QEBAHXZ */
1917 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1918 int __thiscall ios_eof(const ios *this)
1920 TRACE("(%p)\n", this);
1921 return (this->state & IOSTATE_eofbit);
1924 /* ?fail@ios@@QBEHXZ */
1925 /* ?fail@ios@@QEBAHXZ */
1926 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1927 int __thiscall ios_fail(const ios *this)
1929 TRACE("(%p)\n", this);
1930 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1933 /* ?fill@ios@@QAEDD@Z */
1934 /* ?fill@ios@@QEAADD@Z */
1935 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1936 char __thiscall ios_fill_set(ios *this, char fill)
1938 char prev = this->fill;
1940 TRACE("(%p %d)\n", this, fill);
1942 this->fill = fill;
1943 return prev;
1946 /* ?fill@ios@@QBEDXZ */
1947 /* ?fill@ios@@QEBADXZ */
1948 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1949 char __thiscall ios_fill_get(const ios *this)
1951 TRACE("(%p)\n", this);
1952 return this->fill;
1955 /* ?flags@ios@@QAEJJ@Z */
1956 /* ?flags@ios@@QEAAJJ@Z */
1957 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
1958 LONG __thiscall ios_flags_set(ios *this, LONG flags)
1960 LONG prev = this->flags;
1962 TRACE("(%p %x)\n", this, flags);
1964 this->flags = flags;
1965 return prev;
1968 /* ?flags@ios@@QBEJXZ */
1969 /* ?flags@ios@@QEBAJXZ */
1970 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
1971 LONG __thiscall ios_flags_get(const ios *this)
1973 TRACE("(%p)\n", this);
1974 return this->flags;
1977 /* ?good@ios@@QBEHXZ */
1978 /* ?good@ios@@QEBAHXZ */
1979 DEFINE_THISCALL_WRAPPER(ios_good, 4)
1980 int __thiscall ios_good(const ios *this)
1982 TRACE("(%p)\n", this);
1983 return this->state == IOSTATE_goodbit;
1986 /* ?hex@@YAAAVios@@AAV1@@Z */
1987 /* ?hex@@YAAEAVios@@AEAV1@@Z */
1988 ios* __cdecl ios_hex(ios *this)
1990 TRACE("(%p)\n", this);
1991 ios_setf_mask(this, FLAGS_hex, ios_basefield);
1992 return this;
1995 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
1996 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
1997 DEFINE_THISCALL_WRAPPER(ios_init, 8)
1998 void __thiscall ios_init(ios *this, streambuf *sb)
2000 TRACE("(%p %p)\n", this, sb);
2001 if (this->delbuf && this->sb)
2002 call_streambuf_vector_dtor(this->sb, 1);
2003 this->sb = sb;
2004 if (sb == NULL)
2005 this->state |= IOSTATE_badbit;
2006 else
2007 this->state &= ~IOSTATE_badbit;
2010 /* ?iword@ios@@QBEAAJH@Z */
2011 /* ?iword@ios@@QEBAAEAJH@Z */
2012 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2013 LONG* __thiscall ios_iword(const ios *this, int index)
2015 TRACE("(%p %d)\n", this, index);
2016 return &ios_statebuf[index];
2019 /* ?lock@ios@@QAAXXZ */
2020 /* ?lock@ios@@QEAAXXZ */
2021 void __cdecl ios_lock(ios *this)
2023 TRACE("(%p)\n", this);
2024 if (this->do_lock < 0)
2025 EnterCriticalSection(&this->lock);
2028 /* ?lockbuf@ios@@QAAXXZ */
2029 /* ?lockbuf@ios@@QEAAXXZ */
2030 void __cdecl ios_lockbuf(ios *this)
2032 TRACE("(%p)\n", this);
2033 streambuf_lock(this->sb);
2036 /* ?lockc@ios@@KAXXZ */
2037 void __cdecl ios_lockc(void)
2039 TRACE("()\n");
2040 EnterCriticalSection(&ios_static_lock);
2043 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2044 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2045 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2046 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2048 TRACE("(%p)\n", this);
2049 return &this->lock;
2052 /* ?oct@@YAAAVios@@AAV1@@Z */
2053 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2054 ios* __cdecl ios_oct(ios *this)
2056 TRACE("(%p)\n", this);
2057 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2058 return this;
2061 /* ?precision@ios@@QAEHH@Z */
2062 /* ?precision@ios@@QEAAHH@Z */
2063 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2064 int __thiscall ios_precision_set(ios *this, int prec)
2066 int prev = this->precision;
2068 TRACE("(%p %d)\n", this, prec);
2070 this->precision = prec;
2071 return prev;
2074 /* ?precision@ios@@QBEHXZ */
2075 /* ?precision@ios@@QEBAHXZ */
2076 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2077 int __thiscall ios_precision_get(const ios *this)
2079 TRACE("(%p)\n", this);
2080 return this->precision;
2083 /* ?pword@ios@@QBEAAPAXH@Z */
2084 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2085 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2086 void** __thiscall ios_pword(const ios *this, int index)
2088 TRACE("(%p %d)\n", this, index);
2089 return (void**)&ios_statebuf[index];
2092 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2093 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2094 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2095 streambuf* __thiscall ios_rdbuf(const ios *this)
2097 TRACE("(%p)\n", this);
2098 return this->sb;
2101 /* ?rdstate@ios@@QBEHXZ */
2102 /* ?rdstate@ios@@QEBAHXZ */
2103 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2104 int __thiscall ios_rdstate(const ios *this)
2106 TRACE("(%p)\n", this);
2107 return this->state;
2110 /* ?setf@ios@@QAEJJ@Z */
2111 /* ?setf@ios@@QEAAJJ@Z */
2112 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2113 LONG __thiscall ios_setf(ios *this, LONG flags)
2115 LONG prev = this->flags;
2117 TRACE("(%p %x)\n", this, flags);
2119 ios_lock(this);
2120 this->flags |= flags;
2121 ios_unlock(this);
2122 return prev;
2125 /* ?setf@ios@@QAEJJJ@Z */
2126 /* ?setf@ios@@QEAAJJJ@Z */
2127 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2128 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2130 LONG prev = this->flags;
2132 TRACE("(%p %x %x)\n", this, flags, mask);
2134 ios_lock(this);
2135 this->flags = (this->flags & (~mask)) | (flags & mask);
2136 ios_unlock(this);
2137 return prev;
2140 /* ?setlock@ios@@QAAXXZ */
2141 /* ?setlock@ios@@QEAAXXZ */
2142 void __cdecl ios_setlock(ios *this)
2144 TRACE("(%p)\n", this);
2145 this->do_lock--;
2146 if (this->sb)
2147 streambuf_setlock(this->sb);
2150 /* ?sync_with_stdio@ios@@SAXXZ */
2151 void __cdecl ios_sync_with_stdio(void)
2153 FIXME("() stub\n");
2156 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2157 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2158 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2159 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2161 ostream *prev = this->tie;
2163 TRACE("(%p %p)\n", this, ostr);
2165 this->tie = ostr;
2166 return prev;
2169 /* ?tie@ios@@QBEPAVostream@@XZ */
2170 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2171 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2172 ostream* __thiscall ios_tie_get(const ios *this)
2174 TRACE("(%p)\n", this);
2175 return this->tie;
2178 /* ?unlock@ios@@QAAXXZ */
2179 /* ?unlock@ios@@QEAAXXZ */
2180 void __cdecl ios_unlock(ios *this)
2182 TRACE("(%p)\n", this);
2183 if (this->do_lock < 0)
2184 LeaveCriticalSection(&this->lock);
2187 /* ?unlockbuf@ios@@QAAXXZ */
2188 /* ?unlockbuf@ios@@QEAAXXZ */
2189 void __cdecl ios_unlockbuf(ios *this)
2191 TRACE("(%p)\n", this);
2192 streambuf_unlock(this->sb);
2195 /* ?unlockc@ios@@KAXXZ */
2196 void __cdecl ios_unlockc(void)
2198 TRACE("()\n");
2199 LeaveCriticalSection(&ios_static_lock);
2202 /* ?unsetf@ios@@QAEJJ@Z */
2203 /* ?unsetf@ios@@QEAAJJ@Z */
2204 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2205 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2207 LONG prev = this->flags;
2209 TRACE("(%p %x)\n", this, flags);
2211 ios_lock(this);
2212 this->flags &= ~flags;
2213 ios_unlock(this);
2214 return prev;
2217 /* ?width@ios@@QAEHH@Z */
2218 /* ?width@ios@@QEAAHH@Z */
2219 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2220 int __thiscall ios_width_set(ios *this, int width)
2222 int prev = this->width;
2224 TRACE("(%p %d)\n", this, width);
2226 this->width = width;
2227 return prev;
2230 /* ?width@ios@@QBEHXZ */
2231 /* ?width@ios@@QEBAHXZ */
2232 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2233 int __thiscall ios_width_get(const ios *this)
2235 TRACE("(%p)\n", this);
2236 return this->width;
2239 /* ?xalloc@ios@@SAHXZ */
2240 int __cdecl ios_xalloc(void)
2242 int ret;
2244 TRACE("()\n");
2246 ios_lockc();
2247 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2248 ios_unlockc();
2249 return ret;
2252 static inline ios* ostream_get_ios(const ostream *this)
2254 return (ios*)((char*)this + this->vbtable[1]);
2257 static inline ios* ostream_to_ios(const ostream *this)
2259 return (ios*)((char*)this + ostream_vbtable[1]);
2262 static inline ostream* ios_to_ostream(const ios *base)
2264 return (ostream*)((char*)base - ostream_vbtable[1]);
2267 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2268 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2269 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2270 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2272 ios *base;
2274 TRACE("(%p %p %d)\n", this, sb, virt_init);
2276 if (virt_init) {
2277 this->vbtable = ostream_vbtable;
2278 base = ostream_get_ios(this);
2279 ios_sb_ctor(base, sb);
2280 } else {
2281 base = ostream_get_ios(this);
2282 ios_init(base, sb);
2284 base->vtable = &MSVCP_ostream_vtable;
2285 this->unknown = 0;
2286 return this;
2289 /* ??0ostream@@IAE@ABV0@@Z */
2290 /* ??0ostream@@IEAA@AEBV0@@Z */
2291 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2292 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2294 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2297 /* ??0ostream@@IAE@XZ */
2298 /* ??0ostream@@IEAA@XZ */
2299 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2300 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2302 ios *base;
2304 TRACE("(%p %d)\n", this, virt_init);
2306 if (virt_init) {
2307 this->vbtable = ostream_vbtable;
2308 base = ostream_get_ios(this);
2309 ios_ctor(base);
2310 } else
2311 base = ostream_get_ios(this);
2312 base->vtable = &MSVCP_ostream_vtable;
2313 this->unknown = 0;
2314 return this;
2317 /* ??1ostream@@UAE@XZ */
2318 /* ??1ostream@@UEAA@XZ */
2319 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2320 void __thiscall ostream_dtor(ios *base)
2322 ostream *this = ios_to_ostream(base);
2324 TRACE("(%p)\n", this);
2327 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2328 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2329 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2330 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2332 ios *base = ostream_get_ios(this);
2334 TRACE("(%p %p)\n", this, sb);
2336 ios_init(base, sb);
2337 base->state &= IOSTATE_badbit;
2338 base->delbuf = 0;
2339 base->tie = NULL;
2340 base->flags = 0;
2341 base->precision = 6;
2342 base->fill = ' ';
2343 base->width = 0;
2344 return this;
2347 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2348 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2349 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2350 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2352 ios *base_rhs = ostream_get_ios(rhs);
2354 TRACE("(%p %p)\n", this, rhs);
2356 return ostream_assign_sb(this, base_rhs->sb);
2359 /* ??_Dostream@@QAEXXZ */
2360 /* ??_Dostream@@QEAAXXZ */
2361 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2362 void __thiscall ostream_vbase_dtor(ostream *this)
2364 ios *base = ostream_to_ios(this);
2366 TRACE("(%p)\n", this);
2368 ostream_dtor(base);
2369 ios_dtor(base);
2372 /* ??_Eostream@@UAEPAXI@Z */
2373 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2374 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2376 ostream *this = ios_to_ostream(base);
2378 TRACE("(%p %x)\n", this, flags);
2380 if (flags & 2) {
2381 /* we have an array, with the number of elements stored before the first object */
2382 INT_PTR i, *ptr = (INT_PTR *)this-1;
2384 for (i = *ptr-1; i >= 0; i--)
2385 ostream_vbase_dtor(this+i);
2386 MSVCRT_operator_delete(ptr);
2387 } else {
2388 ostream_vbase_dtor(this);
2389 if (flags & 1)
2390 MSVCRT_operator_delete(this);
2392 return this;
2395 /* ??_Gostream@@UAEPAXI@Z */
2396 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2397 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2399 ostream *this = ios_to_ostream(base);
2401 TRACE("(%p %x)\n", this, flags);
2403 ostream_vbase_dtor(this);
2404 if (flags & 1) MSVCRT_operator_delete(this);
2405 return this;
2408 /* ?flush@ostream@@QAEAAV1@XZ */
2409 /* ?flush@ostream@@QEAAAEAV1@XZ */
2410 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2411 ostream* __thiscall ostream_flush(ostream *this)
2413 ios *base = ostream_get_ios(this);
2415 TRACE("(%p)\n", this);
2417 ios_lockbuf(base);
2418 if (call_streambuf_sync(base->sb) == EOF)
2419 ios_clear(base, base->state | IOSTATE_failbit);
2420 ios_unlockbuf(base);
2421 return this;
2424 /* ?opfx@ostream@@QAEHXZ */
2425 /* ?opfx@ostream@@QEAAHXZ */
2426 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2427 int __thiscall ostream_opfx(ostream *this)
2429 ios *base = ostream_get_ios(this);
2431 TRACE("(%p)\n", this);
2433 if (!ios_good(base)) {
2434 ios_clear(base, base->state | IOSTATE_failbit);
2435 return 0;
2437 ios_lock(base);
2438 ios_lockbuf(base);
2439 if (base->tie)
2440 ostream_flush(base->tie);
2441 return 1;
2444 /* ?osfx@ostream@@QAEXXZ */
2445 /* ?osfx@ostream@@QEAAXXZ */
2446 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2447 void __thiscall ostream_osfx(ostream *this)
2449 ios *base = ostream_get_ios(this);
2451 TRACE("(%p)\n", this);
2453 ios_unlockbuf(base);
2454 ios_width_set(base, 0);
2455 if (base->flags & FLAGS_unitbuf)
2456 ostream_flush(this);
2457 if (base->flags & FLAGS_stdio) {
2458 fflush(stdout);
2459 fflush(stderr);
2461 ios_unlock(base);
2464 /* ?put@ostream@@QAEAAV1@C@Z */
2465 /* ?put@ostream@@QEAAAEAV1@C@Z */
2466 /* ?put@ostream@@QAEAAV1@D@Z */
2467 /* ?put@ostream@@QEAAAEAV1@D@Z */
2468 /* ?put@ostream@@QAEAAV1@E@Z */
2469 /* ?put@ostream@@QEAAAEAV1@E@Z */
2470 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2471 ostream* __thiscall ostream_put(ostream *this, char c)
2473 ios *base = ostream_get_ios(this);
2475 TRACE("(%p %c)\n", this, c);
2477 if (ostream_opfx(this)) {
2478 if (streambuf_sputc(base->sb, c) == EOF)
2479 base->state = IOSTATE_badbit | IOSTATE_failbit;
2480 ostream_osfx(this);
2482 return this;
2485 /* ?seekp@ostream@@QAEAAV1@J@Z */
2486 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2487 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2488 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2490 ios *base = ostream_get_ios(this);
2492 TRACE("(%p %d)\n", this, pos);
2494 ios_lockbuf(base);
2495 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2496 ios_clear(base, base->state | IOSTATE_failbit);
2497 ios_unlockbuf(base);
2498 return this;
2501 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2502 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2503 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2504 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2506 ios *base = ostream_get_ios(this);
2508 TRACE("(%p %d %d)\n", this, off, dir);
2510 ios_lockbuf(base);
2511 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2512 ios_clear(base, base->state | IOSTATE_failbit);
2513 ios_unlockbuf(base);
2514 return this;
2517 /* ?tellp@ostream@@QAEJXZ */
2518 /* ?tellp@ostream@@QEAAJXZ */
2519 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2520 streampos __thiscall ostream_tellp(ostream *this)
2522 ios *base = ostream_get_ios(this);
2523 streampos pos;
2525 TRACE("(%p)\n", this);
2527 ios_lockbuf(base);
2528 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2529 ios_clear(base, base->state | IOSTATE_failbit);
2530 ios_unlockbuf(base);
2531 return pos;
2534 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2535 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2536 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2537 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2538 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2539 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2540 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2541 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2543 ios *base = ostream_get_ios(this);
2545 TRACE("(%p %p %d)\n", this, str, count);
2547 if (ostream_opfx(this)) {
2548 if (streambuf_sputn(base->sb, str, count) != count)
2549 base->state = IOSTATE_badbit | IOSTATE_failbit;
2550 ostream_osfx(this);
2552 return this;
2555 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2556 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2557 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2558 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2560 ios *base = ostream_get_ios(this);
2561 int len1 = strlen(str1), len2 = strlen(str2), i;
2563 TRACE("(%p %p %p)\n", this, str1, str2);
2565 /* left of the padding */
2566 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2567 if (streambuf_sputn(base->sb, str1, len1) != len1)
2568 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2569 if (!(base->flags & FLAGS_internal))
2570 if (streambuf_sputn(base->sb, str2, len2) != len2)
2571 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2573 /* add padding to fill the width */
2574 for (i = len1 + len2; i < base->width; i++)
2575 if (streambuf_sputc(base->sb, base->fill) == EOF)
2576 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2577 /* right of the padding */
2578 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2579 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2580 if (streambuf_sputn(base->sb, str1, len1) != len1)
2581 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2582 if (streambuf_sputn(base->sb, str2, len2) != len2)
2583 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2585 return this;
2588 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2590 ios *base = ostream_get_ios(ostr);
2591 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2593 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2595 if (ostream_opfx(ostr)) {
2596 if (base->flags & FLAGS_hex) {
2597 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2598 if (base->flags & FLAGS_showbase) {
2599 prefix_str[0] = '0';
2600 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2602 } else if (base->flags & FLAGS_oct) {
2603 sprintf_fmt[1] = 'o';
2604 if (base->flags & FLAGS_showbase)
2605 prefix_str[0] = '0';
2606 } else { /* FLAGS_dec */
2607 if (unsig)
2608 sprintf_fmt[1] = 'u';
2609 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2610 prefix_str[0] = '+';
2613 if (shrt) {
2614 sprintf_fmt[2] = sprintf_fmt[1];
2615 sprintf_fmt[1] = 'h';
2618 if (sprintf(number_str, sprintf_fmt, n) > 0)
2619 ostream_writepad(ostr, prefix_str, number_str);
2620 else
2621 base->state |= IOSTATE_failbit;
2622 ostream_osfx(ostr);
2624 return ostr;
2627 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2629 ios *base = ostream_get_ios(ostr);
2630 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2631 int prec, max_prec = dbl ? 15 : 6;
2632 int str_length = 1; /* null end char */
2634 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2636 if (ostream_opfx(ostr)) {
2637 if ((base->flags & FLAGS_showpos) && d > 0) {
2638 prefix_str[0] = '+';
2639 str_length++; /* plus sign */
2641 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2642 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2643 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2644 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2645 if (base->flags & FLAGS_showpoint) {
2646 sprintf_fmt[4] = sprintf_fmt[3];
2647 sprintf_fmt[3] = sprintf_fmt[2];
2648 sprintf_fmt[2] = sprintf_fmt[1];
2649 sprintf_fmt[1] = '#';
2652 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2653 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2654 if (str_length > 24) {
2655 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2656 ostream_writepad(ostr, "", "");
2657 } else {
2658 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2659 ostream_writepad(ostr, prefix_str, number_str);
2660 else
2661 base->state |= IOSTATE_failbit;
2663 ostream_osfx(ostr);
2665 return ostr;
2668 /* ??6ostream@@QAEAAV0@C@Z */
2669 /* ??6ostream@@QEAAAEAV0@C@Z */
2670 /* ??6ostream@@QAEAAV0@D@Z */
2671 /* ??6ostream@@QEAAAEAV0@D@Z */
2672 /* ??6ostream@@QAEAAV0@E@Z */
2673 /* ??6ostream@@QEAAAEAV0@E@Z */
2674 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2675 ostream* __thiscall ostream_print_char(ostream *this, char c)
2677 const char c_str[2] = {c, 0};
2679 TRACE("(%p %c)\n", this, c);
2681 if (ostream_opfx(this)) {
2682 ostream_writepad(this, "", c_str);
2683 ostream_osfx(this);
2685 return this;
2688 /* ??6ostream@@QAEAAV0@PBC@Z */
2689 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2690 /* ??6ostream@@QAEAAV0@PBD@Z */
2691 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2692 /* ??6ostream@@QAEAAV0@PBE@Z */
2693 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2694 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2695 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2697 TRACE("(%p %s)\n", this, str);
2698 if (ostream_opfx(this)) {
2699 ostream_writepad(this, "", str);
2700 ostream_osfx(this);
2702 return this;
2705 /* ??6ostream@@QAEAAV0@F@Z */
2706 /* ??6ostream@@QEAAAEAV0@F@Z */
2707 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2708 ostream* __thiscall ostream_print_short(ostream *this, short n)
2710 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2713 /* ??6ostream@@QAEAAV0@G@Z */
2714 /* ??6ostream@@QEAAAEAV0@G@Z */
2715 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2716 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2718 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2721 /* ??6ostream@@QAEAAV0@H@Z */
2722 /* ??6ostream@@QEAAAEAV0@H@Z */
2723 /* ??6ostream@@QAEAAV0@J@Z */
2724 /* ??6ostream@@QEAAAEAV0@J@Z */
2725 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2726 ostream* __thiscall ostream_print_int(ostream *this, int n)
2728 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2731 /* ??6ostream@@QAEAAV0@I@Z */
2732 /* ??6ostream@@QEAAAEAV0@I@Z */
2733 /* ??6ostream@@QAEAAV0@K@Z */
2734 /* ??6ostream@@QEAAAEAV0@K@Z */
2735 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2736 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2738 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2741 /* ??6ostream@@QAEAAV0@M@Z */
2742 /* ??6ostream@@QEAAAEAV0@M@Z */
2743 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2744 ostream* __thiscall ostream_print_float(ostream *this, float f)
2746 return ostream_internal_print_float(this, f, FALSE);
2749 /* ??6ostream@@QAEAAV0@N@Z */
2750 /* ??6ostream@@QEAAAEAV0@N@Z */
2751 /* ??6ostream@@QAEAAV0@O@Z */
2752 /* ??6ostream@@QEAAAEAV0@O@Z */
2753 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2754 ostream* __thiscall ostream_print_double(ostream *this, double d)
2756 return ostream_internal_print_float(this, d, TRUE);
2759 /* ??6ostream@@QAEAAV0@PBX@Z */
2760 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2761 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2762 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2764 ios *base = ostream_get_ios(this);
2765 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2767 TRACE("(%p %p)\n", this, ptr);
2769 if (ostream_opfx(this)) {
2770 if (ptr && base->flags & FLAGS_uppercase)
2771 prefix_str[1] = 'X';
2773 if (sprintf(pointer_str, "%p", ptr) > 0)
2774 ostream_writepad(this, prefix_str, pointer_str);
2775 else
2776 base->state |= IOSTATE_failbit;
2777 ostream_osfx(this);
2779 return this;
2782 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2783 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2784 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2785 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2787 ios *base = ostream_get_ios(this);
2788 int c;
2790 TRACE("(%p %p)\n", this, sb);
2792 if (ostream_opfx(this)) {
2793 while ((c = streambuf_sbumpc(sb)) != EOF) {
2794 if (streambuf_sputc(base->sb, c) == EOF) {
2795 base->state |= IOSTATE_failbit;
2796 break;
2799 ostream_osfx(this);
2801 return this;
2804 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2805 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2806 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2807 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2809 TRACE("(%p %p)\n", this, func);
2810 return func(this);
2813 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2814 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2815 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2816 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2818 TRACE("(%p %p)\n", this, func);
2819 func(ostream_get_ios(this));
2820 return this;
2823 /* ?endl@@YAAAVostream@@AAV1@@Z */
2824 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2825 ostream* __cdecl ostream_endl(ostream *this)
2827 TRACE("(%p)\n", this);
2828 ostream_put(this, '\n');
2829 return ostream_flush(this);
2832 /* ?ends@@YAAAVostream@@AAV1@@Z */
2833 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2834 ostream* __cdecl ostream_ends(ostream *this)
2836 TRACE("(%p)\n", this);
2837 return ostream_put(this, 0);
2840 /* ?flush@@YAAAVostream@@AAV1@@Z */
2841 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2842 ostream* __cdecl ostream_flush_manip(ostream *this)
2844 TRACE("(%p)\n", this);
2845 return ostream_flush(this);
2848 static inline ios* istream_get_ios(const istream *this)
2850 return (ios*)((char*)this + this->vbtable[1]);
2853 static inline ios* istream_to_ios(const istream *this)
2855 return (ios*)((char*)this + istream_vbtable[1]);
2858 static inline istream* ios_to_istream(const ios *base)
2860 return (istream*)((char*)base - istream_vbtable[1]);
2863 /* ??0istream@@QAE@PAVstreambuf@@@Z */
2864 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
2865 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
2866 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
2868 ios *base;
2870 TRACE("(%p %p %d)\n", this, sb, virt_init);
2872 if (virt_init) {
2873 this->vbtable = istream_vbtable;
2874 base = istream_get_ios(this);
2875 ios_sb_ctor(base, sb);
2876 } else {
2877 base = istream_get_ios(this);
2878 ios_init(base, sb);
2880 base->vtable = &MSVCP_istream_vtable;
2881 base->flags |= FLAGS_skipws;
2882 this->extract_delim = 0;
2883 this->count = 0;
2884 return this;
2887 /* ??0istream@@IAE@ABV0@@Z */
2888 /* ??0istream@@IEAA@AEBV0@@Z */
2889 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
2890 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
2892 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
2895 /* ??0istream@@IAE@XZ */
2896 /* ??0istream@@IEAA@XZ */
2897 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
2898 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
2900 ios *base;
2902 TRACE("(%p %d)\n", this, virt_init);
2904 if (virt_init) {
2905 this->vbtable = istream_vbtable;
2906 base = istream_get_ios(this);
2907 ios_ctor(base);
2908 } else
2909 base = istream_get_ios(this);
2910 base->vtable = &MSVCP_istream_vtable;
2911 base->flags |= FLAGS_skipws;
2912 this->extract_delim = 0;
2913 this->count = 0;
2914 return this;
2917 /* ??1istream@@UAE@XZ */
2918 /* ??1istream@@UEAA@XZ */
2919 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
2920 void __thiscall istream_dtor(ios *base)
2922 istream *this = ios_to_istream(base);
2924 TRACE("(%p)\n", this);
2927 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
2928 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2929 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
2930 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
2932 ios *base = istream_get_ios(this);
2934 TRACE("(%p %p)\n", this, sb);
2936 ios_init(base, sb);
2937 base->state &= IOSTATE_badbit;
2938 base->delbuf = 0;
2939 base->tie = NULL;
2940 base->flags = FLAGS_skipws;
2941 base->precision = 6;
2942 base->fill = ' ';
2943 base->width = 0;
2944 this->count = 0;
2945 return this;
2948 /* ??4istream@@IAEAAV0@ABV0@@Z */
2949 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
2950 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
2951 istream* __thiscall istream_assign(istream *this, const istream *rhs)
2953 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
2956 /* ??_Distream@@QAEXXZ */
2957 /* ??_Distream@@QEAAXXZ */
2958 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
2959 void __thiscall istream_vbase_dtor(istream *this)
2961 ios *base = istream_to_ios(this);
2963 TRACE("(%p)\n", this);
2965 istream_dtor(base);
2966 ios_dtor(base);
2969 /* ??_Eistream@@UAEPAXI@Z */
2970 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
2971 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
2973 istream *this = ios_to_istream(base);
2975 TRACE("(%p %x)\n", this, flags);
2977 if (flags & 2) {
2978 /* we have an array, with the number of elements stored before the first object */
2979 INT_PTR i, *ptr = (INT_PTR *)this-1;
2981 for (i = *ptr-1; i >= 0; i--)
2982 istream_vbase_dtor(this+i);
2983 MSVCRT_operator_delete(ptr);
2984 } else {
2985 istream_vbase_dtor(this);
2986 if (flags & 1)
2987 MSVCRT_operator_delete(this);
2989 return this;
2992 /* ??_Gistream@@UAEPAXI@Z */
2993 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
2994 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
2996 istream *this = ios_to_istream(base);
2998 TRACE("(%p %x)\n", this, flags);
3000 istream_vbase_dtor(this);
3001 if (flags & 1) MSVCRT_operator_delete(this);
3002 return this;
3005 /* ?eatwhite@istream@@QAEXXZ */
3006 /* ?eatwhite@istream@@QEAAXXZ */
3007 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3008 void __thiscall istream_eatwhite(istream *this)
3010 ios *base = istream_get_ios(this);
3011 int c;
3013 TRACE("(%p)\n", this);
3015 ios_lockbuf(base);
3016 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3017 ios_unlockbuf(base);
3018 if (c == EOF)
3019 ios_clear(base, base->state | IOSTATE_eofbit);
3022 /* ?gcount@istream@@QBEHXZ */
3023 /* ?gcount@istream@@QEBAHXZ */
3024 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3025 int __thiscall istream_gcount(const istream *this)
3027 TRACE("(%p)\n", this);
3028 return this->count;
3031 /* ?ipfx@istream@@QAEHH@Z */
3032 /* ?ipfx@istream@@QEAAHH@Z */
3033 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3034 int __thiscall istream_ipfx(istream *this, int need)
3036 ios *base = istream_get_ios(this);
3038 TRACE("(%p %d)\n", this, need);
3040 if (need)
3041 this->count = 0;
3042 if (!ios_good(base)) {
3043 ios_clear(base, base->state | IOSTATE_failbit);
3044 return 0;
3046 ios_lock(base);
3047 ios_lockbuf(base);
3048 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3049 ostream_flush(base->tie);
3050 if ((base->flags & FLAGS_skipws) && !need) {
3051 istream_eatwhite(this);
3052 if (base->state & IOSTATE_eofbit) {
3053 base->state |= IOSTATE_failbit;
3054 ios_unlockbuf(base);
3055 ios_unlock(base);
3056 return 0;
3059 return 1;
3062 /* ?isfx@istream@@QAEXXZ */
3063 /* ?isfx@istream@@QEAAXXZ */
3064 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3065 void __thiscall istream_isfx(istream *this)
3067 ios *base = istream_get_ios(this);
3069 TRACE("(%p)\n", this);
3071 ios_unlockbuf(base);
3072 ios_unlock(base);
3075 /* ?get@istream@@IAEAAV1@PADHH@Z */
3076 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3077 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3078 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3080 ios *base = istream_get_ios(this);
3081 int ch, i = 0;
3083 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3085 if (istream_ipfx(this, 1)) {
3086 while (i < count - 1) {
3087 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3088 base->state |= IOSTATE_eofbit;
3089 if (!i) /* tried to read, but not a single character was obtained */
3090 base->state |= IOSTATE_failbit;
3091 break;
3093 if (ch == delim) {
3094 if (this->extract_delim) { /* discard the delimiter */
3095 streambuf_stossc(base->sb);
3096 this->count++;
3098 break;
3100 if (str)
3101 str[i] = ch;
3102 streambuf_stossc(base->sb);
3103 i++;
3105 this->count += i;
3106 istream_isfx(this);
3108 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3109 str[i] = 0;
3110 this->extract_delim = 0;
3111 return this;
3114 /* ?get@istream@@QAEAAV1@PACHD@Z */
3115 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3116 /* ?get@istream@@QAEAAV1@PADHD@Z */
3117 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3118 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3119 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3120 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3121 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3123 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3126 static int istream_internal_get_char(istream *this, char *ch)
3128 ios *base = istream_get_ios(this);
3129 int ret = EOF;
3131 TRACE("(%p %p)\n", this, ch);
3133 if (istream_ipfx(this, 1)) {
3134 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3135 this->count = 1;
3136 } else {
3137 base->state |= IOSTATE_eofbit;
3138 if (ch)
3139 base->state |= IOSTATE_failbit;
3141 if (ch)
3142 *ch = ret;
3143 istream_isfx(this);
3145 return ret;
3148 /* ?get@istream@@QAEAAV1@AAC@Z */
3149 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3150 /* ?get@istream@@QAEAAV1@AAD@Z */
3151 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3152 /* ?get@istream@@QAEAAV1@AAE@Z */
3153 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3154 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3155 istream* __thiscall istream_get_char(istream *this, char *ch)
3157 istream_internal_get_char(this, ch);
3158 return this;
3161 /* ?get@istream@@QAEHXZ */
3162 /* ?get@istream@@QEAAHXZ */
3163 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3164 int __thiscall istream_get(istream *this)
3166 return istream_internal_get_char(this, NULL);
3169 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3170 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3171 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3172 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3174 ios *base = istream_get_ios(this);
3175 int ch;
3177 TRACE("(%p %p %c)\n", this, sb, delim);
3179 if (istream_ipfx(this, 1)) {
3180 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3181 if (ch == EOF) {
3182 base->state |= IOSTATE_eofbit;
3183 break;
3185 if (streambuf_sputc(sb, ch) == EOF)
3186 base->state |= IOSTATE_failbit;
3187 this->count++;
3189 istream_isfx(this);
3191 return this;
3194 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3195 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3196 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3197 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3198 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3199 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3200 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3201 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3203 ios *base = istream_get_ios(this);
3205 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3207 ios_lock(base);
3208 this->extract_delim++;
3209 istream_get_str_delim(this, str, count, (unsigned char) delim);
3210 ios_unlock(base);
3211 return this;
3214 /* ?ignore@istream@@QAEAAV1@HH@Z */
3215 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3216 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3217 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3219 ios *base = istream_get_ios(this);
3221 TRACE("(%p %d %d)\n", this, count, delim);
3223 ios_lock(base);
3224 this->extract_delim++;
3225 istream_get_str_delim(this, NULL, count + 1, delim);
3226 ios_unlock(base);
3227 return this;
3230 /* ?peek@istream@@QAEHXZ */
3231 /* ?peek@istream@@QEAAHXZ */
3232 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3233 int __thiscall istream_peek(istream *this)
3235 ios *base = istream_get_ios(this);
3236 int ret = EOF;
3238 TRACE("(%p)\n", this);
3240 if (istream_ipfx(this, 1)) {
3241 ret = streambuf_sgetc(base->sb);
3242 istream_isfx(this);
3244 return ret;
3247 /* ?putback@istream@@QAEAAV1@D@Z */
3248 /* ?putback@istream@@QEAAAEAV1@D@Z */
3249 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3250 istream* __thiscall istream_putback(istream *this, char ch)
3252 ios *base = istream_get_ios(this);
3254 TRACE("(%p %c)\n", this, ch);
3256 if (ios_good(base)) {
3257 ios_lockbuf(base);
3258 if (streambuf_sputbackc(base->sb, ch) == EOF)
3259 ios_clear(base, base->state | IOSTATE_failbit);
3260 ios_unlockbuf(base);
3262 return this;
3265 /* ?read@istream@@QAEAAV1@PACH@Z */
3266 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3267 /* ?read@istream@@QAEAAV1@PADH@Z */
3268 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3269 /* ?read@istream@@QAEAAV1@PAEH@Z */
3270 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3271 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3272 istream* __thiscall istream_read(istream *this, char *str, int count)
3274 ios *base = istream_get_ios(this);
3276 TRACE("(%p %p %d)\n", this, str, count);
3278 if (istream_ipfx(this, 1)) {
3279 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3280 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3281 istream_isfx(this);
3283 return this;
3286 /* ?seekg@istream@@QAEAAV1@J@Z */
3287 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3288 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3289 istream* __thiscall istream_seekg(istream *this, streampos pos)
3291 ios *base = istream_get_ios(this);
3293 TRACE("(%p %d)\n", this, pos);
3295 ios_lockbuf(base);
3296 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3297 ios_clear(base, base->state | IOSTATE_failbit);
3298 ios_unlockbuf(base);
3299 return this;
3302 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3303 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3304 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3305 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3307 ios *base = istream_get_ios(this);
3309 TRACE("(%p %d %d)\n", this, off, dir);
3311 ios_lockbuf(base);
3312 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3313 ios_clear(base, base->state | IOSTATE_failbit);
3314 ios_unlockbuf(base);
3315 return this;
3318 /* ?sync@istream@@QAEHXZ */
3319 /* ?sync@istream@@QEAAHXZ */
3320 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3321 int __thiscall istream_sync(istream *this)
3323 ios *base = istream_get_ios(this);
3324 int ret;
3326 TRACE("(%p)\n", this);
3328 ios_lockbuf(base);
3329 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3330 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3331 ios_unlockbuf(base);
3332 return ret;
3335 /* ?tellg@istream@@QAEJXZ */
3336 /* ?tellg@istream@@QEAAJXZ */
3337 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3338 streampos __thiscall istream_tellg(istream *this)
3340 ios *base = istream_get_ios(this);
3341 streampos pos;
3343 TRACE("(%p)\n", this);
3345 ios_lockbuf(base);
3346 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3347 ios_clear(base, base->state | IOSTATE_failbit);
3348 ios_unlockbuf(base);
3349 return pos;
3352 static int getint_is_valid_digit(char ch, int base)
3354 if (base == 8) return (ch >= '0' && ch <= '7');
3355 if (base == 16) return isxdigit(ch);
3356 return isdigit(ch);
3359 /* ?getint@istream@@AAEHPAD@Z */
3360 /* ?getint@istream@@AEAAHPEAD@Z */
3361 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3362 int __thiscall istream_getint(istream *this, char *str)
3364 ios *base = istream_get_ios(this);
3365 int ch, num_base = 0, i = 0;
3366 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3368 TRACE("(%p %p)\n", this, str);
3370 if (istream_ipfx(this, 0)) {
3371 num_base = (base->flags & FLAGS_dec) ? 10 :
3372 (base->flags & FLAGS_hex) ? 16 :
3373 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3374 /* scan valid characters, up to 15 (hard limit on Windows) */
3375 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3376 if ((ch == '+' || ch == '-') && scan_sign) {
3377 /* no additional sign allowed */
3378 scan_sign = FALSE;
3379 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3380 /* only hex digits can (and must) follow */
3381 scan_x = valid_integer = FALSE;
3382 num_base = 16;
3383 } else if (ch == '0' && scan_prefix) {
3384 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3385 scan_sign = scan_prefix = FALSE;
3386 scan_x = !num_base || num_base == 16;
3387 valid_integer = TRUE;
3388 if (!num_base)
3389 num_base = 8;
3390 } else if (getint_is_valid_digit(ch, num_base)) {
3391 /* only digits in the corresponding base can follow */
3392 scan_sign = scan_prefix = scan_x = FALSE;
3393 valid_integer = TRUE;
3394 } else {
3395 /* unexpected character, stop scanning */
3396 if (!valid_integer) {
3397 /* the result is not a valid integer */
3398 base->state |= IOSTATE_failbit;
3399 /* put any extracted character back into the stream */
3400 while (i > 0)
3401 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3402 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3403 } else if (ch == EOF) {
3404 base->state |= IOSTATE_eofbit;
3405 if (scan_x && !(base->flags & ios_basefield)) {
3406 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3407 num_base = 0;
3410 break;
3412 str[i++] = ch;
3414 /* append a null terminator */
3415 str[i] = 0;
3416 istream_isfx(this);
3418 return num_base;
3421 /* ?getdouble@istream@@AAEHPADH@Z */
3422 /* ?getdouble@istream@@AEAAHPEADH@Z */
3423 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3424 int __thiscall istream_getdouble(istream *this, char *str, int count)
3426 ios *base = istream_get_ios(this);
3427 int ch, i = 0;
3428 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3429 valid_mantissa = FALSE, valid_exponent = FALSE;
3431 TRACE("(%p %p %d)\n", this, str, count);
3433 if (istream_ipfx(this, 0)) {
3434 if (!count) {
3435 /* can't output anything */
3436 base->state |= IOSTATE_failbit;
3437 i = -1;
3438 } else {
3439 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3440 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3441 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3442 if ((ch == '+' || ch == '-') && scan_sign) {
3443 /* no additional sign allowed */
3444 scan_sign = FALSE;
3445 } else if (ch == '.' && scan_dot) {
3446 /* no sign or additional dot allowed */
3447 scan_sign = scan_dot = FALSE;
3448 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3449 /* sign is allowed again but not dots or exponents */
3450 scan_sign = TRUE;
3451 scan_dot = scan_exp = FALSE;
3452 } else if (isdigit(ch)) {
3453 if (scan_exp)
3454 valid_mantissa = TRUE;
3455 else
3456 valid_exponent = TRUE;
3457 /* no sign allowed after a digit */
3458 scan_sign = FALSE;
3459 } else {
3460 /* unexpected character, stop scanning */
3461 /* check whether the result is a valid double */
3462 if (!scan_exp && !valid_exponent) {
3463 /* put the last character back into the stream, usually the 'e' or 'E' */
3464 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3465 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3466 } else if (ch == EOF)
3467 base->state |= IOSTATE_eofbit;
3468 if (!valid_mantissa)
3469 base->state |= IOSTATE_failbit;
3470 break;
3472 str[i++] = ch;
3474 /* check if character limit has been reached */
3475 if (i == count) {
3476 base->state |= IOSTATE_failbit;
3477 i--;
3479 /* append a null terminator */
3480 str[i] = 0;
3482 istream_isfx(this);
3484 return i;
3487 /* ??5istream@@QAEAAV0@AAC@Z */
3488 /* ??5istream@@QEAAAEAV0@AEAC@Z */
3489 /* ??5istream@@QAEAAV0@AAD@Z */
3490 /* ??5istream@@QEAAAEAV0@AEAD@Z */
3491 /* ??5istream@@QAEAAV0@AAE@Z */
3492 /* ??5istream@@QEAAAEAV0@AEAE@Z */
3493 DEFINE_THISCALL_WRAPPER(istream_read_char, 8)
3494 istream* __thiscall istream_read_char(istream *this, char *ch)
3496 ios *base = istream_get_ios(this);
3497 int ret;
3499 TRACE("(%p %p)\n", this, ch);
3501 if (istream_ipfx(this, 0)) {
3502 if ((ret = streambuf_sbumpc(base->sb)) == EOF)
3503 base->state |= IOSTATE_eofbit | IOSTATE_failbit;
3504 else
3505 *ch = ret;
3506 istream_isfx(this);
3508 return this;
3511 /* ??5istream@@QAEAAV0@PAC@Z */
3512 /* ??5istream@@QEAAAEAV0@PEAC@Z */
3513 /* ??5istream@@QAEAAV0@PAD@Z */
3514 /* ??5istream@@QEAAAEAV0@PEAD@Z */
3515 /* ??5istream@@QAEAAV0@PAE@Z */
3516 /* ??5istream@@QEAAAEAV0@PEAE@Z */
3517 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
3518 istream* __thiscall istream_read_str(istream *this, char *str)
3520 ios *base = istream_get_ios(this);
3521 int ch, count = 0;
3523 TRACE("(%p %p)\n", this, str);
3525 if (istream_ipfx(this, 0)) {
3526 if (str) {
3527 for (ch = streambuf_sgetc(base->sb);
3528 count < (unsigned int) base->width - 1 && !isspace(ch);
3529 ch = streambuf_snextc(base->sb)) {
3530 if (ch == EOF) {
3531 base->state |= IOSTATE_eofbit;
3532 break;
3534 str[count++] = ch;
3537 if (!count) /* nothing to output */
3538 base->state |= IOSTATE_failbit;
3539 else /* append a null terminator */
3540 str[count] = 0;
3541 base->width = 0;
3542 istream_isfx(this);
3544 return this;
3547 static LONG istream_internal_read_integer(istream *this, LONG min_value, LONG max_value, BOOL set_flag)
3549 ios *base = istream_get_ios(this);
3550 char buffer[16];
3551 int num_base;
3552 LONG ret;
3554 TRACE("(%p %d %d %d)\n", this, min_value, max_value, set_flag);
3556 num_base = istream_getint(this, buffer);
3557 errno = 0;
3558 ret = strtol(buffer, NULL, num_base);
3559 /* check for overflow and whether the value fits in the output var */
3560 if (set_flag && errno == ERANGE) {
3561 base->state |= IOSTATE_failbit;
3562 } else if (ret > max_value) {
3563 base->state |= IOSTATE_failbit;
3564 ret = max_value;
3565 } else if (ret < min_value) {
3566 base->state |= IOSTATE_failbit;
3567 ret = min_value;
3569 return ret;
3572 static ULONG istream_internal_read_unsigned_integer(istream *this, LONG min_value, ULONG max_value)
3574 ios *base = istream_get_ios(this);
3575 char buffer[16];
3576 int num_base;
3577 ULONG ret;
3579 TRACE("(%p %d %u)\n", this, min_value, max_value);
3581 num_base = istream_getint(this, buffer);
3582 errno = 0;
3583 ret = strtoul(buffer, NULL, num_base);
3584 /* check for overflow and whether the value fits in the output var */
3585 if ((ret == ULONG_MAX && errno == ERANGE) ||
3586 (ret > max_value && ret < (ULONG) min_value)) {
3587 base->state |= IOSTATE_failbit;
3588 ret = max_value;
3590 return ret;
3593 /* ??5istream@@QAEAAV0@AAF@Z */
3594 /* ??5istream@@QEAAAEAV0@AEAF@Z */
3595 DEFINE_THISCALL_WRAPPER(istream_read_short, 8)
3596 istream* __thiscall istream_read_short(istream *this, short *p)
3598 if (istream_ipfx(this, 0)) {
3599 *p = istream_internal_read_integer(this, SHRT_MIN, SHRT_MAX, FALSE);
3600 istream_isfx(this);
3602 return this;
3605 /* ??5istream@@QAEAAV0@AAG@Z */
3606 /* ??5istream@@QEAAAEAV0@AEAG@Z */
3607 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_short, 8)
3608 istream* __thiscall istream_read_unsigned_short(istream *this, unsigned short *p)
3610 if (istream_ipfx(this, 0)) {
3611 *p = istream_internal_read_unsigned_integer(this, SHRT_MIN, USHRT_MAX);
3612 istream_isfx(this);
3614 return this;
3617 /* ??5istream@@QAEAAV0@AAH@Z */
3618 /* ??5istream@@QEAAAEAV0@AEAH@Z */
3619 DEFINE_THISCALL_WRAPPER(istream_read_int, 8)
3620 istream* __thiscall istream_read_int(istream *this, int *p)
3622 if (istream_ipfx(this, 0)) {
3623 *p = istream_internal_read_integer(this, INT_MIN, INT_MAX, FALSE);
3624 istream_isfx(this);
3626 return this;
3629 /* ??5istream@@QAEAAV0@AAI@Z */
3630 /* ??5istream@@QEAAAEAV0@AEAI@Z */
3631 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_int, 8)
3632 istream* __thiscall istream_read_unsigned_int(istream *this, unsigned int *p)
3634 if (istream_ipfx(this, 0)) {
3635 *p = istream_internal_read_unsigned_integer(this, INT_MIN, UINT_MAX);
3636 istream_isfx(this);
3638 return this;
3641 /* ??5istream@@QAEAAV0@AAJ@Z */
3642 /* ??5istream@@QEAAAEAV0@AEAJ@Z */
3643 DEFINE_THISCALL_WRAPPER(istream_read_long, 8)
3644 istream* __thiscall istream_read_long(istream *this, LONG *p)
3646 if (istream_ipfx(this, 0)) {
3647 *p = istream_internal_read_integer(this, LONG_MIN, LONG_MAX, TRUE);
3648 istream_isfx(this);
3650 return this;
3653 /* ??5istream@@QAEAAV0@AAK@Z */
3654 /* ??5istream@@QEAAAEAV0@AEAK@Z */
3655 DEFINE_THISCALL_WRAPPER(istream_read_unsigned_long, 8)
3656 istream* __thiscall istream_read_unsigned_long(istream *this, ULONG *p)
3658 if (istream_ipfx(this, 0)) {
3659 *p = istream_internal_read_unsigned_integer(this, LONG_MIN, ULONG_MAX);
3660 istream_isfx(this);
3662 return this;
3665 static BOOL istream_internal_read_float(istream *this, int max_chars, double *out)
3667 char buffer[32];
3668 BOOL read = FALSE;
3670 TRACE("(%p %d %p)\n", this, max_chars, out);
3672 if (istream_ipfx(this, 0)) {
3673 /* character count is limited on Windows */
3674 if (istream_getdouble(this, buffer, max_chars) > 0) {
3675 *out = strtod(buffer, NULL);
3676 read = TRUE;
3678 istream_isfx(this);
3680 return read;
3683 /* ??5istream@@QAEAAV0@AAM@Z */
3684 /* ??5istream@@QEAAAEAV0@AEAM@Z */
3685 DEFINE_THISCALL_WRAPPER(istream_read_float, 8)
3686 istream* __thiscall istream_read_float(istream *this, float *f)
3688 double tmp;
3689 if (istream_internal_read_float(this, 20, &tmp)) {
3690 /* check whether the value fits in the output var */
3691 if (tmp > FLT_MAX)
3692 tmp = FLT_MAX;
3693 else if (tmp < -FLT_MAX)
3694 tmp = -FLT_MAX;
3695 else if (tmp > 0 && tmp < FLT_MIN)
3696 tmp = FLT_MIN;
3697 else if (tmp < 0 && tmp > -FLT_MIN)
3698 tmp = -FLT_MIN;
3699 *f = tmp;
3701 return this;
3704 /* ??5istream@@QAEAAV0@AAN@Z */
3705 /* ??5istream@@QEAAAEAV0@AEAN@Z */
3706 DEFINE_THISCALL_WRAPPER(istream_read_double, 8)
3707 istream* __thiscall istream_read_double(istream *this, double *d)
3709 istream_internal_read_float(this, 28, d);
3710 return this;
3713 /* ??5istream@@QAEAAV0@AAO@Z */
3714 /* ??5istream@@QEAAAEAV0@AEAO@Z */
3715 DEFINE_THISCALL_WRAPPER(istream_read_long_double, 8)
3716 istream* __thiscall istream_read_long_double(istream *this, double *ld)
3718 istream_internal_read_float(this, 32, ld);
3719 return this;
3722 /* ??5istream@@QAEAAV0@PAVstreambuf@@@Z */
3723 /* ??5istream@@QEAAAEAV0@PEAVstreambuf@@@Z */
3724 DEFINE_THISCALL_WRAPPER(istream_read_streambuf, 8)
3725 istream* __thiscall istream_read_streambuf(istream *this, streambuf *sb)
3727 ios *base = istream_get_ios(this);
3728 int ch;
3730 TRACE("(%p %p)\n", this, sb);
3732 if (istream_ipfx(this, 0)) {
3733 while ((ch = streambuf_sbumpc(base->sb)) != EOF)
3734 if (streambuf_sputc(sb, ch) == EOF)
3735 base->state |= IOSTATE_failbit;
3736 istream_isfx(this);
3738 return this;
3741 /* ??5istream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
3742 /* ??5istream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
3743 DEFINE_THISCALL_WRAPPER(istream_read_manip, 8)
3744 istream* __thiscall istream_read_manip(istream *this, istream* (__cdecl *func)(istream*))
3746 TRACE("(%p %p)\n", this, func);
3747 return func(this);
3750 /* ??5istream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
3751 /* ??5istream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
3752 DEFINE_THISCALL_WRAPPER(istream_read_ios_manip, 8)
3753 istream* __thiscall istream_read_ios_manip(istream *this, ios* (__cdecl *func)(ios*))
3755 TRACE("(%p %p)\n", this, func);
3756 func(istream_get_ios(this));
3757 return this;
3760 /* ?ws@@YAAAVistream@@AAV1@@Z */
3761 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
3762 istream* __cdecl istream_ws(istream *this)
3764 TRACE("(%p)\n", this);
3765 istream_eatwhite(this);
3766 return this;
3769 /******************************************************************
3770 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
3772 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
3773 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
3775 FIXME("(%p %x) stub\n", this, virt_init);
3776 return this;
3779 /******************************************************************
3780 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
3782 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
3783 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
3785 FIXME("(%p) stub\n", base);
3788 #ifdef __i386__
3790 #define DEFINE_VTBL_WRAPPER(off) \
3791 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
3792 "popl %eax\n\t" \
3793 "popl %ecx\n\t" \
3794 "pushl %eax\n\t" \
3795 "movl 0(%ecx), %eax\n\t" \
3796 "jmp *" #off "(%eax)\n\t")
3798 DEFINE_VTBL_WRAPPER(0);
3799 DEFINE_VTBL_WRAPPER(4);
3800 DEFINE_VTBL_WRAPPER(8);
3801 DEFINE_VTBL_WRAPPER(12);
3802 DEFINE_VTBL_WRAPPER(16);
3803 DEFINE_VTBL_WRAPPER(20);
3804 DEFINE_VTBL_WRAPPER(24);
3805 DEFINE_VTBL_WRAPPER(28);
3806 DEFINE_VTBL_WRAPPER(32);
3807 DEFINE_VTBL_WRAPPER(36);
3808 DEFINE_VTBL_WRAPPER(40);
3809 DEFINE_VTBL_WRAPPER(44);
3810 DEFINE_VTBL_WRAPPER(48);
3811 DEFINE_VTBL_WRAPPER(52);
3812 DEFINE_VTBL_WRAPPER(56);
3814 #endif
3816 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
3817 void (__cdecl *MSVCRT_operator_delete)(void*);
3819 static void init_cxx_funcs(void)
3821 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
3823 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
3825 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
3826 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
3828 else
3830 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
3831 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
3835 static void init_io(void *base)
3837 #ifdef __x86_64__
3838 init_streambuf_rtti(base);
3839 init_filebuf_rtti(base);
3840 init_strstreambuf_rtti(base);
3841 init_stdiobuf_rtti(base);
3842 init_ios_rtti(base);
3843 init_ostream_rtti(base);
3844 init_istream_rtti(base);
3845 #endif
3848 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
3850 switch (reason)
3852 case DLL_WINE_PREATTACH:
3853 return FALSE; /* prefer native version */
3854 case DLL_PROCESS_ATTACH:
3855 init_cxx_funcs();
3856 init_exception(inst);
3857 init_io(inst);
3858 DisableThreadLibraryCalls( inst );
3859 break;
3861 return TRUE;