msvcirt: Implement strstreambuf::overflow.
[wine/multimedia.git] / dlls / msvcirt / msvcirt.c
blob0a34ac0d19073feb41d90668809b5c657ef1df92
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 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 ios */
121 struct _ostream;
122 typedef struct {
123 const vtable_ptr *vtable;
124 streambuf *sb;
125 ios_io_state state;
126 int special[4];
127 int delbuf;
128 struct _ostream *tie;
129 ios_flags flags;
130 int precision;
131 char fill;
132 int width;
133 int do_lock;
134 CRITICAL_SECTION lock;
135 } ios;
137 ios* __thiscall ios_assign(ios*, const ios*);
138 int __thiscall ios_fail(const ios*);
139 void __cdecl ios_lock(ios*);
140 void __cdecl ios_lockc(void);
141 LONG __thiscall ios_setf_mask(ios*, LONG, LONG);
142 void __cdecl ios_unlock(ios*);
143 void __cdecl ios_unlockc(void);
145 /* class ostream */
146 typedef struct _ostream {
147 const vtable_ptr *vtable;
148 } ostream;
150 /* ??_7streambuf@@6B@ */
151 extern const vtable_ptr MSVCP_streambuf_vtable;
152 /* ??_7filebuf@@6B@ */
153 extern const vtable_ptr MSVCP_filebuf_vtable;
154 /* ??_7strstreambuf@@6B@ */
155 extern const vtable_ptr MSVCP_strstreambuf_vtable;
156 /* ??_7ios@@6B@ */
157 extern const vtable_ptr MSVCP_ios_vtable;
159 #ifndef __GNUC__
160 void __asm_dummy_vtables(void) {
161 #endif
162 __ASM_VTABLE(streambuf,
163 VTABLE_ADD_FUNC(streambuf_vector_dtor)
164 VTABLE_ADD_FUNC(streambuf_sync)
165 VTABLE_ADD_FUNC(streambuf_setbuf)
166 VTABLE_ADD_FUNC(streambuf_seekoff)
167 VTABLE_ADD_FUNC(streambuf_seekpos)
168 VTABLE_ADD_FUNC(streambuf_xsputn)
169 VTABLE_ADD_FUNC(streambuf_xsgetn)
170 VTABLE_ADD_FUNC(streambuf_overflow)
171 VTABLE_ADD_FUNC(streambuf_underflow)
172 VTABLE_ADD_FUNC(streambuf_pbackfail)
173 VTABLE_ADD_FUNC(streambuf_doallocate));
174 __ASM_VTABLE(filebuf,
175 VTABLE_ADD_FUNC(filebuf_vector_dtor)
176 VTABLE_ADD_FUNC(filebuf_sync)
177 VTABLE_ADD_FUNC(filebuf_setbuf)
178 VTABLE_ADD_FUNC(filebuf_seekoff)
179 VTABLE_ADD_FUNC(streambuf_seekpos)
180 VTABLE_ADD_FUNC(streambuf_xsputn)
181 VTABLE_ADD_FUNC(streambuf_xsgetn)
182 VTABLE_ADD_FUNC(filebuf_overflow)
183 VTABLE_ADD_FUNC(filebuf_underflow)
184 VTABLE_ADD_FUNC(streambuf_pbackfail)
185 VTABLE_ADD_FUNC(streambuf_doallocate));
186 __ASM_VTABLE(strstreambuf,
187 VTABLE_ADD_FUNC(strstreambuf_vector_dtor)
188 VTABLE_ADD_FUNC(strstreambuf_sync)
189 VTABLE_ADD_FUNC(strstreambuf_setbuf)
190 VTABLE_ADD_FUNC(strstreambuf_seekoff)
191 VTABLE_ADD_FUNC(streambuf_seekpos)
192 VTABLE_ADD_FUNC(streambuf_xsputn)
193 VTABLE_ADD_FUNC(streambuf_xsgetn)
194 VTABLE_ADD_FUNC(strstreambuf_overflow)
195 VTABLE_ADD_FUNC(strstreambuf_underflow)
196 VTABLE_ADD_FUNC(streambuf_pbackfail)
197 VTABLE_ADD_FUNC(strstreambuf_doallocate));
198 __ASM_VTABLE(ios,
199 VTABLE_ADD_FUNC(ios_vector_dtor));
200 #ifndef __GNUC__
202 #endif
204 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
205 DEFINE_RTTI_DATA1(filebuf, 0, &streambuf_rtti_base_descriptor, ".?AVfilebuf@@")
206 DEFINE_RTTI_DATA1(strstreambuf, 0, &streambuf_rtti_base_descriptor, ".?AVstrstreambuf@@")
207 DEFINE_RTTI_DATA0(ios, 0, ".?AVios@@")
209 /* ??0streambuf@@IAE@PADH@Z */
210 /* ??0streambuf@@IEAA@PEADH@Z */
211 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
212 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
214 TRACE("(%p %p %d)\n", this, buffer, length);
215 this->vtable = &MSVCP_streambuf_vtable;
216 this->allocated = 0;
217 this->stored_char = EOF;
218 this->do_lock = -1;
219 this->base = NULL;
220 streambuf_setbuf(this, buffer, length);
221 streambuf_setg(this, NULL, NULL, NULL);
222 streambuf_setp(this, NULL, NULL);
223 InitializeCriticalSection(&this->lock);
224 return this;
227 /* ??0streambuf@@IAE@XZ */
228 /* ??0streambuf@@IEAA@XZ */
229 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
230 streambuf* __thiscall streambuf_ctor(streambuf *this)
232 streambuf_reserve_ctor(this, NULL, 0);
233 this->unbuffered = 0;
234 return this;
237 /* ??0streambuf@@QAE@ABV0@@Z */
238 /* ??0streambuf@@QEAA@AEBV0@@Z */
239 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
240 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
242 TRACE("(%p %p)\n", this, copy);
243 *this = *copy;
244 this->vtable = &MSVCP_streambuf_vtable;
245 return this;
248 /* ??1streambuf@@UAE@XZ */
249 /* ??1streambuf@@UEAA@XZ */
250 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
251 void __thiscall streambuf_dtor(streambuf *this)
253 TRACE("(%p)\n", this);
254 if (this->allocated)
255 MSVCRT_operator_delete(this->base);
256 DeleteCriticalSection(&this->lock);
259 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
260 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
261 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
262 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
264 streambuf_dtor(this);
265 return streambuf_copy_ctor(this, rhs);
268 /* ??_Estreambuf@@UAEPAXI@Z */
269 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
270 #define call_streambuf_vector_dtor(this, flags) CALL_VTBL_FUNC(this, 0,\
271 streambuf*, (streambuf*, unsigned int), (this, flags))
272 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
274 TRACE("(%p %x)\n", this, flags);
275 if (flags & 2) {
276 /* we have an array, with the number of elements stored before the first object */
277 INT_PTR i, *ptr = (INT_PTR *)this-1;
279 for (i = *ptr-1; i >= 0; i--)
280 streambuf_dtor(this+i);
281 MSVCRT_operator_delete(ptr);
282 } else {
283 streambuf_dtor(this);
284 if (flags & 1)
285 MSVCRT_operator_delete(this);
287 return this;
290 /* ??_Gstreambuf@@UAEPAXI@Z */
291 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
292 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
294 TRACE("(%p %x)\n", this, flags);
295 streambuf_dtor(this);
296 if (flags & 1) MSVCRT_operator_delete(this);
297 return this;
300 /* ?doallocate@streambuf@@MAEHXZ */
301 /* ?doallocate@streambuf@@MEAAHXZ */
302 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
303 #define call_streambuf_doallocate(this) CALL_VTBL_FUNC(this, 40, int, (streambuf*), (this))
304 int __thiscall streambuf_doallocate(streambuf *this)
306 char *reserve;
308 TRACE("(%p)\n", this);
309 reserve = MSVCRT_operator_new(RESERVE_SIZE);
310 if (!reserve)
311 return EOF;
313 streambuf_setb(this, reserve, reserve + RESERVE_SIZE, 1);
314 return 1;
317 /* ?allocate@streambuf@@IAEHXZ */
318 /* ?allocate@streambuf@@IEAAHXZ */
319 DEFINE_THISCALL_WRAPPER(streambuf_allocate, 4)
320 int __thiscall streambuf_allocate(streambuf *this)
322 TRACE("(%p)\n", this);
323 if (this->base != NULL || this->unbuffered)
324 return 0;
325 return call_streambuf_doallocate(this);
328 /* ?base@streambuf@@IBEPADXZ */
329 /* ?base@streambuf@@IEBAPEADXZ */
330 DEFINE_THISCALL_WRAPPER(streambuf_base, 4)
331 char* __thiscall streambuf_base(const streambuf *this)
333 TRACE("(%p)\n", this);
334 return this->base;
337 /* ?blen@streambuf@@IBEHXZ */
338 /* ?blen@streambuf@@IEBAHXZ */
339 DEFINE_THISCALL_WRAPPER(streambuf_blen, 4)
340 int __thiscall streambuf_blen(const streambuf *this)
342 TRACE("(%p)\n", this);
343 return this->ebuf - this->base;
346 /* ?eback@streambuf@@IBEPADXZ */
347 /* ?eback@streambuf@@IEBAPEADXZ */
348 DEFINE_THISCALL_WRAPPER(streambuf_eback, 4)
349 char* __thiscall streambuf_eback(const streambuf *this)
351 TRACE("(%p)\n", this);
352 return this->eback;
355 /* ?ebuf@streambuf@@IBEPADXZ */
356 /* ?ebuf@streambuf@@IEBAPEADXZ */
357 DEFINE_THISCALL_WRAPPER(streambuf_ebuf, 4)
358 char* __thiscall streambuf_ebuf(const streambuf *this)
360 TRACE("(%p)\n", this);
361 return this->ebuf;
364 /* ?egptr@streambuf@@IBEPADXZ */
365 /* ?egptr@streambuf@@IEBAPEADXZ */
366 DEFINE_THISCALL_WRAPPER(streambuf_egptr, 4)
367 char* __thiscall streambuf_egptr(const streambuf *this)
369 TRACE("(%p)\n", this);
370 return this->egptr;
373 /* ?epptr@streambuf@@IBEPADXZ */
374 /* ?epptr@streambuf@@IEBAPEADXZ */
375 DEFINE_THISCALL_WRAPPER(streambuf_epptr, 4)
376 char* __thiscall streambuf_epptr(const streambuf *this)
378 TRACE("(%p)\n", this);
379 return this->epptr;
382 /* ?gptr@streambuf@@IBEPADXZ */
383 /* ?gptr@streambuf@@IEBAPEADXZ */
384 DEFINE_THISCALL_WRAPPER(streambuf_gptr, 4)
385 char* __thiscall streambuf_gptr(const streambuf *this)
387 TRACE("(%p)\n", this);
388 return this->gptr;
391 /* ?pbase@streambuf@@IBEPADXZ */
392 /* ?pbase@streambuf@@IEBAPEADXZ */
393 DEFINE_THISCALL_WRAPPER(streambuf_pbase, 4)
394 char* __thiscall streambuf_pbase(const streambuf *this)
396 TRACE("(%p)\n", this);
397 return this->pbase;
400 /* ?pptr@streambuf@@IBEPADXZ */
401 /* ?pptr@streambuf@@IEBAPEADXZ */
402 DEFINE_THISCALL_WRAPPER(streambuf_pptr, 4)
403 char* __thiscall streambuf_pptr(const streambuf *this)
405 TRACE("(%p)\n", this);
406 return this->pptr;
409 /* ?clrlock@streambuf@@QAEXXZ */
410 /* ?clrlock@streambuf@@QEAAXXZ */
411 DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
412 void __thiscall streambuf_clrlock(streambuf *this)
414 TRACE("(%p)\n", this);
415 if (this->do_lock <= 0)
416 this->do_lock++;
419 /* ?lock@streambuf@@QAEXXZ */
420 /* ?lock@streambuf@@QEAAXXZ */
421 DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
422 void __thiscall streambuf_lock(streambuf *this)
424 TRACE("(%p)\n", this);
425 if (this->do_lock < 0)
426 EnterCriticalSection(&this->lock);
429 /* ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
430 /* ?lockptr@streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
431 DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
432 CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
434 TRACE("(%p)\n", this);
435 return &this->lock;
438 /* ?gbump@streambuf@@IAEXH@Z */
439 /* ?gbump@streambuf@@IEAAXH@Z */
440 DEFINE_THISCALL_WRAPPER(streambuf_gbump, 8)
441 void __thiscall streambuf_gbump(streambuf *this, int count)
443 TRACE("(%p %d)\n", this, count);
444 this->gptr += count;
447 /* ?pbump@streambuf@@IAEXH@Z */
448 /* ?pbump@streambuf@@IEAAXH@Z */
449 DEFINE_THISCALL_WRAPPER(streambuf_pbump, 8)
450 void __thiscall streambuf_pbump(streambuf *this, int count)
452 TRACE("(%p %d)\n", this, count);
453 this->pptr += count;
456 /* ?in_avail@streambuf@@QBEHXZ */
457 /* ?in_avail@streambuf@@QEBAHXZ */
458 DEFINE_THISCALL_WRAPPER(streambuf_in_avail, 4)
459 int __thiscall streambuf_in_avail(const streambuf *this)
461 TRACE("(%p)\n", this);
462 return this->egptr - this->gptr;
465 /* ?out_waiting@streambuf@@QBEHXZ */
466 /* ?out_waiting@streambuf@@QEBAHXZ */
467 DEFINE_THISCALL_WRAPPER(streambuf_out_waiting, 4)
468 int __thiscall streambuf_out_waiting(const streambuf *this)
470 TRACE("(%p)\n", this);
471 return this->pptr - this->pbase;
474 /* Unexported */
475 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
476 #define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c))
477 int __thiscall streambuf_overflow(streambuf *this, int c)
479 ERR("overflow is not implemented in streambuf\n");
480 return EOF;
483 /* ?pbackfail@streambuf@@UAEHH@Z */
484 /* ?pbackfail@streambuf@@UEAAHH@Z */
485 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
486 #define call_streambuf_pbackfail(this, c) CALL_VTBL_FUNC(this, 36, int, (streambuf*, int), (this, c))
487 int __thiscall streambuf_pbackfail(streambuf *this, int c)
489 TRACE("(%p %d)\n", this, c);
490 if (this->gptr <= this->eback)
491 return EOF;
492 return *--this->gptr = c;
495 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
496 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
497 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
498 #define call_streambuf_seekoff(this, off, dir, mode) CALL_VTBL_FUNC(this, 12, streampos, (streambuf*, streamoff, ios_seek_dir, int), (this, off, dir, mode))
499 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, ios_seek_dir dir, int mode)
501 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
502 return EOF;
505 /* ?seekpos@streambuf@@UAEJJH@Z */
506 /* ?seekpos@streambuf@@UEAAJJH@Z */
507 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
508 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
510 TRACE("(%p %d %d)\n", this, pos, mode);
511 return call_streambuf_seekoff(this, pos, SEEKDIR_beg, mode);
514 /* ?setb@streambuf@@IAEXPAD0H@Z */
515 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
516 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
517 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
519 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
520 if (this->allocated)
521 MSVCRT_operator_delete(this->base);
522 this->allocated = delete;
523 this->base = ba;
524 this->ebuf = eb;
527 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
528 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
529 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
530 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
532 TRACE("(%p %p %d)\n", this, buffer, length);
533 if (this->base != NULL)
534 return NULL;
536 if (buffer == NULL || !length) {
537 this->unbuffered = 1;
538 this->base = this->ebuf = NULL;
539 } else {
540 this->unbuffered = 0;
541 this->base = buffer;
542 this->ebuf = buffer + length;
544 return this;
547 /* ?setg@streambuf@@IAEXPAD00@Z */
548 /* ?setg@streambuf@@IEAAXPEAD00@Z */
549 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
550 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
552 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
553 this->eback = ek;
554 this->gptr = gp;
555 this->egptr = eg;
558 /* ?setlock@streambuf@@QAEXXZ */
559 /* ?setlock@streambuf@@QEAAXXZ */
560 DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
561 void __thiscall streambuf_setlock(streambuf *this)
563 TRACE("(%p)\n", this);
564 this->do_lock--;
567 /* ?setp@streambuf@@IAEXPAD0@Z */
568 /* ?setp@streambuf@@IEAAXPEAD0@Z */
569 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
570 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
572 TRACE("(%p %p %p)\n", this, pb, ep);
573 this->pbase = this->pptr = pb;
574 this->epptr = ep;
577 /* ?sync@streambuf@@UAEHXZ */
578 /* ?sync@streambuf@@UEAAHXZ */
579 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
580 #define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
581 int __thiscall streambuf_sync(streambuf *this)
583 TRACE("(%p)\n", this);
584 return (this->gptr >= this->egptr && this->pbase >= this->pptr) ? 0 : EOF;
587 /* ?unbuffered@streambuf@@IAEXH@Z */
588 /* ?unbuffered@streambuf@@IEAAXH@Z */
589 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_set, 8)
590 void __thiscall streambuf_unbuffered_set(streambuf *this, int buf)
592 TRACE("(%p %d)\n", this, buf);
593 this->unbuffered = buf;
596 /* ?unbuffered@streambuf@@IBEHXZ */
597 /* ?unbuffered@streambuf@@IEBAHXZ */
598 DEFINE_THISCALL_WRAPPER(streambuf_unbuffered_get, 4)
599 int __thiscall streambuf_unbuffered_get(const streambuf *this)
601 TRACE("(%p)\n", this);
602 return this->unbuffered;
605 /* Unexported */
606 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
607 #define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this))
608 int __thiscall streambuf_underflow(streambuf *this)
610 ERR("underflow is not implemented in streambuf\n");
611 return EOF;
614 /* ?unlock@streambuf@@QAEXXZ */
615 /* ?unlock@streambuf@@QEAAXXZ */
616 DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
617 void __thiscall streambuf_unlock(streambuf *this)
619 TRACE("(%p)\n", this);
620 if (this->do_lock < 0)
621 LeaveCriticalSection(&this->lock);
624 /* ?xsgetn@streambuf@@UAEHPADH@Z */
625 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
626 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
627 #define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count))
628 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
630 int copied = 0, chunk;
632 TRACE("(%p %p %d)\n", this, buffer, count);
634 if (this->unbuffered) {
635 if (this->stored_char == EOF)
636 this->stored_char = call_streambuf_underflow(this);
637 while (copied < count && this->stored_char != EOF) {
638 buffer[copied++] = this->stored_char;
639 this->stored_char = call_streambuf_underflow(this);
641 } else {
642 while (copied < count) {
643 if (call_streambuf_underflow(this) == EOF)
644 break;
645 chunk = this->egptr - this->gptr;
646 if (chunk > count - copied)
647 chunk = count - copied;
648 memcpy(buffer+copied, this->gptr, chunk);
649 this->gptr += chunk;
650 copied += chunk;
653 return copied;
656 /* ?xsputn@streambuf@@UAEHPBDH@Z */
657 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
658 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
659 #define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length))
660 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
662 int copied = 0, chunk;
664 TRACE("(%p %p %d)\n", this, data, length);
666 while (copied < length) {
667 if (this->unbuffered || this->pptr == this->epptr) {
668 if (call_streambuf_overflow(this, data[copied]) == EOF)
669 break;
670 copied++;
671 } else {
672 chunk = this->epptr - this->pptr;
673 if (chunk > length - copied)
674 chunk = length - copied;
675 memcpy(this->pptr, data+copied, chunk);
676 this->pptr += chunk;
677 copied += chunk;
680 return copied;
683 /* ?sgetc@streambuf@@QAEHXZ */
684 /* ?sgetc@streambuf@@QEAAHXZ */
685 DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4)
686 int __thiscall streambuf_sgetc(streambuf *this)
688 TRACE("(%p)\n", this);
689 if (this->unbuffered) {
690 if (this->stored_char == EOF)
691 this->stored_char = call_streambuf_underflow(this);
692 return this->stored_char;
693 } else
694 return call_streambuf_underflow(this);
697 /* ?sputc@streambuf@@QAEHH@Z */
698 /* ?sputc@streambuf@@QEAAHH@Z */
699 DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8)
700 int __thiscall streambuf_sputc(streambuf *this, int ch)
702 TRACE("(%p %d)\n", this, ch);
703 return (this->pptr < this->epptr) ? *this->pptr++ = ch : call_streambuf_overflow(this, ch);
706 /* ?sgetn@streambuf@@QAEHPADH@Z */
707 /* ?sgetn@streambuf@@QEAAHPEADH@Z */
708 DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12)
709 int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count)
711 return call_streambuf_xsgetn(this, buffer, count);
714 /* ?sputn@streambuf@@QAEHPBDH@Z */
715 /* ?sputn@streambuf@@QEAAHPEBDH@Z */
716 DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12)
717 int __thiscall streambuf_sputn(streambuf *this, const char *data, int length)
719 return call_streambuf_xsputn(this, data, length);
722 /* ?snextc@streambuf@@QAEHXZ */
723 /* ?snextc@streambuf@@QEAAHXZ */
724 DEFINE_THISCALL_WRAPPER(streambuf_snextc, 4)
725 int __thiscall streambuf_snextc(streambuf *this)
727 TRACE("(%p)\n", this);
728 if (this->unbuffered) {
729 if (this->stored_char == EOF)
730 call_streambuf_underflow(this);
731 return this->stored_char = call_streambuf_underflow(this);
732 } else {
733 if (this->gptr >= this->egptr)
734 call_streambuf_underflow(this);
735 this->gptr++;
736 return (this->gptr < this->egptr) ? *this->gptr : call_streambuf_underflow(this);
740 /* ?sbumpc@streambuf@@QAEHXZ */
741 /* ?sbumpc@streambuf@@QEAAHXZ */
742 DEFINE_THISCALL_WRAPPER(streambuf_sbumpc, 4)
743 int __thiscall streambuf_sbumpc(streambuf *this)
745 int ret;
747 TRACE("(%p)\n", this);
749 if (this->unbuffered) {
750 ret = this->stored_char;
751 this->stored_char = EOF;
752 if (ret == EOF)
753 ret = call_streambuf_underflow(this);
754 } else {
755 ret = (this->gptr < this->egptr) ? *this->gptr : call_streambuf_underflow(this);
756 this->gptr++;
758 return ret;
761 /* ?stossc@streambuf@@QAEXXZ */
762 /* ?stossc@streambuf@@QEAAXXZ */
763 DEFINE_THISCALL_WRAPPER(streambuf_stossc, 4)
764 void __thiscall streambuf_stossc(streambuf *this)
766 TRACE("(%p)\n", this);
767 if (this->unbuffered) {
768 if (this->stored_char == EOF)
769 call_streambuf_underflow(this);
770 else
771 this->stored_char = EOF;
772 } else {
773 if (this->gptr >= this->egptr)
774 call_streambuf_underflow(this);
775 if (this->gptr < this->egptr)
776 this->gptr++;
780 /* ?sputbackc@streambuf@@QAEHD@Z */
781 /* ?sputbackc@streambuf@@QEAAHD@Z */
782 DEFINE_THISCALL_WRAPPER(streambuf_sputbackc, 8)
783 int __thiscall streambuf_sputbackc(streambuf *this, char ch)
785 TRACE("(%p %d)\n", this, ch);
786 return call_streambuf_pbackfail(this, ch);
789 /* ?dbp@streambuf@@QAEXXZ */
790 /* ?dbp@streambuf@@QEAAXXZ */
791 DEFINE_THISCALL_WRAPPER(streambuf_dbp, 4)
792 void __thiscall streambuf_dbp(streambuf *this)
794 printf("\nSTREAMBUF DEBUG INFO: this=%p, ", this);
795 if (this->unbuffered) {
796 printf("unbuffered\n");
797 } else {
798 printf("_fAlloc=%d\n", this->allocated);
799 printf(" base()=%p, ebuf()=%p, blen()=%d\n", this->base, this->ebuf, streambuf_blen(this));
800 printf("pbase()=%p, pptr()=%p, epptr()=%d\n", this->pbase, this->pptr, this->epptr);
801 printf("eback()=%p, gptr()=%p, egptr()=%d\n", this->eback, this->gptr, this->egptr);
805 /* ??0filebuf@@QAE@ABV0@@Z */
806 /* ??0filebuf@@QEAA@AEBV0@@Z */
807 DEFINE_THISCALL_WRAPPER(filebuf_copy_ctor, 8)
808 filebuf* __thiscall filebuf_copy_ctor(filebuf* this, const filebuf *copy)
810 TRACE("(%p %p)\n", this, copy);
811 *this = *copy;
812 this->base.vtable = &MSVCP_filebuf_vtable;
813 return this;
816 /* ??0filebuf@@QAE@HPADH@Z */
817 /* ??0filebuf@@QEAA@HPEADH@Z */
818 DEFINE_THISCALL_WRAPPER(filebuf_fd_reserve_ctor, 16)
819 filebuf* __thiscall filebuf_fd_reserve_ctor(filebuf* this, filedesc fd, char *buffer, int length)
821 TRACE("(%p %d %p %d)\n", this, fd, buffer, length);
822 streambuf_reserve_ctor(&this->base, buffer, length);
823 this->base.vtable = &MSVCP_filebuf_vtable;
824 this->fd = fd;
825 this->close = 0;
826 return this;
829 /* ??0filebuf@@QAE@H@Z */
830 /* ??0filebuf@@QEAA@H@Z */
831 DEFINE_THISCALL_WRAPPER(filebuf_fd_ctor, 8)
832 filebuf* __thiscall filebuf_fd_ctor(filebuf* this, filedesc fd)
834 filebuf_fd_reserve_ctor(this, fd, NULL, 0);
835 this->base.unbuffered = 0;
836 return this;
839 /* ??0filebuf@@QAE@XZ */
840 /* ??0filebuf@@QEAA@XZ */
841 DEFINE_THISCALL_WRAPPER(filebuf_ctor, 4)
842 filebuf* __thiscall filebuf_ctor(filebuf* this)
844 return filebuf_fd_ctor(this, -1);
847 /* ??1filebuf@@UAE@XZ */
848 /* ??1filebuf@@UEAA@XZ */
849 DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
850 void __thiscall filebuf_dtor(filebuf* this)
852 TRACE("(%p)\n", this);
853 if (this->close)
854 filebuf_close(this);
855 streambuf_dtor(&this->base);
858 /* ??4filebuf@@QAEAAV0@ABV0@@Z */
859 /* ??4filebuf@@QEAAAEAV0@AEBV0@@Z */
860 DEFINE_THISCALL_WRAPPER(filebuf_assign, 8)
861 filebuf* __thiscall filebuf_assign(filebuf* this, const filebuf *rhs)
863 filebuf_dtor(this);
864 return filebuf_copy_ctor(this, rhs);
867 /* ??_Efilebuf@@UAEPAXI@Z */
868 DEFINE_THISCALL_WRAPPER(filebuf_vector_dtor, 8)
869 filebuf* __thiscall filebuf_vector_dtor(filebuf *this, unsigned int flags)
871 TRACE("(%p %x)\n", this, flags);
872 if (flags & 2) {
873 /* we have an array, with the number of elements stored before the first object */
874 INT_PTR i, *ptr = (INT_PTR *)this-1;
876 for (i = *ptr-1; i >= 0; i--)
877 filebuf_dtor(this+i);
878 MSVCRT_operator_delete(ptr);
879 } else {
880 filebuf_dtor(this);
881 if (flags & 1)
882 MSVCRT_operator_delete(this);
884 return this;
887 /* ??_Gfilebuf@@UAEPAXI@Z */
888 DEFINE_THISCALL_WRAPPER(filebuf_scalar_dtor, 8)
889 filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
891 TRACE("(%p %x)\n", this, flags);
892 filebuf_dtor(this);
893 if (flags & 1) MSVCRT_operator_delete(this);
894 return this;
897 /* ?attach@filebuf@@QAEPAV1@H@Z */
898 /* ?attach@filebuf@@QEAAPEAV1@H@Z */
899 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
900 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
902 TRACE("(%p %d)\n", this, fd);
903 if (this->fd != -1)
904 return NULL;
906 streambuf_lock(&this->base);
907 this->fd = fd;
908 streambuf_allocate(&this->base);
909 streambuf_unlock(&this->base);
910 return this;
913 /* ?close@filebuf@@QAEPAV1@XZ */
914 /* ?close@filebuf@@QEAAPEAV1@XZ */
915 DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
916 filebuf* __thiscall filebuf_close(filebuf *this)
918 filebuf *ret;
920 TRACE("(%p)\n", this);
921 if (this->fd == -1)
922 return NULL;
924 streambuf_lock(&this->base);
925 if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
926 ret = NULL;
927 } else {
928 this->fd = -1;
929 ret = this;
931 streambuf_unlock(&this->base);
932 return ret;
935 /* ?fd@filebuf@@QBEHXZ */
936 /* ?fd@filebuf@@QEBAHXZ */
937 DEFINE_THISCALL_WRAPPER(filebuf_fd, 4)
938 filedesc __thiscall filebuf_fd(const filebuf *this)
940 TRACE("(%p)\n", this);
941 return this->fd;
944 /* ?is_open@filebuf@@QBEHXZ */
945 /* ?is_open@filebuf@@QEBAHXZ */
946 DEFINE_THISCALL_WRAPPER(filebuf_is_open, 4)
947 int __thiscall filebuf_is_open(const filebuf *this)
949 TRACE("(%p)\n", this);
950 return this->fd != -1;
953 /* ?open@filebuf@@QAEPAV1@PBDHH@Z */
954 /* ?open@filebuf@@QEAAPEAV1@PEBDHH@Z */
955 DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
956 filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
958 const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
959 const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
960 int op_flags, sh_flags, fd;
962 TRACE("(%p %s %x %x)\n", this, name, mode, protection);
963 if (this->fd != -1)
964 return NULL;
966 /* mode */
967 if (mode & (OPENMODE_app|OPENMODE_trunc))
968 mode |= OPENMODE_out;
969 op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
970 if (op_flags < 0)
971 return NULL;
972 if (mode & OPENMODE_app)
973 op_flags |= _O_APPEND;
974 if ((mode & OPENMODE_trunc) ||
975 ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
976 op_flags |= _O_TRUNC;
977 if (!(mode & OPENMODE_nocreate))
978 op_flags |= _O_CREAT;
979 if (mode & OPENMODE_noreplace)
980 op_flags |= _O_EXCL;
981 op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
983 /* share protection */
984 sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
986 TRACE("op_flags %x, sh_flags %x\n", op_flags, sh_flags);
987 fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
988 if (fd < 0)
989 return NULL;
991 streambuf_lock(&this->base);
992 this->close = 1;
993 this->fd = fd;
994 if ((mode & OPENMODE_ate) &&
995 call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
996 _close(fd);
997 this->fd = -1;
999 streambuf_allocate(&this->base);
1000 streambuf_unlock(&this->base);
1001 return (this->fd == -1) ? NULL : this;
1004 /* ?overflow@filebuf@@UAEHH@Z */
1005 /* ?overflow@filebuf@@UEAAHH@Z */
1006 DEFINE_THISCALL_WRAPPER(filebuf_overflow, 8)
1007 int __thiscall filebuf_overflow(filebuf *this, int c)
1009 TRACE("(%p %d)\n", this, c);
1010 if (call_streambuf_sync(&this->base) == EOF)
1011 return EOF;
1012 if (this->base.unbuffered)
1013 return (c == EOF) ? 1 : _write(this->fd, &c, 1);
1014 if (streambuf_allocate(&this->base) == EOF)
1015 return EOF;
1017 this->base.pbase = this->base.pptr = this->base.base;
1018 this->base.epptr = this->base.ebuf;
1019 if (c != EOF)
1020 *this->base.pptr++ = c;
1021 return 1;
1024 /* ?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z */
1025 /* ?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z */
1026 DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
1027 streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
1029 TRACE("(%p %d %d %d)\n", this, offset, dir, mode);
1030 if (call_streambuf_sync(&this->base) == EOF)
1031 return EOF;
1032 return _lseek(this->fd, offset, dir);
1035 /* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
1036 /* ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z */
1037 DEFINE_THISCALL_WRAPPER(filebuf_setbuf, 12)
1038 streambuf* __thiscall filebuf_setbuf(filebuf *this, char *buffer, int length)
1040 streambuf *ret;
1042 TRACE("(%p %p %d)\n", this, buffer, length);
1043 if (this->base.base != NULL)
1044 return NULL;
1046 streambuf_lock(&this->base);
1047 ret = streambuf_setbuf(&this->base, buffer, length);
1048 streambuf_unlock(&this->base);
1049 return ret;
1052 /* ?setmode@filebuf@@QAEHH@Z */
1053 /* ?setmode@filebuf@@QEAAHH@Z */
1054 DEFINE_THISCALL_WRAPPER(filebuf_setmode, 8)
1055 int __thiscall filebuf_setmode(filebuf *this, int mode)
1057 int ret;
1059 TRACE("(%p %d)\n", this, mode);
1060 if (mode != filebuf_text && mode != filebuf_binary)
1061 return -1;
1063 streambuf_lock(&this->base);
1064 ret = (call_streambuf_sync(&this->base) == EOF) ? -1 : _setmode(this->fd, mode);
1065 streambuf_unlock(&this->base);
1066 return ret;
1069 /* ?sync@filebuf@@UAEHXZ */
1070 /* ?sync@filebuf@@UEAAHXZ */
1071 DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
1072 int __thiscall filebuf_sync(filebuf *this)
1074 int count, mode;
1075 char *ptr;
1076 LONG offset;
1078 TRACE("(%p)\n", this);
1079 if (this->fd == -1)
1080 return EOF;
1081 if (this->base.unbuffered)
1082 return 0;
1084 /* flush output buffer */
1085 if (this->base.pptr != NULL) {
1086 count = this->base.pptr - this->base.pbase;
1087 if (count > 0 && _write(this->fd, this->base.pbase, count) != count)
1088 return EOF;
1089 this->base.pbase = this->base.pptr = this->base.epptr = NULL;
1091 /* flush input buffer */
1092 if (this->base.egptr != NULL) {
1093 offset = this->base.egptr - this->base.gptr;
1094 if (offset > 0) {
1095 mode = _setmode(this->fd, _O_TEXT);
1096 _setmode(this->fd, mode);
1097 if (mode & _O_TEXT) {
1098 /* in text mode, '\n' in the buffer means '\r\n' in the file */
1099 for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
1100 if (*ptr == '\n')
1101 offset++;
1103 if (_lseek(this->fd, -offset, SEEK_CUR) < 0)
1104 return EOF;
1106 this->base.eback = this->base.gptr = this->base.egptr = NULL;
1108 return 0;
1111 /* ?underflow@filebuf@@UAEHXZ */
1112 /* ?underflow@filebuf@@UEAAHXZ */
1113 DEFINE_THISCALL_WRAPPER(filebuf_underflow, 4)
1114 int __thiscall filebuf_underflow(filebuf *this)
1116 int buffer_size, read_bytes;
1117 char c;
1119 TRACE("(%p)\n", this);
1121 if (this->base.unbuffered)
1122 return (_read(this->fd, &c, 1) < 1) ? EOF : c;
1124 if (this->base.gptr >= this->base.egptr) {
1125 if (call_streambuf_sync(&this->base) == EOF)
1126 return EOF;
1127 buffer_size = this->base.ebuf - this->base.base;
1128 read_bytes = _read(this->fd, this->base.base, buffer_size);
1129 if (read_bytes <= 0)
1130 return EOF;
1131 this->base.eback = this->base.gptr = this->base.base;
1132 this->base.egptr = this->base.base + read_bytes;
1134 return *this->base.gptr;
1137 /* ??0strstreambuf@@QAE@ABV0@@Z */
1138 /* ??0strstreambuf@@QEAA@AEBV0@@Z */
1139 DEFINE_THISCALL_WRAPPER(strstreambuf_copy_ctor, 8)
1140 strstreambuf* __thiscall strstreambuf_copy_ctor(strstreambuf *this, const strstreambuf *copy)
1142 TRACE("(%p %p)\n", this, copy);
1143 *this = *copy;
1144 this->base.vtable = &MSVCP_strstreambuf_vtable;
1145 return this;
1148 /* ??0strstreambuf@@QAE@H@Z */
1149 /* ??0strstreambuf@@QEAA@H@Z */
1150 DEFINE_THISCALL_WRAPPER(strstreambuf_dynamic_ctor, 8)
1151 strstreambuf* __thiscall strstreambuf_dynamic_ctor(strstreambuf* this, int length)
1153 TRACE("(%p %d)\n", this, length);
1154 streambuf_ctor(&this->base);
1155 this->base.vtable = &MSVCP_strstreambuf_vtable;
1156 this->dynamic = 1;
1157 this->increase = length;
1158 this->constant = 0;
1159 this->f_alloc = NULL;
1160 this->f_free = NULL;
1161 return this;
1164 /* ??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z */
1165 /* ??0strstreambuf@@QEAA@P6APEAXJ@ZP6AXPEAX@Z@Z */
1166 DEFINE_THISCALL_WRAPPER(strstreambuf_funcs_ctor, 12)
1167 strstreambuf* __thiscall strstreambuf_funcs_ctor(strstreambuf* this, allocFunction falloc, freeFunction ffree)
1169 TRACE("(%p %p %p)\n", this, falloc, ffree);
1170 strstreambuf_dynamic_ctor(this, 1);
1171 this->f_alloc = falloc;
1172 this->f_free = ffree;
1173 return this;
1176 /* ??0strstreambuf@@QAE@PADH0@Z */
1177 /* ??0strstreambuf@@QEAA@PEADH0@Z */
1178 DEFINE_THISCALL_WRAPPER(strstreambuf_buffer_ctor, 16)
1179 strstreambuf* __thiscall strstreambuf_buffer_ctor(strstreambuf *this, char *buffer, int length, char *put)
1181 char *end_buffer;
1183 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1185 if (length > 0)
1186 end_buffer = buffer + length;
1187 else if (length == 0)
1188 end_buffer = buffer + strlen(buffer);
1189 else
1190 end_buffer = (char*) -1;
1192 streambuf_ctor(&this->base);
1193 streambuf_setb(&this->base, buffer, end_buffer, 0);
1194 if (put == NULL) {
1195 streambuf_setg(&this->base, buffer, buffer, end_buffer);
1196 } else {
1197 streambuf_setg(&this->base, buffer, buffer, put);
1198 streambuf_setp(&this->base, put, end_buffer);
1200 this->base.vtable = &MSVCP_strstreambuf_vtable;
1201 this->dynamic = 0;
1202 this->constant = 1;
1203 return this;
1206 /* ??0strstreambuf@@QAE@PAEH0@Z */
1207 /* ??0strstreambuf@@QEAA@PEAEH0@Z */
1208 DEFINE_THISCALL_WRAPPER(strstreambuf_ubuffer_ctor, 16)
1209 strstreambuf* __thiscall strstreambuf_ubuffer_ctor(strstreambuf *this, unsigned char *buffer, int length, unsigned char *put)
1211 TRACE("(%p %p %d %p)\n", this, buffer, length, put);
1212 return strstreambuf_buffer_ctor(this, (char*)buffer, length, (char*)put);
1215 /* ??0strstreambuf@@QAE@XZ */
1216 /* ??0strstreambuf@@QEAA@XZ */
1217 DEFINE_THISCALL_WRAPPER(strstreambuf_ctor, 4)
1218 strstreambuf* __thiscall strstreambuf_ctor(strstreambuf *this)
1220 TRACE("(%p)\n", this);
1221 return strstreambuf_dynamic_ctor(this, 1);
1224 /* ??1strstreambuf@@UAE@XZ */
1225 /* ??1strstreambuf@@UEAA@XZ */
1226 DEFINE_THISCALL_WRAPPER(strstreambuf_dtor, 4)
1227 void __thiscall strstreambuf_dtor(strstreambuf *this)
1229 TRACE("(%p)\n", this);
1230 if (this->dynamic && this->base.base) {
1231 if (this->f_free)
1232 this->f_free(this->base.base);
1233 else
1234 MSVCRT_operator_delete(this->base.base);
1236 streambuf_dtor(&this->base);
1239 /* ??4strstreambuf@@QAEAAV0@ABV0@@Z */
1240 /* ??4strstreambuf@@QEAAAEAV0@AEBV0@@Z */
1241 DEFINE_THISCALL_WRAPPER(strstreambuf_assign, 8)
1242 strstreambuf* __thiscall strstreambuf_assign(strstreambuf *this, const strstreambuf *rhs)
1244 strstreambuf_dtor(this);
1245 return strstreambuf_copy_ctor(this, rhs);
1248 /* ??_Estrstreambuf@@UAEPAXI@Z */
1249 DEFINE_THISCALL_WRAPPER(strstreambuf_vector_dtor, 8)
1250 strstreambuf* __thiscall strstreambuf_vector_dtor(strstreambuf *this, unsigned int flags)
1252 TRACE("(%p %x)\n", this, flags);
1253 if (flags & 2) {
1254 /* we have an array, with the number of elements stored before the first object */
1255 INT_PTR i, *ptr = (INT_PTR *)this-1;
1257 for (i = *ptr-1; i >= 0; i--)
1258 strstreambuf_dtor(this+i);
1259 MSVCRT_operator_delete(ptr);
1260 } else {
1261 strstreambuf_dtor(this);
1262 if (flags & 1)
1263 MSVCRT_operator_delete(this);
1265 return this;
1268 /* ??_Gstrstreambuf@@UAEPAXI@Z */
1269 DEFINE_THISCALL_WRAPPER(strstreambuf_scalar_dtor, 8)
1270 strstreambuf* __thiscall strstreambuf_scalar_dtor(strstreambuf *this, unsigned int flags)
1272 TRACE("(%p %x)\n", this, flags);
1273 strstreambuf_dtor(this);
1274 if (flags & 1) MSVCRT_operator_delete(this);
1275 return this;
1278 /* ?doallocate@strstreambuf@@MAEHXZ */
1279 /* ?doallocate@strstreambuf@@MEAAHXZ */
1280 DEFINE_THISCALL_WRAPPER(strstreambuf_doallocate, 4)
1281 int __thiscall strstreambuf_doallocate(strstreambuf *this)
1283 char *prev_buffer = this->base.base, *new_buffer;
1284 LONG prev_size = this->base.ebuf - this->base.base, new_size;
1286 TRACE("(%p)\n", this);
1288 /* calculate the size of the new buffer */
1289 new_size = (prev_size > 0 ? prev_size : 0) + (this->increase > 0 ? this->increase : 1);
1290 /* get a new buffer */
1291 if (this->f_alloc)
1292 new_buffer = this->f_alloc(new_size);
1293 else
1294 new_buffer = MSVCRT_operator_new(new_size);
1295 if (!new_buffer)
1296 return EOF;
1297 if (this->base.ebuf) {
1298 /* copy the contents and adjust the pointers */
1299 memcpy(new_buffer, this->base.base, prev_size);
1300 if (this->base.egptr) {
1301 this->base.eback += new_buffer - prev_buffer;
1302 this->base.gptr += new_buffer - prev_buffer;
1303 this->base.egptr += new_buffer - prev_buffer;
1305 if (this->base.epptr) {
1306 this->base.pbase += new_buffer - prev_buffer;
1307 this->base.pptr += new_buffer - prev_buffer;
1308 this->base.epptr += new_buffer - prev_buffer;
1310 /* free the old buffer */
1311 if (this->f_free)
1312 this->f_free(this->base.base);
1313 else
1314 MSVCRT_operator_delete(this->base.base);
1316 streambuf_setb(&this->base, new_buffer, new_buffer + new_size, 0);
1317 return 1;
1320 /* ?freeze@strstreambuf@@QAEXH@Z */
1321 /* ?freeze@strstreambuf@@QEAAXH@Z */
1322 DEFINE_THISCALL_WRAPPER(strstreambuf_freeze, 8)
1323 void __thiscall strstreambuf_freeze(strstreambuf *this, int frozen)
1325 TRACE("(%p %d)\n", this, frozen);
1326 if (!this->constant)
1327 this->dynamic = !frozen;
1330 /* ?overflow@strstreambuf@@UAEHH@Z */
1331 /* ?overflow@strstreambuf@@UEAAHH@Z */
1332 DEFINE_THISCALL_WRAPPER(strstreambuf_overflow, 8)
1333 int __thiscall strstreambuf_overflow(strstreambuf *this, int c)
1335 TRACE("(%p %d)\n", this, c);
1336 if (this->base.pptr >= this->base.epptr) {
1337 /* increase the buffer size if it's dynamic */
1338 if (!this->dynamic || call_streambuf_doallocate(&this->base) == EOF)
1339 return EOF;
1340 if (!this->base.epptr)
1341 this->base.pbase = this->base.pptr = this->base.egptr ? this->base.egptr : this->base.base;
1342 this->base.epptr = this->base.ebuf;
1344 if (c != EOF)
1345 *this->base.pptr++ = c;
1346 return 1;
1349 /* ?seekoff@strstreambuf@@UAEJJW4seek_dir@ios@@H@Z */
1350 /* ?seekoff@strstreambuf@@UEAAJJW4seek_dir@ios@@H@Z */
1351 DEFINE_THISCALL_WRAPPER(strstreambuf_seekoff, 16)
1352 streampos __thiscall strstreambuf_seekoff(strstreambuf *this, streamoff offset, ios_seek_dir dir, int mode)
1354 FIXME("(%p %d %d %d) stub\n", this, offset, dir, mode);
1355 return EOF;
1358 /* ?setbuf@strstreambuf@@UAEPAVstreambuf@@PADH@Z */
1359 /* ?setbuf@strstreambuf@@UEAAPEAVstreambuf@@PEADH@Z */
1360 DEFINE_THISCALL_WRAPPER(strstreambuf_setbuf, 12)
1361 streambuf* __thiscall strstreambuf_setbuf(strstreambuf *this, char *buffer, int length)
1363 TRACE("(%p %p %d)\n", this, buffer, length);
1364 if (length)
1365 this->increase = length;
1366 return &this->base;
1369 /* ?str@strstreambuf@@QAEPADXZ */
1370 /* ?str@strstreambuf@@QEAAPEADXZ */
1371 DEFINE_THISCALL_WRAPPER(strstreambuf_str, 4)
1372 char* __thiscall strstreambuf_str(strstreambuf *this)
1374 TRACE("(%p)\n", this);
1375 strstreambuf_freeze(this, 1);
1376 return this->base.base;
1379 /* ?sync@strstreambuf@@UAEHXZ */
1380 /* ?sync@strstreambuf@@UEAAHXZ */
1381 DEFINE_THISCALL_WRAPPER(strstreambuf_sync, 4)
1382 int __thiscall strstreambuf_sync(strstreambuf *this)
1384 TRACE("(%p)\n", this);
1385 return 0;
1388 /* ?underflow@strstreambuf@@UAEHXZ */
1389 /* ?underflow@strstreambuf@@UEAAHXZ */
1390 DEFINE_THISCALL_WRAPPER(strstreambuf_underflow, 4)
1391 int __thiscall strstreambuf_underflow(strstreambuf *this)
1393 TRACE("(%p)\n", this);
1394 if (this->base.gptr < this->base.egptr)
1395 return *this->base.gptr;
1396 /* extend the get area to include the characters written */
1397 if (this->base.egptr < this->base.pptr)
1398 this->base.egptr = this->base.pptr;
1399 return (this->base.gptr < this->base.egptr) ? *this->base.gptr : EOF;
1402 /* ??0ios@@IAE@ABV0@@Z */
1403 /* ??0ios@@IEAA@AEBV0@@Z */
1404 DEFINE_THISCALL_WRAPPER(ios_copy_ctor, 8)
1405 ios* __thiscall ios_copy_ctor(ios *this, const ios *copy)
1407 TRACE("(%p %p)\n", this, copy);
1408 ios_fLockcInit++;
1409 this->vtable = &MSVCP_ios_vtable;
1410 this->sb = NULL;
1411 this->delbuf = 0;
1412 InitializeCriticalSection(&this->lock);
1413 return ios_assign(this, copy);
1416 /* ??0ios@@QAE@PAVstreambuf@@@Z */
1417 /* ??0ios@@QEAA@PEAVstreambuf@@@Z */
1418 DEFINE_THISCALL_WRAPPER(ios_sb_ctor, 8)
1419 ios* __thiscall ios_sb_ctor(ios *this, streambuf *sb)
1421 TRACE("(%p %p)\n", this, sb);
1422 ios_fLockcInit++;
1423 this->vtable = &MSVCP_ios_vtable;
1424 this->sb = sb;
1425 this->state = sb ? IOSTATE_goodbit : IOSTATE_badbit;
1426 this->special[0] = this->special[1] = 0;
1427 this->delbuf = 0;
1428 this->tie = NULL;
1429 this->flags = 0;
1430 this->precision = 6;
1431 this->fill = ' ';
1432 this->width = 0;
1433 this->do_lock = -1;
1434 InitializeCriticalSection(&this->lock);
1435 return this;
1438 /* ??0ios@@IAE@XZ */
1439 /* ??0ios@@IEAA@XZ */
1440 DEFINE_THISCALL_WRAPPER(ios_ctor, 4)
1441 ios* __thiscall ios_ctor(ios *this)
1443 return ios_sb_ctor(this, NULL);
1446 /* ??1ios@@UAE@XZ */
1447 /* ??1ios@@UEAA@XZ */
1448 DEFINE_THISCALL_WRAPPER(ios_dtor, 4)
1449 void __thiscall ios_dtor(ios *this)
1451 TRACE("(%p)\n", this);
1452 ios_fLockcInit--;
1453 if (this->delbuf && this->sb)
1454 call_streambuf_vector_dtor(this->sb, 1);
1455 this->sb = NULL;
1456 this->state = IOSTATE_badbit;
1457 DeleteCriticalSection(&this->lock);
1460 /* ??4ios@@IAEAAV0@ABV0@@Z */
1461 /* ??4ios@@IEAAAEAV0@AEBV0@@Z */
1462 DEFINE_THISCALL_WRAPPER(ios_assign, 8)
1463 ios* __thiscall ios_assign(ios *this, const ios *rhs)
1465 TRACE("(%p %p)\n", this, rhs);
1466 this->state = rhs->state;
1467 if (!this->sb)
1468 this->state |= IOSTATE_badbit;
1469 this->tie = rhs->tie;
1470 this->flags = rhs->flags;
1471 this->precision = (char) rhs->precision;
1472 this->fill = rhs->fill;
1473 this->width = (char) rhs->width;
1474 return this;
1477 /* ??7ios@@QBEHXZ */
1478 /* ??7ios@@QEBAHXZ */
1479 DEFINE_THISCALL_WRAPPER(ios_op_not, 4)
1480 int __thiscall ios_op_not(const ios *this)
1482 TRACE("(%p)\n", this);
1483 return ios_fail(this);
1486 /* ??Bios@@QBEPAXXZ */
1487 /* ??Bios@@QEBAPEAXXZ */
1488 DEFINE_THISCALL_WRAPPER(ios_op_void, 4)
1489 void* __thiscall ios_op_void(const ios *this)
1491 TRACE("(%p)\n", this);
1492 return ios_fail(this) ? NULL : (void*)this;
1495 /* ??_Eios@@UAEPAXI@Z */
1496 DEFINE_THISCALL_WRAPPER(ios_vector_dtor, 8)
1497 ios* __thiscall ios_vector_dtor(ios *this, unsigned int flags)
1499 TRACE("(%p %x)\n", this, flags);
1500 if (flags & 2) {
1501 /* we have an array, with the number of elements stored before the first object */
1502 INT_PTR i, *ptr = (INT_PTR *)this-1;
1504 for (i = *ptr-1; i >= 0; i--)
1505 ios_dtor(this+i);
1506 MSVCRT_operator_delete(ptr);
1507 } else {
1508 ios_dtor(this);
1509 if (flags & 1)
1510 MSVCRT_operator_delete(this);
1512 return this;
1515 /* ??_Gios@@UAEPAXI@Z */
1516 DEFINE_THISCALL_WRAPPER(ios_scalar_dtor, 8)
1517 ios* __thiscall ios_scalar_dtor(ios *this, unsigned int flags)
1519 TRACE("(%p %x)\n", this, flags);
1520 ios_dtor(this);
1521 if (flags & 1) MSVCRT_operator_delete(this);
1522 return this;
1525 /* ?bad@ios@@QBEHXZ */
1526 /* ?bad@ios@@QEBAHXZ */
1527 DEFINE_THISCALL_WRAPPER(ios_bad, 4)
1528 int __thiscall ios_bad(const ios *this)
1530 TRACE("(%p)\n", this);
1531 return (this->state & IOSTATE_badbit);
1534 /* ?bitalloc@ios@@SAJXZ */
1535 LONG __cdecl ios_bitalloc(void)
1537 TRACE("()\n");
1538 ios_lockc();
1539 ios_maxbit <<= 1;
1540 ios_unlockc();
1541 return ios_maxbit;
1544 /* ?clear@ios@@QAEXH@Z */
1545 /* ?clear@ios@@QEAAXH@Z */
1546 DEFINE_THISCALL_WRAPPER(ios_clear, 8)
1547 void __thiscall ios_clear(ios *this, int state)
1549 TRACE("(%p %d)\n", this, state);
1550 ios_lock(this);
1551 this->state = state;
1552 ios_unlock(this);
1555 /* ?clrlock@ios@@QAAXXZ */
1556 /* ?clrlock@ios@@QEAAXXZ */
1557 void __cdecl ios_clrlock(ios *this)
1559 TRACE("(%p)\n", this);
1560 if (this->do_lock <= 0)
1561 this->do_lock++;
1562 if (this->sb)
1563 streambuf_clrlock(this->sb);
1566 /* ?delbuf@ios@@QAEXH@Z */
1567 /* ?delbuf@ios@@QEAAXH@Z */
1568 DEFINE_THISCALL_WRAPPER(ios_delbuf_set, 8)
1569 void __thiscall ios_delbuf_set(ios *this, int delete)
1571 TRACE("(%p %d)\n", this, delete);
1572 this->delbuf = delete;
1575 /* ?delbuf@ios@@QBEHXZ */
1576 /* ?delbuf@ios@@QEBAHXZ */
1577 DEFINE_THISCALL_WRAPPER(ios_delbuf_get, 4)
1578 int __thiscall ios_delbuf_get(const ios *this)
1580 TRACE("(%p)\n", this);
1581 return this->delbuf;
1584 /* ?dec@@YAAAVios@@AAV1@@Z */
1585 /* ?dec@@YAAEAVios@@AEAV1@@Z */
1586 ios* __cdecl ios_dec(ios *this)
1588 TRACE("(%p)\n", this);
1589 ios_setf_mask(this, FLAGS_dec, ios_basefield);
1590 return this;
1593 /* ?eof@ios@@QBEHXZ */
1594 /* ?eof@ios@@QEBAHXZ */
1595 DEFINE_THISCALL_WRAPPER(ios_eof, 4)
1596 int __thiscall ios_eof(const ios *this)
1598 TRACE("(%p)\n", this);
1599 return (this->state & IOSTATE_eofbit);
1602 /* ?fail@ios@@QBEHXZ */
1603 /* ?fail@ios@@QEBAHXZ */
1604 DEFINE_THISCALL_WRAPPER(ios_fail, 4)
1605 int __thiscall ios_fail(const ios *this)
1607 TRACE("(%p)\n", this);
1608 return (this->state & (IOSTATE_failbit|IOSTATE_badbit));
1611 /* ?fill@ios@@QAEDD@Z */
1612 /* ?fill@ios@@QEAADD@Z */
1613 DEFINE_THISCALL_WRAPPER(ios_fill_set, 8)
1614 char __thiscall ios_fill_set(ios *this, char fill)
1616 char prev = this->fill;
1618 TRACE("(%p %d)\n", this, fill);
1620 this->fill = fill;
1621 return prev;
1624 /* ?fill@ios@@QBEDXZ */
1625 /* ?fill@ios@@QEBADXZ */
1626 DEFINE_THISCALL_WRAPPER(ios_fill_get, 4)
1627 char __thiscall ios_fill_get(const ios *this)
1629 TRACE("(%p)\n", this);
1630 return this->fill;
1633 /* ?flags@ios@@QAEJJ@Z */
1634 /* ?flags@ios@@QEAAJJ@Z */
1635 DEFINE_THISCALL_WRAPPER(ios_flags_set, 8)
1636 LONG __thiscall ios_flags_set(ios *this, LONG flags)
1638 LONG prev = this->flags;
1640 TRACE("(%p %x)\n", this, flags);
1642 this->flags = flags;
1643 return prev;
1646 /* ?flags@ios@@QBEJXZ */
1647 /* ?flags@ios@@QEBAJXZ */
1648 DEFINE_THISCALL_WRAPPER(ios_flags_get, 4)
1649 LONG __thiscall ios_flags_get(const ios *this)
1651 TRACE("(%p)\n", this);
1652 return this->flags;
1655 /* ?good@ios@@QBEHXZ */
1656 /* ?good@ios@@QEBAHXZ */
1657 DEFINE_THISCALL_WRAPPER(ios_good, 4)
1658 int __thiscall ios_good(const ios *this)
1660 TRACE("(%p)\n", this);
1661 return this->state == IOSTATE_goodbit;
1664 /* ?hex@@YAAAVios@@AAV1@@Z */
1665 /* ?hex@@YAAEAVios@@AEAV1@@Z */
1666 ios* __cdecl ios_hex(ios *this)
1668 TRACE("(%p)\n", this);
1669 ios_setf_mask(this, FLAGS_hex, ios_basefield);
1670 return this;
1673 /* ?init@ios@@IAEXPAVstreambuf@@@Z */
1674 /* ?init@ios@@IEAAXPEAVstreambuf@@@Z */
1675 DEFINE_THISCALL_WRAPPER(ios_init, 8)
1676 void __thiscall ios_init(ios *this, streambuf *sb)
1678 TRACE("(%p %p)\n", this, sb);
1679 if (this->delbuf && this->sb)
1680 call_streambuf_vector_dtor(this->sb, 1);
1681 this->sb = sb;
1682 if (sb == NULL)
1683 this->state |= IOSTATE_badbit;
1684 else
1685 this->state &= ~IOSTATE_badbit;
1688 /* ?iword@ios@@QBEAAJH@Z */
1689 /* ?iword@ios@@QEBAAEAJH@Z */
1690 DEFINE_THISCALL_WRAPPER(ios_iword, 8)
1691 LONG* __thiscall ios_iword(const ios *this, int index)
1693 TRACE("(%p %d)\n", this, index);
1694 return &ios_statebuf[index];
1697 /* ?lock@ios@@QAAXXZ */
1698 /* ?lock@ios@@QEAAXXZ */
1699 void __cdecl ios_lock(ios *this)
1701 TRACE("(%p)\n", this);
1702 if (this->do_lock < 0)
1703 EnterCriticalSection(&this->lock);
1706 /* ?lockbuf@ios@@QAAXXZ */
1707 /* ?lockbuf@ios@@QEAAXXZ */
1708 void __cdecl ios_lockbuf(ios *this)
1710 TRACE("(%p)\n", this);
1711 streambuf_lock(this->sb);
1714 /* ?lockc@ios@@KAXXZ */
1715 void __cdecl ios_lockc(void)
1717 TRACE("()\n");
1718 EnterCriticalSection(&ios_static_lock);
1721 /* ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
1722 /* ?lockptr@ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
1723 DEFINE_THISCALL_WRAPPER(ios_lockptr, 4)
1724 CRITICAL_SECTION* __thiscall ios_lockptr(ios *this)
1726 TRACE("(%p)\n", this);
1727 return &this->lock;
1730 /* ?oct@@YAAAVios@@AAV1@@Z */
1731 /* ?oct@@YAAEAVios@@AEAV1@@Z */
1732 ios* __cdecl ios_oct(ios *this)
1734 TRACE("(%p)\n", this);
1735 ios_setf_mask(this, FLAGS_oct, ios_basefield);
1736 return this;
1739 /* ?precision@ios@@QAEHH@Z */
1740 /* ?precision@ios@@QEAAHH@Z */
1741 DEFINE_THISCALL_WRAPPER(ios_precision_set, 8)
1742 int __thiscall ios_precision_set(ios *this, int prec)
1744 int prev = this->precision;
1746 TRACE("(%p %d)\n", this, prec);
1748 this->precision = prec;
1749 return prev;
1752 /* ?precision@ios@@QBEHXZ */
1753 /* ?precision@ios@@QEBAHXZ */
1754 DEFINE_THISCALL_WRAPPER(ios_precision_get, 4)
1755 int __thiscall ios_precision_get(const ios *this)
1757 TRACE("(%p)\n", this);
1758 return this->precision;
1761 /* ?pword@ios@@QBEAAPAXH@Z */
1762 /* ?pword@ios@@QEBAAEAPEAXH@Z */
1763 DEFINE_THISCALL_WRAPPER(ios_pword, 8)
1764 void** __thiscall ios_pword(const ios *this, int index)
1766 TRACE("(%p %d)\n", this, index);
1767 return (void**)&ios_statebuf[index];
1770 /* ?rdbuf@ios@@QBEPAVstreambuf@@XZ */
1771 /* ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ */
1772 DEFINE_THISCALL_WRAPPER(ios_rdbuf, 4)
1773 streambuf* __thiscall ios_rdbuf(const ios *this)
1775 TRACE("(%p)\n", this);
1776 return this->sb;
1779 /* ?rdstate@ios@@QBEHXZ */
1780 /* ?rdstate@ios@@QEBAHXZ */
1781 DEFINE_THISCALL_WRAPPER(ios_rdstate, 4)
1782 int __thiscall ios_rdstate(const ios *this)
1784 TRACE("(%p)\n", this);
1785 return this->state;
1788 /* ?setf@ios@@QAEJJ@Z */
1789 /* ?setf@ios@@QEAAJJ@Z */
1790 DEFINE_THISCALL_WRAPPER(ios_setf, 8)
1791 LONG __thiscall ios_setf(ios *this, LONG flags)
1793 LONG prev = this->flags;
1795 TRACE("(%p %x)\n", this, flags);
1797 ios_lock(this);
1798 this->flags |= flags;
1799 ios_unlock(this);
1800 return prev;
1803 /* ?setf@ios@@QAEJJJ@Z */
1804 /* ?setf@ios@@QEAAJJJ@Z */
1805 DEFINE_THISCALL_WRAPPER(ios_setf_mask, 12)
1806 LONG __thiscall ios_setf_mask(ios *this, LONG flags, LONG mask)
1808 LONG prev = this->flags;
1810 TRACE("(%p %x %x)\n", this, flags, mask);
1812 ios_lock(this);
1813 this->flags = (this->flags & (~mask)) | (flags & mask);
1814 ios_unlock(this);
1815 return prev;
1818 /* ?setlock@ios@@QAAXXZ */
1819 /* ?setlock@ios@@QEAAXXZ */
1820 void __cdecl ios_setlock(ios *this)
1822 TRACE("(%p)\n", this);
1823 this->do_lock--;
1824 if (this->sb)
1825 streambuf_setlock(this->sb);
1828 /* ?sync_with_stdio@ios@@SAXXZ */
1829 void __cdecl ios_sync_with_stdio(void)
1831 FIXME("() stub\n");
1834 /* ?tie@ios@@QAEPAVostream@@PAV2@@Z */
1835 /* ?tie@ios@@QEAAPEAVostream@@PEAV2@@Z */
1836 DEFINE_THISCALL_WRAPPER(ios_tie_set, 8)
1837 ostream* __thiscall ios_tie_set(ios *this, ostream *ostr)
1839 ostream *prev = this->tie;
1841 TRACE("(%p %p)\n", this, ostr);
1843 this->tie = ostr;
1844 return prev;
1847 /* ?tie@ios@@QBEPAVostream@@XZ */
1848 /* ?tie@ios@@QEBAPEAVostream@@XZ */
1849 DEFINE_THISCALL_WRAPPER(ios_tie_get, 4)
1850 ostream* __thiscall ios_tie_get(const ios *this)
1852 TRACE("(%p)\n", this);
1853 return this->tie;
1856 /* ?unlock@ios@@QAAXXZ */
1857 /* ?unlock@ios@@QEAAXXZ */
1858 void __cdecl ios_unlock(ios *this)
1860 TRACE("(%p)\n", this);
1861 if (this->do_lock < 0)
1862 LeaveCriticalSection(&this->lock);
1865 /* ?unlockbuf@ios@@QAAXXZ */
1866 /* ?unlockbuf@ios@@QEAAXXZ */
1867 void __cdecl ios_unlockbuf(ios *this)
1869 TRACE("(%p)\n", this);
1870 streambuf_unlock(this->sb);
1873 /* ?unlockc@ios@@KAXXZ */
1874 void __cdecl ios_unlockc(void)
1876 TRACE("()\n");
1877 LeaveCriticalSection(&ios_static_lock);
1880 /* ?unsetf@ios@@QAEJJ@Z */
1881 /* ?unsetf@ios@@QEAAJJ@Z */
1882 DEFINE_THISCALL_WRAPPER(ios_unsetf, 8)
1883 LONG __thiscall ios_unsetf(ios *this, LONG flags)
1885 LONG prev = this->flags;
1887 TRACE("(%p %x)\n", this, flags);
1889 ios_lock(this);
1890 this->flags &= ~flags;
1891 ios_unlock(this);
1892 return prev;
1895 /* ?width@ios@@QAEHH@Z */
1896 /* ?width@ios@@QEAAHH@Z */
1897 DEFINE_THISCALL_WRAPPER(ios_width_set, 8)
1898 int __thiscall ios_width_set(ios *this, int width)
1900 int prev = this->width;
1902 TRACE("(%p %d)\n", this, width);
1904 this->width = width;
1905 return prev;
1908 /* ?width@ios@@QBEHXZ */
1909 /* ?width@ios@@QEBAHXZ */
1910 DEFINE_THISCALL_WRAPPER(ios_width_get, 4)
1911 int __thiscall ios_width_get(const ios *this)
1913 TRACE("(%p)\n", this);
1914 return this->width;
1917 /* ?xalloc@ios@@SAHXZ */
1918 int __cdecl ios_xalloc(void)
1920 int ret;
1922 TRACE("()\n");
1924 ios_lockc();
1925 ret = (ios_curindex < STATEBUF_SIZE-1) ? ++ios_curindex : -1;
1926 ios_unlockc();
1927 return ret;
1930 /******************************************************************
1931 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
1933 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_ctor,8)
1934 void * __thiscall MSVCIRT_ostrstream_ctor(ostream *this, BOOL virt_init)
1936 FIXME("(%p %x) stub\n", this, virt_init);
1937 return this;
1940 /******************************************************************
1941 * ??1ostrstream@@UAE@XZ (MSVCRTI.@)
1943 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_dtor,4)
1944 void __thiscall MSVCIRT_ostrstream_dtor(ios *base)
1946 FIXME("(%p) stub\n", base);
1949 /******************************************************************
1950 * ??6ostream@@QAEAAV0@E@Z (MSVCRTI.@)
1951 * class ostream & __thiscall ostream::operator<<(unsigned char)
1953 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_uchar,8)
1954 void * __thiscall MSVCIRT_operator_sl_uchar(ostream * _this, unsigned char ch)
1956 FIXME("(%p)->(%c) stub\n", _this, ch);
1957 return _this;
1960 /******************************************************************
1961 * ??6ostream@@QAEAAV0@H@Z (MSVCRTI.@)
1962 * class ostream & __thiscall ostream::operator<<(int)
1964 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_int,8)
1965 void * __thiscall MSVCIRT_operator_sl_int(ostream * _this, int integer)
1967 FIXME("(%p)->(%d) stub\n", _this, integer);
1968 return _this;
1971 /******************************************************************
1972 * ??6ostream@@QAEAAV0@PBD@Z (MSVCRTI.@)
1973 * class ostream & __thiscall ostream::operator<<(char const *)
1975 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_pchar,8)
1976 void * __thiscall MSVCIRT_operator_sl_pchar(ostream * _this, const char * string)
1978 FIXME("(%p)->(%s) stub\n", _this, debugstr_a(string));
1979 return _this;
1982 /******************************************************************
1983 * ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z (MSVCRTI.@)
1984 * class ostream & __thiscall ostream::operator<<(class ostream & (__cdecl*)(class ostream &))
1986 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_callback,8)
1987 void * __thiscall MSVCIRT_operator_sl_callback(ostream * _this, ostream * (__cdecl*func)(ostream*))
1989 TRACE("%p, %p\n", _this, func);
1990 return func(_this);
1993 /******************************************************************
1994 * ?endl@@YAAAVostream@@AAV1@@Z (MSVCRTI.@)
1995 * class ostream & __cdecl endl(class ostream &)
1997 void * CDECL MSVCIRT_endl(ostream * _this)
1999 FIXME("(%p)->() stub\n", _this);
2000 return _this;
2003 /******************************************************************
2004 * ?ends@@YAAAVostream@@AAV1@@Z (MSVCRTI.@)
2005 * class ostream & __cdecl ends(class ostream &)
2007 void * CDECL MSVCIRT_ends(ostream * _this)
2009 FIXME("(%p)->() stub\n", _this);
2010 return _this;
2013 #ifdef __i386__
2015 #define DEFINE_VTBL_WRAPPER(off) \
2016 __ASM_GLOBAL_FUNC(vtbl_wrapper_ ## off, \
2017 "popl %eax\n\t" \
2018 "popl %ecx\n\t" \
2019 "pushl %eax\n\t" \
2020 "movl 0(%ecx), %eax\n\t" \
2021 "jmp *" #off "(%eax)\n\t")
2023 DEFINE_VTBL_WRAPPER(0);
2024 DEFINE_VTBL_WRAPPER(4);
2025 DEFINE_VTBL_WRAPPER(8);
2026 DEFINE_VTBL_WRAPPER(12);
2027 DEFINE_VTBL_WRAPPER(16);
2028 DEFINE_VTBL_WRAPPER(20);
2029 DEFINE_VTBL_WRAPPER(24);
2030 DEFINE_VTBL_WRAPPER(28);
2031 DEFINE_VTBL_WRAPPER(32);
2032 DEFINE_VTBL_WRAPPER(36);
2033 DEFINE_VTBL_WRAPPER(40);
2034 DEFINE_VTBL_WRAPPER(44);
2035 DEFINE_VTBL_WRAPPER(48);
2036 DEFINE_VTBL_WRAPPER(52);
2037 DEFINE_VTBL_WRAPPER(56);
2039 #endif
2041 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
2042 void (__cdecl *MSVCRT_operator_delete)(void*);
2044 static void init_cxx_funcs(void)
2046 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
2048 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
2050 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPEAX_K@Z");
2051 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
2053 else
2055 MSVCRT_operator_new = (void*)GetProcAddress(hmod, "??2@YAPAXI@Z");
2056 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
2060 static void init_io(void *base)
2062 #ifdef __x86_64__
2063 init_streambuf_rtti(base);
2064 init_filebuf_rtti(base);
2065 init_strstreambuf_rtti(base);
2066 init_ios_rtti(base);
2067 #endif
2070 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
2072 switch (reason)
2074 case DLL_WINE_PREATTACH:
2075 return FALSE; /* prefer native version */
2076 case DLL_PROCESS_ATTACH:
2077 init_cxx_funcs();
2078 init_exception(inst);
2079 init_io(inst);
2080 DisableThreadLibraryCalls( inst );
2081 break;
2083 return TRUE;