msvcirt: Add initial implementation of streambuf.
[wine.git] / dlls / msvcirt / msvcirt.c
blobe0781b915b610d9ebb1a6f4e3855ff6744fe4462
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 <stdarg.h>
23 #include <stdio.h>
25 #include "msvcirt.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(msvcirt);
32 /* class streambuf */
33 typedef struct {
34 const vtable_ptr *vtable;
35 int allocated;
36 int unbuffered;
37 int unknown;
38 char *base;
39 char *ebuf;
40 char *pbase;
41 char *pptr;
42 char *epptr;
43 char *eback;
44 char *gptr;
45 char *egptr;
46 int unknown2;
47 CRITICAL_SECTION lock;
48 } streambuf;
50 streambuf* __thiscall streambuf_setbuf(streambuf*, char*, int);
51 void __thiscall streambuf_setg(streambuf*, char*, char*, char*);
52 void __thiscall streambuf_setp(streambuf*, char*, char*);
54 typedef struct {
55 LPVOID VTable;
56 } class_ios;
58 typedef struct {
59 LPVOID VTable;
60 } class_ostream;
62 typedef struct {
63 LPVOID VTable;
64 } class_strstreambuf;
66 /* ??_7streambuf@@6B@ */
67 extern const vtable_ptr MSVCP_streambuf_vtable;
69 #ifndef __GNUC__
70 void __asm_dummy_vtables(void) {
71 #endif
72 __ASM_VTABLE(streambuf,
73 VTABLE_ADD_FUNC(streambuf_vector_dtor)
74 VTABLE_ADD_FUNC(streambuf_sync)
75 VTABLE_ADD_FUNC(streambuf_setbuf)
76 VTABLE_ADD_FUNC(streambuf_seekoff)
77 VTABLE_ADD_FUNC(streambuf_seekpos)
78 VTABLE_ADD_FUNC(streambuf_xsputn)
79 VTABLE_ADD_FUNC(streambuf_xsgetn)
80 VTABLE_ADD_FUNC(streambuf_overflow)
81 VTABLE_ADD_FUNC(streambuf_underflow)
82 VTABLE_ADD_FUNC(streambuf_pbackfail)
83 VTABLE_ADD_FUNC(streambuf_doallocate));
84 #ifndef __GNUC__
86 #endif
88 DEFINE_RTTI_DATA0(streambuf, 0, ".?AVstreambuf@@")
90 /* ??0streambuf@@IAE@PADH@Z */
91 /* ??0streambuf@@IEAA@PEADH@Z */
92 DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
93 streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int length)
95 TRACE("(%p %p %d)\n", this, buffer, length);
96 this->vtable = &MSVCP_streambuf_vtable;
97 this->allocated = 0;
98 this->unknown = -1;
99 this->unknown2 = -1;
100 this->base = NULL;
101 streambuf_setbuf(this, buffer, length);
102 streambuf_setg(this, NULL, NULL, NULL);
103 streambuf_setp(this, NULL, NULL);
104 InitializeCriticalSection(&this->lock);
105 return this;
108 /* ??0streambuf@@IAE@XZ */
109 /* ??0streambuf@@IEAA@XZ */
110 DEFINE_THISCALL_WRAPPER(streambuf_ctor, 4)
111 streambuf* __thiscall streambuf_ctor(streambuf *this)
113 streambuf_reserve_ctor(this, NULL, 0);
114 this->unbuffered = 0;
115 return this;
118 /* ??0streambuf@@QAE@ABV0@@Z */
119 /* ??0streambuf@@QEAA@AEBV0@@Z */
120 DEFINE_THISCALL_WRAPPER(streambuf_copy_ctor, 8)
121 streambuf* __thiscall streambuf_copy_ctor(streambuf *this, const streambuf *copy)
123 TRACE("(%p %p)\n", this, copy);
124 *this = *copy;
125 this->vtable = &MSVCP_streambuf_vtable;
126 return this;
129 /* ??1streambuf@@UAE@XZ */
130 /* ??1streambuf@@UEAA@XZ */
131 DEFINE_THISCALL_WRAPPER(streambuf_dtor, 4)
132 void __thiscall streambuf_dtor(streambuf *this)
134 TRACE("(%p)\n", this);
135 if (this->allocated)
136 MSVCRT_operator_delete(this->base);
137 DeleteCriticalSection(&this->lock);
140 /* ??4streambuf@@QAEAAV0@ABV0@@Z */
141 /* ??4streambuf@@QEAAAEAV0@AEBV0@@Z */
142 DEFINE_THISCALL_WRAPPER(streambuf_assign, 8)
143 streambuf* __thiscall streambuf_assign(streambuf *this, const streambuf *rhs)
145 streambuf_dtor(this);
146 return streambuf_copy_ctor(this, rhs);
149 /* ??_Estreambuf@@UAEPAXI@Z */
150 DEFINE_THISCALL_WRAPPER(streambuf_vector_dtor, 8)
151 streambuf* __thiscall streambuf_vector_dtor(streambuf *this, unsigned int flags)
153 TRACE("(%p %x)\n", this, flags);
154 if (flags & 2) {
155 /* we have an array, with the number of elements stored before the first object */
156 INT_PTR i, *ptr = (INT_PTR *)this-1;
158 for (i = *ptr-1; i >= 0; i--)
159 streambuf_dtor(this+i);
160 MSVCRT_operator_delete(ptr);
161 } else {
162 streambuf_dtor(this);
163 if (flags & 1)
164 MSVCRT_operator_delete(this);
166 return this;
169 /* ??_Gstreambuf@@UAEPAXI@Z */
170 DEFINE_THISCALL_WRAPPER(streambuf_scalar_dtor, 8)
171 streambuf* __thiscall streambuf_scalar_dtor(streambuf *this, unsigned int flags)
173 TRACE("(%p %x)\n", this, flags);
174 streambuf_dtor(this);
175 if (flags & 1) MSVCRT_operator_delete(this);
176 return this;
179 /* ?doallocate@streambuf@@MAEHXZ */
180 /* ?doallocate@streambuf@@MEAAHXZ */
181 DEFINE_THISCALL_WRAPPER(streambuf_doallocate, 4)
182 int __thiscall streambuf_doallocate(streambuf *this)
184 FIXME("(%p): stub\n", this);
185 return EOF;
188 /* Unexported */
189 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
190 int __thiscall streambuf_overflow(streambuf *this, int c)
192 return EOF;
195 /* ?pbackfail@streambuf@@UAEHH@Z */
196 /* ?pbackfail@streambuf@@UEAAHH@Z */
197 DEFINE_THISCALL_WRAPPER(streambuf_pbackfail, 8)
198 int __thiscall streambuf_pbackfail(streambuf *this, int c)
200 FIXME("(%p %d): stub\n", this, c);
201 return 0;
204 /* ?seekoff@streambuf@@UAEJJW4seek_dir@ios@@H@Z */
205 /* ?seekoff@streambuf@@UEAAJJW4seek_dir@ios@@H@Z */
206 DEFINE_THISCALL_WRAPPER(streambuf_seekoff, 16)
207 streampos __thiscall streambuf_seekoff(streambuf *this, streamoff offset, int dir, int mode)
209 FIXME("(%p %d %d %d): stub\n", this, offset, dir, mode);
210 return EOF;
213 /* ?seekpos@streambuf@@UAEJJH@Z */
214 /* ?seekpos@streambuf@@UEAAJJH@Z */
215 DEFINE_THISCALL_WRAPPER(streambuf_seekpos, 12)
216 streampos __thiscall streambuf_seekpos(streambuf *this, streampos pos, int mode)
218 FIXME("(%p %d %d): stub\n", this, pos, mode);
219 return EOF;
222 /* ?setb@streambuf@@IAEXPAD0H@Z */
223 /* ?setb@streambuf@@IEAAXPEAD0H@Z */
224 DEFINE_THISCALL_WRAPPER(streambuf_setb, 16)
225 void __thiscall streambuf_setb(streambuf *this, char *ba, char *eb, int delete)
227 TRACE("(%p %p %p %d)\n", this, ba, eb, delete);
228 if (this->allocated)
229 MSVCRT_operator_delete(this->base);
230 this->allocated = delete;
231 this->base = ba;
232 this->ebuf = eb;
235 /* ?setbuf@streambuf@@UAEPAV1@PADH@Z */
236 /* ?setbuf@streambuf@@UEAAPEAV1@PEADH@Z */
237 DEFINE_THISCALL_WRAPPER(streambuf_setbuf, 12)
238 streambuf* __thiscall streambuf_setbuf(streambuf *this, char *buffer, int length)
240 TRACE("(%p %p %d)\n", this, buffer, length);
241 if (this->base != NULL)
242 return NULL;
244 if (buffer == NULL || !length) {
245 this->unbuffered = 1;
246 this->base = this->ebuf = NULL;
247 } else {
248 this->unbuffered = 0;
249 this->base = buffer;
250 this->ebuf = buffer + length;
252 return this;
255 /* ?setg@streambuf@@IAEXPAD00@Z */
256 /* ?setg@streambuf@@IEAAXPEAD00@Z */
257 DEFINE_THISCALL_WRAPPER(streambuf_setg, 16)
258 void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
260 TRACE("(%p %p %p %p)\n", this, ek, gp, eg);
261 this->eback = ek;
262 this->gptr = gp;
263 this->egptr = eg;
266 /* ?setp@streambuf@@IAEXPAD0@Z */
267 /* ?setp@streambuf@@IEAAXPEAD0@Z */
268 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
269 void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
271 TRACE("(%p %p %p)\n", this, pb, ep);
272 this->pbase = this->pptr = pb;
273 this->epptr = ep;
276 /* ?sync@streambuf@@UAEHXZ */
277 /* ?sync@streambuf@@UEAAHXZ */
278 DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
279 int __thiscall streambuf_sync(streambuf *this)
281 FIXME("(%p): stub\n", this);
282 return EOF;
285 /* Unexported */
286 DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4)
287 int __thiscall streambuf_underflow(streambuf *this)
289 return EOF;
292 /* ?xsgetn@streambuf@@UAEHPADH@Z */
293 /* ?xsgetn@streambuf@@UEAAHPEADH@Z */
294 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
295 int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count)
297 FIXME("(%p %p %d): stub\n", this, buffer, count);
298 return 0;
301 /* ?xsputn@streambuf@@UAEHPBDH@Z */
302 /* ?xsputn@streambuf@@UEAAHPEBDH@Z */
303 DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12)
304 int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length)
306 FIXME("(%p %p %d): stub\n", this, data, length);
307 return 0;
310 /******************************************************************
311 * ??1ios@@UAE@XZ (MSVCRTI.@)
312 * class ios & __thiscall ios::-ios<<(void)
314 DEFINE_THISCALL_WRAPPER(MSVCIRT_ios_sl_void,4)
315 void * __thiscall MSVCIRT_ios_sl_void(class_ios * _this)
317 FIXME("(%p) stub\n", _this);
318 return _this;
321 /******************************************************************
322 * ??0ostrstream@@QAE@XZ (MSVCRTI.@)
323 * class ostream & __thiscall ostrstream::ostrstream<<(void)
325 DEFINE_THISCALL_WRAPPER(MSVCIRT_ostrstream_sl_void,4)
326 void * __thiscall MSVCIRT_ostrstream_sl_void(class_ostream * _this)
328 FIXME("(%p) stub\n", _this);
329 return _this;
332 /******************************************************************
333 * ??6ostream@@QAEAAV0@E@Z (MSVCRTI.@)
334 * class ostream & __thiscall ostream::operator<<(unsigned char)
336 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_uchar,8)
337 void * __thiscall MSVCIRT_operator_sl_uchar(class_ostream * _this, unsigned char ch)
339 FIXME("(%p)->(%c) stub\n", _this, ch);
340 return _this;
343 /******************************************************************
344 * ??6ostream@@QAEAAV0@H@Z (MSVCRTI.@)
345 * class ostream & __thiscall ostream::operator<<(int)
347 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_int,8)
348 void * __thiscall MSVCIRT_operator_sl_int(class_ostream * _this, int integer)
350 FIXME("(%p)->(%d) stub\n", _this, integer);
351 return _this;
354 /******************************************************************
355 * ??6ostream@@QAEAAV0@PBD@Z (MSVCRTI.@)
356 * class ostream & __thiscall ostream::operator<<(char const *)
358 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_pchar,8)
359 void * __thiscall MSVCIRT_operator_sl_pchar(class_ostream * _this, const char * string)
361 FIXME("(%p)->(%s) stub\n", _this, debugstr_a(string));
362 return _this;
365 /******************************************************************
366 * ??6ostream@@QAEAAV0@P6AAAV0@AAV0@@Z@Z (MSVCRTI.@)
367 * class ostream & __thiscall ostream::operator<<(class ostream & (__cdecl*)(class ostream &))
369 DEFINE_THISCALL_WRAPPER(MSVCIRT_operator_sl_callback,8)
370 void * __thiscall MSVCIRT_operator_sl_callback(class_ostream * _this, class_ostream * (__cdecl*func)(class_ostream*))
372 TRACE("%p, %p\n", _this, func);
373 return func(_this);
376 /******************************************************************
377 * ?endl@@YAAAVostream@@AAV1@@Z (MSVCRTI.@)
378 * class ostream & __cdecl endl(class ostream &)
380 void * CDECL MSVCIRT_endl(class_ostream * _this)
382 FIXME("(%p)->() stub\n", _this);
383 return _this;
386 /******************************************************************
387 * ?ends@@YAAAVostream@@AAV1@@Z (MSVCRTI.@)
388 * class ostream & __cdecl ends(class ostream &)
390 void * CDECL MSVCIRT_ends(class_ostream * _this)
392 FIXME("(%p)->() stub\n", _this);
393 return _this;
396 /******************************************************************
397 * ?str@strstreambuf@@QAEPADXZ (MSVCRTI.@)
398 * class strstreambuf & __thiscall strstreambuf::str(class strstreambuf &)
400 DEFINE_THISCALL_WRAPPER(MSVCIRT_str_sl_void,4)
401 char * __thiscall MSVCIRT_str_sl_void(class_strstreambuf * _this)
403 FIXME("(%p)->() stub\n", _this);
404 return 0;
407 void (__cdecl *MSVCRT_operator_delete)(void*);
409 static void init_cxx_funcs(void)
411 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
413 if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
415 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPEAX@Z");
417 else
419 MSVCRT_operator_delete = (void*)GetProcAddress(hmod, "??3@YAXPAX@Z");
423 static void init_io(void *base)
425 #ifdef __x86_64__
426 init_streambuf_rtti(base);
427 #endif
430 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
432 switch (reason)
434 case DLL_WINE_PREATTACH:
435 return FALSE; /* prefer native version */
436 case DLL_PROCESS_ATTACH:
437 init_cxx_funcs();
438 init_exception(inst);
439 init_io(inst);
440 DisableThreadLibraryCalls( inst );
441 break;
443 return TRUE;