wined3d: Pass a texture and sub-resource index to wined3d_volume_download_data().
[wine.git] / dlls / msvcirt / msvcirt.c
blob14383245bd5b703b7e6666fb8c848a1c578abdf1
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 <fcntl.h>
23 #include <io.h>
24 #include <share.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <sys/stat.h>
29 #include "msvcirt.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
36 #define RESERVE_SIZE 512
37 #define STATEBUF_SIZE 8
39 /* ?sh_none@filebuf@@2HB */
40 const int filebuf_sh_none = 0x800;
41 /* ?sh_read@filebuf@@2HB */
42 const int filebuf_sh_read = 0xa00;
43 /* ?sh_write@filebuf@@2HB */
44 const int filebuf_sh_write = 0xc00;
45 /* ?openprot@filebuf@@2HB */
46 const int filebuf_openprot = 420;
47 /* ?binary@filebuf@@2HB */
48 const int filebuf_binary = _O_BINARY;
49 /* ?text@filebuf@@2HB */
50 const int filebuf_text = _O_TEXT;
52 /* ?adjustfield@ios@@2JB */
53 const LONG ios_adjustfield = FLAGS_left | FLAGS_right | FLAGS_internal;
54 /* ?basefield@ios@@2JB */
55 const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
56 /* ?floatfield@ios@@2JB */
57 const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
58 /* ?fLockcInit@ios@@0HA */
59 /* FIXME: should be initialized to 0 and increased on construction of cin, cout, cerr and clog */
60 int ios_fLockcInit = 4;
61 /* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
62 extern CRITICAL_SECTION ios_static_lock;
63 CRITICAL_SECTION_DEBUG ios_static_lock_debug =
65 0, 0, &ios_static_lock,
66 { &ios_static_lock_debug.ProcessLocksList, &ios_static_lock_debug.ProcessLocksList },
67 0, 0, { (DWORD_PTR)(__FILE__ ": ios_static_lock") }
69 CRITICAL_SECTION ios_static_lock = { &ios_static_lock_debug, -1, 0, 0, 0, 0 };
70 /* ?x_maxbit@ios@@0JA */
71 LONG ios_maxbit = 0x8000;
72 /* ?x_curindex@ios@@0HA */
73 int ios_curindex = -1;
74 /* ?x_statebuf@ios@@0PAJA */
75 LONG ios_statebuf[STATEBUF_SIZE] = {0};
77 /* class streambuf */
78 typedef struct {
79 const vtable_ptr *vtable;
80 int allocated;
81 int unbuffered;
82 int stored_char;
83 char *base;
84 char *ebuf;
85 char *pbase;
86 char *pptr;
87 char *epptr;
88 char *eback;
89 char *gptr;
90 char *egptr;
91 int do_lock;
92 CRITICAL_SECTION lock;
93 } streambuf;
95 void __thiscall streambuf_setb(streambuf*, char*, char*, int);
96 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
97 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
98 void __thiscall streambuf_setp(streambuf*, char*, char*);
100 /* class filebuf */
101 typedef struct {
102 streambuf base;
103 filedesc fd;
104 int close;
105 } filebuf;
107 filebuf* __thiscall filebuf_close(filebuf*);
109 /* class strstreambuf */
110 typedef struct {
111 streambuf base;
112 int dynamic;
113 int increase;
114 int unknown;
115 int constant;
116 allocFunction f_alloc;
117 freeFunction f_free;
118 } strstreambuf;
120 /* class stdiobuf */
121 typedef struct {
122 streambuf base;
123 FILE *file;
124 } stdiobuf;
126 /* class ios */
127 struct _ostream;
128 typedef struct {
129 const vtable_ptr *vtable;
130 streambuf *sb;
131 ios_io_state state;
132 int special[4];
133 int delbuf;
134 struct _ostream *tie;
135 ios_flags flags;
136 int precision;
137 char fill;
138 int width;
139 int do_lock;
140 CRITICAL_SECTION lock;
141 } ios;
143 ios* __thiscall ios_assign(ios*, const ios*);
144 int __thiscall ios_fail(const ios*);
145 void __cdecl ios_lock(ios*);
146 void __cdecl ios_lockc(void);
147 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
148 void __cdecl ios_unlock(ios*);
149 void __cdecl ios_unlockc(void);
151 /* class ostream */
152 typedef struct _ostream {
153 const int *vbtable;
154 int unknown;
155 } ostream;
157 /* class istream */
158 typedef struct {
159 const int *vbtable;
160 int extract_delim;
161 int count;
162 } istream;
164 /* ??_7streambuf@@6B@ */
165 extern const vtable_ptr MSVCP_streambuf_vtable;
166 /* ??_7filebuf@@6B@ */
167 extern const vtable_ptr MSVCP_filebuf_vtable;
168 /* ??_7strstreambuf@@6B@ */
169 extern const vtable_ptr MSVCP_strstreambuf_vtable;
170 /* ??_7stdiobuf@@6B@ */
171 extern const vtable_ptr MSVCP_stdiobuf_vtable;
172 /* ??_7ios@@6B@ */
173 extern const vtable_ptr MSVCP_ios_vtable;
174 /* ??_7ostream@@6B@ */
175 extern const vtable_ptr MSVCP_ostream_vtable;
176 /* ??_7istream@@6B@ */
177 extern const vtable_ptr MSVCP_istream_vtable;
179 #ifndef __GNUC__
180 void __asm_dummy_vtables(void) {
181 #endif
182 __ASM_VTABLE(streambuf,
183 VTABLE_ADD_FUNC(streambuf_vector_dtor)
184 VTABLE_ADD_FUNC(streambuf_sync)
185 VTABLE_ADD_FUNC(streambuf_setbuf)
186 VTABLE_ADD_FUNC(streambuf_seekoff)
187 VTABLE_ADD_FUNC(streambuf_seekpos)
188 VTABLE_ADD_FUNC(streambuf_xsputn)
189 VTABLE_ADD_FUNC(streambuf_xsgetn)
190 VTABLE_ADD_FUNC(streambuf_overflow)
191 VTABLE_ADD_FUNC(streambuf_underflow)
192 VTABLE_ADD_FUNC(streambuf_pbackfail)
193 VTABLE_ADD_FUNC(streambuf_doallocate));
194 __ASM_VTABLE(filebuf,
195 VTABLE_ADD_FUNC(filebuf_vector_dtor)
196 VTABLE_ADD_FUNC(filebuf_sync)
197 VTABLE_ADD_FUNC(filebuf_setbuf)
198 VTABLE_ADD_FUNC(filebuf_seekoff)
199 VTABLE_ADD_FUNC(streambuf_seekpos)
200 VTABLE_ADD_FUNC(streambuf_xsputn)
201 VTABLE_ADD_FUNC(streambuf_xsgetn)
202 VTABLE_ADD_FUNC(filebuf_overflow)
203 VTABLE_ADD_FUNC(filebuf_underflow)
204 VTABLE_ADD_FUNC(streambuf_pbackfail)
205 VTABLE_ADD_FUNC(streambuf_doallocate));
206 __ASM_VTABLE(strstreambuf,
207 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
208 VTABLE_ADD_FUNC(strstreambuf_sync)
209 VTABLE_ADD_FUNC(strstreambuf_setbuf)
210 VTABLE_ADD_FUNC(strstreambuf_seekoff)
211 VTABLE_ADD_FUNC(streambuf_seekpos)
212 VTABLE_ADD_FUNC(streambuf_xsputn)
213 VTABLE_ADD_FUNC(streambuf_xsgetn)
214 VTABLE_ADD_FUNC(strstreambuf_overflow)
215 VTABLE_ADD_FUNC(strstreambuf_underflow)
216 VTABLE_ADD_FUNC(streambuf_pbackfail)
217 VTABLE_ADD_FUNC(strstreambuf_doallocate));
218 __ASM_VTABLE(stdiobuf,
219 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
220 VTABLE_ADD_FUNC(stdiobuf_sync)
221 VTABLE_ADD_FUNC(streambuf_setbuf)
222 VTABLE_ADD_FUNC(stdiobuf_seekoff)
223 VTABLE_ADD_FUNC(streambuf_seekpos)
224 VTABLE_ADD_FUNC(streambuf_xsputn)
225 VTABLE_ADD_FUNC(streambuf_xsgetn)
226 VTABLE_ADD_FUNC(stdiobuf_overflow)
227 VTABLE_ADD_FUNC(stdiobuf_underflow)
228 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
229 VTABLE_ADD_FUNC(streambuf_doallocate));
230 __ASM_VTABLE(ios,
231 VTABLE_ADD_FUNC(ios_vector_dtor));
232 __ASM_VTABLE(ostream,
233 VTABLE_ADD_FUNC(ostream_vector_dtor));
234 __ASM_VTABLE(istream,
235 VTABLE_ADD_FUNC(istream_vector_dtor));
236 #ifndef __GNUC__
238 #endif
240 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
241 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
243 /* ??_8ostream@@7B@ */
244 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
245 /* ??_8istream@@7B@ */
246 const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
248 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
249 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
250 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
251 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
252 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
253 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
254 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
256 /* ??0streambuf@@IAE@PADH@Z */
257 /* ??0streambuf@@IEAA@PEADH@Z */
258 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
259 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
261 TRACE("(%p %p %d)\n", this, buffer, length);
262 this->vtable = &MSVCP_streambuf_vtable;
263 this->allocated = 0;
264 this->stored_char = EOF;
265 this->do_lock = -1;
266 this->base = NULL;
267 streambuf_setbuf(this, buffer, length);
268 streambuf_setg(this, NULL, NULL, NULL);
269 streambuf_setp(this, NULL, NULL);
270 InitializeCriticalSection(&this->lock);
271 return this;
274 /* ??0streambuf@@IAE@XZ */
275 /* ??0streambuf@@IEAA@XZ */
276 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
277 streambuf* __thiscall streambuf_ctor(streambuf *this)
279 streambuf_reserve_ctor(this, NULL, 0);
280 this->unbuffered = 0;
281 return this;
284 /* ??0streambuf@@QAE@ABV0@@Z */
285 /* ??0streambuf@@QEAA@AEBV0@@Z */
286 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
287 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
289 TRACE("(%p %p)\n", this, copy);
290 *this = *copy;
291 this->vtable = &MSVCP_streambuf_vtable;
292 return this;
295 /* ??1streambuf@@UAE@XZ */
296 /* ??1streambuf@@UEAA@XZ */
297 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
298 void __thiscall streambuf_dtor(streambuf *this)
300 TRACE("(%p)\n", this);
301 if (this->allocated)
302 MSVCRT_operator_delete(this->base);
303 DeleteCriticalSection(&this->lock);
306 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
307 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
308 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
309 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
311 streambuf_dtor(this);
312 return streambuf_copy_ctor(this, rhs);
315 /* ??_Estreambuf@@UAEPAXI@Z */
316 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
317 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
318 streambuf*, (streambuf*, unsigned int), (this, flags))
319 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
321 TRACE("(%p %x)\n", this, flags);
322 if (flags & 2) {
323 /* we have an array, with the number of elements stored before the first object */
324 INT_PTR i, *ptr = (INT_PTR *)this-1;
326 for (i = *ptr-1; i >= 0; i--)
327 streambuf_dtor(this+i);
328 MSVCRT_operator_delete(ptr);
329 } else {
330 streambuf_dtor(this);
331 if (flags & 1)
332 MSVCRT_operator_delete(this);
334 return this;
337 /* ??_Gstreambuf@@UAEPAXI@Z */
338 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
339 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
341 TRACE("(%p %x)\n", this, flags);
342 streambuf_dtor(this);
343 if (flags & 1) MSVCRT_operator_delete(this);
344 return this;
347 /* ?doallocate@streambuf@@MAEHXZ */
348 /* ?doallocate@streambuf@@MEAAHXZ */
349 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
350 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
351 int __thiscall streambuf_doallocate(streambuf *this)
353 char *reserve;
355 TRACE("(%p)\n", this);
356 reserve = MSVCRT_operator_new(RESERVE_SIZE);
357 if (!reserve)
358 return EOF;
360 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
361 return 1;
364 /* ?allocate@streambuf@@IAEHXZ */
365 /* ?allocate@streambuf@@IEAAHXZ */
366 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
367 int __thiscall streambuf_allocate(streambuf *this)
369 TRACE("(%p)\n", this);
370 if (this->base != NULL || this->unbuffered)
371 return 0;
372 return call_streambuf_doallocate(this);
375 /* ?base@streambuf@@IBEPADXZ */
376 /* ?base@streambuf@@IEBAPEADXZ */
377 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
378 char* __thiscall streambuf_base(const streambuf *this)
380 TRACE("(%p)\n", this);
381 return this->base;
384 /* ?blen@streambuf@@IBEHXZ */
385 /* ?blen@streambuf@@IEBAHXZ */
386 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
387 int __thiscall streambuf_blen(const streambuf *this)
389 TRACE("(%p)\n", this);
390 return this->ebuf - this->base;
393 /* ?eback@streambuf@@IBEPADXZ */
394 /* ?eback@streambuf@@IEBAPEADXZ */
395 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
396 char* __thiscall streambuf_eback(const streambuf *this)
398 TRACE("(%p)\n", this);
399 return this->eback;
402 /* ?ebuf@streambuf@@IBEPADXZ */
403 /* ?ebuf@streambuf@@IEBAPEADXZ */
404 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
405 char* __thiscall streambuf_ebuf(const streambuf *this)
407 TRACE("(%p)\n", this);
408 return this->ebuf;
411 /* ?egptr@streambuf@@IBEPADXZ */
412 /* ?egptr@streambuf@@IEBAPEADXZ */
413 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
414 char* __thiscall streambuf_egptr(const streambuf *this)
416 TRACE("(%p)\n", this);
417 return this->egptr;
420 /* ?epptr@streambuf@@IBEPADXZ */
421 /* ?epptr@streambuf@@IEBAPEADXZ */
422 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
423 char* __thiscall streambuf_epptr(const streambuf *this)
425 TRACE("(%p)\n", this);
426 return this->epptr;
429 /* ?gptr@streambuf@@IBEPADXZ */
430 /* ?gptr@streambuf@@IEBAPEADXZ */
431 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
432 char* __thiscall streambuf_gptr(const streambuf *this)
434 TRACE("(%p)\n", this);
435 return this->gptr;
438 /* ?pbase@streambuf@@IBEPADXZ */
439 /* ?pbase@streambuf@@IEBAPEADXZ */
440 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
441 char* __thiscall streambuf_pbase(const streambuf *this)
443 TRACE("(%p)\n", this);
444 return this->pbase;
447 /* ?pptr@streambuf@@IBEPADXZ */
448 /* ?pptr@streambuf@@IEBAPEADXZ */
449 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
450 char* __thiscall streambuf_pptr(const streambuf *this)
452 TRACE("(%p)\n", this);
453 return this->pptr;
456 /* ?clrlock@streambuf@@QAEXXZ */
457 /* ?clrlock@streambuf@@QEAAXXZ */
458 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
459 void __thiscall streambuf_clrlock(streambuf *this)
461 TRACE("(%p)\n", this);
462 if (this->do_lock <= 0)
463 this->do_lock++;
466 /* ?lock@streambuf@@QAEXXZ */
467 /* ?lock@streambuf@@QEAAXXZ */
468 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
469 void __thiscall streambuf_lock(streambuf *this)
471 TRACE("(%p)\n", this);
472 if (this->do_lock < 0)
473 EnterCriticalSection(&this->lock);
476 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
477 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
478 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
479 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
481 TRACE("(%p)\n", this);
482 return &this->lock;
485 /* ?gbump@streambuf@@IAEXH@Z */
486 /* ?gbump@streambuf@@IEAAXH@Z */
487 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
488 void __thiscall streambuf_gbump(streambuf *this, int count)
490 TRACE("(%p %d)\n", this, count);
491 this->gptr += count;
494 /* ?pbump@streambuf@@IAEXH@Z */
495 /* ?pbump@streambuf@@IEAAXH@Z */
496 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
497 void __thiscall streambuf_pbump(streambuf *this, int count)
499 TRACE("(%p %d)\n", this, count);
500 this->pptr += count;
503 /* ?in_avail@streambuf@@QBEHXZ */
504 /* ?in_avail@streambuf@@QEBAHXZ */
505 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
506 int __thiscall streambuf_in_avail(const streambuf *this)
508 TRACE("(%p)\n", this);
509 return this->egptr - this->gptr;
512 /* ?out_waiting@streambuf@@QBEHXZ */
513 /* ?out_waiting@streambuf@@QEBAHXZ */
514 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
515 int __thiscall streambuf_out_waiting(const streambuf *this)
517 TRACE("(%p)\n", this);
518 return this->pptr - this->pbase;
521 /* Unexported */
522 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
523 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
524 int __thiscall streambuf_overflow(streambuf *this, int c)
526 ERR("overflow is not implemented in streambuf\n");
527 return EOF;
530 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
531 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
532 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
533 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
534 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
536 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
537 return EOF;
540 /* ?seekpos@streambuf@@UAEJJH@Z */
541 /* ?seekpos@streambuf@@UEAAJJH@Z */
542 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
543 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
545 TRACE("(%p %d %d)\n", this, pos, mode);
546 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
549 /* ?pbackfail@streambuf@@UAEHH@Z */
550 /* ?pbackfail@streambuf@@UEAAHH@Z */
551 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
552 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
553 int __thiscall streambuf_pbackfail(streambuf *this, int c)
555 TRACE("(%p %d)\n", this, c);
556 if (this->gptr > this->eback)
557 return *--this->gptr = c;
558 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
559 return EOF;
560 if (!this->unbuffered && this->egptr) {
561 /* 'c' should be the next character read */
562 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
563 *this->gptr = c;
565 return c;
568 /* ?setb@streambuf@@IAEXPAD0H@Z */
569 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
570 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
571 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
573 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
574 if (this->allocated)
575 MSVCRT_operator_delete(this->base);
576 this->allocated = delete;
577 this->base = ba;
578 this->ebuf = eb;
581 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
582 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
583 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
584 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
586 TRACE("(%p %p %d)\n", this, buffer, length);
587 if (this->base != NULL)
588 return NULL;
590 if (buffer == NULL || !length) {
591 this->unbuffered = 1;
592 this->base = this->ebuf = NULL;
593 } else {
594 this->unbuffered = 0;
595 this->base = buffer;
596 this->ebuf = buffer + length;
598 return this;
601 /* ?setg@streambuf@@IAEXPAD00@Z */
602 /* ?setg@streambuf@@IEAAXPEAD00@Z */
603 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
604 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
606 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
607 this->eback = ek;
608 this->gptr = gp;
609 this->egptr = eg;
612 /* ?setlock@streambuf@@QAEXXZ */
613 /* ?setlock@streambuf@@QEAAXXZ */
614 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
615 void __thiscall streambuf_setlock(streambuf *this)
617 TRACE("(%p)\n", this);
618 this->do_lock--;
621 /* ?setp@streambuf@@IAEXPAD0@Z */
622 /* ?setp@streambuf@@IEAAXPEAD0@Z */
623 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
624 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
626 TRACE("(%p %p %p)\n", this, pb, ep);
627 this->pbase = this->pptr = pb;
628 this->epptr = ep;
631 /* ?sync@streambuf@@UAEHXZ */
632 /* ?sync@streambuf@@UEAAHXZ */
633 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
634 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
635 int __thiscall streambuf_sync(streambuf *this)
637 TRACE("(%p)\n", this);
638 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
641 /* ?unbuffered@streambuf@@IAEXH@Z */
642 /* ?unbuffered@streambuf@@IEAAXH@Z */
643 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
644 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
646 TRACE("(%p %d)\n", this, buf);
647 this->unbuffered = buf;
650 /* ?unbuffered@streambuf@@IBEHXZ */
651 /* ?unbuffered@streambuf@@IEBAHXZ */
652 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
653 int __thiscall streambuf_unbuffered_get(const streambuf *this)
655 TRACE("(%p)\n", this);
656 return this->unbuffered;
659 /* Unexported */
660 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
661 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
662 int __thiscall streambuf_underflow(streambuf *this)
664 ERR("underflow is not implemented in streambuf\n");
665 return EOF;
668 /* ?unlock@streambuf@@QAEXXZ */
669 /* ?unlock@streambuf@@QEAAXXZ */
670 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
671 void __thiscall streambuf_unlock(streambuf *this)
673 TRACE("(%p)\n", this);
674 if (this->do_lock < 0)
675 LeaveCriticalSection(&this->lock);
678 /* ?xsgetn@streambuf@@UAEHPADH@Z */
679 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
680 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
681 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
682 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
684 int copied = 0, chunk;
686 TRACE("(%p %p %d)\n", this, buffer, count);
688 if (this->unbuffered) {
689 if (this->stored_char == EOF)
690 this->stored_char = call_streambuf_underflow(this);
691 while (copied < count && this->stored_char != EOF) {
692 buffer[copied++] = this->stored_char;
693 this->stored_char = call_streambuf_underflow(this);
695 } else {
696 while (copied < count) {
697 if (call_streambuf_underflow(this) == EOF)
698 break;
699 chunk = this->egptr - this->gptr;
700 if (chunk > count - copied)
701 chunk = count - copied;
702 memcpy(buffer+copied, this->gptr, chunk);
703 this->gptr += chunk;
704 copied += chunk;
707 return copied;
710 /* ?xsputn@streambuf@@UAEHPBDH@Z */
711 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
712 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
713 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
714 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
716 int copied = 0, chunk;
718 TRACE("(%p %p %d)\n", this, data, length);
720 while (copied < length) {
721 if (this->unbuffered || this->pptr == this->epptr) {
722 if (call_streambuf_overflow(this, data[copied]) == EOF)
723 break;
724 copied++;
725 } else {
726 chunk = this->epptr - this->pptr;
727 if (chunk > length - copied)
728 chunk = length - copied;
729 memcpy(this->pptr, data+copied, chunk);
730 this->pptr += chunk;
731 copied += chunk;
734 return copied;
737 /* ?sgetc@streambuf@@QAEHXZ */
738 /* ?sgetc@streambuf@@QEAAHXZ */
739 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
740 int __thiscall streambuf_sgetc(streambuf *this)
742 TRACE("(%p)\n", this);
743 if (this->unbuffered) {
744 if (this->stored_char == EOF)
745 this->stored_char = call_streambuf_underflow(this);
746 return this->stored_char;
747 } else
748 return call_streambuf_underflow(this);
751 /* ?sputc@streambuf@@QAEHH@Z */
752 /* ?sputc@streambuf@@QEAAHH@Z */
753 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
754 int __thiscall streambuf_sputc(streambuf *this, int ch)
756 TRACE("(%p %d)\n", this, ch);
757 return (this->pptr < this->epptr) ? (unsigned char)(*this->pptr++ = ch) : call_streambuf_overflow(this, ch);
760 /* ?sgetn@streambuf@@QAEHPADH@Z */
761 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
762 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
763 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
765 return call_streambuf_xsgetn(this, buffer, count);
768 /* ?sputn@streambuf@@QAEHPBDH@Z */
769 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
770 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
771 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
773 return call_streambuf_xsputn(this, data, length);
776 /* ?snextc@streambuf@@QAEHXZ */
777 /* ?snextc@streambuf@@QEAAHXZ */
778 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
779 int __thiscall streambuf_snextc(streambuf *this)
781 TRACE("(%p)\n", this);
782 if (this->unbuffered) {
783 if (this->stored_char == EOF)
784 call_streambuf_underflow(this);
785 return this->stored_char = call_streambuf_underflow(this);
786 } else {
787 if (this->gptr >= this->egptr)
788 call_streambuf_underflow(this);
789 this->gptr++;
790 return (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
794 /* ?sbumpc@streambuf@@QAEHXZ */
795 /* ?sbumpc@streambuf@@QEAAHXZ */
796 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
797 int __thiscall streambuf_sbumpc(streambuf *this)
799 int ret;
801 TRACE("(%p)\n", this);
803 if (this->unbuffered) {
804 ret = this->stored_char;
805 this->stored_char = EOF;
806 if (ret == EOF)
807 ret = call_streambuf_underflow(this);
808 } else {
809 ret = (this->gptr < this->egptr) ? (unsigned char)(*this->gptr) : call_streambuf_underflow(this);
810 this->gptr++;
812 return ret;
815 /* ?stossc@streambuf@@QAEXXZ */
816 /* ?stossc@streambuf@@QEAAXXZ */
817 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
818 void __thiscall streambuf_stossc(streambuf *this)
820 TRACE("(%p)\n", this);
821 if (this->unbuffered) {
822 if (this->stored_char == EOF)
823 call_streambuf_underflow(this);
824 else
825 this->stored_char = EOF;
826 } else {
827 if (this->gptr >= this->egptr)
828 call_streambuf_underflow(this);
829 if (this->gptr < this->egptr)
830 this->gptr++;
834 /* ?sputbackc@streambuf@@QAEHD@Z */
835 /* ?sputbackc@streambuf@@QEAAHD@Z */
836 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
837 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
839 TRACE("(%p %d)\n", this, ch);
840 return call_streambuf_pbackfail(this, ch);
843 /* ?dbp@streambuf@@QAEXXZ */
844 /* ?dbp@streambuf@@QEAAXXZ */
845 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
846 void __thiscall streambuf_dbp(streambuf *this)
848 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
849 if (this->unbuffered) {
850 printf("unbuffered\n");
851 } else {
852 printf("_fAlloc=%d\n", this->allocated);
853 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
854 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
855 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
859 /* ??0filebuf@@QAE@ABV0@@Z */
860 /* ??0filebuf@@QEAA@AEBV0@@Z */
861 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
862 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
864 TRACE("(%p %p)\n", this, copy);
865 *this = *copy;
866 this->base.vtable = &MSVCP_filebuf_vtable;
867 return this;
870 /* ??0filebuf@@QAE@HPADH@Z */
871 /* ??0filebuf@@QEAA@HPEADH@Z */
872 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
873 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
875 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
876 streambuf_reserve_ctor(&this->base, buffer, length);
877 this->base.vtable = &MSVCP_filebuf_vtable;
878 this->fd = fd;
879 this->close = 0;
880 return this;
883 /* ??0filebuf@@QAE@H@Z */
884 /* ??0filebuf@@QEAA@H@Z */
885 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
886 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
888 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
889 this->base.unbuffered = 0;
890 return this;
893 /* ??0filebuf@@QAE@XZ */
894 /* ??0filebuf@@QEAA@XZ */
895 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
896 filebuf* __thiscall filebuf_ctor(filebuf* this)
898 return filebuf_fd_ctor(this, -1);
901 /* ??1filebuf@@UAE@XZ */
902 /* ??1filebuf@@UEAA@XZ */
903 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
904 void __thiscall filebuf_dtor(filebuf* this)
906 TRACE("(%p)\n", this);
907 if (this->close)
908 filebuf_close(this);
909 streambuf_dtor(&this->base);
912 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
913 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
914 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
915 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
917 filebuf_dtor(this);
918 return filebuf_copy_ctor(this, rhs);
921 /* ??_Efilebuf@@UAEPAXI@Z */
922 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
923 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
925 TRACE("(%p %x)\n", this, flags);
926 if (flags & 2) {
927 /* we have an array, with the number of elements stored before the first object */
928 INT_PTR i, *ptr = (INT_PTR *)this-1;
930 for (i = *ptr-1; i >= 0; i--)
931 filebuf_dtor(this+i);
932 MSVCRT_operator_delete(ptr);
933 } else {
934 filebuf_dtor(this);
935 if (flags & 1)
936 MSVCRT_operator_delete(this);
938 return this;
941 /* ??_Gfilebuf@@UAEPAXI@Z */
942 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
943 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
945 TRACE("(%p %x)\n", this, flags);
946 filebuf_dtor(this);
947 if (flags & 1) MSVCRT_operator_delete(this);
948 return this;
951 /* ?attach@filebuf@@QAEPAV1@H@Z */
952 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
953 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
954 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
956 TRACE("(%p %d)\n", this, fd);
957 if (this->fd != -1)
958 return NULL;
960 streambuf_lock(&this->base);
961 this->fd = fd;
962 streambuf_allocate(&this->base);
963 streambuf_unlock(&this->base);
964 return this;
967 /* ?close@filebuf@@QAEPAV1@XZ */
968 /* ?close@filebuf@@QEAAPEAV1@XZ */
969 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
970 filebuf* __thiscall filebuf_close(filebuf *this)
972 filebuf *ret;
974 TRACE("(%p)\n", this);
975 if (this->fd == -1)
976 return NULL;
978 streambuf_lock(&this->base);
979 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
980 ret = NULL;
981 } else {
982 this->fd = -1;
983 ret = this;
985 streambuf_unlock(&this->base);
986 return ret;
989 /* ?fd@filebuf@@QBEHXZ */
990 /* ?fd@filebuf@@QEBAHXZ */
991 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
992 filedesc __thiscall filebuf_fd(const filebuf *this)
994 TRACE("(%p)\n", this);
995 return this->fd;
998 /* ?is_open@filebuf@@QBEHXZ */
999 /* ?is_open@filebuf@@QEBAHXZ */
1000 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
1001 int __thiscall filebuf_is_open(const filebuf *this)
1003 TRACE("(%p)\n", this);
1004 return this->fd != -1;
1007 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
1008 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
1009 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
1010 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
1012 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
1013 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1014 int op_flags, sh_flags, fd;
1016 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1017 if (this->fd != -1)
1018 return NULL;
1020 /* mode */
1021 if (mode & (OPENMODE_app|OPENMODE_trunc))
1022 mode |= OPENMODE_out;
1023 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1024 if (op_flags < 0)
1025 return NULL;
1026 if (mode & OPENMODE_app)
1027 op_flags |= _O_APPEND;
1028 if ((mode & OPENMODE_trunc) ||
1029 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1030 op_flags |= _O_TRUNC;
1031 if (!(mode & OPENMODE_nocreate))
1032 op_flags |= _O_CREAT;
1033 if (mode & OPENMODE_noreplace)
1034 op_flags |= _O_EXCL;
1035 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1037 /* share protection */
1038 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1040 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1041 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1042 if (fd < 0)
1043 return NULL;
1045 streambuf_lock(&this->base);
1046 this->close = 1;
1047 this->fd = fd;
1048 if ((mode & OPENMODE_ate) &&
1049 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1050 _close(fd);
1051 this->fd = -1;
1053 streambuf_allocate(&this->base);
1054 streambuf_unlock(&this->base);
1055 return (this->fd == -1) ? NULL : this;
1058 /* ?overflow@filebuf@@UAEHH@Z */
1059 /* ?overflow@filebuf@@UEAAHH@Z */
1060 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1061 int __thiscall filebuf_overflow(filebuf *this, int c)
1063 TRACE("(%p %d)\n", this, c);
1064 if (call_streambuf_sync(&this->base) == EOF)
1065 return EOF;
1066 if (this->base.unbuffered)
1067 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1068 if (streambuf_allocate(&this->base) == EOF)
1069 return EOF;
1071 this->base.pbase = this->base.pptr = this->base.base;
1072 this->base.epptr = this->base.ebuf;
1073 if (c != EOF)
1074 *this->base.pptr++ = c;
1075 return 1;
1078 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1079 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1080 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1081 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1083 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1084 if (call_streambuf_sync(&this->base) == EOF)
1085 return EOF;
1086 return _lseek(this->fd, offset, dir);
1089 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1090 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1091 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1092 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1094 streambuf *ret;
1096 TRACE("(%p %p %d)\n", this, buffer, length);
1097 if (this->base.base != NULL)
1098 return NULL;
1100 streambuf_lock(&this->base);
1101 ret = streambuf_setbuf(&this->base, buffer, length);
1102 streambuf_unlock(&this->base);
1103 return ret;
1106 /* ?setmode@filebuf@@QAEHH@Z */
1107 /* ?setmode@filebuf@@QEAAHH@Z */
1108 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1109 int __thiscall filebuf_setmode(filebuf *this, int mode)
1111 int ret;
1113 TRACE("(%p %d)\n", this, mode);
1114 if (mode != filebuf_text && mode != filebuf_binary)
1115 return -1;
1117 streambuf_lock(&this->base);
1118 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1119 streambuf_unlock(&this->base);
1120 return ret;
1123 /* ?sync@filebuf@@UAEHXZ */
1124 /* ?sync@filebuf@@UEAAHXZ */
1125 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1126 int __thiscall filebuf_sync(filebuf *this)
1128 int count, mode;
1129 char *ptr;
1130 LONG offset;
1132 TRACE("(%p)\n", this);
1133 if (this->fd == -1)
1134 return EOF;
1135 if (this->base.unbuffered)
1136 return 0;
1138 /* flush output buffer */
1139 if (this->base.pptr != NULL) {
1140 count = this->base.pptr - this->base.pbase;
1141 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1142 return EOF;
1144 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1145 /* flush input buffer */
1146 if (this->base.egptr != NULL) {
1147 offset = this->base.egptr - this->base.gptr;
1148 if (offset > 0) {
1149 mode = _setmode(this->fd, _O_TEXT);
1150 _setmode(this->fd, mode);
1151 if (mode & _O_TEXT) {
1152 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1153 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1154 if (*ptr == '\n')
1155 offset++;
1157 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1158 return EOF;
1161 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1162 return 0;
1165 /* ?underflow@filebuf@@UAEHXZ */
1166 /* ?underflow@filebuf@@UEAAHXZ */
1167 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1168 int __thiscall filebuf_underflow(filebuf *this)
1170 int buffer_size, read_bytes;
1171 char c;
1173 TRACE("(%p)\n", this);
1175 if (this->base.unbuffered)
1176 return (_read(this->fd, &c, 1) < 1) ? EOF : (unsigned char) c;
1178 if (this->base.gptr >= this->base.egptr) {
1179 if (call_streambuf_sync(&this->base) == EOF)
1180 return EOF;
1181 buffer_size = this->base.ebuf - this->base.base;
1182 read_bytes = _read(this->fd, this->base.base, buffer_size);
1183 if (read_bytes <= 0)
1184 return EOF;
1185 this->base.eback = this->base.gptr = this->base.base;
1186 this->base.egptr = this->base.base + read_bytes;
1188 return (unsigned char) *this->base.gptr;
1191 /* ??0strstreambuf@@QAE@ABV0@@Z */
1192 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1193 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1194 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1196 TRACE("(%p %p)\n", this, copy);
1197 *this = *copy;
1198 this->base.vtable = &MSVCP_strstreambuf_vtable;
1199 return this;
1202 /* ??0strstreambuf@@QAE@H@Z */
1203 /* ??0strstreambuf@@QEAA@H@Z */
1204 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1205 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1207 TRACE("(%p %d)\n", this, length);
1208 streambuf_ctor(&this->base);
1209 this->base.vtable = &MSVCP_strstreambuf_vtable;
1210 this->dynamic = 1;
1211 this->increase = length;
1212 this->constant = 0;
1213 this->f_alloc = NULL;
1214 this->f_free = NULL;
1215 return this;
1218 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1219 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1220 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1221 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1223 TRACE("(%p %p %p)\n", this, falloc, ffree);
1224 strstreambuf_dynamic_ctor(this, 1);
1225 this->f_alloc = falloc;
1226 this->f_free = ffree;
1227 return this;
1230 /* ??0strstreambuf@@QAE@PADH0@Z */
1231 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1232 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1233 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1235 char *end_buffer;
1237 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1239 if (length > 0)
1240 end_buffer = buffer + length;
1241 else if (length == 0)
1242 end_buffer = buffer + strlen(buffer);
1243 else
1244 end_buffer = (char*) -1;
1246 streambuf_ctor(&this->base);
1247 streambuf_setb(&this->base, buffer, end_buffer, 0);
1248 if (put == NULL) {
1249 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1250 } else {
1251 streambuf_setg(&this->base, buffer, buffer, put);
1252 streambuf_setp(&this->base, put, end_buffer);
1254 this->base.vtable = &MSVCP_strstreambuf_vtable;
1255 this->dynamic = 0;
1256 this->constant = 1;
1257 return this;
1260 /* ??0strstreambuf@@QAE@PAEH0@Z */
1261 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1262 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1263 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1265 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1266 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1269 /* ??0strstreambuf@@QAE@XZ */
1270 /* ??0strstreambuf@@QEAA@XZ */
1271 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1272 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1274 TRACE("(%p)\n", this);
1275 return strstreambuf_dynamic_ctor(this, 1);
1278 /* ??1strstreambuf@@UAE@XZ */
1279 /* ??1strstreambuf@@UEAA@XZ */
1280 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1281 void __thiscall strstreambuf_dtor(strstreambuf *this)
1283 TRACE("(%p)\n", this);
1284 if (this->dynamic && this->base.base) {
1285 if (this->f_free)
1286 this->f_free(this->base.base);
1287 else
1288 MSVCRT_operator_delete(this->base.base);
1290 streambuf_dtor(&this->base);
1293 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1294 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1295 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1296 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1298 strstreambuf_dtor(this);
1299 return strstreambuf_copy_ctor(this, rhs);
1302 /* ??_Estrstreambuf@@UAEPAXI@Z */
1303 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1304 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1306 TRACE("(%p %x)\n", this, flags);
1307 if (flags & 2) {
1308 /* we have an array, with the number of elements stored before the first object */
1309 INT_PTR i, *ptr = (INT_PTR *)this-1;
1311 for (i = *ptr-1; i >= 0; i--)
1312 strstreambuf_dtor(this+i);
1313 MSVCRT_operator_delete(ptr);
1314 } else {
1315 strstreambuf_dtor(this);
1316 if (flags & 1)
1317 MSVCRT_operator_delete(this);
1319 return this;
1322 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1323 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1324 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1326 TRACE("(%p %x)\n", this, flags);
1327 strstreambuf_dtor(this);
1328 if (flags & 1) MSVCRT_operator_delete(this);
1329 return this;
1332 /* ?doallocate@strstreambuf@@MAEHXZ */
1333 /* ?doallocate@strstreambuf@@MEAAHXZ */
1334 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1335 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1337 char *prev_buffer = this->base.base, *new_buffer;
1338 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1340 TRACE("(%p)\n", this);
1342 /* calculate the size of the new buffer */
1343 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1344 /* get a new buffer */
1345 if (this->f_alloc)
1346 new_buffer = this->f_alloc(new_size);
1347 else
1348 new_buffer = MSVCRT_operator_new(new_size);
1349 if (!new_buffer)
1350 return EOF;
1351 if (this->base.ebuf) {
1352 /* copy the contents and adjust the pointers */
1353 memcpy(new_buffer, this->base.base, prev_size);
1354 if (this->base.egptr) {
1355 this->base.eback += new_buffer - prev_buffer;
1356 this->base.gptr += new_buffer - prev_buffer;
1357 this->base.egptr += new_buffer - prev_buffer;
1359 if (this->base.epptr) {
1360 this->base.pbase += new_buffer - prev_buffer;
1361 this->base.pptr += new_buffer - prev_buffer;
1362 this->base.epptr += new_buffer - prev_buffer;
1364 /* free the old buffer */
1365 if (this->f_free)
1366 this->f_free(this->base.base);
1367 else
1368 MSVCRT_operator_delete(this->base.base);
1370 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1371 return 1;
1374 /* ?freeze@strstreambuf@@QAEXH@Z */
1375 /* ?freeze@strstreambuf@@QEAAXH@Z */
1376 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1377 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1379 TRACE("(%p %d)\n", this, frozen);
1380 if (!this->constant)
1381 this->dynamic = !frozen;
1384 /* ?overflow@strstreambuf@@UAEHH@Z */
1385 /* ?overflow@strstreambuf@@UEAAHH@Z */
1386 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1387 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1389 TRACE("(%p %d)\n", this, c);
1390 if (this->base.pptr >= this->base.epptr) {
1391 /* increase the buffer size if it's dynamic */
1392 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1393 return EOF;
1394 if (!this->base.epptr)
1395 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1396 this->base.epptr = this->base.ebuf;
1398 if (c != EOF)
1399 *this->base.pptr++ = c;
1400 return 1;
1403 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1404 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1405 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1406 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1408 char *base[3];
1410 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1412 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1413 return EOF;
1414 /* read buffer */
1415 if (mode & OPENMODE_in) {
1416 call_streambuf_underflow(&this->base);
1417 base[SEEKDIR_beg] = this->base.eback;
1418 base[SEEKDIR_cur] = this->base.gptr;
1419 base[SEEKDIR_end] = this->base.egptr;
1420 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1421 return EOF;
1422 this->base.gptr = base[dir] + offset;
1424 /* write buffer */
1425 if (mode & OPENMODE_out) {
1426 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1427 return EOF;
1428 base[SEEKDIR_beg] = this->base.pbase;
1429 base[SEEKDIR_cur] = this->base.pptr;
1430 base[SEEKDIR_end] = this->base.epptr;
1431 if (base[dir] + offset < this->base.pbase)
1432 return EOF;
1433 if (base[dir] + offset > this->base.epptr) {
1434 /* make room if the buffer is dynamic */
1435 if (!this->dynamic)
1436 return EOF;
1437 this->increase = offset;
1438 if (call_streambuf_doallocate(&this->base) == EOF)
1439 return EOF;
1441 this->base.pptr = base[dir] + offset;
1442 return this->base.pptr - base[SEEKDIR_beg];
1444 return this->base.gptr - base[SEEKDIR_beg];
1447 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1448 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1449 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1450 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1452 TRACE("(%p %p %d)\n", this, buffer, length);
1453 if (length)
1454 this->increase = length;
1455 return &this->base;
1458 /* ?str@strstreambuf@@QAEPADXZ */
1459 /* ?str@strstreambuf@@QEAAPEADXZ */
1460 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1461 char* __thiscall strstreambuf_str(strstreambuf *this)
1463 TRACE("(%p)\n", this);
1464 strstreambuf_freeze(this, 1);
1465 return this->base.base;
1468 /* ?sync@strstreambuf@@UAEHXZ */
1469 /* ?sync@strstreambuf@@UEAAHXZ */
1470 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1471 int __thiscall strstreambuf_sync(strstreambuf *this)
1473 TRACE("(%p)\n", this);
1474 return 0;
1477 /* ?underflow@strstreambuf@@UAEHXZ */
1478 /* ?underflow@strstreambuf@@UEAAHXZ */
1479 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1480 int __thiscall strstreambuf_underflow(strstreambuf *this)
1482 TRACE("(%p)\n", this);
1483 if (this->base.gptr < this->base.egptr)
1484 return (unsigned char) *this->base.gptr;
1485 /* extend the get area to include the characters written */
1486 if (this->base.egptr < this->base.pptr) {
1487 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1488 this->base.eback = this->base.base;
1489 this->base.egptr = this->base.pptr;
1491 return (this->base.gptr < this->base.egptr) ? (unsigned char)(*this->base.gptr) : EOF;
1494 /* ??0stdiobuf@@QAE@ABV0@@Z */
1495 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1496 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1497 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1499 TRACE("(%p %p)\n", this, copy);
1500 *this = *copy;
1501 this->base.vtable = &MSVCP_stdiobuf_vtable;
1502 return this;
1505 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1506 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1507 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1508 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1510 TRACE("(%p %p)\n", this, file);
1511 streambuf_reserve_ctor(&this->base, NULL, 0);
1512 this->base.vtable = &MSVCP_stdiobuf_vtable;
1513 this->file = file;
1514 return this;
1517 /* ??1stdiobuf@@UAE@XZ */
1518 /* ??1stdiobuf@@UEAA@XZ */
1519 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1520 void __thiscall stdiobuf_dtor(stdiobuf *this)
1522 TRACE("(%p)\n", this);
1523 call_streambuf_sync(&this->base);
1524 streambuf_dtor(&this->base);
1527 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1528 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1529 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1530 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1532 stdiobuf_dtor(this);
1533 return stdiobuf_copy_ctor(this, rhs);
1536 /* ??_Estdiobuf@@UAEPAXI@Z */
1537 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1538 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1540 TRACE("(%p %x)\n", this, flags);
1541 if (flags & 2) {
1542 /* we have an array, with the number of elements stored before the first object */
1543 INT_PTR i, *ptr = (INT_PTR *)this-1;
1545 for (i = *ptr-1; i >= 0; i--)
1546 stdiobuf_dtor(this+i);
1547 MSVCRT_operator_delete(ptr);
1548 } else {
1549 stdiobuf_dtor(this);
1550 if (flags & 1)
1551 MSVCRT_operator_delete(this);
1553 return this;
1556 /* ??_Gstdiobuf@@UAEPAXI@Z */
1557 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1558 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1560 TRACE("(%p %x)\n", this, flags);
1561 stdiobuf_dtor(this);
1562 if (flags & 1) MSVCRT_operator_delete(this);
1563 return this;
1566 /* ?overflow@stdiobuf@@UAEHH@Z */
1567 /* ?overflow@stdiobuf@@UEAAHH@Z */
1568 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1569 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1571 TRACE("(%p %d)\n", this, c);
1572 if (this->base.unbuffered)
1573 return (c == EOF) ? 1 : fputc(c, this->file);
1574 if (streambuf_allocate(&this->base) == EOF)
1575 return EOF;
1577 if (!this->base.epptr) {
1578 /* set the put area to the second half of the buffer */
1579 streambuf_setp(&this->base,
1580 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1581 } else if (this->base.pptr > this->base.pbase) {
1582 /* flush the put area */
1583 int count = this->base.pptr - this->base.pbase;
1584 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1585 return EOF;
1586 this->base.pptr = this->base.pbase;
1588 if (c != EOF) {
1589 if (this->base.pbase >= this->base.epptr)
1590 return fputc(c, this->file);
1591 *this->base.pptr++ = c;
1593 return 1;
1596 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1597 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1598 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1599 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1601 TRACE("(%p %d)\n", this, c);
1602 return streambuf_pbackfail(&this->base, c);
1605 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1606 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1607 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1608 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1610 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1611 call_streambuf_overflow(&this->base, EOF);
1612 if (fseek(this->file, offset, dir))
1613 return EOF;
1614 return ftell(this->file);
1617 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1618 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1619 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1620 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1622 char *reserve;
1623 int buffer_size = read_size + write_size;
1625 TRACE("(%p %d %d)\n", this, read_size, write_size);
1626 if (read_size < 0 || write_size < 0)
1627 return 0;
1628 if (!buffer_size) {
1629 this->base.unbuffered = 1;
1630 return 0;
1632 /* get a new buffer */
1633 reserve = MSVCRT_operator_new(buffer_size);
1634 if (!reserve)
1635 return 0;
1636 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1637 this->base.unbuffered = 0;
1638 /* set the get/put areas */
1639 if (read_size > 0)
1640 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1641 else
1642 streambuf_setg(&this->base, NULL, NULL, NULL);
1643 if (write_size > 0)
1644 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1645 else
1646 streambuf_setp(&this->base, NULL, NULL);
1647 return 1;
1650 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1651 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1652 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1653 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1655 TRACE("(%p)\n", this);
1656 return this->file;
1659 /* ?sync@stdiobuf@@UAEHXZ */
1660 /* ?sync@stdiobuf@@UEAAHXZ */
1661 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1662 int __thiscall stdiobuf_sync(stdiobuf *this)
1664 TRACE("(%p)\n", this);
1665 if (this->base.unbuffered)
1666 return 0;
1667 /* flush the put area */
1668 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1669 return EOF;
1670 /* flush the get area */
1671 if (this->base.gptr < this->base.egptr) {
1672 char *ptr;
1673 int fd, mode, offset = this->base.egptr - this->base.gptr;
1674 if ((fd = fileno(this->file)) < 0)
1675 return EOF;
1676 mode = _setmode(fd, _O_TEXT);
1677 _setmode(fd, mode);
1678 if (mode & _O_TEXT) {
1679 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1680 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1681 if (*ptr == '\n')
1682 offset++;
1684 if (fseek(this->file, -offset, SEEK_CUR))
1685 return EOF;
1686 this->base.gptr = this->base.egptr;
1688 return 0;
1691 /* ?underflow@stdiobuf@@UAEHXZ */
1692 /* ?underflow@stdiobuf@@UEAAHXZ */
1693 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1694 int __thiscall stdiobuf_underflow(stdiobuf *this)
1696 TRACE("(%p)\n", this);
1697 if (!this->file)
1698 return EOF;
1699 if (this->base.unbuffered)
1700 return fgetc(this->file);
1701 if (streambuf_allocate(&this->base) == EOF)
1702 return EOF;
1704 if (!this->base.egptr) {
1705 /* set the get area to the first half of the buffer */
1706 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1707 streambuf_setg(&this->base, this->base.base, middle, middle);
1709 if (this->base.gptr >= this->base.egptr) {
1710 /* read characters from the file */
1711 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1712 if (!this->base.eback ||
1713 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1714 return EOF;
1715 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1716 this->base.gptr = this->base.egptr - read_bytes;
1718 return (unsigned char) *this->base.gptr++;
1721 /* ??0ios@@IAE@ABV0@@Z */
1722 /* ??0ios@@IEAA@AEBV0@@Z */
1723 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1724 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1726 TRACE("(%p %p)\n", this, copy);
1727 ios_fLockcInit++;
1728 this->vtable = &MSVCP_ios_vtable;
1729 this->sb = NULL;
1730 this->delbuf = 0;
1731 InitializeCriticalSection(&this->lock);
1732 return ios_assign(this, copy);
1735 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1736 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1737 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1738 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1740 TRACE("(%p %p)\n", this, sb);
1741 ios_fLockcInit++;
1742 this->vtable = &MSVCP_ios_vtable;
1743 this->sb = sb;
1744 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1745 this->special[0] = this->special[1] = 0;
1746 this->delbuf = 0;
1747 this->tie = NULL;
1748 this->flags = 0;
1749 this->precision = 6;
1750 this->fill = ' ';
1751 this->width = 0;
1752 this->do_lock = -1;
1753 InitializeCriticalSection(&this->lock);
1754 return this;
1757 /* ??0ios@@IAE@XZ */
1758 /* ??0ios@@IEAA@XZ */
1759 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1760 ios* __thiscall ios_ctor(ios *this)
1762 return ios_sb_ctor(this, NULL);
1765 /* ??1ios@@UAE@XZ */
1766 /* ??1ios@@UEAA@XZ */
1767 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1768 void __thiscall ios_dtor(ios *this)
1770 TRACE("(%p)\n", this);
1771 ios_fLockcInit--;
1772 if (this->delbuf && this->sb)
1773 call_streambuf_vector_dtor(this->sb, 1);
1774 this->sb = NULL;
1775 this->state = IOSTATE_badbit;
1776 DeleteCriticalSection(&this->lock);
1779 /* ??4ios@@IAEAAV0@ABV0@@Z */
1780 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1781 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1782 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1784 TRACE("(%p %p)\n", this, rhs);
1785 this->state = rhs->state;
1786 if (!this->sb)
1787 this->state |= IOSTATE_badbit;
1788 this->tie = rhs->tie;
1789 this->flags = rhs->flags;
1790 this->precision = (char) rhs->precision;
1791 this->fill = rhs->fill;
1792 this->width = (char) rhs->width;
1793 return this;
1796 /* ??7ios@@QBEHXZ */
1797 /* ??7ios@@QEBAHXZ */
1798 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1799 int __thiscall ios_op_not(const ios *this)
1801 TRACE("(%p)\n", this);
1802 return ios_fail(this);
1805 /* ??Bios@@QBEPAXXZ */
1806 /* ??Bios@@QEBAPEAXXZ */
1807 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1808 void* __thiscall ios_op_void(const ios *this)
1810 TRACE("(%p)\n", this);
1811 return ios_fail(this) ? NULL : (void*)this;
1814 /* ??_Eios@@UAEPAXI@Z */
1815 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1816 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1818 TRACE("(%p %x)\n", this, flags);
1819 if (flags & 2) {
1820 /* we have an array, with the number of elements stored before the first object */
1821 INT_PTR i, *ptr = (INT_PTR *)this-1;
1823 for (i = *ptr-1; i >= 0; i--)
1824 ios_dtor(this+i);
1825 MSVCRT_operator_delete(ptr);
1826 } else {
1827 ios_dtor(this);
1828 if (flags & 1)
1829 MSVCRT_operator_delete(this);
1831 return this;
1834 /* ??_Gios@@UAEPAXI@Z */
1835 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1836 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1838 TRACE("(%p %x)\n", this, flags);
1839 ios_dtor(this);
1840 if (flags & 1) MSVCRT_operator_delete(this);
1841 return this;
1844 /* ?bad@ios@@QBEHXZ */
1845 /* ?bad@ios@@QEBAHXZ */
1846 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1847 int __thiscall ios_bad(const ios *this)
1849 TRACE("(%p)\n", this);
1850 return (this->state & IOSTATE_badbit);
1853 /* ?bitalloc@ios@@SAJXZ */
1854 LONG __cdecl ios_bitalloc(void)
1856 TRACE("()\n");
1857 ios_lockc();
1858 ios_maxbit <<= 1;
1859 ios_unlockc();
1860 return ios_maxbit;
1863 /* ?clear@ios@@QAEXH@Z */
1864 /* ?clear@ios@@QEAAXH@Z */
1865 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1866 void __thiscall ios_clear(ios *this, int state)
1868 TRACE("(%p %d)\n", this, state);
1869 ios_lock(this);
1870 this->state = state;
1871 ios_unlock(this);
1874 /* ?clrlock@ios@@QAAXXZ */
1875 /* ?clrlock@ios@@QEAAXXZ */
1876 void __cdecl ios_clrlock(ios *this)
1878 TRACE("(%p)\n", this);
1879 if (this->do_lock <= 0)
1880 this->do_lock++;
1881 if (this->sb)
1882 streambuf_clrlock(this->sb);
1885 /* ?delbuf@ios@@QAEXH@Z */
1886 /* ?delbuf@ios@@QEAAXH@Z */
1887 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1888 void __thiscall ios_delbuf_set(ios *this, int delete)
1890 TRACE("(%p %d)\n", this, delete);
1891 this->delbuf = delete;
1894 /* ?delbuf@ios@@QBEHXZ */
1895 /* ?delbuf@ios@@QEBAHXZ */
1896 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1897 int __thiscall ios_delbuf_get(const ios *this)
1899 TRACE("(%p)\n", this);
1900 return this->delbuf;
1903 /* ?dec@@YAAAVios@@AAV1@@Z */
1904 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1905 ios* __cdecl ios_dec(ios *this)
1907 TRACE("(%p)\n", this);
1908 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1909 return this;
1912 /* ?eof@ios@@QBEHXZ */
1913 /* ?eof@ios@@QEBAHXZ */
1914 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1915 int __thiscall ios_eof(const ios *this)
1917 TRACE("(%p)\n", this);
1918 return (this->state & IOSTATE_eofbit);
1921 /* ?fail@ios@@QBEHXZ */
1922 /* ?fail@ios@@QEBAHXZ */
1923 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1924 int __thiscall ios_fail(const ios *this)
1926 TRACE("(%p)\n", this);
1927 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1930 /* ?fill@ios@@QAEDD@Z */
1931 /* ?fill@ios@@QEAADD@Z */
1932 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1933 char __thiscall ios_fill_set(ios *this, char fill)
1935 char prev = this->fill;
1937 TRACE("(%p %d)\n", this, fill);
1939 this->fill = fill;
1940 return prev;
1943 /* ?fill@ios@@QBEDXZ */
1944 /* ?fill@ios@@QEBADXZ */
1945 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1946 char __thiscall ios_fill_get(const ios *this)
1948 TRACE("(%p)\n", this);
1949 return this->fill;
1952 /* ?flags@ios@@QAEJJ@Z */
1953 /* ?flags@ios@@QEAAJJ@Z */
1954 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
1955 LONG __thiscall ios_flags_set(ios *this, LONG flags)
1957 LONG prev = this->flags;
1959 TRACE("(%p %x)\n", this, flags);
1961 this->flags = flags;
1962 return prev;
1965 /* ?flags@ios@@QBEJXZ */
1966 /* ?flags@ios@@QEBAJXZ */
1967 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
1968 LONG __thiscall ios_flags_get(const ios *this)
1970 TRACE("(%p)\n", this);
1971 return this->flags;
1974 /* ?good@ios@@QBEHXZ */
1975 /* ?good@ios@@QEBAHXZ */
1976 DEFINE_THISCALL_WRAPPER(ios_good, 4)
1977 int __thiscall ios_good(const ios *this)
1979 TRACE("(%p)\n", this);
1980 return this->state == IOSTATE_goodbit;
1983 /* ?hex@@YAAAVios@@AAV1@@Z */
1984 /* ?hex@@YAAEAVios@@AEAV1@@Z */
1985 ios* __cdecl ios_hex(ios *this)
1987 TRACE("(%p)\n", this);
1988 ios_setf_mask(this, FLAGS_hex, ios_basefield);
1989 return this;
1992 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
1993 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
1994 DEFINE_THISCALL_WRAPPER(ios_init, 8)
1995 void __thiscall ios_init(ios *this, streambuf *sb)
1997 TRACE("(%p %p)\n", this, sb);
1998 if (this->delbuf && this->sb)
1999 call_streambuf_vector_dtor(this->sb, 1);
2000 this->sb = sb;
2001 if (sb == NULL)
2002 this->state |= IOSTATE_badbit;
2003 else
2004 this->state &= ~IOSTATE_badbit;
2007 /* ?iword@ios@@QBEAAJH@Z */
2008 /* ?iword@ios@@QEBAAEAJH@Z */
2009 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
2010 LONG* __thiscall ios_iword(const ios *this, int index)
2012 TRACE("(%p %d)\n", this, index);
2013 return &ios_statebuf[index];
2016 /* ?lock@ios@@QAAXXZ */
2017 /* ?lock@ios@@QEAAXXZ */
2018 void __cdecl ios_lock(ios *this)
2020 TRACE("(%p)\n", this);
2021 if (this->do_lock < 0)
2022 EnterCriticalSection(&this->lock);
2025 /* ?lockbuf@ios@@QAAXXZ */
2026 /* ?lockbuf@ios@@QEAAXXZ */
2027 void __cdecl ios_lockbuf(ios *this)
2029 TRACE("(%p)\n", this);
2030 streambuf_lock(this->sb);
2033 /* ?lockc@ios@@KAXXZ */
2034 void __cdecl ios_lockc(void)
2036 TRACE("()\n");
2037 EnterCriticalSection(&ios_static_lock);
2040 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2041 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2042 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2043 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2045 TRACE("(%p)\n", this);
2046 return &this->lock;
2049 /* ?oct@@YAAAVios@@AAV1@@Z */
2050 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2051 ios* __cdecl ios_oct(ios *this)
2053 TRACE("(%p)\n", this);
2054 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2055 return this;
2058 /* ?precision@ios@@QAEHH@Z */
2059 /* ?precision@ios@@QEAAHH@Z */
2060 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2061 int __thiscall ios_precision_set(ios *this, int prec)
2063 int prev = this->precision;
2065 TRACE("(%p %d)\n", this, prec);
2067 this->precision = prec;
2068 return prev;
2071 /* ?precision@ios@@QBEHXZ */
2072 /* ?precision@ios@@QEBAHXZ */
2073 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2074 int __thiscall ios_precision_get(const ios *this)
2076 TRACE("(%p)\n", this);
2077 return this->precision;
2080 /* ?pword@ios@@QBEAAPAXH@Z */
2081 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2082 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2083 void** __thiscall ios_pword(const ios *this, int index)
2085 TRACE("(%p %d)\n", this, index);
2086 return (void**)&ios_statebuf[index];
2089 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2090 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2091 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2092 streambuf* __thiscall ios_rdbuf(const ios *this)
2094 TRACE("(%p)\n", this);
2095 return this->sb;
2098 /* ?rdstate@ios@@QBEHXZ */
2099 /* ?rdstate@ios@@QEBAHXZ */
2100 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2101 int __thiscall ios_rdstate(const ios *this)
2103 TRACE("(%p)\n", this);
2104 return this->state;
2107 /* ?setf@ios@@QAEJJ@Z */
2108 /* ?setf@ios@@QEAAJJ@Z */
2109 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2110 LONG __thiscall ios_setf(ios *this, LONG flags)
2112 LONG prev = this->flags;
2114 TRACE("(%p %x)\n", this, flags);
2116 ios_lock(this);
2117 this->flags |= flags;
2118 ios_unlock(this);
2119 return prev;
2122 /* ?setf@ios@@QAEJJJ@Z */
2123 /* ?setf@ios@@QEAAJJJ@Z */
2124 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2125 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2127 LONG prev = this->flags;
2129 TRACE("(%p %x %x)\n", this, flags, mask);
2131 ios_lock(this);
2132 this->flags = (this->flags & (~mask)) | (flags & mask);
2133 ios_unlock(this);
2134 return prev;
2137 /* ?setlock@ios@@QAAXXZ */
2138 /* ?setlock@ios@@QEAAXXZ */
2139 void __cdecl ios_setlock(ios *this)
2141 TRACE("(%p)\n", this);
2142 this->do_lock--;
2143 if (this->sb)
2144 streambuf_setlock(this->sb);
2147 /* ?sync_with_stdio@ios@@SAXXZ */
2148 void __cdecl ios_sync_with_stdio(void)
2150 FIXME("() stub\n");
2153 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2154 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2155 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2156 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2158 ostream *prev = this->tie;
2160 TRACE("(%p %p)\n", this, ostr);
2162 this->tie = ostr;
2163 return prev;
2166 /* ?tie@ios@@QBEPAVostream@@XZ */
2167 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2168 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2169 ostream* __thiscall ios_tie_get(const ios *this)
2171 TRACE("(%p)\n", this);
2172 return this->tie;
2175 /* ?unlock@ios@@QAAXXZ */
2176 /* ?unlock@ios@@QEAAXXZ */
2177 void __cdecl ios_unlock(ios *this)
2179 TRACE("(%p)\n", this);
2180 if (this->do_lock < 0)
2181 LeaveCriticalSection(&this->lock);
2184 /* ?unlockbuf@ios@@QAAXXZ */
2185 /* ?unlockbuf@ios@@QEAAXXZ */
2186 void __cdecl ios_unlockbuf(ios *this)
2188 TRACE("(%p)\n", this);
2189 streambuf_unlock(this->sb);
2192 /* ?unlockc@ios@@KAXXZ */
2193 void __cdecl ios_unlockc(void)
2195 TRACE("()\n");
2196 LeaveCriticalSection(&ios_static_lock);
2199 /* ?unsetf@ios@@QAEJJ@Z */
2200 /* ?unsetf@ios@@QEAAJJ@Z */
2201 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2202 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2204 LONG prev = this->flags;
2206 TRACE("(%p %x)\n", this, flags);
2208 ios_lock(this);
2209 this->flags &= ~flags;
2210 ios_unlock(this);
2211 return prev;
2214 /* ?width@ios@@QAEHH@Z */
2215 /* ?width@ios@@QEAAHH@Z */
2216 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2217 int __thiscall ios_width_set(ios *this, int width)
2219 int prev = this->width;
2221 TRACE("(%p %d)\n", this, width);
2223 this->width = width;
2224 return prev;
2227 /* ?width@ios@@QBEHXZ */
2228 /* ?width@ios@@QEBAHXZ */
2229 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2230 int __thiscall ios_width_get(const ios *this)
2232 TRACE("(%p)\n", this);
2233 return this->width;
2236 /* ?xalloc@ios@@SAHXZ */
2237 int __cdecl ios_xalloc(void)
2239 int ret;
2241 TRACE("()\n");
2243 ios_lockc();
2244 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2245 ios_unlockc();
2246 return ret;
2249 static inline ios* ostream_get_ios(const ostream *this)
2251 return (ios*)((char*)this + this->vbtable[1]);
2254 static inline ios* ostream_to_ios(const ostream *this)
2256 return (ios*)((char*)this + ostream_vbtable[1]);
2259 static inline ostream* ios_to_ostream(const ios *base)
2261 return (ostream*)((char*)base - ostream_vbtable[1]);
2264 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2265 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2266 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2267 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2269 ios *base;
2271 TRACE("(%p %p %d)\n", this, sb, virt_init);
2273 if (virt_init) {
2274 this->vbtable = ostream_vbtable;
2275 base = ostream_get_ios(this);
2276 ios_sb_ctor(base, sb);
2277 } else {
2278 base = ostream_get_ios(this);
2279 ios_init(base, sb);
2281 base->vtable = &MSVCP_ostream_vtable;
2282 this->unknown = 0;
2283 return this;
2286 /* ??0ostream@@IAE@ABV0@@Z */
2287 /* ??0ostream@@IEAA@AEBV0@@Z */
2288 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2289 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2291 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2294 /* ??0ostream@@IAE@XZ */
2295 /* ??0ostream@@IEAA@XZ */
2296 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2297 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2299 ios *base;
2301 TRACE("(%p %d)\n", this, virt_init);
2303 if (virt_init) {
2304 this->vbtable = ostream_vbtable;
2305 base = ostream_get_ios(this);
2306 ios_ctor(base);
2307 } else
2308 base = ostream_get_ios(this);
2309 base->vtable = &MSVCP_ostream_vtable;
2310 this->unknown = 0;
2311 return this;
2314 /* ??1ostream@@UAE@XZ */
2315 /* ??1ostream@@UEAA@XZ */
2316 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2317 void __thiscall ostream_dtor(ios *base)
2319 ostream *this = ios_to_ostream(base);
2321 TRACE("(%p)\n", this);
2324 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2325 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2326 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2327 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2329 ios *base = ostream_get_ios(this);
2331 TRACE("(%p %p)\n", this, sb);
2333 ios_init(base, sb);
2334 base->state &= IOSTATE_badbit;
2335 base->delbuf = 0;
2336 base->tie = NULL;
2337 base->flags = 0;
2338 base->precision = 6;
2339 base->fill = ' ';
2340 base->width = 0;
2341 return this;
2344 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2345 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2346 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2347 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2349 ios *base_rhs = ostream_get_ios(rhs);
2351 TRACE("(%p %p)\n", this, rhs);
2353 return ostream_assign_sb(this, base_rhs->sb);
2356 /* ??_Dostream@@QAEXXZ */
2357 /* ??_Dostream@@QEAAXXZ */
2358 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2359 void __thiscall ostream_vbase_dtor(ostream *this)
2361 ios *base = ostream_to_ios(this);
2363 TRACE("(%p)\n", this);
2365 ostream_dtor(base);
2366 ios_dtor(base);
2369 /* ??_Eostream@@UAEPAXI@Z */
2370 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2371 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2373 ostream *this = ios_to_ostream(base);
2375 TRACE("(%p %x)\n", this, flags);
2377 if (flags & 2) {
2378 /* we have an array, with the number of elements stored before the first object */
2379 INT_PTR i, *ptr = (INT_PTR *)this-1;
2381 for (i = *ptr-1; i >= 0; i--)
2382 ostream_vbase_dtor(this+i);
2383 MSVCRT_operator_delete(ptr);
2384 } else {
2385 ostream_vbase_dtor(this);
2386 if (flags & 1)
2387 MSVCRT_operator_delete(this);
2389 return this;
2392 /* ??_Gostream@@UAEPAXI@Z */
2393 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2394 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2396 ostream *this = ios_to_ostream(base);
2398 TRACE("(%p %x)\n", this, flags);
2400 ostream_vbase_dtor(this);
2401 if (flags & 1) MSVCRT_operator_delete(this);
2402 return this;
2405 /* ?flush@ostream@@QAEAAV1@XZ */
2406 /* ?flush@ostream@@QEAAAEAV1@XZ */
2407 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2408 ostream* __thiscall ostream_flush(ostream *this)
2410 ios *base = ostream_get_ios(this);
2412 TRACE("(%p)\n", this);
2414 ios_lockbuf(base);
2415 if (call_streambuf_sync(base->sb) == EOF)
2416 ios_clear(base, base->state | IOSTATE_failbit);
2417 ios_unlockbuf(base);
2418 return this;
2421 /* ?opfx@ostream@@QAEHXZ */
2422 /* ?opfx@ostream@@QEAAHXZ */
2423 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2424 int __thiscall ostream_opfx(ostream *this)
2426 ios *base = ostream_get_ios(this);
2428 TRACE("(%p)\n", this);
2430 if (!ios_good(base)) {
2431 ios_clear(base, base->state | IOSTATE_failbit);
2432 return 0;
2434 ios_lock(base);
2435 ios_lockbuf(base);
2436 if (base->tie)
2437 ostream_flush(base->tie);
2438 return 1;
2441 /* ?osfx@ostream@@QAEXXZ */
2442 /* ?osfx@ostream@@QEAAXXZ */
2443 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2444 void __thiscall ostream_osfx(ostream *this)
2446 ios *base = ostream_get_ios(this);
2448 TRACE("(%p)\n", this);
2450 ios_unlockbuf(base);
2451 ios_width_set(base, 0);
2452 if (base->flags & FLAGS_unitbuf)
2453 ostream_flush(this);
2454 if (base->flags & FLAGS_stdio) {
2455 fflush(stdout);
2456 fflush(stderr);
2458 ios_unlock(base);
2461 /* ?put@ostream@@QAEAAV1@C@Z */
2462 /* ?put@ostream@@QEAAAEAV1@C@Z */
2463 /* ?put@ostream@@QAEAAV1@D@Z */
2464 /* ?put@ostream@@QEAAAEAV1@D@Z */
2465 /* ?put@ostream@@QAEAAV1@E@Z */
2466 /* ?put@ostream@@QEAAAEAV1@E@Z */
2467 DEFINE_THISCALL_WRAPPER(ostream_put, 8)
2468 ostream* __thiscall ostream_put(ostream *this, char c)
2470 ios *base = ostream_get_ios(this);
2472 TRACE("(%p %c)\n", this, c);
2474 if (ostream_opfx(this)) {
2475 if (streambuf_sputc(base->sb, c) == EOF)
2476 base->state = IOSTATE_badbit | IOSTATE_failbit;
2477 ostream_osfx(this);
2479 return this;
2482 /* ?seekp@ostream@@QAEAAV1@J@Z */
2483 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2484 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2485 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2487 ios *base = ostream_get_ios(this);
2489 TRACE("(%p %d)\n", this, pos);
2491 ios_lockbuf(base);
2492 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2493 ios_clear(base, base->state | IOSTATE_failbit);
2494 ios_unlockbuf(base);
2495 return this;
2498 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2499 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2500 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2501 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2503 ios *base = ostream_get_ios(this);
2505 TRACE("(%p %d %d)\n", this, off, dir);
2507 ios_lockbuf(base);
2508 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2509 ios_clear(base, base->state | IOSTATE_failbit);
2510 ios_unlockbuf(base);
2511 return this;
2514 /* ?tellp@ostream@@QAEJXZ */
2515 /* ?tellp@ostream@@QEAAJXZ */
2516 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2517 streampos __thiscall ostream_tellp(ostream *this)
2519 ios *base = ostream_get_ios(this);
2520 streampos pos;
2522 TRACE("(%p)\n", this);
2524 ios_lockbuf(base);
2525 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2526 ios_clear(base, base->state | IOSTATE_failbit);
2527 ios_unlockbuf(base);
2528 return pos;
2531 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2532 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2533 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2534 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2535 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2536 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2537 DEFINE_THISCALL_WRAPPER(ostream_write, 12)
2538 ostream* __thiscall ostream_write(ostream *this, const char *str, int count)
2540 ios *base = ostream_get_ios(this);
2542 TRACE("(%p %p %d)\n", this, str, count);
2544 if (ostream_opfx(this)) {
2545 if (streambuf_sputn(base->sb, str, count) != count)
2546 base->state = IOSTATE_badbit | IOSTATE_failbit;
2547 ostream_osfx(this);
2549 return this;
2552 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2553 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2554 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2555 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2557 ios *base = ostream_get_ios(this);
2558 int len1 = strlen(str1), len2 = strlen(str2), i;
2560 TRACE("(%p %p %p)\n", this, str1, str2);
2562 /* left of the padding */
2563 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2564 if (streambuf_sputn(base->sb, str1, len1) != len1)
2565 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2566 if (!(base->flags & FLAGS_internal))
2567 if (streambuf_sputn(base->sb, str2, len2) != len2)
2568 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2570 /* add padding to fill the width */
2571 for (i = len1 + len2; i < base->width; i++)
2572 if (streambuf_sputc(base->sb, base->fill) == EOF)
2573 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2574 /* right of the padding */
2575 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2576 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2577 if (streambuf_sputn(base->sb, str1, len1) != len1)
2578 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2579 if (streambuf_sputn(base->sb, str2, len2) != len2)
2580 base->state |= IOSTATE_failbit | IOSTATE_badbit;
2582 return this;
2585 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2587 ios *base = ostream_get_ios(ostr);
2588 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2590 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2592 if (ostream_opfx(ostr)) {
2593 if (base->flags & FLAGS_hex) {
2594 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2595 if (base->flags & FLAGS_showbase) {
2596 prefix_str[0] = '0';
2597 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2599 } else if (base->flags & FLAGS_oct) {
2600 sprintf_fmt[1] = 'o';
2601 if (base->flags & FLAGS_showbase)
2602 prefix_str[0] = '0';
2603 } else { /* FLAGS_dec */
2604 if (unsig)
2605 sprintf_fmt[1] = 'u';
2606 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2607 prefix_str[0] = '+';
2610 if (shrt) {
2611 sprintf_fmt[2] = sprintf_fmt[1];
2612 sprintf_fmt[1] = 'h';
2615 if (sprintf(number_str, sprintf_fmt, n) > 0)
2616 ostream_writepad(ostr, prefix_str, number_str);
2617 else
2618 base->state |= IOSTATE_failbit;
2619 ostream_osfx(ostr);
2621 return ostr;
2624 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2626 ios *base = ostream_get_ios(ostr);
2627 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2628 int prec, max_prec = dbl ? 15 : 6;
2629 int str_length = 1; /* null end char */
2631 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2633 if (ostream_opfx(ostr)) {
2634 if ((base->flags & FLAGS_showpos) && d > 0) {
2635 prefix_str[0] = '+';
2636 str_length++; /* plus sign */
2638 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2639 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2640 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2641 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2642 if (base->flags & FLAGS_showpoint) {
2643 sprintf_fmt[4] = sprintf_fmt[3];
2644 sprintf_fmt[3] = sprintf_fmt[2];
2645 sprintf_fmt[2] = sprintf_fmt[1];
2646 sprintf_fmt[1] = '#';
2649 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2650 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2651 if (str_length > 24) {
2652 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2653 ostream_writepad(ostr, "", "");
2654 } else {
2655 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2656 ostream_writepad(ostr, prefix_str, number_str);
2657 else
2658 base->state |= IOSTATE_failbit;
2660 ostream_osfx(ostr);
2662 return ostr;
2665 /* ??6ostream@@QAEAAV0@C@Z */
2666 /* ??6ostream@@QEAAAEAV0@C@Z */
2667 /* ??6ostream@@QAEAAV0@D@Z */
2668 /* ??6ostream@@QEAAAEAV0@D@Z */
2669 /* ??6ostream@@QAEAAV0@E@Z */
2670 /* ??6ostream@@QEAAAEAV0@E@Z */
2671 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2672 ostream* __thiscall ostream_print_char(ostream *this, char c)
2674 const char c_str[2] = {c, 0};
2676 TRACE("(%p %c)\n", this, c);
2678 if (ostream_opfx(this)) {
2679 ostream_writepad(this, "", c_str);
2680 ostream_osfx(this);
2682 return this;
2685 /* ??6ostream@@QAEAAV0@PBC@Z */
2686 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2687 /* ??6ostream@@QAEAAV0@PBD@Z */
2688 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2689 /* ??6ostream@@QAEAAV0@PBE@Z */
2690 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2691 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2692 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2694 TRACE("(%p %s)\n", this, str);
2695 if (ostream_opfx(this)) {
2696 ostream_writepad(this, "", str);
2697 ostream_osfx(this);
2699 return this;
2702 /* ??6ostream@@QAEAAV0@F@Z */
2703 /* ??6ostream@@QEAAAEAV0@F@Z */
2704 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2705 ostream* __thiscall ostream_print_short(ostream *this, short n)
2707 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2710 /* ??6ostream@@QAEAAV0@G@Z */
2711 /* ??6ostream@@QEAAAEAV0@G@Z */
2712 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2713 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2715 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2718 /* ??6ostream@@QAEAAV0@H@Z */
2719 /* ??6ostream@@QEAAAEAV0@H@Z */
2720 /* ??6ostream@@QAEAAV0@J@Z */
2721 /* ??6ostream@@QEAAAEAV0@J@Z */
2722 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2723 ostream* __thiscall ostream_print_int(ostream *this, int n)
2725 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2728 /* ??6ostream@@QAEAAV0@I@Z */
2729 /* ??6ostream@@QEAAAEAV0@I@Z */
2730 /* ??6ostream@@QAEAAV0@K@Z */
2731 /* ??6ostream@@QEAAAEAV0@K@Z */
2732 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2733 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2735 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2738 /* ??6ostream@@QAEAAV0@M@Z */
2739 /* ??6ostream@@QEAAAEAV0@M@Z */
2740 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2741 ostream* __thiscall ostream_print_float(ostream *this, float f)
2743 return ostream_internal_print_float(this, f, FALSE);
2746 /* ??6ostream@@QAEAAV0@N@Z */
2747 /* ??6ostream@@QEAAAEAV0@N@Z */
2748 /* ??6ostream@@QAEAAV0@O@Z */
2749 /* ??6ostream@@QEAAAEAV0@O@Z */
2750 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2751 ostream* __thiscall ostream_print_double(ostream *this, double d)
2753 return ostream_internal_print_float(this, d, TRUE);
2756 /* ??6ostream@@QAEAAV0@PBX@Z */
2757 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2758 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2759 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2761 ios *base = ostream_get_ios(this);
2762 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2764 TRACE("(%p %p)\n", this, ptr);
2766 if (ostream_opfx(this)) {
2767 if (ptr && base->flags & FLAGS_uppercase)
2768 prefix_str[1] = 'X';
2770 if (sprintf(pointer_str, "%p", ptr) > 0)
2771 ostream_writepad(this, prefix_str, pointer_str);
2772 else
2773 base->state |= IOSTATE_failbit;
2774 ostream_osfx(this);
2776 return this;
2779 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2780 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2781 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2782 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2784 ios *base = ostream_get_ios(this);
2785 int c;
2787 TRACE("(%p %p)\n", this, sb);
2789 if (ostream_opfx(this)) {
2790 while ((c = streambuf_sbumpc(sb)) != EOF) {
2791 if (streambuf_sputc(base->sb, c) == EOF) {
2792 base->state |= IOSTATE_failbit;
2793 break;
2796 ostream_osfx(this);
2798 return this;
2801 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2802 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2803 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2804 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2806 TRACE("(%p %p)\n", this, func);
2807 return func(this);
2810 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2811 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2812 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2813 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2815 TRACE("(%p %p)\n", this, func);
2816 func(ostream_get_ios(this));
2817 return this;
2820 /* ?endl@@YAAAVostream@@AAV1@@Z */
2821 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2822 ostream* __cdecl ostream_endl(ostream *this)
2824 TRACE("(%p)\n", this);
2825 ostream_put(this, '\n');
2826 return ostream_flush(this);
2829 /* ?ends@@YAAAVostream@@AAV1@@Z */
2830 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2831 ostream* __cdecl ostream_ends(ostream *this)
2833 TRACE("(%p)\n", this);
2834 return ostream_put(this, 0);
2837 /* ?flush@@YAAAVostream@@AAV1@@Z */
2838 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2839 ostream* __cdecl ostream_flush_manip(ostream *this)
2841 TRACE("(%p)\n", this);
2842 return ostream_flush(this);
2845 static inline ios* istream_get_ios(const istream *this)
2847 return (ios*)((char*)this + this->vbtable[1]);
2850 static inline ios* istream_to_ios(const istream *this)
2852 return (ios*)((char*)this + istream_vbtable[1]);
2855 static inline istream* ios_to_istream(const ios *base)
2857 return (istream*)((char*)base - istream_vbtable[1]);
2860 /* ??0istream@@QAE@PAVstreambuf@@@Z */
2861 /* ??0istream@@QEAA@PEAVstreambuf@@@Z */
2862 DEFINE_THISCALL_WRAPPER(istream_sb_ctor, 12)
2863 istream* __thiscall istream_sb_ctor(istream *this, streambuf *sb, BOOL virt_init)
2865 ios *base;
2867 TRACE("(%p %p %d)\n", this, sb, virt_init);
2869 if (virt_init) {
2870 this->vbtable = istream_vbtable;
2871 base = istream_get_ios(this);
2872 ios_sb_ctor(base, sb);
2873 } else {
2874 base = istream_get_ios(this);
2875 ios_init(base, sb);
2877 base->vtable = &MSVCP_istream_vtable;
2878 base->flags |= FLAGS_skipws;
2879 this->extract_delim = 0;
2880 this->count = 0;
2881 return this;
2884 /* ??0istream@@IAE@ABV0@@Z */
2885 /* ??0istream@@IEAA@AEBV0@@Z */
2886 DEFINE_THISCALL_WRAPPER(istream_copy_ctor, 12)
2887 istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
2889 return istream_sb_ctor(this, istream_get_ios(copy)->sb, virt_init);
2892 /* ??0istream@@IAE@XZ */
2893 /* ??0istream@@IEAA@XZ */
2894 DEFINE_THISCALL_WRAPPER(istream_ctor, 8)
2895 istream* __thiscall istream_ctor(istream *this, BOOL virt_init)
2897 ios *base;
2899 TRACE("(%p %d)\n", this, virt_init);
2901 if (virt_init) {
2902 this->vbtable = istream_vbtable;
2903 base = istream_get_ios(this);
2904 ios_ctor(base);
2905 } else
2906 base = istream_get_ios(this);
2907 base->vtable = &MSVCP_istream_vtable;
2908 base->flags |= FLAGS_skipws;
2909 this->extract_delim = 0;
2910 this->count = 0;
2911 return this;
2914 /* ??1istream@@UAE@XZ */
2915 /* ??1istream@@UEAA@XZ */
2916 DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
2917 void __thiscall istream_dtor(ios *base)
2919 istream *this = ios_to_istream(base);
2921 TRACE("(%p)\n", this);
2924 /* ??4istream@@IAEAAV0@PAVstreambuf@@@Z */
2925 /* ??4istream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2926 DEFINE_THISCALL_WRAPPER(istream_assign_sb, 8)
2927 istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
2929 ios *base = istream_get_ios(this);
2931 TRACE("(%p %p)\n", this, sb);
2933 ios_init(base, sb);
2934 base->state &= IOSTATE_badbit;
2935 base->delbuf = 0;
2936 base->tie = NULL;
2937 base->flags = FLAGS_skipws;
2938 base->precision = 6;
2939 base->fill = ' ';
2940 base->width = 0;
2941 this->count = 0;
2942 return this;
2945 /* ??4istream@@IAEAAV0@ABV0@@Z */
2946 /* ??4istream@@IEAAAEAV0@AEBV0@@Z */
2947 DEFINE_THISCALL_WRAPPER(istream_assign, 8)
2948 istream* __thiscall istream_assign(istream *this, const istream *rhs)
2950 return istream_assign_sb(this, istream_get_ios(rhs)->sb);
2953 /* ??_Distream@@QAEXXZ */
2954 /* ??_Distream@@QEAAXXZ */
2955 DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
2956 void __thiscall istream_vbase_dtor(istream *this)
2958 ios *base = istream_to_ios(this);
2960 TRACE("(%p)\n", this);
2962 istream_dtor(base);
2963 ios_dtor(base);
2966 /* ??_Eistream@@UAEPAXI@Z */
2967 DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
2968 istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
2970 istream *this = ios_to_istream(base);
2972 TRACE("(%p %x)\n", this, flags);
2974 if (flags & 2) {
2975 /* we have an array, with the number of elements stored before the first object */
2976 INT_PTR i, *ptr = (INT_PTR *)this-1;
2978 for (i = *ptr-1; i >= 0; i--)
2979 istream_vbase_dtor(this+i);
2980 MSVCRT_operator_delete(ptr);
2981 } else {
2982 istream_vbase_dtor(this);
2983 if (flags & 1)
2984 MSVCRT_operator_delete(this);
2986 return this;
2989 /* ??_Gistream@@UAEPAXI@Z */
2990 DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
2991 istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
2993 istream *this = ios_to_istream(base);
2995 TRACE("(%p %x)\n", this, flags);
2997 istream_vbase_dtor(this);
2998 if (flags & 1) MSVCRT_operator_delete(this);
2999 return this;
3002 /* ?eatwhite@istream@@QAEXXZ */
3003 /* ?eatwhite@istream@@QEAAXXZ */
3004 DEFINE_THISCALL_WRAPPER(istream_eatwhite, 4)
3005 void __thiscall istream_eatwhite(istream *this)
3007 ios *base = istream_get_ios(this);
3008 int c;
3010 TRACE("(%p)\n", this);
3012 ios_lockbuf(base);
3013 for (c = streambuf_sgetc(base->sb); isspace(c); c = streambuf_snextc(base->sb));
3014 ios_unlockbuf(base);
3015 if (c == EOF)
3016 ios_clear(base, base->state | IOSTATE_eofbit);
3019 /* ?gcount@istream@@QBEHXZ */
3020 /* ?gcount@istream@@QEBAHXZ */
3021 DEFINE_THISCALL_WRAPPER(istream_gcount, 4)
3022 int __thiscall istream_gcount(const istream *this)
3024 TRACE("(%p)\n", this);
3025 return this->count;
3028 /* ?ipfx@istream@@QAEHH@Z */
3029 /* ?ipfx@istream@@QEAAHH@Z */
3030 DEFINE_THISCALL_WRAPPER(istream_ipfx, 8)
3031 int __thiscall istream_ipfx(istream *this, int need)
3033 ios *base = istream_get_ios(this);
3035 TRACE("(%p %d)\n", this, need);
3037 if (need)
3038 this->count = 0;
3039 if (!ios_good(base)) {
3040 ios_clear(base, base->state | IOSTATE_failbit);
3041 return 0;
3043 ios_lock(base);
3044 ios_lockbuf(base);
3045 if (base->tie && (!need || streambuf_in_avail(base->sb) < need))
3046 ostream_flush(base->tie);
3047 if ((base->flags & FLAGS_skipws) && !need) {
3048 istream_eatwhite(this);
3049 if (base->state & IOSTATE_eofbit) {
3050 base->state |= IOSTATE_failbit;
3051 ios_unlockbuf(base);
3052 ios_unlock(base);
3053 return 0;
3056 return 1;
3059 /* ?isfx@istream@@QAEXXZ */
3060 /* ?isfx@istream@@QEAAXXZ */
3061 DEFINE_THISCALL_WRAPPER(istream_isfx, 4)
3062 void __thiscall istream_isfx(istream *this)
3064 ios *base = istream_get_ios(this);
3066 TRACE("(%p)\n", this);
3068 ios_unlockbuf(base);
3069 ios_unlock(base);
3072 /* ?get@istream@@IAEAAV1@PADHH@Z */
3073 /* ?get@istream@@IEAAAEAV1@PEADHH@Z */
3074 DEFINE_THISCALL_WRAPPER(istream_get_str_delim, 16)
3075 istream* __thiscall istream_get_str_delim(istream *this, char *str, int count, int delim)
3077 ios *base = istream_get_ios(this);
3078 int ch, i = 0;
3080 TRACE("(%p %p %d %d)\n", this, str, count, delim);
3082 if (istream_ipfx(this, 1)) {
3083 while (i < count - 1) {
3084 if ((ch = streambuf_sgetc(base->sb)) == EOF) {
3085 base->state |= IOSTATE_eofbit;
3086 if (!i) /* tried to read, but not a single character was obtained */
3087 base->state |= IOSTATE_failbit;
3088 break;
3090 if (ch == delim) {
3091 if (this->extract_delim) { /* discard the delimiter */
3092 streambuf_stossc(base->sb);
3093 this->count++;
3095 break;
3097 if (str)
3098 str[i] = ch;
3099 streambuf_stossc(base->sb);
3100 i++;
3102 this->count += i;
3103 istream_isfx(this);
3105 if (str && count) /* append a null terminator, unless a string of 0 characters was requested */
3106 str[i] = 0;
3107 this->extract_delim = 0;
3108 return this;
3111 /* ?get@istream@@QAEAAV1@PACHD@Z */
3112 /* ?get@istream@@QEAAAEAV1@PEACHD@Z */
3113 /* ?get@istream@@QAEAAV1@PADHD@Z */
3114 /* ?get@istream@@QEAAAEAV1@PEADHD@Z */
3115 /* ?get@istream@@QAEAAV1@PAEHD@Z */
3116 /* ?get@istream@@QEAAAEAV1@PEAEHD@Z */
3117 DEFINE_THISCALL_WRAPPER(istream_get_str, 16)
3118 istream* __thiscall istream_get_str(istream *this, char *str, int count, char delim)
3120 return istream_get_str_delim(this, str, count, (unsigned char) delim);
3123 static int istream_internal_get_char(istream *this, char *ch)
3125 ios *base = istream_get_ios(this);
3126 int ret = EOF;
3128 TRACE("(%p %p)\n", this, ch);
3130 if (istream_ipfx(this, 1)) {
3131 if ((ret = streambuf_sbumpc(base->sb)) != EOF) {
3132 this->count = 1;
3133 } else {
3134 base->state |= IOSTATE_eofbit;
3135 if (ch)
3136 base->state |= IOSTATE_failbit;
3138 if (ch)
3139 *ch = ret;
3140 istream_isfx(this);
3142 return ret;
3145 /* ?get@istream@@QAEAAV1@AAC@Z */
3146 /* ?get@istream@@QEAAAEAV1@AEAC@Z */
3147 /* ?get@istream@@QAEAAV1@AAD@Z */
3148 /* ?get@istream@@QEAAAEAV1@AEAD@Z */
3149 /* ?get@istream@@QAEAAV1@AAE@Z */
3150 /* ?get@istream@@QEAAAEAV1@AEAE@Z */
3151 DEFINE_THISCALL_WRAPPER(istream_get_char, 8)
3152 istream* __thiscall istream_get_char(istream *this, char *ch)
3154 istream_internal_get_char(this, ch);
3155 return this;
3158 /* ?get@istream@@QAEHXZ */
3159 /* ?get@istream@@QEAAHXZ */
3160 DEFINE_THISCALL_WRAPPER(istream_get, 4)
3161 int __thiscall istream_get(istream *this)
3163 return istream_internal_get_char(this, NULL);
3166 /* ?get@istream@@QAEAAV1@AAVstreambuf@@D@Z */
3167 /* ?get@istream@@QEAAAEAV1@AEAVstreambuf@@D@Z */
3168 DEFINE_THISCALL_WRAPPER(istream_get_sb, 12)
3169 istream* __thiscall istream_get_sb(istream *this, streambuf *sb, char delim)
3171 ios *base = istream_get_ios(this);
3172 int ch;
3174 TRACE("(%p %p %c)\n", this, sb, delim);
3176 if (istream_ipfx(this, 1)) {
3177 for (ch = streambuf_sgetc(base->sb); ch != delim; ch = streambuf_snextc(base->sb)) {
3178 if (ch == EOF) {
3179 base->state |= IOSTATE_eofbit;
3180 break;
3182 if (streambuf_sputc(sb, ch) == EOF)
3183 base->state |= IOSTATE_failbit;
3184 this->count++;
3186 istream_isfx(this);
3188 return this;
3191 /* ?getline@istream@@QAEAAV1@PACHD@Z */
3192 /* ?getline@istream@@QEAAAEAV1@PEACHD@Z */
3193 /* ?getline@istream@@QAEAAV1@PADHD@Z */
3194 /* ?getline@istream@@QEAAAEAV1@PEADHD@Z */
3195 /* ?getline@istream@@QAEAAV1@PAEHD@Z */
3196 /* ?getline@istream@@QEAAAEAV1@PEAEHD@Z */
3197 DEFINE_THISCALL_WRAPPER(istream_getline, 16)
3198 istream* __thiscall istream_getline(istream *this, char *str, int count, char delim)
3200 ios *base = istream_get_ios(this);
3202 TRACE("(%p %p %d %c)\n", this, str, count, delim);
3204 ios_lock(base);
3205 this->extract_delim++;
3206 istream_get_str_delim(this, str, count, (unsigned char) delim);
3207 ios_unlock(base);
3208 return this;
3211 /* ?ignore@istream@@QAEAAV1@HH@Z */
3212 /* ?ignore@istream@@QEAAAEAV1@HH@Z */
3213 DEFINE_THISCALL_WRAPPER(istream_ignore, 12)
3214 istream* __thiscall istream_ignore(istream *this, int count, int delim)
3216 ios *base = istream_get_ios(this);
3218 TRACE("(%p %d %d)\n", this, count, delim);
3220 ios_lock(base);
3221 this->extract_delim++;
3222 istream_get_str_delim(this, NULL, count + 1, delim);
3223 ios_unlock(base);
3224 return this;
3227 /* ?peek@istream@@QAEHXZ */
3228 /* ?peek@istream@@QEAAHXZ */
3229 DEFINE_THISCALL_WRAPPER(istream_peek, 4)
3230 int __thiscall istream_peek(istream *this)
3232 ios *base = istream_get_ios(this);
3233 int ret = EOF;
3235 TRACE("(%p)\n", this);
3237 if (istream_ipfx(this, 1)) {
3238 ret = streambuf_sgetc(base->sb);
3239 istream_isfx(this);
3241 return ret;
3244 /* ?putback@istream@@QAEAAV1@D@Z */
3245 /* ?putback@istream@@QEAAAEAV1@D@Z */
3246 DEFINE_THISCALL_WRAPPER(istream_putback, 8)
3247 istream* __thiscall istream_putback(istream *this, char ch)
3249 ios *base = istream_get_ios(this);
3251 TRACE("(%p %c)\n", this, ch);
3253 if (ios_good(base)) {
3254 ios_lockbuf(base);
3255 if (streambuf_sputbackc(base->sb, ch) == EOF)
3256 ios_clear(base, base->state | IOSTATE_failbit);
3257 ios_unlockbuf(base);
3259 return this;
3262 /* ?read@istream@@QAEAAV1@PACH@Z */
3263 /* ?read@istream@@QEAAAEAV1@PEACH@Z */
3264 /* ?read@istream@@QAEAAV1@PADH@Z */
3265 /* ?read@istream@@QEAAAEAV1@PEADH@Z */
3266 /* ?read@istream@@QAEAAV1@PAEH@Z */
3267 /* ?read@istream@@QEAAAEAV1@PEAEH@Z */
3268 DEFINE_THISCALL_WRAPPER(istream_read, 12)
3269 istream* __thiscall istream_read(istream *this, char *str, int count)
3271 ios *base = istream_get_ios(this);
3273 TRACE("(%p %p %d)\n", this, str, count);
3275 if (istream_ipfx(this, 1)) {
3276 if ((this->count = streambuf_sgetn(base->sb, str, count)) != count)
3277 base->state = IOSTATE_eofbit | IOSTATE_failbit;
3278 istream_isfx(this);
3280 return this;
3283 /* ?seekg@istream@@QAEAAV1@J@Z */
3284 /* ?seekg@istream@@QEAAAEAV1@J@Z */
3285 DEFINE_THISCALL_WRAPPER(istream_seekg, 8)
3286 istream* __thiscall istream_seekg(istream *this, streampos pos)
3288 ios *base = istream_get_ios(this);
3290 TRACE("(%p %d)\n", this, pos);
3292 ios_lockbuf(base);
3293 if (streambuf_seekpos(base->sb, pos, OPENMODE_in) == EOF)
3294 ios_clear(base, base->state | IOSTATE_failbit);
3295 ios_unlockbuf(base);
3296 return this;
3299 /* ?seekg@istream@@QAEAAV1@JW4seek_dir@ios@@@Z */
3300 /* ?seekg@istream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
3301 DEFINE_THISCALL_WRAPPER(istream_seekg_offset, 12)
3302 istream* __thiscall istream_seekg_offset(istream *this, streamoff off, ios_seek_dir dir)
3304 ios *base = istream_get_ios(this);
3306 TRACE("(%p %d %d)\n", this, off, dir);
3308 ios_lockbuf(base);
3309 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_in) == EOF)
3310 ios_clear(base, base->state | IOSTATE_failbit);
3311 ios_unlockbuf(base);
3312 return this;
3315 /* ?sync@istream@@QAEHXZ */
3316 /* ?sync@istream@@QEAAHXZ */
3317 DEFINE_THISCALL_WRAPPER(istream_sync, 4)
3318 int __thiscall istream_sync(istream *this)
3320 ios *base = istream_get_ios(this);
3321 int ret;
3323 TRACE("(%p)\n", this);
3325 ios_lockbuf(base);
3326 if ((ret = call_streambuf_sync(base->sb)) == EOF)
3327 ios_clear(base, base->state | IOSTATE_badbit | IOSTATE_failbit);
3328 ios_unlockbuf(base);
3329 return ret;
3332 /* ?tellg@istream@@QAEJXZ */
3333 /* ?tellg@istream@@QEAAJXZ */
3334 DEFINE_THISCALL_WRAPPER(istream_tellg, 4)
3335 streampos __thiscall istream_tellg(istream *this)
3337 ios *base = istream_get_ios(this);
3338 streampos pos;
3340 TRACE("(%p)\n", this);
3342 ios_lockbuf(base);
3343 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_in)) == EOF)
3344 ios_clear(base, base->state | IOSTATE_failbit);
3345 ios_unlockbuf(base);
3346 return pos;
3349 static int getint_is_valid_digit(char ch, int base)
3351 if (base == 8) return (ch >= '0' && ch <= '7');
3352 if (base == 16) return isxdigit(ch);
3353 return isdigit(ch);
3356 /* ?getint@istream@@AAEHPAD@Z */
3357 /* ?getint@istream@@AEAAHPEAD@Z */
3358 DEFINE_THISCALL_WRAPPER(istream_getint, 8)
3359 int __thiscall istream_getint(istream *this, char *str)
3361 ios *base = istream_get_ios(this);
3362 int ch, num_base = 0, i = 0;
3363 BOOL scan_sign = TRUE, scan_prefix = TRUE, scan_x = FALSE, valid_integer = FALSE;
3365 TRACE("(%p %p)\n", this, str);
3367 if (istream_ipfx(this, 0)) {
3368 num_base = (base->flags & FLAGS_dec) ? 10 :
3369 (base->flags & FLAGS_hex) ? 16 :
3370 (base->flags & FLAGS_oct) ? 8 : 0; /* 0 = autodetect */
3371 /* scan valid characters, up to 15 (hard limit on Windows) */
3372 for (ch = streambuf_sgetc(base->sb); i < 15; ch = streambuf_snextc(base->sb)) {
3373 if ((ch == '+' || ch == '-') && scan_sign) {
3374 /* no additional sign allowed */
3375 scan_sign = FALSE;
3376 } else if ((ch == 'x' || ch == 'X') && scan_x) {
3377 /* only hex digits can (and must) follow */
3378 scan_x = valid_integer = FALSE;
3379 num_base = 16;
3380 } else if (ch == '0' && scan_prefix) {
3381 /* might be the octal prefix, the beginning of the hex prefix or a decimal zero */
3382 scan_sign = scan_prefix = FALSE;
3383 scan_x = !num_base || num_base == 16;
3384 valid_integer = TRUE;
3385 if (!num_base)
3386 num_base = 8;
3387 } else if (getint_is_valid_digit(ch, num_base)) {
3388 /* only digits in the corresponding base can follow */
3389 scan_sign = scan_prefix = scan_x = FALSE;
3390 valid_integer = TRUE;
3391 } else {
3392 /* unexpected character, stop scanning */
3393 if (!valid_integer) {
3394 /* the result is not a valid integer */
3395 base->state |= IOSTATE_failbit;
3396 /* put any extracted character back into the stream */
3397 while (i > 0)
3398 if (streambuf_sputbackc(base->sb, str[--i]) == EOF)
3399 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3400 } else if (ch == EOF) {
3401 base->state |= IOSTATE_eofbit;
3402 if (scan_x && !(base->flags & ios_basefield)) {
3403 /* when autodetecting, a single zero followed by EOF is regarded as decimal */
3404 num_base = 0;
3407 break;
3409 str[i++] = ch;
3411 /* append a null terminator */
3412 str[i] = 0;
3413 istream_isfx(this);
3415 return num_base;
3418 /* ?getdouble@istream@@AAEHPADH@Z */
3419 /* ?getdouble@istream@@AEAAHPEADH@Z */
3420 DEFINE_THISCALL_WRAPPER(istream_getdouble, 12)
3421 int __thiscall istream_getdouble(istream *this, char *str, int count)
3423 ios *base = istream_get_ios(this);
3424 int ch, i = 0;
3425 BOOL scan_sign = TRUE, scan_dot = TRUE, scan_exp = TRUE,
3426 valid_mantissa = FALSE, valid_exponent = FALSE;
3428 TRACE("(%p %p %d)\n", this, str, count);
3430 if (istream_ipfx(this, 0)) {
3431 if (!count) {
3432 /* can't output anything */
3433 base->state |= IOSTATE_failbit;
3434 i = -1;
3435 } else {
3436 /* valid mantissas: +d. +.d +d.d (where d are sequences of digits and the sign is optional) */
3437 /* valid exponents: e+d E+d (where d are sequences of digits and the sign is optional) */
3438 for (ch = streambuf_sgetc(base->sb); i < count; ch = streambuf_snextc(base->sb)) {
3439 if ((ch == '+' || ch == '-') && scan_sign) {
3440 /* no additional sign allowed */
3441 scan_sign = FALSE;
3442 } else if (ch == '.' && scan_dot) {
3443 /* no sign or additional dot allowed */
3444 scan_sign = scan_dot = FALSE;
3445 } else if ((ch == 'e' || ch == 'E') && scan_exp) {
3446 /* sign is allowed again but not dots or exponents */
3447 scan_sign = TRUE;
3448 scan_dot = scan_exp = FALSE;
3449 } else if (isdigit(ch)) {
3450 if (scan_exp)
3451 valid_mantissa = TRUE;
3452 else
3453 valid_exponent = TRUE;
3454 /* no sign allowed after a digit */
3455 scan_sign = FALSE;
3456 } else {
3457 /* unexpected character, stop scanning */
3458 /* check whether the result is a valid double */
3459 if (!scan_exp && !valid_exponent) {
3460 /* put the last character back into the stream, usually the 'e' or 'E' */
3461 if (streambuf_sputbackc(base->sb, str[i--]) == EOF)
3462 base->state |= IOSTATE_badbit; /* characters have been lost for good */
3463 } else if (ch == EOF)
3464 base->state |= IOSTATE_eofbit;
3465 if (!valid_mantissa)
3466 base->state |= IOSTATE_failbit;
3467 break;
3469 str[i++] = ch;
3471 /* check if character limit has been reached */
3472 if (i == count) {
3473 base->state |= IOSTATE_failbit;
3474 i--;
3476 /* append a null terminator */
3477 str[i] = 0;
3479 istream_isfx(this);
3481 return i;
3484 /* ?ws@@YAAAVistream@@AAV1@@Z */
3485 /* ?ws@@YAAEAVistream@@AEAV1@@Z */
3486 istream* __cdecl istream_ws(istream *this)
3488 TRACE("(%p)\n", this);
3489 istream_eatwhite(this);
3490 return this;
3493 /******************************************************************
3494 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
3496 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
3497 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
3499 FIXME("(%p %x) stub\n", this, virt_init);
3500 return this;
3503 /******************************************************************
3504 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
3506 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
3507 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
3509 FIXME("(%p) stub\n", base);
3512 #ifdef __i386__
3514 #define DEFINE_VTBL_WRAPPER(off) \
3515 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
3516 "popl %eax\n\t" \
3517 "popl %ecx\n\t" \
3518 "pushl %eax\n\t" \
3519 "movl 0(%ecx), %eax\n\t" \
3520 "jmp *" #off "(%eax)\n\t")
3522 DEFINE_VTBL_WRAPPER(0);
3523 DEFINE_VTBL_WRAPPER(4);
3524 DEFINE_VTBL_WRAPPER(8);
3525 DEFINE_VTBL_WRAPPER(12);
3526 DEFINE_VTBL_WRAPPER(16);
3527 DEFINE_VTBL_WRAPPER(20);
3528 DEFINE_VTBL_WRAPPER(24);
3529 DEFINE_VTBL_WRAPPER(28);
3530 DEFINE_VTBL_WRAPPER(32);
3531 DEFINE_VTBL_WRAPPER(36);
3532 DEFINE_VTBL_WRAPPER(40);
3533 DEFINE_VTBL_WRAPPER(44);
3534 DEFINE_VTBL_WRAPPER(48);
3535 DEFINE_VTBL_WRAPPER(52);
3536 DEFINE_VTBL_WRAPPER(56);
3538 #endif
3540 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
3541 void (__cdecl *MSVCRT_operator_delete)(void*);
3543 static void init_cxx_funcs(void)
3545 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
3547 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
3549 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
3550 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
3552 else
3554 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
3555 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
3559 static void init_io(void *base)
3561 #ifdef __x86_64__
3562 init_streambuf_rtti(base);
3563 init_filebuf_rtti(base);
3564 init_strstreambuf_rtti(base);
3565 init_stdiobuf_rtti(base);
3566 init_ios_rtti(base);
3567 init_ostream_rtti(base);
3568 init_istream_rtti(base);
3569 #endif
3572 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
3574 switch (reason)
3576 case DLL_WINE_PREATTACH:
3577 return FALSE; /* prefer native version */
3578 case DLL_PROCESS_ATTACH:
3579 init_cxx_funcs();
3580 init_exception(inst);
3581 init_io(inst);
3582 DisableThreadLibraryCalls( inst );
3583 break;
3585 return TRUE;