po: German translation: Fix grammar errors.
[wine/multimedia.git] / dlls / msvcirt / msvcirt.c
blobff31e8cb0590a181669bdadee6027d733ffa3c3a
1 /*
2 * Copyright (C) 2007 Alexandre Julliard
3 * Copyright (C) 2015 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 ios */
110 struct _ostream;
111 typedef struct {
112 const vtable_ptr *vtable;
113 streambuf *sb;
114 ios_io_state state;
115 int special[4];
116 int delbuf;
117 struct _ostream *tie;
118 ios_flags flags;
119 int precision;
120 char fill;
121 int width;
122 int do_lock;
123 CRITICAL_SECTION lock;
124 } ios;
126 ios* __thiscall ios_assign(ios*, const ios*);
127 int __thiscall ios_fail(const ios*);
128 void __cdecl ios_lock(ios*);
129 void __cdecl ios_lockc(void);
130 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
131 void __cdecl ios_unlock(ios*);
132 void __cdecl ios_unlockc(void);
134 /* class ostream */
135 typedef struct _ostream {
136 const vtable_ptr *vtable;
137 } ostream;
139 typedef struct {
140 LPVOID VTable;
141 } class_strstreambuf;
143 /* ??_7streambuf@@6B@ */
144 extern const vtable_ptr MSVCP_streambuf_vtable;
145 /* ??_7filebuf@@6B@ */
146 extern const vtable_ptr MSVCP_filebuf_vtable;
147 /* ??_7ios@@6B@ */
148 extern const vtable_ptr MSVCP_ios_vtable;
150 #ifndef __GNUC__
151 void __asm_dummy_vtables(void) {
152 #endif
153 __ASM_VTABLE(streambuf,
154 VTABLE_ADD_FUNC(streambuf_vector_dtor)
155 VTABLE_ADD_FUNC(streambuf_sync)
156 VTABLE_ADD_FUNC(streambuf_setbuf)
157 VTABLE_ADD_FUNC(streambuf_seekoff)
158 VTABLE_ADD_FUNC(streambuf_seekpos)
159 VTABLE_ADD_FUNC(streambuf_xsputn)
160 VTABLE_ADD_FUNC(streambuf_xsgetn)
161 VTABLE_ADD_FUNC(streambuf_overflow)
162 VTABLE_ADD_FUNC(streambuf_underflow)
163 VTABLE_ADD_FUNC(streambuf_pbackfail)
164 VTABLE_ADD_FUNC(streambuf_doallocate));
165 __ASM_VTABLE(filebuf,
166 VTABLE_ADD_FUNC(filebuf_vector_dtor)
167 VTABLE_ADD_FUNC(filebuf_sync)
168 VTABLE_ADD_FUNC(filebuf_setbuf)
169 VTABLE_ADD_FUNC(filebuf_seekoff)
170 VTABLE_ADD_FUNC(streambuf_seekpos)
171 VTABLE_ADD_FUNC(streambuf_xsputn)
172 VTABLE_ADD_FUNC(streambuf_xsgetn)
173 VTABLE_ADD_FUNC(filebuf_overflow)
174 VTABLE_ADD_FUNC(filebuf_underflow)
175 VTABLE_ADD_FUNC(streambuf_pbackfail)
176 VTABLE_ADD_FUNC(streambuf_doallocate));
177 __ASM_VTABLE(ios,
178 VTABLE_ADD_FUNC(ios_vector_dtor));
179 #ifndef __GNUC__
181 #endif
183 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
184 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
185 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
187 /* ??0streambuf@@IAE@PADH@Z */
188 /* ??0streambuf@@IEAA@PEADH@Z */
189 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
190 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
192 TRACE("(%p %p %d)\n", this, buffer, length);
193 this->vtable = &MSVCP_streambuf_vtable;
194 this->allocated = 0;
195 this->stored_char = EOF;
196 this->do_lock = -1;
197 this->base = NULL;
198 streambuf_setbuf(this, buffer, length);
199 streambuf_setg(this, NULL, NULL, NULL);
200 streambuf_setp(this, NULL, NULL);
201 InitializeCriticalSection(&this->lock);
202 return this;
205 /* ??0streambuf@@IAE@XZ */
206 /* ??0streambuf@@IEAA@XZ */
207 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
208 streambuf* __thiscall streambuf_ctor(streambuf *this)
210 streambuf_reserve_ctor(this, NULL, 0);
211 this->unbuffered = 0;
212 return this;
215 /* ??0streambuf@@QAE@ABV0@@Z */
216 /* ??0streambuf@@QEAA@AEBV0@@Z */
217 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
218 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
220 TRACE("(%p %p)\n", this, copy);
221 *this = *copy;
222 this->vtable = &MSVCP_streambuf_vtable;
223 return this;
226 /* ??1streambuf@@UAE@XZ */
227 /* ??1streambuf@@UEAA@XZ */
228 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
229 void __thiscall streambuf_dtor(streambuf *this)
231 TRACE("(%p)\n", this);
232 if (this->allocated)
233 MSVCRT_operator_delete(this->base);
234 DeleteCriticalSection(&this->lock);
237 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
238 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
239 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
240 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
242 streambuf_dtor(this);
243 return streambuf_copy_ctor(this, rhs);
246 /* ??_Estreambuf@@UAEPAXI@Z */
247 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
248 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
249 streambuf*, (streambuf*, unsigned int), (this, flags))
250 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
252 TRACE("(%p %x)\n", this, flags);
253 if (flags & 2) {
254 /* we have an array, with the number of elements stored before the first object */
255 INT_PTR i, *ptr = (INT_PTR *)this-1;
257 for (i = *ptr-1; i >= 0; i--)
258 streambuf_dtor(this+i);
259 MSVCRT_operator_delete(ptr);
260 } else {
261 streambuf_dtor(this);
262 if (flags & 1)
263 MSVCRT_operator_delete(this);
265 return this;
268 /* ??_Gstreambuf@@UAEPAXI@Z */
269 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
270 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
272 TRACE("(%p %x)\n", this, flags);
273 streambuf_dtor(this);
274 if (flags & 1) MSVCRT_operator_delete(this);
275 return this;
278 /* ?doallocate@streambuf@@MAEHXZ */
279 /* ?doallocate@streambuf@@MEAAHXZ */
280 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
281 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
282 int __thiscall streambuf_doallocate(streambuf *this)
284 char *reserve;
286 TRACE("(%p)\n", this);
287 reserve = MSVCRT_operator_new(RESERVE_SIZE);
288 if (!reserve)
289 return EOF;
291 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
292 return 1;
295 /* ?allocate@streambuf@@IAEHXZ */
296 /* ?allocate@streambuf@@IEAAHXZ */
297 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
298 int __thiscall streambuf_allocate(streambuf *this)
300 TRACE("(%p)\n", this);
301 if (this->base != NULL || this->unbuffered)
302 return 0;
303 return call_streambuf_doallocate(this);
306 /* ?base@streambuf@@IBEPADXZ */
307 /* ?base@streambuf@@IEBAPEADXZ */
308 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
309 char* __thiscall streambuf_base(const streambuf *this)
311 TRACE("(%p)\n", this);
312 return this->base;
315 /* ?blen@streambuf@@IBEHXZ */
316 /* ?blen@streambuf@@IEBAHXZ */
317 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
318 int __thiscall streambuf_blen(const streambuf *this)
320 TRACE("(%p)\n", this);
321 return this->ebuf - this->base;
324 /* ?eback@streambuf@@IBEPADXZ */
325 /* ?eback@streambuf@@IEBAPEADXZ */
326 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
327 char* __thiscall streambuf_eback(const streambuf *this)
329 TRACE("(%p)\n", this);
330 return this->eback;
333 /* ?ebuf@streambuf@@IBEPADXZ */
334 /* ?ebuf@streambuf@@IEBAPEADXZ */
335 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
336 char* __thiscall streambuf_ebuf(const streambuf *this)
338 TRACE("(%p)\n", this);
339 return this->ebuf;
342 /* ?egptr@streambuf@@IBEPADXZ */
343 /* ?egptr@streambuf@@IEBAPEADXZ */
344 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
345 char* __thiscall streambuf_egptr(const streambuf *this)
347 TRACE("(%p)\n", this);
348 return this->egptr;
351 /* ?epptr@streambuf@@IBEPADXZ */
352 /* ?epptr@streambuf@@IEBAPEADXZ */
353 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
354 char* __thiscall streambuf_epptr(const streambuf *this)
356 TRACE("(%p)\n", this);
357 return this->epptr;
360 /* ?gptr@streambuf@@IBEPADXZ */
361 /* ?gptr@streambuf@@IEBAPEADXZ */
362 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
363 char* __thiscall streambuf_gptr(const streambuf *this)
365 TRACE("(%p)\n", this);
366 return this->gptr;
369 /* ?pbase@streambuf@@IBEPADXZ */
370 /* ?pbase@streambuf@@IEBAPEADXZ */
371 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
372 char* __thiscall streambuf_pbase(const streambuf *this)
374 TRACE("(%p)\n", this);
375 return this->pbase;
378 /* ?pptr@streambuf@@IBEPADXZ */
379 /* ?pptr@streambuf@@IEBAPEADXZ */
380 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
381 char* __thiscall streambuf_pptr(const streambuf *this)
383 TRACE("(%p)\n", this);
384 return this->pptr;
387 /* ?clrlock@streambuf@@QAEXXZ */
388 /* ?clrlock@streambuf@@QEAAXXZ */
389 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
390 void __thiscall streambuf_clrlock(streambuf *this)
392 TRACE("(%p)\n", this);
393 if (this->do_lock <= 0)
394 this->do_lock++;
397 /* ?lock@streambuf@@QAEXXZ */
398 /* ?lock@streambuf@@QEAAXXZ */
399 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
400 void __thiscall streambuf_lock(streambuf *this)
402 TRACE("(%p)\n", this);
403 if (this->do_lock < 0)
404 EnterCriticalSection(&this->lock);
407 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
408 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
409 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
410 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
412 TRACE("(%p)\n", this);
413 return &this->lock;
416 /* ?gbump@streambuf@@IAEXH@Z */
417 /* ?gbump@streambuf@@IEAAXH@Z */
418 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
419 void __thiscall streambuf_gbump(streambuf *this, int count)
421 TRACE("(%p %d)\n", this, count);
422 this->gptr += count;
425 /* ?pbump@streambuf@@IAEXH@Z */
426 /* ?pbump@streambuf@@IEAAXH@Z */
427 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
428 void __thiscall streambuf_pbump(streambuf *this, int count)
430 TRACE("(%p %d)\n", this, count);
431 this->pptr += count;
434 /* ?in_avail@streambuf@@QBEHXZ */
435 /* ?in_avail@streambuf@@QEBAHXZ */
436 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
437 int __thiscall streambuf_in_avail(const streambuf *this)
439 TRACE("(%p)\n", this);
440 return this->egptr - this->gptr;
443 /* ?out_waiting@streambuf@@QBEHXZ */
444 /* ?out_waiting@streambuf@@QEBAHXZ */
445 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
446 int __thiscall streambuf_out_waiting(const streambuf *this)
448 TRACE("(%p)\n", this);
449 return this->pptr - this->pbase;
452 /* Unexported */
453 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
454 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
455 int __thiscall streambuf_overflow(streambuf *this, int c)
457 ERR("overflow is not implemented in streambuf\n");
458 return EOF;
461 /* ?pbackfail@streambuf@@UAEHH@Z */
462 /* ?pbackfail@streambuf@@UEAAHH@Z */
463 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
464 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
465 int __thiscall streambuf_pbackfail(streambuf *this, int c)
467 TRACE("(%p %d)\n", this, c);
468 if (this->gptr <= this->eback)
469 return EOF;
470 return *--this->gptr = c;
473 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
474 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
475 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
476 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
477 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
479 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
480 return EOF;
483 /* ?seekpos@streambuf@@UAEJJH@Z */
484 /* ?seekpos@streambuf@@UEAAJJH@Z */
485 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
486 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
488 TRACE("(%p %d %d)\n", this, pos, mode);
489 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
492 /* ?setb@streambuf@@IAEXPAD0H@Z */
493 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
494 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
495 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
497 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
498 if (this->allocated)
499 MSVCRT_operator_delete(this->base);
500 this->allocated = delete;
501 this->base = ba;
502 this->ebuf = eb;
505 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
506 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
507 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
508 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
510 TRACE("(%p %p %d)\n", this, buffer, length);
511 if (this->base != NULL)
512 return NULL;
514 if (buffer == NULL || !length) {
515 this->unbuffered = 1;
516 this->base = this->ebuf = NULL;
517 } else {
518 this->unbuffered = 0;
519 this->base = buffer;
520 this->ebuf = buffer + length;
522 return this;
525 /* ?setg@streambuf@@IAEXPAD00@Z */
526 /* ?setg@streambuf@@IEAAXPEAD00@Z */
527 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
528 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
530 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
531 this->eback = ek;
532 this->gptr = gp;
533 this->egptr = eg;
536 /* ?setlock@streambuf@@QAEXXZ */
537 /* ?setlock@streambuf@@QEAAXXZ */
538 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
539 void __thiscall streambuf_setlock(streambuf *this)
541 TRACE("(%p)\n", this);
542 this->do_lock--;
545 /* ?setp@streambuf@@IAEXPAD0@Z */
546 /* ?setp@streambuf@@IEAAXPEAD0@Z */
547 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
548 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
550 TRACE("(%p %p %p)\n", this, pb, ep);
551 this->pbase = this->pptr = pb;
552 this->epptr = ep;
555 /* ?sync@streambuf@@UAEHXZ */
556 /* ?sync@streambuf@@UEAAHXZ */
557 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
558 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
559 int __thiscall streambuf_sync(streambuf *this)
561 TRACE("(%p)\n", this);
562 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
565 /* ?unbuffered@streambuf@@IAEXH@Z */
566 /* ?unbuffered@streambuf@@IEAAXH@Z */
567 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
568 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
570 TRACE("(%p %d)\n", this, buf);
571 this->unbuffered = buf;
574 /* ?unbuffered@streambuf@@IBEHXZ */
575 /* ?unbuffered@streambuf@@IEBAHXZ */
576 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
577 int __thiscall streambuf_unbuffered_get(const streambuf *this)
579 TRACE("(%p)\n", this);
580 return this->unbuffered;
583 /* Unexported */
584 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
585 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
586 int __thiscall streambuf_underflow(streambuf *this)
588 ERR("underflow is not implemented in streambuf\n");
589 return EOF;
592 /* ?unlock@streambuf@@QAEXXZ */
593 /* ?unlock@streambuf@@QEAAXXZ */
594 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
595 void __thiscall streambuf_unlock(streambuf *this)
597 TRACE("(%p)\n", this);
598 if (this->do_lock < 0)
599 LeaveCriticalSection(&this->lock);
602 /* ?xsgetn@streambuf@@UAEHPADH@Z */
603 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
604 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
605 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
606 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
608 int copied = 0, chunk;
610 TRACE("(%p %p %d)\n", this, buffer, count);
612 if (this->unbuffered) {
613 if (this->stored_char == EOF)
614 this->stored_char = call_streambuf_underflow(this);
615 while (copied < count && this->stored_char != EOF) {
616 buffer[copied++] = this->stored_char;
617 this->stored_char = call_streambuf_underflow(this);
619 } else {
620 while (copied < count) {
621 if (call_streambuf_underflow(this) == EOF)
622 break;
623 chunk = this->egptr - this->gptr;
624 if (chunk > count - copied)
625 chunk = count - copied;
626 memcpy(buffer+copied, this->gptr, chunk);
627 this->gptr += chunk;
628 copied += chunk;
631 return copied;
634 /* ?xsputn@streambuf@@UAEHPBDH@Z */
635 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
636 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
637 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
638 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
640 int copied = 0, chunk;
642 TRACE("(%p %p %d)\n", this, data, length);
644 while (copied < length) {
645 if (this->unbuffered || this->pptr == this->epptr) {
646 if (call_streambuf_overflow(this, data[copied]) == EOF)
647 break;
648 copied++;
649 } else {
650 chunk = this->epptr - this->pptr;
651 if (chunk > length - copied)
652 chunk = length - copied;
653 memcpy(this->pptr, data+copied, chunk);
654 this->pptr += chunk;
655 copied += chunk;
658 return copied;
661 /* ?sgetc@streambuf@@QAEHXZ */
662 /* ?sgetc@streambuf@@QEAAHXZ */
663 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
664 int __thiscall streambuf_sgetc(streambuf *this)
666 TRACE("(%p)\n", this);
667 if (this->unbuffered) {
668 if (this->stored_char == EOF)
669 this->stored_char = call_streambuf_underflow(this);
670 return this->stored_char;
671 } else
672 return call_streambuf_underflow(this);
675 /* ?sputc@streambuf@@QAEHH@Z */
676 /* ?sputc@streambuf@@QEAAHH@Z */
677 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
678 int __thiscall streambuf_sputc(streambuf *this, int ch)
680 TRACE("(%p %d)\n", this, ch);
681 return (this->pptr < this->epptr) ? *this->pptr++ = ch : call_streambuf_overflow(this, ch);
684 /* ?sgetn@streambuf@@QAEHPADH@Z */
685 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
686 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
687 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
689 return call_streambuf_xsgetn(this, buffer, count);
692 /* ?sputn@streambuf@@QAEHPBDH@Z */
693 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
694 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
695 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
697 return call_streambuf_xsputn(this, data, length);
700 /* ?snextc@streambuf@@QAEHXZ */
701 /* ?snextc@streambuf@@QEAAHXZ */
702 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
703 int __thiscall streambuf_snextc(streambuf *this)
705 TRACE("(%p)\n", this);
706 if (this->unbuffered) {
707 if (this->stored_char == EOF)
708 call_streambuf_underflow(this);
709 return this->stored_char = call_streambuf_underflow(this);
710 } else {
711 if (this->gptr >= this->egptr)
712 call_streambuf_underflow(this);
713 this->gptr++;
714 return (this->gptr < this->egptr) ? *this->gptr : call_streambuf_underflow(this);
718 /* ?sbumpc@streambuf@@QAEHXZ */
719 /* ?sbumpc@streambuf@@QEAAHXZ */
720 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
721 int __thiscall streambuf_sbumpc(streambuf *this)
723 int ret;
725 TRACE("(%p)\n", this);
727 if (this->unbuffered) {
728 ret = this->stored_char;
729 this->stored_char = EOF;
730 if (ret == EOF)
731 ret = call_streambuf_underflow(this);
732 } else {
733 ret = (this->gptr < this->egptr) ? *this->gptr : call_streambuf_underflow(this);
734 this->gptr++;
736 return ret;
739 /* ?stossc@streambuf@@QAEXXZ */
740 /* ?stossc@streambuf@@QEAAXXZ */
741 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
742 void __thiscall streambuf_stossc(streambuf *this)
744 TRACE("(%p)\n", this);
745 if (this->unbuffered) {
746 if (this->stored_char == EOF)
747 call_streambuf_underflow(this);
748 else
749 this->stored_char = EOF;
750 } else {
751 if (this->gptr >= this->egptr)
752 call_streambuf_underflow(this);
753 if (this->gptr < this->egptr)
754 this->gptr++;
758 /* ?sputbackc@streambuf@@QAEHD@Z */
759 /* ?sputbackc@streambuf@@QEAAHD@Z */
760 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
761 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
763 TRACE("(%p %d)\n", this, ch);
764 return call_streambuf_pbackfail(this, ch);
767 /* ?dbp@streambuf@@QAEXXZ */
768 /* ?dbp@streambuf@@QEAAXXZ */
769 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
770 void __thiscall streambuf_dbp(streambuf *this)
772 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
773 if (this->unbuffered) {
774 printf("unbuffered\n");
775 } else {
776 printf("_fAlloc=%d\n", this->allocated);
777 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
778 printf("pbase()=%p, pptr()=%p, epptr()=%d\n", this->pbase, this->pptr, this->epptr);
779 printf("eback()=%p, gptr()=%p, egptr()=%d\n", this->eback, this->gptr, this->egptr);
783 /* ??0filebuf@@QAE@ABV0@@Z */
784 /* ??0filebuf@@QEAA@AEBV0@@Z */
785 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
786 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
788 TRACE("(%p %p)\n", this, copy);
789 *this = *copy;
790 this->base.vtable = &MSVCP_filebuf_vtable;
791 return this;
794 /* ??0filebuf@@QAE@HPADH@Z */
795 /* ??0filebuf@@QEAA@HPEADH@Z */
796 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
797 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
799 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
800 streambuf_reserve_ctor(&this->base, buffer, length);
801 this->base.vtable = &MSVCP_filebuf_vtable;
802 this->fd = fd;
803 this->close = 0;
804 return this;
807 /* ??0filebuf@@QAE@H@Z */
808 /* ??0filebuf@@QEAA@H@Z */
809 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
810 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
812 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
813 this->base.unbuffered = 0;
814 return this;
817 /* ??0filebuf@@QAE@XZ */
818 /* ??0filebuf@@QEAA@XZ */
819 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
820 filebuf* __thiscall filebuf_ctor(filebuf* this)
822 return filebuf_fd_ctor(this, -1);
825 /* ??1filebuf@@UAE@XZ */
826 /* ??1filebuf@@UEAA@XZ */
827 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
828 void __thiscall filebuf_dtor(filebuf* this)
830 TRACE("(%p)\n", this);
831 if (this->close)
832 filebuf_close(this);
833 streambuf_dtor(&this->base);
836 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
837 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
838 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
839 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
841 filebuf_dtor(this);
842 return filebuf_copy_ctor(this, rhs);
845 /* ??_Efilebuf@@UAEPAXI@Z */
846 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
847 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
849 TRACE("(%p %x)\n", this, flags);
850 if (flags & 2) {
851 /* we have an array, with the number of elements stored before the first object */
852 INT_PTR i, *ptr = (INT_PTR *)this-1;
854 for (i = *ptr-1; i >= 0; i--)
855 filebuf_dtor(this+i);
856 MSVCRT_operator_delete(ptr);
857 } else {
858 filebuf_dtor(this);
859 if (flags & 1)
860 MSVCRT_operator_delete(this);
862 return this;
865 /* ??_Gfilebuf@@UAEPAXI@Z */
866 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
867 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
869 TRACE("(%p %x)\n", this, flags);
870 filebuf_dtor(this);
871 if (flags & 1) MSVCRT_operator_delete(this);
872 return this;
875 /* ?attach@filebuf@@QAEPAV1@H@Z */
876 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
877 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
878 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
880 TRACE("(%p %d)\n", this, fd);
881 if (this->fd != -1)
882 return NULL;
884 streambuf_lock(&this->base);
885 this->fd = fd;
886 streambuf_allocate(&this->base);
887 streambuf_unlock(&this->base);
888 return this;
891 /* ?close@filebuf@@QAEPAV1@XZ */
892 /* ?close@filebuf@@QEAAPEAV1@XZ */
893 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
894 filebuf* __thiscall filebuf_close(filebuf *this)
896 filebuf *ret;
898 TRACE("(%p)\n", this);
899 if (this->fd == -1)
900 return NULL;
902 streambuf_lock(&this->base);
903 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
904 ret = NULL;
905 } else {
906 this->fd = -1;
907 ret = this;
909 streambuf_unlock(&this->base);
910 return ret;
913 /* ?fd@filebuf@@QBEHXZ */
914 /* ?fd@filebuf@@QEBAHXZ */
915 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
916 filedesc __thiscall filebuf_fd(const filebuf *this)
918 TRACE("(%p)\n", this);
919 return this->fd;
922 /* ?is_open@filebuf@@QBEHXZ */
923 /* ?is_open@filebuf@@QEBAHXZ */
924 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
925 int __thiscall filebuf_is_open(const filebuf *this)
927 TRACE("(%p)\n", this);
928 return this->fd != -1;
931 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
932 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
933 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
934 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
936 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
937 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
938 int op_flags, sh_flags, fd;
940 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
941 if (this->fd != -1)
942 return NULL;
944 /* mode */
945 if (mode & (OPENMODE_app|OPENMODE_trunc))
946 mode |= OPENMODE_out;
947 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
948 if (op_flags < 0)
949 return NULL;
950 if (mode & OPENMODE_app)
951 op_flags |= _O_APPEND;
952 if ((mode & OPENMODE_trunc) ||
953 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
954 op_flags |= _O_TRUNC;
955 if (!(mode & OPENMODE_nocreate))
956 op_flags |= _O_CREAT;
957 if (mode & OPENMODE_noreplace)
958 op_flags |= _O_EXCL;
959 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
961 /* share protection */
962 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
964 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
965 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
966 if (fd < 0)
967 return NULL;
969 streambuf_lock(&this->base);
970 this->close = 1;
971 this->fd = fd;
972 if ((mode & OPENMODE_ate) &&
973 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
974 _close(fd);
975 this->fd = -1;
977 streambuf_allocate(&this->base);
978 streambuf_unlock(&this->base);
979 return (this->fd == -1) ? NULL : this;
982 /* ?overflow@filebuf@@UAEHH@Z */
983 /* ?overflow@filebuf@@UEAAHH@Z */
984 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
985 int __thiscall filebuf_overflow(filebuf *this, int c)
987 TRACE("(%p %d)\n", this, c);
988 if (call_streambuf_sync(&this->base) == EOF)
989 return EOF;
990 if (this->base.unbuffered)
991 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
992 if (streambuf_allocate(&this->base) == EOF)
993 return EOF;
995 this->base.pbase = this->base.pptr = this->base.base;
996 this->base.epptr = this->base.ebuf;
997 if (c != EOF)
998 *this->base.pptr++ = c;
999 return 1;
1002 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1003 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1004 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1005 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1007 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1008 if (call_streambuf_sync(&this->base) == EOF)
1009 return EOF;
1010 return _lseek(this->fd, offset, dir);
1013 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1014 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1015 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1016 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1018 streambuf *ret;
1020 TRACE("(%p %p %d)\n", this, buffer, length);
1021 if (this->base.base != NULL)
1022 return NULL;
1024 streambuf_lock(&this->base);
1025 ret = streambuf_setbuf(&this->base, buffer, length);
1026 streambuf_unlock(&this->base);
1027 return ret;
1030 /* ?setmode@filebuf@@QAEHH@Z */
1031 /* ?setmode@filebuf@@QEAAHH@Z */
1032 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1033 int __thiscall filebuf_setmode(filebuf *this, int mode)
1035 int ret;
1037 TRACE("(%p %d)\n", this, mode);
1038 if (mode != filebuf_text && mode != filebuf_binary)
1039 return -1;
1041 streambuf_lock(&this->base);
1042 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1043 streambuf_unlock(&this->base);
1044 return ret;
1047 /* ?sync@filebuf@@UAEHXZ */
1048 /* ?sync@filebuf@@UEAAHXZ */
1049 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1050 int __thiscall filebuf_sync(filebuf *this)
1052 int count, mode;
1053 char *ptr;
1054 LONG offset;
1056 TRACE("(%p)\n", this);
1057 if (this->fd == -1)
1058 return EOF;
1059 if (this->base.unbuffered)
1060 return 0;
1062 /* flush output buffer */
1063 if (this->base.pptr != NULL) {
1064 count = this->base.pptr - this->base.pbase;
1065 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1066 return EOF;
1067 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1069 /* flush input buffer */
1070 if (this->base.egptr != NULL) {
1071 offset = this->base.egptr - this->base.gptr;
1072 if (offset > 0) {
1073 mode = _setmode(this->fd, _O_TEXT);
1074 _setmode(this->fd, mode);
1075 if (mode & _O_TEXT) {
1076 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1077 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1078 if (*ptr == '\n')
1079 offset++;
1081 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1082 return EOF;
1084 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1086 return 0;
1089 /* ?underflow@filebuf@@UAEHXZ */
1090 /* ?underflow@filebuf@@UEAAHXZ */
1091 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1092 int __thiscall filebuf_underflow(filebuf *this)
1094 int buffer_size, read_bytes;
1095 char c;
1097 TRACE("(%p)\n", this);
1099 if (this->base.unbuffered)
1100 return (_read(this->fd, &c, 1) < 1) ? EOF : c;
1102 if (this->base.gptr >= this->base.egptr) {
1103 if (call_streambuf_sync(&this->base) == EOF)
1104 return EOF;
1105 buffer_size = this->base.ebuf - this->base.base;
1106 read_bytes = _read(this->fd, this->base.base, buffer_size);
1107 if (read_bytes <= 0)
1108 return EOF;
1109 this->base.eback = this->base.gptr = this->base.base;
1110 this->base.egptr = this->base.base + read_bytes;
1112 return *this->base.gptr;
1115 /* ??0ios@@IAE@ABV0@@Z */
1116 /* ??0ios@@IEAA@AEBV0@@Z */
1117 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1118 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1120 TRACE("(%p %p)\n", this, copy);
1121 ios_fLockcInit++;
1122 this->vtable = &MSVCP_ios_vtable;
1123 this->sb = NULL;
1124 this->delbuf = 0;
1125 InitializeCriticalSection(&this->lock);
1126 return ios_assign(this, copy);
1129 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1130 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1131 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1132 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1134 TRACE("(%p %p)\n", this, sb);
1135 ios_fLockcInit++;
1136 this->vtable = &MSVCP_ios_vtable;
1137 this->sb = sb;
1138 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1139 this->special[0] = this->special[1] = 0;
1140 this->delbuf = 0;
1141 this->tie = NULL;
1142 this->flags = 0;
1143 this->precision = 6;
1144 this->fill = ' ';
1145 this->width = 0;
1146 this->do_lock = -1;
1147 InitializeCriticalSection(&this->lock);
1148 return this;
1151 /* ??0ios@@IAE@XZ */
1152 /* ??0ios@@IEAA@XZ */
1153 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1154 ios* __thiscall ios_ctor(ios *this)
1156 return ios_sb_ctor(this, NULL);
1159 /* ??1ios@@UAE@XZ */
1160 /* ??1ios@@UEAA@XZ */
1161 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1162 void __thiscall ios_dtor(ios *this)
1164 TRACE("(%p)\n", this);
1165 ios_fLockcInit--;
1166 if (this->delbuf && this->sb)
1167 call_streambuf_vector_dtor(this->sb, 1);
1168 this->sb = NULL;
1169 this->state = IOSTATE_badbit;
1170 DeleteCriticalSection(&this->lock);
1173 /* ??4ios@@IAEAAV0@ABV0@@Z */
1174 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1175 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1176 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1178 TRACE("(%p %p)\n", this, rhs);
1179 this->state = rhs->state;
1180 if (!this->sb)
1181 this->state |= IOSTATE_badbit;
1182 this->tie = rhs->tie;
1183 this->flags = rhs->flags;
1184 this->precision = (char) rhs->precision;
1185 this->fill = rhs->fill;
1186 this->width = (char) rhs->width;
1187 return this;
1190 /* ??7ios@@QBEHXZ */
1191 /* ??7ios@@QEBAHXZ */
1192 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1193 int __thiscall ios_op_not(const ios *this)
1195 TRACE("(%p)\n", this);
1196 return ios_fail(this);
1199 /* ??Bios@@QBEPAXXZ */
1200 /* ??Bios@@QEBAPEAXXZ */
1201 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1202 void* __thiscall ios_op_void(const ios *this)
1204 TRACE("(%p)\n", this);
1205 return ios_fail(this) ? NULL : (void*)this;
1208 /* ??_Eios@@UAEPAXI@Z */
1209 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1210 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1212 TRACE("(%p %x)\n", this, flags);
1213 if (flags & 2) {
1214 /* we have an array, with the number of elements stored before the first object */
1215 INT_PTR i, *ptr = (INT_PTR *)this-1;
1217 for (i = *ptr-1; i >= 0; i--)
1218 ios_dtor(this+i);
1219 MSVCRT_operator_delete(ptr);
1220 } else {
1221 ios_dtor(this);
1222 if (flags & 1)
1223 MSVCRT_operator_delete(this);
1225 return this;
1228 /* ??_Gios@@UAEPAXI@Z */
1229 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1230 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1232 TRACE("(%p %x)\n", this, flags);
1233 ios_dtor(this);
1234 if (flags & 1) MSVCRT_operator_delete(this);
1235 return this;
1238 /* ?bad@ios@@QBEHXZ */
1239 /* ?bad@ios@@QEBAHXZ */
1240 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1241 int __thiscall ios_bad(const ios *this)
1243 TRACE("(%p)\n", this);
1244 return (this->state & IOSTATE_badbit);
1247 /* ?bitalloc@ios@@SAJXZ */
1248 LONG __cdecl ios_bitalloc(void)
1250 TRACE("()\n");
1251 ios_lockc();
1252 ios_maxbit <<= 1;
1253 ios_unlockc();
1254 return ios_maxbit;
1257 /* ?clear@ios@@QAEXH@Z */
1258 /* ?clear@ios@@QEAAXH@Z */
1259 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1260 void __thiscall ios_clear(ios *this, int state)
1262 TRACE("(%p %d)\n", this, state);
1263 ios_lock(this);
1264 this->state = state;
1265 ios_unlock(this);
1268 /* ?clrlock@ios@@QAAXXZ */
1269 /* ?clrlock@ios@@QEAAXXZ */
1270 void __cdecl ios_clrlock(ios *this)
1272 TRACE("(%p)\n", this);
1273 if (this->do_lock <= 0)
1274 this->do_lock++;
1275 if (this->sb)
1276 streambuf_clrlock(this->sb);
1279 /* ?delbuf@ios@@QAEXH@Z */
1280 /* ?delbuf@ios@@QEAAXH@Z */
1281 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1282 void __thiscall ios_delbuf_set(ios *this, int delete)
1284 TRACE("(%p %d)\n", this, delete);
1285 this->delbuf = delete;
1288 /* ?delbuf@ios@@QBEHXZ */
1289 /* ?delbuf@ios@@QEBAHXZ */
1290 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1291 int __thiscall ios_delbuf_get(const ios *this)
1293 TRACE("(%p)\n", this);
1294 return this->delbuf;
1297 /* ?dec@@YAAAVios@@AAV1@@Z */
1298 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1299 ios* __cdecl ios_dec(ios *this)
1301 TRACE("(%p)\n", this);
1302 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1303 return this;
1306 /* ?eof@ios@@QBEHXZ */
1307 /* ?eof@ios@@QEBAHXZ */
1308 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1309 int __thiscall ios_eof(const ios *this)
1311 TRACE("(%p)\n", this);
1312 return (this->state & IOSTATE_eofbit);
1315 /* ?fail@ios@@QBEHXZ */
1316 /* ?fail@ios@@QEBAHXZ */
1317 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1318 int __thiscall ios_fail(const ios *this)
1320 TRACE("(%p)\n", this);
1321 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1324 /* ?fill@ios@@QAEDD@Z */
1325 /* ?fill@ios@@QEAADD@Z */
1326 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1327 char __thiscall ios_fill_set(ios *this, char fill)
1329 char prev = this->fill;
1331 TRACE("(%p %d)\n", this, fill);
1333 this->fill = fill;
1334 return prev;
1337 /* ?fill@ios@@QBEDXZ */
1338 /* ?fill@ios@@QEBADXZ */
1339 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1340 char __thiscall ios_fill_get(const ios *this)
1342 TRACE("(%p)\n", this);
1343 return this->fill;
1346 /* ?flags@ios@@QAEJJ@Z */
1347 /* ?flags@ios@@QEAAJJ@Z */
1348 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
1349 LONG __thiscall ios_flags_set(ios *this, LONG flags)
1351 LONG prev = this->flags;
1353 TRACE("(%p %x)\n", this, flags);
1355 this->flags = flags;
1356 return prev;
1359 /* ?flags@ios@@QBEJXZ */
1360 /* ?flags@ios@@QEBAJXZ */
1361 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
1362 LONG __thiscall ios_flags_get(const ios *this)
1364 TRACE("(%p)\n", this);
1365 return this->flags;
1368 /* ?good@ios@@QBEHXZ */
1369 /* ?good@ios@@QEBAHXZ */
1370 DEFINE_THISCALL_WRAPPER(ios_good, 4)
1371 int __thiscall ios_good(const ios *this)
1373 TRACE("(%p)\n", this);
1374 return this->state == IOSTATE_goodbit;
1377 /* ?hex@@YAAAVios@@AAV1@@Z */
1378 /* ?hex@@YAAEAVios@@AEAV1@@Z */
1379 ios* __cdecl ios_hex(ios *this)
1381 TRACE("(%p)\n", this);
1382 ios_setf_mask(this, FLAGS_hex, ios_basefield);
1383 return this;
1386 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
1387 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
1388 DEFINE_THISCALL_WRAPPER(ios_init, 8)
1389 void __thiscall ios_init(ios *this, streambuf *sb)
1391 TRACE("(%p %p)\n", this, sb);
1392 if (this->delbuf && this->sb)
1393 call_streambuf_vector_dtor(this->sb, 1);
1394 this->sb = sb;
1395 if (sb == NULL)
1396 this->state |= IOSTATE_badbit;
1397 else
1398 this->state &= ~IOSTATE_badbit;
1401 /* ?iword@ios@@QBEAAJH@Z */
1402 /* ?iword@ios@@QEBAAEAJH@Z */
1403 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
1404 LONG* __thiscall ios_iword(const ios *this, int index)
1406 TRACE("(%p %d)\n", this, index);
1407 return &ios_statebuf[index];
1410 /* ?lock@ios@@QAAXXZ */
1411 /* ?lock@ios@@QEAAXXZ */
1412 void __cdecl ios_lock(ios *this)
1414 TRACE("(%p)\n", this);
1415 if (this->do_lock < 0)
1416 EnterCriticalSection(&this->lock);
1419 /* ?lockbuf@ios@@QAAXXZ */
1420 /* ?lockbuf@ios@@QEAAXXZ */
1421 void __cdecl ios_lockbuf(ios *this)
1423 TRACE("(%p)\n", this);
1424 streambuf_lock(this->sb);
1427 /* ?lockc@ios@@KAXXZ */
1428 void __cdecl ios_lockc(void)
1430 TRACE("()\n");
1431 EnterCriticalSection(&ios_static_lock);
1434 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
1435 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
1436 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
1437 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
1439 TRACE("(%p)\n", this);
1440 return &this->lock;
1443 /* ?oct@@YAAAVios@@AAV1@@Z */
1444 /* ?oct@@YAAEAVios@@AEAV1@@Z */
1445 ios* __cdecl ios_oct(ios *this)
1447 TRACE("(%p)\n", this);
1448 ios_setf_mask(this, FLAGS_oct, ios_basefield);
1449 return this;
1452 /* ?precision@ios@@QAEHH@Z */
1453 /* ?precision@ios@@QEAAHH@Z */
1454 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
1455 int __thiscall ios_precision_set(ios *this, int prec)
1457 int prev = this->precision;
1459 TRACE("(%p %d)\n", this, prec);
1461 this->precision = prec;
1462 return prev;
1465 /* ?precision@ios@@QBEHXZ */
1466 /* ?precision@ios@@QEBAHXZ */
1467 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
1468 int __thiscall ios_precision_get(const ios *this)
1470 TRACE("(%p)\n", this);
1471 return this->precision;
1474 /* ?pword@ios@@QBEAAPAXH@Z */
1475 /* ?pword@ios@@QEBAAEAPEAXH@Z */
1476 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
1477 void** __thiscall ios_pword(const ios *this, int index)
1479 TRACE("(%p %d)\n", this, index);
1480 return (void**)&ios_statebuf[index];
1483 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
1484 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
1485 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
1486 streambuf* __thiscall ios_rdbuf(const ios *this)
1488 TRACE("(%p)\n", this);
1489 return this->sb;
1492 /* ?rdstate@ios@@QBEHXZ */
1493 /* ?rdstate@ios@@QEBAHXZ */
1494 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
1495 int __thiscall ios_rdstate(const ios *this)
1497 TRACE("(%p)\n", this);
1498 return this->state;
1501 /* ?setf@ios@@QAEJJ@Z */
1502 /* ?setf@ios@@QEAAJJ@Z */
1503 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
1504 LONG __thiscall ios_setf(ios *this, LONG flags)
1506 LONG prev = this->flags;
1508 TRACE("(%p %x)\n", this, flags);
1510 ios_lock(this);
1511 this->flags |= flags;
1512 ios_unlock(this);
1513 return prev;
1516 /* ?setf@ios@@QAEJJJ@Z */
1517 /* ?setf@ios@@QEAAJJJ@Z */
1518 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
1519 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
1521 LONG prev = this->flags;
1523 TRACE("(%p %x %x)\n", this, flags, mask);
1525 ios_lock(this);
1526 this->flags = (this->flags & (~mask)) | (flags & mask);
1527 ios_unlock(this);
1528 return prev;
1531 /* ?setlock@ios@@QAAXXZ */
1532 /* ?setlock@ios@@QEAAXXZ */
1533 void __cdecl ios_setlock(ios *this)
1535 TRACE("(%p)\n", this);
1536 this->do_lock--;
1537 if (this->sb)
1538 streambuf_setlock(this->sb);
1541 /* ?sync_with_stdio@ios@@SAXXZ */
1542 void __cdecl ios_sync_with_stdio(void)
1544 FIXME("() stub\n");
1547 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
1548 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
1549 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
1550 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
1552 ostream *prev = this->tie;
1554 TRACE("(%p %p)\n", this, ostr);
1556 this->tie = ostr;
1557 return prev;
1560 /* ?tie@ios@@QBEPAVostream@@XZ */
1561 /* ?tie@ios@@QEBAPEAVostream@@XZ */
1562 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
1563 ostream* __thiscall ios_tie_get(const ios *this)
1565 TRACE("(%p)\n", this);
1566 return this->tie;
1569 /* ?unlock@ios@@QAAXXZ */
1570 /* ?unlock@ios@@QEAAXXZ */
1571 void __cdecl ios_unlock(ios *this)
1573 TRACE("(%p)\n", this);
1574 if (this->do_lock < 0)
1575 LeaveCriticalSection(&this->lock);
1578 /* ?unlockbuf@ios@@QAAXXZ */
1579 /* ?unlockbuf@ios@@QEAAXXZ */
1580 void __cdecl ios_unlockbuf(ios *this)
1582 TRACE("(%p)\n", this);
1583 streambuf_unlock(this->sb);
1586 /* ?unlockc@ios@@KAXXZ */
1587 void __cdecl ios_unlockc(void)
1589 TRACE("()\n");
1590 LeaveCriticalSection(&ios_static_lock);
1593 /* ?unsetf@ios@@QAEJJ@Z */
1594 /* ?unsetf@ios@@QEAAJJ@Z */
1595 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
1596 LONG __thiscall ios_unsetf(ios *this, LONG flags)
1598 LONG prev = this->flags;
1600 TRACE("(%p %x)\n", this, flags);
1602 ios_lock(this);
1603 this->flags &= ~flags;
1604 ios_unlock(this);
1605 return prev;
1608 /* ?width@ios@@QAEHH@Z */
1609 /* ?width@ios@@QEAAHH@Z */
1610 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
1611 int __thiscall ios_width_set(ios *this, int width)
1613 int prev = this->width;
1615 TRACE("(%p %d)\n", this, width);
1617 this->width = width;
1618 return prev;
1621 /* ?width@ios@@QBEHXZ */
1622 /* ?width@ios@@QEBAHXZ */
1623 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
1624 int __thiscall ios_width_get(const ios *this)
1626 TRACE("(%p)\n", this);
1627 return this->width;
1630 /* ?xalloc@ios@@SAHXZ */
1631 int __cdecl ios_xalloc(void)
1633 int ret;
1635 TRACE("()\n");
1637 ios_lockc();
1638 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
1639 ios_unlockc();
1640 return ret;
1643 /******************************************************************
1644 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
1646 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
1647 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
1649 FIXME("(%p %x) stub\n", this, virt_init);
1650 return this;
1653 /******************************************************************
1654 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
1656 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
1657 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
1659 FIXME("(%p) stub\n", base);
1662 /******************************************************************
1663 * ??6ostream@@QAEAAV0@E@Z (MSVCRTI.@)
1664 * class ostream & __thiscall ostream::operator<<(unsigned char)
1666 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_uchar,8)
1667 void * __thiscall MSVCIRT_operator_sl_uchar(ostream * _this, unsigned char ch)
1669 FIXME("(%p)->(%c) stub\n", _this, ch);
1670 return _this;
1673 /******************************************************************
1674 * ??6ostream@@QAEAAV0@H@Z (MSVCRTI.@)
1675 * class ostream & __thiscall ostream::operator<<(int)
1677 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_int,8)
1678 void * __thiscall MSVCIRT_operator_sl_int(ostream * _this, int integer)
1680 FIXME("(%p)->(%d) stub\n", _this, integer);
1681 return _this;
1684 /******************************************************************
1685 * ??6ostream@@QAEAAV0@PBD@Z (MSVCRTI.@)
1686 * class ostream & __thiscall ostream::operator<<(char const *)
1688 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_pchar,8)
1689 void * __thiscall MSVCIRT_operator_sl_pchar(ostream * _this, const char * string)
1691 FIXME("(%p)->(%s) stub\n", _this, debugstr_a(string));
1692 return _this;
1695 /******************************************************************
1696 * ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z (MSVCRTI.@)
1697 * class ostream & __thiscall ostream::operator<<(class ostream & (__cdecl*)(class ostream &))
1699 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_callback,8)
1700 void * __thiscall MSVCIRT_operator_sl_callback(ostream * _this, ostream * (__cdecl*func)(ostream*))
1702 TRACE("%p, %p\n", _this, func);
1703 return func(_this);
1706 /******************************************************************
1707 * ?endl@@YAAAVostream@@AAV1@@Z (MSVCRTI.@)
1708 * class ostream & __cdecl endl(class ostream &)
1710 void * CDECL MSVCIRT_endl(ostream * _this)
1712 FIXME("(%p)->() stub\n", _this);
1713 return _this;
1716 /******************************************************************
1717 * ?ends@@YAAAVostream@@AAV1@@Z (MSVCRTI.@)
1718 * class ostream & __cdecl ends(class ostream &)
1720 void * CDECL MSVCIRT_ends(ostream * _this)
1722 FIXME("(%p)->() stub\n", _this);
1723 return _this;
1726 /******************************************************************
1727 * ?str@strstreambuf@@QAEPADXZ (MSVCRTI.@)
1728 * class strstreambuf & __thiscall strstreambuf::str(class strstreambuf &)
1730 DEFINE_THISCALL_WRAPPER(MSVCIRT_str_sl_void,4)
1731 char * __thiscall MSVCIRT_str_sl_void(class_strstreambuf * _this)
1733 FIXME("(%p)->() stub\n", _this);
1734 return 0;
1737 #ifdef __i386__
1739 #define DEFINE_VTBL_WRAPPER(off) \
1740 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
1741 "popl %eax\n\t" \
1742 "popl %ecx\n\t" \
1743 "pushl %eax\n\t" \
1744 "movl 0(%ecx), %eax\n\t" \
1745 "jmp *" #off "(%eax)\n\t")
1747 DEFINE_VTBL_WRAPPER(0);
1748 DEFINE_VTBL_WRAPPER(4);
1749 DEFINE_VTBL_WRAPPER(8);
1750 DEFINE_VTBL_WRAPPER(12);
1751 DEFINE_VTBL_WRAPPER(16);
1752 DEFINE_VTBL_WRAPPER(20);
1753 DEFINE_VTBL_WRAPPER(24);
1754 DEFINE_VTBL_WRAPPER(28);
1755 DEFINE_VTBL_WRAPPER(32);
1756 DEFINE_VTBL_WRAPPER(36);
1757 DEFINE_VTBL_WRAPPER(40);
1758 DEFINE_VTBL_WRAPPER(44);
1759 DEFINE_VTBL_WRAPPER(48);
1760 DEFINE_VTBL_WRAPPER(52);
1761 DEFINE_VTBL_WRAPPER(56);
1763 #endif
1765 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
1766 void (__cdecl *MSVCRT_operator_delete)(void*);
1768 static void init_cxx_funcs(void)
1770 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
1772 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
1774 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
1775 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
1777 else
1779 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
1780 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
1784 static void init_io(void *base)
1786 #ifdef __x86_64__
1787 init_streambuf_rtti(base);
1788 init_filebuf_rtti(base);
1789 init_ios_rtti(base);
1790 #endif
1793 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
1795 switch (reason)
1797 case DLL_WINE_PREATTACH:
1798 return FALSE; /* prefer native version */
1799 case DLL_PROCESS_ATTACH:
1800 init_cxx_funcs();
1801 init_exception(inst);
1802 init_io(inst);
1803 DisableThreadLibraryCalls( inst );
1804 break;
1806 return TRUE;