msvcirt: Implement ostream::operator<< for streambuf.
[wine.git] / dlls / msvcirt / msvcirt.c
blob32c1bf4ddcab7bc685c8b9d8c8b6a7464afab5f5
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 /* ??_7streambuf@@6B@ */
158 extern const vtable_ptr MSVCP_streambuf_vtable;
159 /* ??_7filebuf@@6B@ */
160 extern const vtable_ptr MSVCP_filebuf_vtable;
161 /* ??_7strstreambuf@@6B@ */
162 extern const vtable_ptr MSVCP_strstreambuf_vtable;
163 /* ??_7stdiobuf@@6B@ */
164 extern const vtable_ptr MSVCP_stdiobuf_vtable;
165 /* ??_7ios@@6B@ */
166 extern const vtable_ptr MSVCP_ios_vtable;
167 /* ??_7ostream@@6B@ */
168 extern const vtable_ptr MSVCP_ostream_vtable;
170 #ifndef __GNUC__
171 void __asm_dummy_vtables(void) {
172 #endif
173 __ASM_VTABLE(streambuf,
174 VTABLE_ADD_FUNC(streambuf_vector_dtor)
175 VTABLE_ADD_FUNC(streambuf_sync)
176 VTABLE_ADD_FUNC(streambuf_setbuf)
177 VTABLE_ADD_FUNC(streambuf_seekoff)
178 VTABLE_ADD_FUNC(streambuf_seekpos)
179 VTABLE_ADD_FUNC(streambuf_xsputn)
180 VTABLE_ADD_FUNC(streambuf_xsgetn)
181 VTABLE_ADD_FUNC(streambuf_overflow)
182 VTABLE_ADD_FUNC(streambuf_underflow)
183 VTABLE_ADD_FUNC(streambuf_pbackfail)
184 VTABLE_ADD_FUNC(streambuf_doallocate));
185 __ASM_VTABLE(filebuf,
186 VTABLE_ADD_FUNC(filebuf_vector_dtor)
187 VTABLE_ADD_FUNC(filebuf_sync)
188 VTABLE_ADD_FUNC(filebuf_setbuf)
189 VTABLE_ADD_FUNC(filebuf_seekoff)
190 VTABLE_ADD_FUNC(streambuf_seekpos)
191 VTABLE_ADD_FUNC(streambuf_xsputn)
192 VTABLE_ADD_FUNC(streambuf_xsgetn)
193 VTABLE_ADD_FUNC(filebuf_overflow)
194 VTABLE_ADD_FUNC(filebuf_underflow)
195 VTABLE_ADD_FUNC(streambuf_pbackfail)
196 VTABLE_ADD_FUNC(streambuf_doallocate));
197 __ASM_VTABLE(strstreambuf,
198 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
199 VTABLE_ADD_FUNC(strstreambuf_sync)
200 VTABLE_ADD_FUNC(strstreambuf_setbuf)
201 VTABLE_ADD_FUNC(strstreambuf_seekoff)
202 VTABLE_ADD_FUNC(streambuf_seekpos)
203 VTABLE_ADD_FUNC(streambuf_xsputn)
204 VTABLE_ADD_FUNC(streambuf_xsgetn)
205 VTABLE_ADD_FUNC(strstreambuf_overflow)
206 VTABLE_ADD_FUNC(strstreambuf_underflow)
207 VTABLE_ADD_FUNC(streambuf_pbackfail)
208 VTABLE_ADD_FUNC(strstreambuf_doallocate));
209 __ASM_VTABLE(stdiobuf,
210 VTABLE_ADD_FUNC(stdiobuf_vector_dtor)
211 VTABLE_ADD_FUNC(stdiobuf_sync)
212 VTABLE_ADD_FUNC(streambuf_setbuf)
213 VTABLE_ADD_FUNC(stdiobuf_seekoff)
214 VTABLE_ADD_FUNC(streambuf_seekpos)
215 VTABLE_ADD_FUNC(streambuf_xsputn)
216 VTABLE_ADD_FUNC(streambuf_xsgetn)
217 VTABLE_ADD_FUNC(stdiobuf_overflow)
218 VTABLE_ADD_FUNC(stdiobuf_underflow)
219 VTABLE_ADD_FUNC(stdiobuf_pbackfail)
220 VTABLE_ADD_FUNC(streambuf_doallocate));
221 __ASM_VTABLE(ios,
222 VTABLE_ADD_FUNC(ios_vector_dtor));
223 __ASM_VTABLE(ostream,
224 VTABLE_ADD_FUNC(ostream_vector_dtor));
225 #ifndef __GNUC__
227 #endif
229 #define ALIGNED_SIZE(size, alignment) (((size)+((alignment)-1))/(alignment)*(alignment))
230 #define VBTABLE_ENTRY(class, offset, vbase) ALIGNED_SIZE(sizeof(class), TYPE_ALIGNMENT(vbase))-offset
232 /* ??_8ostream@@7B@ */
233 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
235 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
236 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
237 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
238 DEFINE_RTTI_DATA1(stdiobuf, 0, &streambuf_rtti_base_descriptor, ".?AVstdiobuf@@")
239 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
240 DEFINE_RTTI_DATA1(ostream, sizeof(ostream), &ios_rtti_base_descriptor, ".?AVostream@@")
242 /* ??0streambuf@@IAE@PADH@Z */
243 /* ??0streambuf@@IEAA@PEADH@Z */
244 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
245 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
247 TRACE("(%p %p %d)\n", this, buffer, length);
248 this->vtable = &MSVCP_streambuf_vtable;
249 this->allocated = 0;
250 this->stored_char = EOF;
251 this->do_lock = -1;
252 this->base = NULL;
253 streambuf_setbuf(this, buffer, length);
254 streambuf_setg(this, NULL, NULL, NULL);
255 streambuf_setp(this, NULL, NULL);
256 InitializeCriticalSection(&this->lock);
257 return this;
260 /* ??0streambuf@@IAE@XZ */
261 /* ??0streambuf@@IEAA@XZ */
262 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
263 streambuf* __thiscall streambuf_ctor(streambuf *this)
265 streambuf_reserve_ctor(this, NULL, 0);
266 this->unbuffered = 0;
267 return this;
270 /* ??0streambuf@@QAE@ABV0@@Z */
271 /* ??0streambuf@@QEAA@AEBV0@@Z */
272 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
273 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
275 TRACE("(%p %p)\n", this, copy);
276 *this = *copy;
277 this->vtable = &MSVCP_streambuf_vtable;
278 return this;
281 /* ??1streambuf@@UAE@XZ */
282 /* ??1streambuf@@UEAA@XZ */
283 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
284 void __thiscall streambuf_dtor(streambuf *this)
286 TRACE("(%p)\n", this);
287 if (this->allocated)
288 MSVCRT_operator_delete(this->base);
289 DeleteCriticalSection(&this->lock);
292 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
293 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
294 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
295 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
297 streambuf_dtor(this);
298 return streambuf_copy_ctor(this, rhs);
301 /* ??_Estreambuf@@UAEPAXI@Z */
302 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
303 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
304 streambuf*, (streambuf*, unsigned int), (this, flags))
305 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
307 TRACE("(%p %x)\n", this, flags);
308 if (flags & 2) {
309 /* we have an array, with the number of elements stored before the first object */
310 INT_PTR i, *ptr = (INT_PTR *)this-1;
312 for (i = *ptr-1; i >= 0; i--)
313 streambuf_dtor(this+i);
314 MSVCRT_operator_delete(ptr);
315 } else {
316 streambuf_dtor(this);
317 if (flags & 1)
318 MSVCRT_operator_delete(this);
320 return this;
323 /* ??_Gstreambuf@@UAEPAXI@Z */
324 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
325 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
327 TRACE("(%p %x)\n", this, flags);
328 streambuf_dtor(this);
329 if (flags & 1) MSVCRT_operator_delete(this);
330 return this;
333 /* ?doallocate@streambuf@@MAEHXZ */
334 /* ?doallocate@streambuf@@MEAAHXZ */
335 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
336 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
337 int __thiscall streambuf_doallocate(streambuf *this)
339 char *reserve;
341 TRACE("(%p)\n", this);
342 reserve = MSVCRT_operator_new(RESERVE_SIZE);
343 if (!reserve)
344 return EOF;
346 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
347 return 1;
350 /* ?allocate@streambuf@@IAEHXZ */
351 /* ?allocate@streambuf@@IEAAHXZ */
352 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
353 int __thiscall streambuf_allocate(streambuf *this)
355 TRACE("(%p)\n", this);
356 if (this->base != NULL || this->unbuffered)
357 return 0;
358 return call_streambuf_doallocate(this);
361 /* ?base@streambuf@@IBEPADXZ */
362 /* ?base@streambuf@@IEBAPEADXZ */
363 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
364 char* __thiscall streambuf_base(const streambuf *this)
366 TRACE("(%p)\n", this);
367 return this->base;
370 /* ?blen@streambuf@@IBEHXZ */
371 /* ?blen@streambuf@@IEBAHXZ */
372 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
373 int __thiscall streambuf_blen(const streambuf *this)
375 TRACE("(%p)\n", this);
376 return this->ebuf - this->base;
379 /* ?eback@streambuf@@IBEPADXZ */
380 /* ?eback@streambuf@@IEBAPEADXZ */
381 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
382 char* __thiscall streambuf_eback(const streambuf *this)
384 TRACE("(%p)\n", this);
385 return this->eback;
388 /* ?ebuf@streambuf@@IBEPADXZ */
389 /* ?ebuf@streambuf@@IEBAPEADXZ */
390 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
391 char* __thiscall streambuf_ebuf(const streambuf *this)
393 TRACE("(%p)\n", this);
394 return this->ebuf;
397 /* ?egptr@streambuf@@IBEPADXZ */
398 /* ?egptr@streambuf@@IEBAPEADXZ */
399 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
400 char* __thiscall streambuf_egptr(const streambuf *this)
402 TRACE("(%p)\n", this);
403 return this->egptr;
406 /* ?epptr@streambuf@@IBEPADXZ */
407 /* ?epptr@streambuf@@IEBAPEADXZ */
408 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
409 char* __thiscall streambuf_epptr(const streambuf *this)
411 TRACE("(%p)\n", this);
412 return this->epptr;
415 /* ?gptr@streambuf@@IBEPADXZ */
416 /* ?gptr@streambuf@@IEBAPEADXZ */
417 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
418 char* __thiscall streambuf_gptr(const streambuf *this)
420 TRACE("(%p)\n", this);
421 return this->gptr;
424 /* ?pbase@streambuf@@IBEPADXZ */
425 /* ?pbase@streambuf@@IEBAPEADXZ */
426 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
427 char* __thiscall streambuf_pbase(const streambuf *this)
429 TRACE("(%p)\n", this);
430 return this->pbase;
433 /* ?pptr@streambuf@@IBEPADXZ */
434 /* ?pptr@streambuf@@IEBAPEADXZ */
435 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
436 char* __thiscall streambuf_pptr(const streambuf *this)
438 TRACE("(%p)\n", this);
439 return this->pptr;
442 /* ?clrlock@streambuf@@QAEXXZ */
443 /* ?clrlock@streambuf@@QEAAXXZ */
444 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
445 void __thiscall streambuf_clrlock(streambuf *this)
447 TRACE("(%p)\n", this);
448 if (this->do_lock <= 0)
449 this->do_lock++;
452 /* ?lock@streambuf@@QAEXXZ */
453 /* ?lock@streambuf@@QEAAXXZ */
454 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
455 void __thiscall streambuf_lock(streambuf *this)
457 TRACE("(%p)\n", this);
458 if (this->do_lock < 0)
459 EnterCriticalSection(&this->lock);
462 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
463 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
464 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
465 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
467 TRACE("(%p)\n", this);
468 return &this->lock;
471 /* ?gbump@streambuf@@IAEXH@Z */
472 /* ?gbump@streambuf@@IEAAXH@Z */
473 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
474 void __thiscall streambuf_gbump(streambuf *this, int count)
476 TRACE("(%p %d)\n", this, count);
477 this->gptr += count;
480 /* ?pbump@streambuf@@IAEXH@Z */
481 /* ?pbump@streambuf@@IEAAXH@Z */
482 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
483 void __thiscall streambuf_pbump(streambuf *this, int count)
485 TRACE("(%p %d)\n", this, count);
486 this->pptr += count;
489 /* ?in_avail@streambuf@@QBEHXZ */
490 /* ?in_avail@streambuf@@QEBAHXZ */
491 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
492 int __thiscall streambuf_in_avail(const streambuf *this)
494 TRACE("(%p)\n", this);
495 return this->egptr - this->gptr;
498 /* ?out_waiting@streambuf@@QBEHXZ */
499 /* ?out_waiting@streambuf@@QEBAHXZ */
500 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
501 int __thiscall streambuf_out_waiting(const streambuf *this)
503 TRACE("(%p)\n", this);
504 return this->pptr - this->pbase;
507 /* Unexported */
508 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
509 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
510 int __thiscall streambuf_overflow(streambuf *this, int c)
512 ERR("overflow is not implemented in streambuf\n");
513 return EOF;
516 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
517 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
518 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
519 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
520 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
522 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
523 return EOF;
526 /* ?seekpos@streambuf@@UAEJJH@Z */
527 /* ?seekpos@streambuf@@UEAAJJH@Z */
528 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
529 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
531 TRACE("(%p %d %d)\n", this, pos, mode);
532 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
535 /* ?pbackfail@streambuf@@UAEHH@Z */
536 /* ?pbackfail@streambuf@@UEAAHH@Z */
537 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
538 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
539 int __thiscall streambuf_pbackfail(streambuf *this, int c)
541 TRACE("(%p %d)\n", this, c);
542 if (this->gptr > this->eback)
543 return *--this->gptr = c;
544 if (call_streambuf_seekoff(this, -1, SEEKDIR_cur, OPENMODE_in) == EOF)
545 return EOF;
546 if (!this->unbuffered && this->egptr) {
547 /* 'c' should be the next character read */
548 memmove(this->gptr + 1, this->gptr, this->egptr - this->gptr - 1);
549 *this->gptr = c;
551 return c;
554 /* ?setb@streambuf@@IAEXPAD0H@Z */
555 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
556 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
557 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
559 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
560 if (this->allocated)
561 MSVCRT_operator_delete(this->base);
562 this->allocated = delete;
563 this->base = ba;
564 this->ebuf = eb;
567 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
568 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
569 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
570 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
572 TRACE("(%p %p %d)\n", this, buffer, length);
573 if (this->base != NULL)
574 return NULL;
576 if (buffer == NULL || !length) {
577 this->unbuffered = 1;
578 this->base = this->ebuf = NULL;
579 } else {
580 this->unbuffered = 0;
581 this->base = buffer;
582 this->ebuf = buffer + length;
584 return this;
587 /* ?setg@streambuf@@IAEXPAD00@Z */
588 /* ?setg@streambuf@@IEAAXPEAD00@Z */
589 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
590 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
592 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
593 this->eback = ek;
594 this->gptr = gp;
595 this->egptr = eg;
598 /* ?setlock@streambuf@@QAEXXZ */
599 /* ?setlock@streambuf@@QEAAXXZ */
600 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
601 void __thiscall streambuf_setlock(streambuf *this)
603 TRACE("(%p)\n", this);
604 this->do_lock--;
607 /* ?setp@streambuf@@IAEXPAD0@Z */
608 /* ?setp@streambuf@@IEAAXPEAD0@Z */
609 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
610 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
612 TRACE("(%p %p %p)\n", this, pb, ep);
613 this->pbase = this->pptr = pb;
614 this->epptr = ep;
617 /* ?sync@streambuf@@UAEHXZ */
618 /* ?sync@streambuf@@UEAAHXZ */
619 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
620 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
621 int __thiscall streambuf_sync(streambuf *this)
623 TRACE("(%p)\n", this);
624 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
627 /* ?unbuffered@streambuf@@IAEXH@Z */
628 /* ?unbuffered@streambuf@@IEAAXH@Z */
629 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
630 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
632 TRACE("(%p %d)\n", this, buf);
633 this->unbuffered = buf;
636 /* ?unbuffered@streambuf@@IBEHXZ */
637 /* ?unbuffered@streambuf@@IEBAHXZ */
638 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
639 int __thiscall streambuf_unbuffered_get(const streambuf *this)
641 TRACE("(%p)\n", this);
642 return this->unbuffered;
645 /* Unexported */
646 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
647 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
648 int __thiscall streambuf_underflow(streambuf *this)
650 ERR("underflow is not implemented in streambuf\n");
651 return EOF;
654 /* ?unlock@streambuf@@QAEXXZ */
655 /* ?unlock@streambuf@@QEAAXXZ */
656 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
657 void __thiscall streambuf_unlock(streambuf *this)
659 TRACE("(%p)\n", this);
660 if (this->do_lock < 0)
661 LeaveCriticalSection(&this->lock);
664 /* ?xsgetn@streambuf@@UAEHPADH@Z */
665 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
666 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
667 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
668 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
670 int copied = 0, chunk;
672 TRACE("(%p %p %d)\n", this, buffer, count);
674 if (this->unbuffered) {
675 if (this->stored_char == EOF)
676 this->stored_char = call_streambuf_underflow(this);
677 while (copied < count && this->stored_char != EOF) {
678 buffer[copied++] = this->stored_char;
679 this->stored_char = call_streambuf_underflow(this);
681 } else {
682 while (copied < count) {
683 if (call_streambuf_underflow(this) == EOF)
684 break;
685 chunk = this->egptr - this->gptr;
686 if (chunk > count - copied)
687 chunk = count - copied;
688 memcpy(buffer+copied, this->gptr, chunk);
689 this->gptr += chunk;
690 copied += chunk;
693 return copied;
696 /* ?xsputn@streambuf@@UAEHPBDH@Z */
697 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
698 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
699 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
700 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
702 int copied = 0, chunk;
704 TRACE("(%p %p %d)\n", this, data, length);
706 while (copied < length) {
707 if (this->unbuffered || this->pptr == this->epptr) {
708 if (call_streambuf_overflow(this, data[copied]) == EOF)
709 break;
710 copied++;
711 } else {
712 chunk = this->epptr - this->pptr;
713 if (chunk > length - copied)
714 chunk = length - copied;
715 memcpy(this->pptr, data+copied, chunk);
716 this->pptr += chunk;
717 copied += chunk;
720 return copied;
723 /* ?sgetc@streambuf@@QAEHXZ */
724 /* ?sgetc@streambuf@@QEAAHXZ */
725 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
726 int __thiscall streambuf_sgetc(streambuf *this)
728 TRACE("(%p)\n", this);
729 if (this->unbuffered) {
730 if (this->stored_char == EOF)
731 this->stored_char = call_streambuf_underflow(this);
732 return this->stored_char;
733 } else
734 return call_streambuf_underflow(this);
737 /* ?sputc@streambuf@@QAEHH@Z */
738 /* ?sputc@streambuf@@QEAAHH@Z */
739 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
740 int __thiscall streambuf_sputc(streambuf *this, int ch)
742 TRACE("(%p %d)\n", this, ch);
743 return (this->pptr < this->epptr) ? *this->pptr++ = ch : call_streambuf_overflow(this, ch);
746 /* ?sgetn@streambuf@@QAEHPADH@Z */
747 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
748 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
749 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
751 return call_streambuf_xsgetn(this, buffer, count);
754 /* ?sputn@streambuf@@QAEHPBDH@Z */
755 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
756 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
757 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
759 return call_streambuf_xsputn(this, data, length);
762 /* ?snextc@streambuf@@QAEHXZ */
763 /* ?snextc@streambuf@@QEAAHXZ */
764 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
765 int __thiscall streambuf_snextc(streambuf *this)
767 TRACE("(%p)\n", this);
768 if (this->unbuffered) {
769 if (this->stored_char == EOF)
770 call_streambuf_underflow(this);
771 return this->stored_char = call_streambuf_underflow(this);
772 } else {
773 if (this->gptr >= this->egptr)
774 call_streambuf_underflow(this);
775 this->gptr++;
776 return (this->gptr < this->egptr) ? *this->gptr : call_streambuf_underflow(this);
780 /* ?sbumpc@streambuf@@QAEHXZ */
781 /* ?sbumpc@streambuf@@QEAAHXZ */
782 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
783 int __thiscall streambuf_sbumpc(streambuf *this)
785 int ret;
787 TRACE("(%p)\n", this);
789 if (this->unbuffered) {
790 ret = this->stored_char;
791 this->stored_char = EOF;
792 if (ret == EOF)
793 ret = call_streambuf_underflow(this);
794 } else {
795 ret = (this->gptr < this->egptr) ? *this->gptr : call_streambuf_underflow(this);
796 this->gptr++;
798 return ret;
801 /* ?stossc@streambuf@@QAEXXZ */
802 /* ?stossc@streambuf@@QEAAXXZ */
803 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
804 void __thiscall streambuf_stossc(streambuf *this)
806 TRACE("(%p)\n", this);
807 if (this->unbuffered) {
808 if (this->stored_char == EOF)
809 call_streambuf_underflow(this);
810 else
811 this->stored_char = EOF;
812 } else {
813 if (this->gptr >= this->egptr)
814 call_streambuf_underflow(this);
815 if (this->gptr < this->egptr)
816 this->gptr++;
820 /* ?sputbackc@streambuf@@QAEHD@Z */
821 /* ?sputbackc@streambuf@@QEAAHD@Z */
822 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
823 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
825 TRACE("(%p %d)\n", this, ch);
826 return call_streambuf_pbackfail(this, ch);
829 /* ?dbp@streambuf@@QAEXXZ */
830 /* ?dbp@streambuf@@QEAAXXZ */
831 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
832 void __thiscall streambuf_dbp(streambuf *this)
834 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
835 if (this->unbuffered) {
836 printf("unbuffered\n");
837 } else {
838 printf("_fAlloc=%d\n", this->allocated);
839 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
840 printf("pbase()=%p, pptr()=%p, epptr()=%p\n", this->pbase, this->pptr, this->epptr);
841 printf("eback()=%p, gptr()=%p, egptr()=%p\n", this->eback, this->gptr, this->egptr);
845 /* ??0filebuf@@QAE@ABV0@@Z */
846 /* ??0filebuf@@QEAA@AEBV0@@Z */
847 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
848 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
850 TRACE("(%p %p)\n", this, copy);
851 *this = *copy;
852 this->base.vtable = &MSVCP_filebuf_vtable;
853 return this;
856 /* ??0filebuf@@QAE@HPADH@Z */
857 /* ??0filebuf@@QEAA@HPEADH@Z */
858 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
859 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
861 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
862 streambuf_reserve_ctor(&this->base, buffer, length);
863 this->base.vtable = &MSVCP_filebuf_vtable;
864 this->fd = fd;
865 this->close = 0;
866 return this;
869 /* ??0filebuf@@QAE@H@Z */
870 /* ??0filebuf@@QEAA@H@Z */
871 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
872 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
874 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
875 this->base.unbuffered = 0;
876 return this;
879 /* ??0filebuf@@QAE@XZ */
880 /* ??0filebuf@@QEAA@XZ */
881 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
882 filebuf* __thiscall filebuf_ctor(filebuf* this)
884 return filebuf_fd_ctor(this, -1);
887 /* ??1filebuf@@UAE@XZ */
888 /* ??1filebuf@@UEAA@XZ */
889 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
890 void __thiscall filebuf_dtor(filebuf* this)
892 TRACE("(%p)\n", this);
893 if (this->close)
894 filebuf_close(this);
895 streambuf_dtor(&this->base);
898 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
899 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
900 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
901 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
903 filebuf_dtor(this);
904 return filebuf_copy_ctor(this, rhs);
907 /* ??_Efilebuf@@UAEPAXI@Z */
908 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
909 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
911 TRACE("(%p %x)\n", this, flags);
912 if (flags & 2) {
913 /* we have an array, with the number of elements stored before the first object */
914 INT_PTR i, *ptr = (INT_PTR *)this-1;
916 for (i = *ptr-1; i >= 0; i--)
917 filebuf_dtor(this+i);
918 MSVCRT_operator_delete(ptr);
919 } else {
920 filebuf_dtor(this);
921 if (flags & 1)
922 MSVCRT_operator_delete(this);
924 return this;
927 /* ??_Gfilebuf@@UAEPAXI@Z */
928 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
929 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
931 TRACE("(%p %x)\n", this, flags);
932 filebuf_dtor(this);
933 if (flags & 1) MSVCRT_operator_delete(this);
934 return this;
937 /* ?attach@filebuf@@QAEPAV1@H@Z */
938 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
939 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
940 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
942 TRACE("(%p %d)\n", this, fd);
943 if (this->fd != -1)
944 return NULL;
946 streambuf_lock(&this->base);
947 this->fd = fd;
948 streambuf_allocate(&this->base);
949 streambuf_unlock(&this->base);
950 return this;
953 /* ?close@filebuf@@QAEPAV1@XZ */
954 /* ?close@filebuf@@QEAAPEAV1@XZ */
955 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
956 filebuf* __thiscall filebuf_close(filebuf *this)
958 filebuf *ret;
960 TRACE("(%p)\n", this);
961 if (this->fd == -1)
962 return NULL;
964 streambuf_lock(&this->base);
965 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
966 ret = NULL;
967 } else {
968 this->fd = -1;
969 ret = this;
971 streambuf_unlock(&this->base);
972 return ret;
975 /* ?fd@filebuf@@QBEHXZ */
976 /* ?fd@filebuf@@QEBAHXZ */
977 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
978 filedesc __thiscall filebuf_fd(const filebuf *this)
980 TRACE("(%p)\n", this);
981 return this->fd;
984 /* ?is_open@filebuf@@QBEHXZ */
985 /* ?is_open@filebuf@@QEBAHXZ */
986 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
987 int __thiscall filebuf_is_open(const filebuf *this)
989 TRACE("(%p)\n", this);
990 return this->fd != -1;
993 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
994 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
995 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
996 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
998 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
999 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
1000 int op_flags, sh_flags, fd;
1002 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
1003 if (this->fd != -1)
1004 return NULL;
1006 /* mode */
1007 if (mode & (OPENMODE_app|OPENMODE_trunc))
1008 mode |= OPENMODE_out;
1009 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
1010 if (op_flags < 0)
1011 return NULL;
1012 if (mode & OPENMODE_app)
1013 op_flags |= _O_APPEND;
1014 if ((mode & OPENMODE_trunc) ||
1015 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
1016 op_flags |= _O_TRUNC;
1017 if (!(mode & OPENMODE_nocreate))
1018 op_flags |= _O_CREAT;
1019 if (mode & OPENMODE_noreplace)
1020 op_flags |= _O_EXCL;
1021 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
1023 /* share protection */
1024 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
1026 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
1027 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
1028 if (fd < 0)
1029 return NULL;
1031 streambuf_lock(&this->base);
1032 this->close = 1;
1033 this->fd = fd;
1034 if ((mode & OPENMODE_ate) &&
1035 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
1036 _close(fd);
1037 this->fd = -1;
1039 streambuf_allocate(&this->base);
1040 streambuf_unlock(&this->base);
1041 return (this->fd == -1) ? NULL : this;
1044 /* ?overflow@filebuf@@UAEHH@Z */
1045 /* ?overflow@filebuf@@UEAAHH@Z */
1046 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1047 int __thiscall filebuf_overflow(filebuf *this, int c)
1049 TRACE("(%p %d)\n", this, c);
1050 if (call_streambuf_sync(&this->base) == EOF)
1051 return EOF;
1052 if (this->base.unbuffered)
1053 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1054 if (streambuf_allocate(&this->base) == EOF)
1055 return EOF;
1057 this->base.pbase = this->base.pptr = this->base.base;
1058 this->base.epptr = this->base.ebuf;
1059 if (c != EOF)
1060 *this->base.pptr++ = c;
1061 return 1;
1064 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1065 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1066 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1067 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1069 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1070 if (call_streambuf_sync(&this->base) == EOF)
1071 return EOF;
1072 return _lseek(this->fd, offset, dir);
1075 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1076 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1077 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1078 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1080 streambuf *ret;
1082 TRACE("(%p %p %d)\n", this, buffer, length);
1083 if (this->base.base != NULL)
1084 return NULL;
1086 streambuf_lock(&this->base);
1087 ret = streambuf_setbuf(&this->base, buffer, length);
1088 streambuf_unlock(&this->base);
1089 return ret;
1092 /* ?setmode@filebuf@@QAEHH@Z */
1093 /* ?setmode@filebuf@@QEAAHH@Z */
1094 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1095 int __thiscall filebuf_setmode(filebuf *this, int mode)
1097 int ret;
1099 TRACE("(%p %d)\n", this, mode);
1100 if (mode != filebuf_text && mode != filebuf_binary)
1101 return -1;
1103 streambuf_lock(&this->base);
1104 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1105 streambuf_unlock(&this->base);
1106 return ret;
1109 /* ?sync@filebuf@@UAEHXZ */
1110 /* ?sync@filebuf@@UEAAHXZ */
1111 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1112 int __thiscall filebuf_sync(filebuf *this)
1114 int count, mode;
1115 char *ptr;
1116 LONG offset;
1118 TRACE("(%p)\n", this);
1119 if (this->fd == -1)
1120 return EOF;
1121 if (this->base.unbuffered)
1122 return 0;
1124 /* flush output buffer */
1125 if (this->base.pptr != NULL) {
1126 count = this->base.pptr - this->base.pbase;
1127 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1128 return EOF;
1129 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1131 /* flush input buffer */
1132 if (this->base.egptr != NULL) {
1133 offset = this->base.egptr - this->base.gptr;
1134 if (offset > 0) {
1135 mode = _setmode(this->fd, _O_TEXT);
1136 _setmode(this->fd, mode);
1137 if (mode & _O_TEXT) {
1138 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1139 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1140 if (*ptr == '\n')
1141 offset++;
1143 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1144 return EOF;
1146 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1148 return 0;
1151 /* ?underflow@filebuf@@UAEHXZ */
1152 /* ?underflow@filebuf@@UEAAHXZ */
1153 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1154 int __thiscall filebuf_underflow(filebuf *this)
1156 int buffer_size, read_bytes;
1157 char c;
1159 TRACE("(%p)\n", this);
1161 if (this->base.unbuffered)
1162 return (_read(this->fd, &c, 1) < 1) ? EOF : c;
1164 if (this->base.gptr >= this->base.egptr) {
1165 if (call_streambuf_sync(&this->base) == EOF)
1166 return EOF;
1167 buffer_size = this->base.ebuf - this->base.base;
1168 read_bytes = _read(this->fd, this->base.base, buffer_size);
1169 if (read_bytes <= 0)
1170 return EOF;
1171 this->base.eback = this->base.gptr = this->base.base;
1172 this->base.egptr = this->base.base + read_bytes;
1174 return *this->base.gptr;
1177 /* ??0strstreambuf@@QAE@ABV0@@Z */
1178 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1179 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1180 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1182 TRACE("(%p %p)\n", this, copy);
1183 *this = *copy;
1184 this->base.vtable = &MSVCP_strstreambuf_vtable;
1185 return this;
1188 /* ??0strstreambuf@@QAE@H@Z */
1189 /* ??0strstreambuf@@QEAA@H@Z */
1190 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1191 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1193 TRACE("(%p %d)\n", this, length);
1194 streambuf_ctor(&this->base);
1195 this->base.vtable = &MSVCP_strstreambuf_vtable;
1196 this->dynamic = 1;
1197 this->increase = length;
1198 this->constant = 0;
1199 this->f_alloc = NULL;
1200 this->f_free = NULL;
1201 return this;
1204 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1205 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1206 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1207 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1209 TRACE("(%p %p %p)\n", this, falloc, ffree);
1210 strstreambuf_dynamic_ctor(this, 1);
1211 this->f_alloc = falloc;
1212 this->f_free = ffree;
1213 return this;
1216 /* ??0strstreambuf@@QAE@PADH0@Z */
1217 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1218 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1219 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1221 char *end_buffer;
1223 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1225 if (length > 0)
1226 end_buffer = buffer + length;
1227 else if (length == 0)
1228 end_buffer = buffer + strlen(buffer);
1229 else
1230 end_buffer = (char*) -1;
1232 streambuf_ctor(&this->base);
1233 streambuf_setb(&this->base, buffer, end_buffer, 0);
1234 if (put == NULL) {
1235 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1236 } else {
1237 streambuf_setg(&this->base, buffer, buffer, put);
1238 streambuf_setp(&this->base, put, end_buffer);
1240 this->base.vtable = &MSVCP_strstreambuf_vtable;
1241 this->dynamic = 0;
1242 this->constant = 1;
1243 return this;
1246 /* ??0strstreambuf@@QAE@PAEH0@Z */
1247 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1248 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1249 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1251 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1252 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1255 /* ??0strstreambuf@@QAE@XZ */
1256 /* ??0strstreambuf@@QEAA@XZ */
1257 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1258 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1260 TRACE("(%p)\n", this);
1261 return strstreambuf_dynamic_ctor(this, 1);
1264 /* ??1strstreambuf@@UAE@XZ */
1265 /* ??1strstreambuf@@UEAA@XZ */
1266 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1267 void __thiscall strstreambuf_dtor(strstreambuf *this)
1269 TRACE("(%p)\n", this);
1270 if (this->dynamic && this->base.base) {
1271 if (this->f_free)
1272 this->f_free(this->base.base);
1273 else
1274 MSVCRT_operator_delete(this->base.base);
1276 streambuf_dtor(&this->base);
1279 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1280 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1281 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1282 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1284 strstreambuf_dtor(this);
1285 return strstreambuf_copy_ctor(this, rhs);
1288 /* ??_Estrstreambuf@@UAEPAXI@Z */
1289 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1290 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1292 TRACE("(%p %x)\n", this, flags);
1293 if (flags & 2) {
1294 /* we have an array, with the number of elements stored before the first object */
1295 INT_PTR i, *ptr = (INT_PTR *)this-1;
1297 for (i = *ptr-1; i >= 0; i--)
1298 strstreambuf_dtor(this+i);
1299 MSVCRT_operator_delete(ptr);
1300 } else {
1301 strstreambuf_dtor(this);
1302 if (flags & 1)
1303 MSVCRT_operator_delete(this);
1305 return this;
1308 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1309 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1310 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1312 TRACE("(%p %x)\n", this, flags);
1313 strstreambuf_dtor(this);
1314 if (flags & 1) MSVCRT_operator_delete(this);
1315 return this;
1318 /* ?doallocate@strstreambuf@@MAEHXZ */
1319 /* ?doallocate@strstreambuf@@MEAAHXZ */
1320 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1321 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1323 char *prev_buffer = this->base.base, *new_buffer;
1324 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1326 TRACE("(%p)\n", this);
1328 /* calculate the size of the new buffer */
1329 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1330 /* get a new buffer */
1331 if (this->f_alloc)
1332 new_buffer = this->f_alloc(new_size);
1333 else
1334 new_buffer = MSVCRT_operator_new(new_size);
1335 if (!new_buffer)
1336 return EOF;
1337 if (this->base.ebuf) {
1338 /* copy the contents and adjust the pointers */
1339 memcpy(new_buffer, this->base.base, prev_size);
1340 if (this->base.egptr) {
1341 this->base.eback += new_buffer - prev_buffer;
1342 this->base.gptr += new_buffer - prev_buffer;
1343 this->base.egptr += new_buffer - prev_buffer;
1345 if (this->base.epptr) {
1346 this->base.pbase += new_buffer - prev_buffer;
1347 this->base.pptr += new_buffer - prev_buffer;
1348 this->base.epptr += new_buffer - prev_buffer;
1350 /* free the old buffer */
1351 if (this->f_free)
1352 this->f_free(this->base.base);
1353 else
1354 MSVCRT_operator_delete(this->base.base);
1356 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1357 return 1;
1360 /* ?freeze@strstreambuf@@QAEXH@Z */
1361 /* ?freeze@strstreambuf@@QEAAXH@Z */
1362 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1363 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1365 TRACE("(%p %d)\n", this, frozen);
1366 if (!this->constant)
1367 this->dynamic = !frozen;
1370 /* ?overflow@strstreambuf@@UAEHH@Z */
1371 /* ?overflow@strstreambuf@@UEAAHH@Z */
1372 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1373 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1375 TRACE("(%p %d)\n", this, c);
1376 if (this->base.pptr >= this->base.epptr) {
1377 /* increase the buffer size if it's dynamic */
1378 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1379 return EOF;
1380 if (!this->base.epptr)
1381 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1382 this->base.epptr = this->base.ebuf;
1384 if (c != EOF)
1385 *this->base.pptr++ = c;
1386 return 1;
1389 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1390 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1391 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1392 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1394 char *base[3];
1396 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1398 if ((unsigned int)dir > SEEKDIR_end || !(mode & (OPENMODE_in|OPENMODE_out)))
1399 return EOF;
1400 /* read buffer */
1401 if (mode & OPENMODE_in) {
1402 call_streambuf_underflow(&this->base);
1403 base[SEEKDIR_beg] = this->base.eback;
1404 base[SEEKDIR_cur] = this->base.gptr;
1405 base[SEEKDIR_end] = this->base.egptr;
1406 if (base[dir] + offset < this->base.eback || base[dir] + offset > this->base.egptr)
1407 return EOF;
1408 this->base.gptr = base[dir] + offset;
1410 /* write buffer */
1411 if (mode & OPENMODE_out) {
1412 if (!this->base.epptr && call_streambuf_overflow(&this->base, EOF) == EOF)
1413 return EOF;
1414 base[SEEKDIR_beg] = this->base.pbase;
1415 base[SEEKDIR_cur] = this->base.pptr;
1416 base[SEEKDIR_end] = this->base.epptr;
1417 if (base[dir] + offset < this->base.pbase)
1418 return EOF;
1419 if (base[dir] + offset > this->base.epptr) {
1420 /* make room if the buffer is dynamic */
1421 if (!this->dynamic)
1422 return EOF;
1423 this->increase = offset;
1424 if (call_streambuf_doallocate(&this->base) == EOF)
1425 return EOF;
1427 this->base.pptr = base[dir] + offset;
1428 return this->base.pptr - base[SEEKDIR_beg];
1430 return this->base.gptr - base[SEEKDIR_beg];
1433 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1434 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1435 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1436 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1438 TRACE("(%p %p %d)\n", this, buffer, length);
1439 if (length)
1440 this->increase = length;
1441 return &this->base;
1444 /* ?str@strstreambuf@@QAEPADXZ */
1445 /* ?str@strstreambuf@@QEAAPEADXZ */
1446 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1447 char* __thiscall strstreambuf_str(strstreambuf *this)
1449 TRACE("(%p)\n", this);
1450 strstreambuf_freeze(this, 1);
1451 return this->base.base;
1454 /* ?sync@strstreambuf@@UAEHXZ */
1455 /* ?sync@strstreambuf@@UEAAHXZ */
1456 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1457 int __thiscall strstreambuf_sync(strstreambuf *this)
1459 TRACE("(%p)\n", this);
1460 return 0;
1463 /* ?underflow@strstreambuf@@UAEHXZ */
1464 /* ?underflow@strstreambuf@@UEAAHXZ */
1465 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1466 int __thiscall strstreambuf_underflow(strstreambuf *this)
1468 TRACE("(%p)\n", this);
1469 if (this->base.gptr < this->base.egptr)
1470 return *this->base.gptr;
1471 /* extend the get area to include the characters written */
1472 if (this->base.egptr < this->base.pptr) {
1473 this->base.gptr = this->base.base + (this->base.gptr - this->base.eback);
1474 this->base.eback = this->base.base;
1475 this->base.egptr = this->base.pptr;
1477 return (this->base.gptr < this->base.egptr) ? *this->base.gptr : EOF;
1480 /* ??0stdiobuf@@QAE@ABV0@@Z */
1481 /* ??0stdiobuf@@QEAA@AEBV0@@Z */
1482 DEFINE_THISCALL_WRAPPER(stdiobuf_copy_ctor, 8)
1483 stdiobuf* __thiscall stdiobuf_copy_ctor(stdiobuf *this, const stdiobuf *copy)
1485 TRACE("(%p %p)\n", this, copy);
1486 *this = *copy;
1487 this->base.vtable = &MSVCP_stdiobuf_vtable;
1488 return this;
1491 /* ??0stdiobuf@@QAE@PAU_iobuf@@@Z */
1492 /* ??0stdiobuf@@QEAA@PEAU_iobuf@@@Z */
1493 DEFINE_THISCALL_WRAPPER(stdiobuf_file_ctor, 8)
1494 stdiobuf* __thiscall stdiobuf_file_ctor(stdiobuf *this, FILE *file)
1496 TRACE("(%p %p)\n", this, file);
1497 streambuf_reserve_ctor(&this->base, NULL, 0);
1498 this->base.vtable = &MSVCP_stdiobuf_vtable;
1499 this->file = file;
1500 return this;
1503 /* ??1stdiobuf@@UAE@XZ */
1504 /* ??1stdiobuf@@UEAA@XZ */
1505 DEFINE_THISCALL_WRAPPER(stdiobuf_dtor, 4)
1506 void __thiscall stdiobuf_dtor(stdiobuf *this)
1508 TRACE("(%p)\n", this);
1509 call_streambuf_sync(&this->base);
1510 streambuf_dtor(&this->base);
1513 /* ??4stdiobuf@@QAEAAV0@ABV0@@Z */
1514 /* ??4stdiobuf@@QEAAAEAV0@AEBV0@@Z */
1515 DEFINE_THISCALL_WRAPPER(stdiobuf_assign, 8)
1516 stdiobuf* __thiscall stdiobuf_assign(stdiobuf *this, const stdiobuf *rhs)
1518 stdiobuf_dtor(this);
1519 return stdiobuf_copy_ctor(this, rhs);
1522 /* ??_Estdiobuf@@UAEPAXI@Z */
1523 DEFINE_THISCALL_WRAPPER(stdiobuf_vector_dtor, 8)
1524 stdiobuf* __thiscall stdiobuf_vector_dtor(stdiobuf *this, unsigned int flags)
1526 TRACE("(%p %x)\n", this, flags);
1527 if (flags & 2) {
1528 /* we have an array, with the number of elements stored before the first object */
1529 INT_PTR i, *ptr = (INT_PTR *)this-1;
1531 for (i = *ptr-1; i >= 0; i--)
1532 stdiobuf_dtor(this+i);
1533 MSVCRT_operator_delete(ptr);
1534 } else {
1535 stdiobuf_dtor(this);
1536 if (flags & 1)
1537 MSVCRT_operator_delete(this);
1539 return this;
1542 /* ??_Gstdiobuf@@UAEPAXI@Z */
1543 DEFINE_THISCALL_WRAPPER(stdiobuf_scalar_dtor, 8)
1544 stdiobuf* __thiscall stdiobuf_scalar_dtor(stdiobuf *this, unsigned int flags)
1546 TRACE("(%p %x)\n", this, flags);
1547 stdiobuf_dtor(this);
1548 if (flags & 1) MSVCRT_operator_delete(this);
1549 return this;
1552 /* ?overflow@stdiobuf@@UAEHH@Z */
1553 /* ?overflow@stdiobuf@@UEAAHH@Z */
1554 DEFINE_THISCALL_WRAPPER(stdiobuf_overflow, 8)
1555 int __thiscall stdiobuf_overflow(stdiobuf *this, int c)
1557 TRACE("(%p %d)\n", this, c);
1558 if (this->base.unbuffered)
1559 return (c == EOF) ? 1 : fputc(c, this->file);
1560 if (streambuf_allocate(&this->base) == EOF)
1561 return EOF;
1563 if (!this->base.epptr) {
1564 /* set the put area to the second half of the buffer */
1565 streambuf_setp(&this->base,
1566 this->base.base + (this->base.ebuf - this->base.base) / 2, this->base.ebuf);
1567 } else if (this->base.pptr > this->base.pbase) {
1568 /* flush the put area */
1569 int count = this->base.pptr - this->base.pbase;
1570 if (fwrite(this->base.pbase, sizeof(char), count, this->file) != count)
1571 return EOF;
1572 this->base.pptr = this->base.pbase;
1574 if (c != EOF) {
1575 if (this->base.pbase >= this->base.epptr)
1576 return fputc(c, this->file);
1577 *this->base.pptr++ = c;
1579 return 1;
1582 /* ?pbackfail@stdiobuf@@UAEHH@Z */
1583 /* ?pbackfail@stdiobuf@@UEAAHH@Z */
1584 DEFINE_THISCALL_WRAPPER(stdiobuf_pbackfail, 8)
1585 int __thiscall stdiobuf_pbackfail(stdiobuf *this, int c)
1587 TRACE("(%p %d)\n", this, c);
1588 return streambuf_pbackfail(&this->base, c);
1591 /* ?seekoff@stdiobuf@@UAEJJW4seek_dir@ios@@H@Z */
1592 /* ?seekoff@stdiobuf@@UEAAJJW4seek_dir@ios@@H@Z */
1593 DEFINE_THISCALL_WRAPPER(stdiobuf_seekoff, 16)
1594 streampos __thiscall stdiobuf_seekoff(stdiobuf *this, streamoff offset, ios_seek_dir dir, int mode)
1596 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1597 call_streambuf_overflow(&this->base, EOF);
1598 if (fseek(this->file, offset, dir))
1599 return EOF;
1600 return ftell(this->file);
1603 /* ?setrwbuf@stdiobuf@@QAEHHH@Z */
1604 /* ?setrwbuf@stdiobuf@@QEAAHHH@Z */
1605 DEFINE_THISCALL_WRAPPER(stdiobuf_setrwbuf, 12)
1606 int __thiscall stdiobuf_setrwbuf(stdiobuf *this, int read_size, int write_size)
1608 char *reserve;
1609 int buffer_size = read_size + write_size;
1611 TRACE("(%p %d %d)\n", this, read_size, write_size);
1612 if (read_size < 0 || write_size < 0)
1613 return 0;
1614 if (!buffer_size) {
1615 this->base.unbuffered = 1;
1616 return 0;
1618 /* get a new buffer */
1619 reserve = MSVCRT_operator_new(buffer_size);
1620 if (!reserve)
1621 return 0;
1622 streambuf_setb(&this->base, reserve, reserve + buffer_size, 1);
1623 this->base.unbuffered = 0;
1624 /* set the get/put areas */
1625 if (read_size > 0)
1626 streambuf_setg(&this->base, reserve, reserve + read_size, reserve + read_size);
1627 else
1628 streambuf_setg(&this->base, NULL, NULL, NULL);
1629 if (write_size > 0)
1630 streambuf_setp(&this->base, reserve + read_size, reserve + buffer_size);
1631 else
1632 streambuf_setp(&this->base, NULL, NULL);
1633 return 1;
1636 /* ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ */
1637 /* ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ */
1638 DEFINE_THISCALL_WRAPPER(stdiobuf_stdiofile, 4)
1639 FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
1641 TRACE("(%p)\n", this);
1642 return this->file;
1645 /* ?sync@stdiobuf@@UAEHXZ */
1646 /* ?sync@stdiobuf@@UEAAHXZ */
1647 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
1648 int __thiscall stdiobuf_sync(stdiobuf *this)
1650 TRACE("(%p)\n", this);
1651 if (this->base.unbuffered)
1652 return 0;
1653 /* flush the put area */
1654 if (call_streambuf_overflow(&this->base, EOF) == EOF)
1655 return EOF;
1656 /* flush the get area */
1657 if (this->base.gptr < this->base.egptr) {
1658 char *ptr;
1659 int fd, mode, offset = this->base.egptr - this->base.gptr;
1660 if ((fd = fileno(this->file)) < 0)
1661 return EOF;
1662 mode = _setmode(fd, _O_TEXT);
1663 _setmode(fd, mode);
1664 if (mode & _O_TEXT) {
1665 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1666 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1667 if (*ptr == '\n')
1668 offset++;
1670 if (fseek(this->file, -offset, SEEK_CUR))
1671 return EOF;
1672 this->base.gptr = this->base.egptr;
1674 return 0;
1677 /* ?underflow@stdiobuf@@UAEHXZ */
1678 /* ?underflow@stdiobuf@@UEAAHXZ */
1679 DEFINE_THISCALL_WRAPPER(stdiobuf_underflow, 4)
1680 int __thiscall stdiobuf_underflow(stdiobuf *this)
1682 TRACE("(%p)\n", this);
1683 if (!this->file)
1684 return EOF;
1685 if (this->base.unbuffered)
1686 return fgetc(this->file);
1687 if (streambuf_allocate(&this->base) == EOF)
1688 return EOF;
1690 if (!this->base.egptr) {
1691 /* set the get area to the first half of the buffer */
1692 char *middle = this->base.base + (this->base.ebuf - this->base.base) / 2;
1693 streambuf_setg(&this->base, this->base.base, middle, middle);
1695 if (this->base.gptr >= this->base.egptr) {
1696 /* read characters from the file */
1697 int buffer_size = this->base.egptr - this->base.eback, read_bytes;
1698 if (!this->base.eback ||
1699 (read_bytes = fread(this->base.eback, sizeof(char), buffer_size, this->file)) <= 0)
1700 return EOF;
1701 memmove(this->base.egptr - read_bytes, this->base.eback, read_bytes);
1702 this->base.gptr = this->base.egptr - read_bytes;
1704 return *this->base.gptr++;
1707 /* ??0ios@@IAE@ABV0@@Z */
1708 /* ??0ios@@IEAA@AEBV0@@Z */
1709 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1710 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1712 TRACE("(%p %p)\n", this, copy);
1713 ios_fLockcInit++;
1714 this->vtable = &MSVCP_ios_vtable;
1715 this->sb = NULL;
1716 this->delbuf = 0;
1717 InitializeCriticalSection(&this->lock);
1718 return ios_assign(this, copy);
1721 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1722 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1723 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1724 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1726 TRACE("(%p %p)\n", this, sb);
1727 ios_fLockcInit++;
1728 this->vtable = &MSVCP_ios_vtable;
1729 this->sb = sb;
1730 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1731 this->special[0] = this->special[1] = 0;
1732 this->delbuf = 0;
1733 this->tie = NULL;
1734 this->flags = 0;
1735 this->precision = 6;
1736 this->fill = ' ';
1737 this->width = 0;
1738 this->do_lock = -1;
1739 InitializeCriticalSection(&this->lock);
1740 return this;
1743 /* ??0ios@@IAE@XZ */
1744 /* ??0ios@@IEAA@XZ */
1745 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1746 ios* __thiscall ios_ctor(ios *this)
1748 return ios_sb_ctor(this, NULL);
1751 /* ??1ios@@UAE@XZ */
1752 /* ??1ios@@UEAA@XZ */
1753 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1754 void __thiscall ios_dtor(ios *this)
1756 TRACE("(%p)\n", this);
1757 ios_fLockcInit--;
1758 if (this->delbuf && this->sb)
1759 call_streambuf_vector_dtor(this->sb, 1);
1760 this->sb = NULL;
1761 this->state = IOSTATE_badbit;
1762 DeleteCriticalSection(&this->lock);
1765 /* ??4ios@@IAEAAV0@ABV0@@Z */
1766 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1767 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1768 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1770 TRACE("(%p %p)\n", this, rhs);
1771 this->state = rhs->state;
1772 if (!this->sb)
1773 this->state |= IOSTATE_badbit;
1774 this->tie = rhs->tie;
1775 this->flags = rhs->flags;
1776 this->precision = (char) rhs->precision;
1777 this->fill = rhs->fill;
1778 this->width = (char) rhs->width;
1779 return this;
1782 /* ??7ios@@QBEHXZ */
1783 /* ??7ios@@QEBAHXZ */
1784 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1785 int __thiscall ios_op_not(const ios *this)
1787 TRACE("(%p)\n", this);
1788 return ios_fail(this);
1791 /* ??Bios@@QBEPAXXZ */
1792 /* ??Bios@@QEBAPEAXXZ */
1793 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1794 void* __thiscall ios_op_void(const ios *this)
1796 TRACE("(%p)\n", this);
1797 return ios_fail(this) ? NULL : (void*)this;
1800 /* ??_Eios@@UAEPAXI@Z */
1801 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1802 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1804 TRACE("(%p %x)\n", this, flags);
1805 if (flags & 2) {
1806 /* we have an array, with the number of elements stored before the first object */
1807 INT_PTR i, *ptr = (INT_PTR *)this-1;
1809 for (i = *ptr-1; i >= 0; i--)
1810 ios_dtor(this+i);
1811 MSVCRT_operator_delete(ptr);
1812 } else {
1813 ios_dtor(this);
1814 if (flags & 1)
1815 MSVCRT_operator_delete(this);
1817 return this;
1820 /* ??_Gios@@UAEPAXI@Z */
1821 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1822 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1824 TRACE("(%p %x)\n", this, flags);
1825 ios_dtor(this);
1826 if (flags & 1) MSVCRT_operator_delete(this);
1827 return this;
1830 /* ?bad@ios@@QBEHXZ */
1831 /* ?bad@ios@@QEBAHXZ */
1832 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1833 int __thiscall ios_bad(const ios *this)
1835 TRACE("(%p)\n", this);
1836 return (this->state & IOSTATE_badbit);
1839 /* ?bitalloc@ios@@SAJXZ */
1840 LONG __cdecl ios_bitalloc(void)
1842 TRACE("()\n");
1843 ios_lockc();
1844 ios_maxbit <<= 1;
1845 ios_unlockc();
1846 return ios_maxbit;
1849 /* ?clear@ios@@QAEXH@Z */
1850 /* ?clear@ios@@QEAAXH@Z */
1851 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1852 void __thiscall ios_clear(ios *this, int state)
1854 TRACE("(%p %d)\n", this, state);
1855 ios_lock(this);
1856 this->state = state;
1857 ios_unlock(this);
1860 /* ?clrlock@ios@@QAAXXZ */
1861 /* ?clrlock@ios@@QEAAXXZ */
1862 void __cdecl ios_clrlock(ios *this)
1864 TRACE("(%p)\n", this);
1865 if (this->do_lock <= 0)
1866 this->do_lock++;
1867 if (this->sb)
1868 streambuf_clrlock(this->sb);
1871 /* ?delbuf@ios@@QAEXH@Z */
1872 /* ?delbuf@ios@@QEAAXH@Z */
1873 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1874 void __thiscall ios_delbuf_set(ios *this, int delete)
1876 TRACE("(%p %d)\n", this, delete);
1877 this->delbuf = delete;
1880 /* ?delbuf@ios@@QBEHXZ */
1881 /* ?delbuf@ios@@QEBAHXZ */
1882 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1883 int __thiscall ios_delbuf_get(const ios *this)
1885 TRACE("(%p)\n", this);
1886 return this->delbuf;
1889 /* ?dec@@YAAAVios@@AAV1@@Z */
1890 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1891 ios* __cdecl ios_dec(ios *this)
1893 TRACE("(%p)\n", this);
1894 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1895 return this;
1898 /* ?eof@ios@@QBEHXZ */
1899 /* ?eof@ios@@QEBAHXZ */
1900 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1901 int __thiscall ios_eof(const ios *this)
1903 TRACE("(%p)\n", this);
1904 return (this->state & IOSTATE_eofbit);
1907 /* ?fail@ios@@QBEHXZ */
1908 /* ?fail@ios@@QEBAHXZ */
1909 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1910 int __thiscall ios_fail(const ios *this)
1912 TRACE("(%p)\n", this);
1913 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1916 /* ?fill@ios@@QAEDD@Z */
1917 /* ?fill@ios@@QEAADD@Z */
1918 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1919 char __thiscall ios_fill_set(ios *this, char fill)
1921 char prev = this->fill;
1923 TRACE("(%p %d)\n", this, fill);
1925 this->fill = fill;
1926 return prev;
1929 /* ?fill@ios@@QBEDXZ */
1930 /* ?fill@ios@@QEBADXZ */
1931 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1932 char __thiscall ios_fill_get(const ios *this)
1934 TRACE("(%p)\n", this);
1935 return this->fill;
1938 /* ?flags@ios@@QAEJJ@Z */
1939 /* ?flags@ios@@QEAAJJ@Z */
1940 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
1941 LONG __thiscall ios_flags_set(ios *this, LONG flags)
1943 LONG prev = this->flags;
1945 TRACE("(%p %x)\n", this, flags);
1947 this->flags = flags;
1948 return prev;
1951 /* ?flags@ios@@QBEJXZ */
1952 /* ?flags@ios@@QEBAJXZ */
1953 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
1954 LONG __thiscall ios_flags_get(const ios *this)
1956 TRACE("(%p)\n", this);
1957 return this->flags;
1960 /* ?good@ios@@QBEHXZ */
1961 /* ?good@ios@@QEBAHXZ */
1962 DEFINE_THISCALL_WRAPPER(ios_good, 4)
1963 int __thiscall ios_good(const ios *this)
1965 TRACE("(%p)\n", this);
1966 return this->state == IOSTATE_goodbit;
1969 /* ?hex@@YAAAVios@@AAV1@@Z */
1970 /* ?hex@@YAAEAVios@@AEAV1@@Z */
1971 ios* __cdecl ios_hex(ios *this)
1973 TRACE("(%p)\n", this);
1974 ios_setf_mask(this, FLAGS_hex, ios_basefield);
1975 return this;
1978 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
1979 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
1980 DEFINE_THISCALL_WRAPPER(ios_init, 8)
1981 void __thiscall ios_init(ios *this, streambuf *sb)
1983 TRACE("(%p %p)\n", this, sb);
1984 if (this->delbuf && this->sb)
1985 call_streambuf_vector_dtor(this->sb, 1);
1986 this->sb = sb;
1987 if (sb == NULL)
1988 this->state |= IOSTATE_badbit;
1989 else
1990 this->state &= ~IOSTATE_badbit;
1993 /* ?iword@ios@@QBEAAJH@Z */
1994 /* ?iword@ios@@QEBAAEAJH@Z */
1995 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
1996 LONG* __thiscall ios_iword(const ios *this, int index)
1998 TRACE("(%p %d)\n", this, index);
1999 return &ios_statebuf[index];
2002 /* ?lock@ios@@QAAXXZ */
2003 /* ?lock@ios@@QEAAXXZ */
2004 void __cdecl ios_lock(ios *this)
2006 TRACE("(%p)\n", this);
2007 if (this->do_lock < 0)
2008 EnterCriticalSection(&this->lock);
2011 /* ?lockbuf@ios@@QAAXXZ */
2012 /* ?lockbuf@ios@@QEAAXXZ */
2013 void __cdecl ios_lockbuf(ios *this)
2015 TRACE("(%p)\n", this);
2016 streambuf_lock(this->sb);
2019 /* ?lockc@ios@@KAXXZ */
2020 void __cdecl ios_lockc(void)
2022 TRACE("()\n");
2023 EnterCriticalSection(&ios_static_lock);
2026 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
2027 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
2028 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
2029 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
2031 TRACE("(%p)\n", this);
2032 return &this->lock;
2035 /* ?oct@@YAAAVios@@AAV1@@Z */
2036 /* ?oct@@YAAEAVios@@AEAV1@@Z */
2037 ios* __cdecl ios_oct(ios *this)
2039 TRACE("(%p)\n", this);
2040 ios_setf_mask(this, FLAGS_oct, ios_basefield);
2041 return this;
2044 /* ?precision@ios@@QAEHH@Z */
2045 /* ?precision@ios@@QEAAHH@Z */
2046 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
2047 int __thiscall ios_precision_set(ios *this, int prec)
2049 int prev = this->precision;
2051 TRACE("(%p %d)\n", this, prec);
2053 this->precision = prec;
2054 return prev;
2057 /* ?precision@ios@@QBEHXZ */
2058 /* ?precision@ios@@QEBAHXZ */
2059 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
2060 int __thiscall ios_precision_get(const ios *this)
2062 TRACE("(%p)\n", this);
2063 return this->precision;
2066 /* ?pword@ios@@QBEAAPAXH@Z */
2067 /* ?pword@ios@@QEBAAEAPEAXH@Z */
2068 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
2069 void** __thiscall ios_pword(const ios *this, int index)
2071 TRACE("(%p %d)\n", this, index);
2072 return (void**)&ios_statebuf[index];
2075 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
2076 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
2077 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
2078 streambuf* __thiscall ios_rdbuf(const ios *this)
2080 TRACE("(%p)\n", this);
2081 return this->sb;
2084 /* ?rdstate@ios@@QBEHXZ */
2085 /* ?rdstate@ios@@QEBAHXZ */
2086 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
2087 int __thiscall ios_rdstate(const ios *this)
2089 TRACE("(%p)\n", this);
2090 return this->state;
2093 /* ?setf@ios@@QAEJJ@Z */
2094 /* ?setf@ios@@QEAAJJ@Z */
2095 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
2096 LONG __thiscall ios_setf(ios *this, LONG flags)
2098 LONG prev = this->flags;
2100 TRACE("(%p %x)\n", this, flags);
2102 ios_lock(this);
2103 this->flags |= flags;
2104 ios_unlock(this);
2105 return prev;
2108 /* ?setf@ios@@QAEJJJ@Z */
2109 /* ?setf@ios@@QEAAJJJ@Z */
2110 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
2111 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
2113 LONG prev = this->flags;
2115 TRACE("(%p %x %x)\n", this, flags, mask);
2117 ios_lock(this);
2118 this->flags = (this->flags & (~mask)) | (flags & mask);
2119 ios_unlock(this);
2120 return prev;
2123 /* ?setlock@ios@@QAAXXZ */
2124 /* ?setlock@ios@@QEAAXXZ */
2125 void __cdecl ios_setlock(ios *this)
2127 TRACE("(%p)\n", this);
2128 this->do_lock--;
2129 if (this->sb)
2130 streambuf_setlock(this->sb);
2133 /* ?sync_with_stdio@ios@@SAXXZ */
2134 void __cdecl ios_sync_with_stdio(void)
2136 FIXME("() stub\n");
2139 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
2140 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
2141 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
2142 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
2144 ostream *prev = this->tie;
2146 TRACE("(%p %p)\n", this, ostr);
2148 this->tie = ostr;
2149 return prev;
2152 /* ?tie@ios@@QBEPAVostream@@XZ */
2153 /* ?tie@ios@@QEBAPEAVostream@@XZ */
2154 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
2155 ostream* __thiscall ios_tie_get(const ios *this)
2157 TRACE("(%p)\n", this);
2158 return this->tie;
2161 /* ?unlock@ios@@QAAXXZ */
2162 /* ?unlock@ios@@QEAAXXZ */
2163 void __cdecl ios_unlock(ios *this)
2165 TRACE("(%p)\n", this);
2166 if (this->do_lock < 0)
2167 LeaveCriticalSection(&this->lock);
2170 /* ?unlockbuf@ios@@QAAXXZ */
2171 /* ?unlockbuf@ios@@QEAAXXZ */
2172 void __cdecl ios_unlockbuf(ios *this)
2174 TRACE("(%p)\n", this);
2175 streambuf_unlock(this->sb);
2178 /* ?unlockc@ios@@KAXXZ */
2179 void __cdecl ios_unlockc(void)
2181 TRACE("()\n");
2182 LeaveCriticalSection(&ios_static_lock);
2185 /* ?unsetf@ios@@QAEJJ@Z */
2186 /* ?unsetf@ios@@QEAAJJ@Z */
2187 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
2188 LONG __thiscall ios_unsetf(ios *this, LONG flags)
2190 LONG prev = this->flags;
2192 TRACE("(%p %x)\n", this, flags);
2194 ios_lock(this);
2195 this->flags &= ~flags;
2196 ios_unlock(this);
2197 return prev;
2200 /* ?width@ios@@QAEHH@Z */
2201 /* ?width@ios@@QEAAHH@Z */
2202 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
2203 int __thiscall ios_width_set(ios *this, int width)
2205 int prev = this->width;
2207 TRACE("(%p %d)\n", this, width);
2209 this->width = width;
2210 return prev;
2213 /* ?width@ios@@QBEHXZ */
2214 /* ?width@ios@@QEBAHXZ */
2215 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
2216 int __thiscall ios_width_get(const ios *this)
2218 TRACE("(%p)\n", this);
2219 return this->width;
2222 /* ?xalloc@ios@@SAHXZ */
2223 int __cdecl ios_xalloc(void)
2225 int ret;
2227 TRACE("()\n");
2229 ios_lockc();
2230 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
2231 ios_unlockc();
2232 return ret;
2235 static inline ios* ostream_get_ios(const ostream *this)
2237 return (ios*)((char*)this + this->vbtable[1]);
2240 static inline ios* ostream_to_ios(const ostream *this)
2242 return (ios*)((char*)this + ostream_vbtable[1]);
2245 static inline ostream* ios_to_ostream(const ios *base)
2247 return (ostream*)((char*)base - ostream_vbtable[1]);
2250 /* ??0ostream@@QAE@PAVstreambuf@@@Z */
2251 /* ??0ostream@@QEAA@PEAVstreambuf@@@Z */
2252 DEFINE_THISCALL_WRAPPER(ostream_sb_ctor, 12)
2253 ostream* __thiscall ostream_sb_ctor(ostream *this, streambuf *sb, BOOL virt_init)
2255 ios *base;
2257 TRACE("(%p %p %d)\n", this, sb, virt_init);
2259 if (virt_init) {
2260 this->vbtable = ostream_vbtable;
2261 base = ostream_get_ios(this);
2262 ios_sb_ctor(base, sb);
2263 } else {
2264 base = ostream_get_ios(this);
2265 ios_init(base, sb);
2267 base->vtable = &MSVCP_ostream_vtable;
2268 this->unknown = 0;
2269 return this;
2272 /* ??0ostream@@IAE@ABV0@@Z */
2273 /* ??0ostream@@IEAA@AEBV0@@Z */
2274 DEFINE_THISCALL_WRAPPER(ostream_copy_ctor, 12)
2275 ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
2277 return ostream_sb_ctor(this, ostream_get_ios(copy)->sb, virt_init);
2280 /* ??0ostream@@IAE@XZ */
2281 /* ??0ostream@@IEAA@XZ */
2282 DEFINE_THISCALL_WRAPPER(ostream_ctor, 8)
2283 ostream* __thiscall ostream_ctor(ostream *this, BOOL virt_init)
2285 ios *base;
2287 TRACE("(%p %d)\n", this, virt_init);
2289 if (virt_init) {
2290 this->vbtable = ostream_vbtable;
2291 base = ostream_get_ios(this);
2292 ios_ctor(base);
2293 } else
2294 base = ostream_get_ios(this);
2295 base->vtable = &MSVCP_ostream_vtable;
2296 this->unknown = 0;
2297 return this;
2300 /* ??1ostream@@UAE@XZ */
2301 /* ??1ostream@@UEAA@XZ */
2302 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
2303 void __thiscall ostream_dtor(ios *base)
2305 ostream *this = ios_to_ostream(base);
2307 TRACE("(%p)\n", this);
2310 /* ??4ostream@@IAEAAV0@PAVstreambuf@@@Z */
2311 /* ??4ostream@@IEAAAEAV0@PEAVstreambuf@@@Z */
2312 DEFINE_THISCALL_WRAPPER(ostream_assign_sb, 8)
2313 ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
2315 ios *base = ostream_get_ios(this);
2317 TRACE("(%p %p)\n", this, sb);
2319 ios_init(base, sb);
2320 base->state &= IOSTATE_badbit;
2321 base->delbuf = 0;
2322 base->tie = NULL;
2323 base->flags = 0;
2324 base->precision = 6;
2325 base->fill = ' ';
2326 base->width = 0;
2327 return this;
2330 /* ??4ostream@@IAEAAV0@ABV0@@Z */
2331 /* ??4ostream@@IEAAAEAV0@AEBV0@@Z */
2332 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
2333 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
2335 ios *base_rhs = ostream_get_ios(rhs);
2337 TRACE("(%p %p)\n", this, rhs);
2339 return ostream_assign_sb(this, base_rhs->sb);
2342 /* ??_Dostream@@QAEXXZ */
2343 /* ??_Dostream@@QEAAXXZ */
2344 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
2345 void __thiscall ostream_vbase_dtor(ostream *this)
2347 ios *base = ostream_to_ios(this);
2349 TRACE("(%p)\n", this);
2351 ostream_dtor(base);
2352 ios_dtor(base);
2355 /* ??_Eostream@@UAEPAXI@Z */
2356 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
2357 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
2359 ostream *this = ios_to_ostream(base);
2361 TRACE("(%p %x)\n", this, flags);
2363 if (flags & 2) {
2364 /* we have an array, with the number of elements stored before the first object */
2365 INT_PTR i, *ptr = (INT_PTR *)this-1;
2367 for (i = *ptr-1; i >= 0; i--)
2368 ostream_vbase_dtor(this+i);
2369 MSVCRT_operator_delete(ptr);
2370 } else {
2371 ostream_vbase_dtor(this);
2372 if (flags & 1)
2373 MSVCRT_operator_delete(this);
2375 return this;
2378 /* ??_Gostream@@UAEPAXI@Z */
2379 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
2380 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
2382 ostream *this = ios_to_ostream(base);
2384 TRACE("(%p %x)\n", this, flags);
2386 ostream_vbase_dtor(this);
2387 if (flags & 1) MSVCRT_operator_delete(this);
2388 return this;
2391 /* ?flush@ostream@@QAEAAV1@XZ */
2392 /* ?flush@ostream@@QEAAAEAV1@XZ */
2393 DEFINE_THISCALL_WRAPPER(ostream_flush, 4)
2394 ostream* __thiscall ostream_flush(ostream *this)
2396 ios *base = ostream_get_ios(this);
2398 TRACE("(%p)\n", this);
2400 ios_lockbuf(base);
2401 if (call_streambuf_sync(base->sb) == EOF)
2402 ios_clear(base, base->state | IOSTATE_failbit);
2403 ios_unlockbuf(base);
2404 return this;
2407 /* ?opfx@ostream@@QAEHXZ */
2408 /* ?opfx@ostream@@QEAAHXZ */
2409 DEFINE_THISCALL_WRAPPER(ostream_opfx, 4)
2410 int __thiscall ostream_opfx(ostream *this)
2412 ios *base = ostream_get_ios(this);
2414 TRACE("(%p)\n", this);
2416 if (!ios_good(base)) {
2417 ios_clear(base, base->state | IOSTATE_failbit);
2418 return 0;
2420 ios_lock(base);
2421 ios_lockbuf(base);
2422 if (base->tie)
2423 ostream_flush(base->tie);
2424 return 1;
2427 /* ?osfx@ostream@@QAEXXZ */
2428 /* ?osfx@ostream@@QEAAXXZ */
2429 DEFINE_THISCALL_WRAPPER(ostream_osfx, 4)
2430 void __thiscall ostream_osfx(ostream *this)
2432 ios *base = ostream_get_ios(this);
2434 TRACE("(%p)\n", this);
2436 ios_unlockbuf(base);
2437 ios_width_set(base, 0);
2438 if (base->flags & FLAGS_unitbuf)
2439 ostream_flush(this);
2440 if (base->flags & FLAGS_stdio) {
2441 fflush(stdout);
2442 fflush(stderr);
2444 ios_unlock(base);
2447 /* ?put@ostream@@QAEAAV1@D@Z */
2448 /* ?put@ostream@@QEAAAEAV1@D@Z */
2449 DEFINE_THISCALL_WRAPPER(ostream_put_char, 8)
2450 ostream* __thiscall ostream_put_char(ostream *this, char c)
2452 ios *base = ostream_get_ios(this);
2454 TRACE("(%p %c)\n", this, c);
2456 if (ostream_opfx(this)) {
2457 if (streambuf_sputc(base->sb, c) == EOF)
2458 base->state = IOSTATE_badbit | IOSTATE_failbit;
2459 ostream_osfx(this);
2461 return this;
2464 /* ?put@ostream@@QAEAAV1@C@Z */
2465 /* ?put@ostream@@QEAAAEAV1@C@Z */
2466 DEFINE_THISCALL_WRAPPER(ostream_put_signed_char, 8)
2467 ostream* __thiscall ostream_put_signed_char(ostream *this, signed char c)
2469 return ostream_put_char(this, (char) c);
2472 /* ?put@ostream@@QAEAAV1@E@Z */
2473 /* ?put@ostream@@QEAAAEAV1@E@Z */
2474 DEFINE_THISCALL_WRAPPER(ostream_put_unsigned_char, 8)
2475 ostream* __thiscall ostream_put_unsigned_char(ostream *this, unsigned char c)
2477 return ostream_put_char(this, (char) c);
2480 /* ?seekp@ostream@@QAEAAV1@J@Z */
2481 /* ?seekp@ostream@@QEAAAEAV1@J@Z */
2482 DEFINE_THISCALL_WRAPPER(ostream_seekp, 8)
2483 ostream* __thiscall ostream_seekp(ostream *this, streampos pos)
2485 ios *base = ostream_get_ios(this);
2487 TRACE("(%p %d)\n", this, pos);
2489 ios_lockbuf(base);
2490 if (streambuf_seekpos(base->sb, pos, OPENMODE_out) == EOF)
2491 ios_clear(base, base->state | IOSTATE_failbit);
2492 ios_unlockbuf(base);
2493 return this;
2496 /* ?seekp@ostream@@QAEAAV1@JW4seek_dir@ios@@@Z */
2497 /* ?seekp@ostream@@QEAAAEAV1@JW4seek_dir@ios@@@Z */
2498 DEFINE_THISCALL_WRAPPER(ostream_seekp_offset, 12)
2499 ostream* __thiscall ostream_seekp_offset(ostream *this, streamoff off, ios_seek_dir dir)
2501 ios *base = ostream_get_ios(this);
2503 TRACE("(%p %d %d)\n", this, off, dir);
2505 ios_lockbuf(base);
2506 if (call_streambuf_seekoff(base->sb, off, dir, OPENMODE_out) == EOF)
2507 ios_clear(base, base->state | IOSTATE_failbit);
2508 ios_unlockbuf(base);
2509 return this;
2512 /* ?tellp@ostream@@QAEJXZ */
2513 /* ?tellp@ostream@@QEAAJXZ */
2514 DEFINE_THISCALL_WRAPPER(ostream_tellp, 4)
2515 streampos __thiscall ostream_tellp(ostream *this)
2517 ios *base = ostream_get_ios(this);
2518 streampos pos;
2520 TRACE("(%p)\n", this);
2522 ios_lockbuf(base);
2523 if ((pos = call_streambuf_seekoff(base->sb, 0, SEEKDIR_cur, OPENMODE_out)) == EOF)
2524 ios_clear(base, base->state | IOSTATE_failbit);
2525 ios_unlockbuf(base);
2526 return pos;
2529 /* ?write@ostream@@QAEAAV1@PBDH@Z */
2530 /* ?write@ostream@@QEAAAEAV1@PEBDH@Z */
2531 DEFINE_THISCALL_WRAPPER(ostream_write_char, 12)
2532 ostream* __thiscall ostream_write_char(ostream *this, const char *str, int count)
2534 ios *base = ostream_get_ios(this);
2536 TRACE("(%p %p %d)\n", this, str, count);
2538 if (ostream_opfx(this)) {
2539 if (streambuf_sputn(base->sb, str, count) != count)
2540 base->state = IOSTATE_badbit | IOSTATE_failbit;
2541 ostream_osfx(this);
2543 return this;
2546 /* ?write@ostream@@QAEAAV1@PBCH@Z */
2547 /* ?write@ostream@@QEAAAEAV1@PEBCH@Z */
2548 DEFINE_THISCALL_WRAPPER(ostream_write_signed_char, 12)
2549 ostream* __thiscall ostream_write_signed_char(ostream *this, const signed char *str, int count)
2551 return ostream_write_char(this, (const char*) str, count);
2554 /* ?write@ostream@@QAEAAV1@PBEH@Z */
2555 /* ?write@ostream@@QEAAAEAV1@PEBEH@Z */
2556 DEFINE_THISCALL_WRAPPER(ostream_write_unsigned_char, 12)
2557 ostream* __thiscall ostream_write_unsigned_char(ostream *this, const unsigned char *str, int count)
2559 return ostream_write_char(this, (const char*) str, count);
2562 /* ?writepad@ostream@@AAEAAV1@PBD0@Z */
2563 /* ?writepad@ostream@@AEAAAEAV1@PEBD0@Z */
2564 DEFINE_THISCALL_WRAPPER(ostream_writepad, 12)
2565 ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char *str2)
2567 ios *base = ostream_get_ios(this);
2568 int len1 = strlen(str1), len2 = strlen(str2), i;
2570 TRACE("(%p %p %p)\n", this, str1, str2);
2572 /* left of the padding */
2573 if (base->flags & (FLAGS_left|FLAGS_internal)) {
2574 if (streambuf_sputn(base->sb, str1, len1) != len1)
2575 ios_clear(base, base->state | IOSTATE_failbit | IOSTATE_badbit);
2576 if (!(base->flags & FLAGS_internal))
2577 if (streambuf_sputn(base->sb, str2, len2) != len2)
2578 ios_clear(base, base->state | IOSTATE_failbit | IOSTATE_badbit);
2580 /* add padding to fill the width */
2581 for (i = len1 + len2; i < base->width; i++)
2582 if (streambuf_sputc(base->sb, base->fill) == EOF)
2583 ios_clear(base, base->state | IOSTATE_failbit | IOSTATE_badbit);
2584 /* right of the padding */
2585 if ((base->flags & (FLAGS_left|FLAGS_internal)) != FLAGS_left) {
2586 if (!(base->flags & (FLAGS_left|FLAGS_internal)))
2587 if (streambuf_sputn(base->sb, str1, len1) != len1)
2588 ios_clear(base, base->state | IOSTATE_failbit | IOSTATE_badbit);
2589 if (streambuf_sputn(base->sb, str2, len2) != len2)
2590 ios_clear(base, base->state | IOSTATE_failbit | IOSTATE_badbit);
2592 return this;
2595 static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
2597 ios *base = ostream_get_ios(ostr);
2598 char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
2600 TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
2602 if (ostream_opfx(ostr)) {
2603 if (base->flags & FLAGS_hex) {
2604 sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2605 if (base->flags & FLAGS_showbase) {
2606 prefix_str[0] = '0';
2607 prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
2609 } else if (base->flags & FLAGS_oct) {
2610 sprintf_fmt[1] = 'o';
2611 if (base->flags & FLAGS_showbase)
2612 prefix_str[0] = '0';
2613 } else { /* FLAGS_dec */
2614 if (unsig)
2615 sprintf_fmt[1] = 'u';
2616 if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
2617 prefix_str[0] = '+';
2620 if (shrt) {
2621 sprintf_fmt[2] = sprintf_fmt[1];
2622 sprintf_fmt[1] = 'h';
2625 if (sprintf(number_str, sprintf_fmt, n) > 0)
2626 ostream_writepad(ostr, prefix_str, number_str);
2627 else
2628 base->state |= IOSTATE_failbit;
2629 ostream_osfx(ostr);
2631 return ostr;
2634 static ostream* ostream_internal_print_float(ostream *ostr, double d, BOOL dbl)
2636 ios *base = ostream_get_ios(ostr);
2637 char prefix_str[2] = {0}, number_str[24], sprintf_fmt[6] = {'%','.','*','f',0};
2638 int prec, max_prec = dbl ? 15 : 6;
2639 int str_length = 1; /* null end char */
2641 TRACE("(%p %lf %d)\n", ostr, d, dbl);
2643 if (ostream_opfx(ostr)) {
2644 if ((base->flags & FLAGS_showpos) && d > 0) {
2645 prefix_str[0] = '+';
2646 str_length++; /* plus sign */
2648 if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) == FLAGS_scientific)
2649 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'E' : 'e';
2650 else if ((base->flags & (FLAGS_scientific|FLAGS_fixed)) != FLAGS_fixed)
2651 sprintf_fmt[3] = (base->flags & FLAGS_uppercase) ? 'G' : 'g';
2652 if (base->flags & FLAGS_showpoint) {
2653 sprintf_fmt[4] = sprintf_fmt[3];
2654 sprintf_fmt[3] = sprintf_fmt[2];
2655 sprintf_fmt[2] = sprintf_fmt[1];
2656 sprintf_fmt[1] = '#';
2659 prec = (base->precision >= 0 && base->precision <= max_prec) ? base->precision : max_prec;
2660 str_length += _scprintf(sprintf_fmt, prec, d); /* number representation */
2661 if (str_length > 24) {
2662 /* when the output length exceeds 24 characters, Windows prints an empty string with padding */
2663 ostream_writepad(ostr, "", "");
2664 } else {
2665 if (sprintf(number_str, sprintf_fmt, prec, d) > 0)
2666 ostream_writepad(ostr, prefix_str, number_str);
2667 else
2668 base->state |= IOSTATE_failbit;
2670 ostream_osfx(ostr);
2672 return ostr;
2675 /* ??6ostream@@QAEAAV0@C@Z */
2676 /* ??6ostream@@QEAAAEAV0@C@Z */
2677 /* ??6ostream@@QAEAAV0@D@Z */
2678 /* ??6ostream@@QEAAAEAV0@D@Z */
2679 DEFINE_THISCALL_WRAPPER(ostream_print_char, 8)
2680 ostream* __thiscall ostream_print_char(ostream *this, char c)
2682 const char c_str[2] = {c, 0};
2684 TRACE("(%p %c)\n", this, c);
2686 if (ostream_opfx(this)) {
2687 ostream_writepad(this, "", c_str);
2688 ostream_osfx(this);
2690 return this;
2693 /* ??6ostream@@QAEAAV0@E@Z */
2694 /* ??6ostream@@QEAAAEAV0@E@Z */
2695 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_char, 8)
2696 ostream* __thiscall ostream_print_unsigned_char(ostream *this, unsigned char c)
2698 return ostream_print_char(this, c);
2701 /* ??6ostream@@QAEAAV0@PBC@Z */
2702 /* ??6ostream@@QEAAAEAV0@PEBC@Z */
2703 /* ??6ostream@@QAEAAV0@PBD@Z */
2704 /* ??6ostream@@QEAAAEAV0@PEBD@Z */
2705 DEFINE_THISCALL_WRAPPER(ostream_print_str, 8)
2706 ostream* __thiscall ostream_print_str(ostream *this, const char *str)
2708 TRACE("(%p %s)\n", this, str);
2709 if (ostream_opfx(this)) {
2710 ostream_writepad(this, "", str);
2711 ostream_osfx(this);
2713 return this;
2716 /* ??6ostream@@QAEAAV0@PBE@Z */
2717 /* ??6ostream@@QEAAAEAV0@PEBE@Z */
2718 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_str, 8)
2719 ostream* __thiscall ostream_print_unsigned_str(ostream *this, const unsigned char *str)
2721 return ostream_print_str(this, (const char*) str);
2724 /* ??6ostream@@QAEAAV0@F@Z */
2725 /* ??6ostream@@QEAAAEAV0@F@Z */
2726 DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
2727 ostream* __thiscall ostream_print_short(ostream *this, short n)
2729 return ostream_internal_print_integer(this, n, FALSE, TRUE);
2732 /* ??6ostream@@QAEAAV0@G@Z */
2733 /* ??6ostream@@QEAAAEAV0@G@Z */
2734 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
2735 ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
2737 return ostream_internal_print_integer(this, n, TRUE, TRUE);
2740 /* ??6ostream@@QAEAAV0@H@Z */
2741 /* ??6ostream@@QEAAAEAV0@H@Z */
2742 /* ??6ostream@@QAEAAV0@J@Z */
2743 /* ??6ostream@@QEAAAEAV0@J@Z */
2744 DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
2745 ostream* __thiscall ostream_print_int(ostream *this, int n)
2747 return ostream_internal_print_integer(this, n, FALSE, FALSE);
2750 /* ??6ostream@@QAEAAV0@I@Z */
2751 /* ??6ostream@@QEAAAEAV0@I@Z */
2752 /* ??6ostream@@QAEAAV0@K@Z */
2753 /* ??6ostream@@QEAAAEAV0@K@Z */
2754 DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
2755 ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
2757 return ostream_internal_print_integer(this, n, TRUE, FALSE);
2760 /* ??6ostream@@QAEAAV0@M@Z */
2761 /* ??6ostream@@QEAAAEAV0@M@Z */
2762 DEFINE_THISCALL_WRAPPER(ostream_print_float, 8)
2763 ostream* __thiscall ostream_print_float(ostream *this, float f)
2765 return ostream_internal_print_float(this, f, FALSE);
2768 /* ??6ostream@@QAEAAV0@N@Z */
2769 /* ??6ostream@@QEAAAEAV0@N@Z */
2770 /* ??6ostream@@QAEAAV0@O@Z */
2771 /* ??6ostream@@QEAAAEAV0@O@Z */
2772 DEFINE_THISCALL_WRAPPER(ostream_print_double, 12)
2773 ostream* __thiscall ostream_print_double(ostream *this, double d)
2775 return ostream_internal_print_float(this, d, TRUE);
2778 /* ??6ostream@@QAEAAV0@PBX@Z */
2779 /* ??6ostream@@QEAAAEAV0@PEBX@Z */
2780 DEFINE_THISCALL_WRAPPER(ostream_print_ptr, 8)
2781 ostream* __thiscall ostream_print_ptr(ostream *this, const void *ptr)
2783 ios *base = ostream_get_ios(this);
2784 char prefix_str[3] = {'0','x',0}, pointer_str[17];
2786 TRACE("(%p %p)\n", this, ptr);
2788 if (ostream_opfx(this)) {
2789 if (ptr && base->flags & FLAGS_uppercase)
2790 prefix_str[1] = 'X';
2792 if (sprintf(pointer_str, "%p", ptr) > 0)
2793 ostream_writepad(this, prefix_str, pointer_str);
2794 else
2795 base->state |= IOSTATE_failbit;
2796 ostream_osfx(this);
2798 return this;
2801 /* ??6ostream@@QAEAAV0@PAVstreambuf@@@Z */
2802 /* ??6ostream@@QEAAAEAV0@PEAVstreambuf@@@Z */
2803 DEFINE_THISCALL_WRAPPER(ostream_print_streambuf, 8)
2804 ostream* __thiscall ostream_print_streambuf(ostream *this, streambuf *sb)
2806 ios *base = ostream_get_ios(this);
2807 int c;
2809 TRACE("(%p %p)\n", this, sb);
2811 if (ostream_opfx(this)) {
2812 while ((c = streambuf_sbumpc(sb)) != EOF) {
2813 if (streambuf_sputc(base->sb, c) == EOF) {
2814 base->state |= IOSTATE_failbit;
2815 break;
2818 ostream_osfx(this);
2820 return this;
2823 /* ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z */
2824 /* ??6ostream@@QEAAAEAV0@P6AAEAV0@AEAV0@@Z@Z */
2825 DEFINE_THISCALL_WRAPPER(ostream_print_manip, 8)
2826 ostream* __thiscall ostream_print_manip(ostream *this, ostream* (__cdecl *func)(ostream*))
2828 TRACE("(%p %p)\n", this, func);
2829 return func(this);
2832 /* ??6ostream@@QAEAAV0@P6AAAVios@@AAV1@@Z@Z */
2833 /* ??6ostream@@QEAAAEAV0@P6AAEAVios@@AEAV1@@Z@Z */
2834 DEFINE_THISCALL_WRAPPER(ostream_print_ios_manip, 8)
2835 ostream* __thiscall ostream_print_ios_manip(ostream *this, ios* (__cdecl *func)(ios*))
2837 TRACE("(%p %p)\n", this, func);
2838 func(ostream_get_ios(this));
2839 return this;
2842 /* ?endl@@YAAAVostream@@AAV1@@Z */
2843 /* ?endl@@YAAEAVostream@@AEAV1@@Z */
2844 ostream* __cdecl ostream_endl(ostream *this)
2846 FIXME("(%p) stub\n", this);
2847 return this;
2850 /* ?ends@@YAAAVostream@@AAV1@@Z */
2851 /* ?ends@@YAAEAVostream@@AEAV1@@Z */
2852 ostream* __cdecl ostream_ends(ostream *this)
2854 FIXME("(%p) stub\n", this);
2855 return this;
2858 /* ?flush@@YAAAVostream@@AAV1@@Z */
2859 /* ?flush@@YAAEAVostream@@AEAV1@@Z */
2860 ostream* __cdecl ostream_flush_manip(ostream *this)
2862 FIXME("(%p) stub\n", this);
2863 return this;
2866 /******************************************************************
2867 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
2869 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
2870 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
2872 FIXME("(%p %x) stub\n", this, virt_init);
2873 return this;
2876 /******************************************************************
2877 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
2879 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
2880 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
2882 FIXME("(%p) stub\n", base);
2885 #ifdef __i386__
2887 #define DEFINE_VTBL_WRAPPER(off) \
2888 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
2889 "popl %eax\n\t" \
2890 "popl %ecx\n\t" \
2891 "pushl %eax\n\t" \
2892 "movl 0(%ecx), %eax\n\t" \
2893 "jmp *" #off "(%eax)\n\t")
2895 DEFINE_VTBL_WRAPPER(0);
2896 DEFINE_VTBL_WRAPPER(4);
2897 DEFINE_VTBL_WRAPPER(8);
2898 DEFINE_VTBL_WRAPPER(12);
2899 DEFINE_VTBL_WRAPPER(16);
2900 DEFINE_VTBL_WRAPPER(20);
2901 DEFINE_VTBL_WRAPPER(24);
2902 DEFINE_VTBL_WRAPPER(28);
2903 DEFINE_VTBL_WRAPPER(32);
2904 DEFINE_VTBL_WRAPPER(36);
2905 DEFINE_VTBL_WRAPPER(40);
2906 DEFINE_VTBL_WRAPPER(44);
2907 DEFINE_VTBL_WRAPPER(48);
2908 DEFINE_VTBL_WRAPPER(52);
2909 DEFINE_VTBL_WRAPPER(56);
2911 #endif
2913 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
2914 void (__cdecl *MSVCRT_operator_delete)(void*);
2916 static void init_cxx_funcs(void)
2918 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
2920 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
2922 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
2923 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
2925 else
2927 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
2928 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
2932 static void init_io(void *base)
2934 #ifdef __x86_64__
2935 init_streambuf_rtti(base);
2936 init_filebuf_rtti(base);
2937 init_strstreambuf_rtti(base);
2938 init_stdiobuf_rtti(base);
2939 init_ios_rtti(base);
2940 init_ostream_rtti(base);
2941 #endif
2944 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
2946 switch (reason)
2948 case DLL_WINE_PREATTACH:
2949 return FALSE; /* prefer native version */
2950 case DLL_PROCESS_ATTACH:
2951 init_cxx_funcs();
2952 init_exception(inst);
2953 init_io(inst);
2954 DisableThreadLibraryCalls( inst );
2955 break;
2957 return TRUE;