po: German translation: Fix grammar errors.
[wine/multimedia.git] / dlls / msvcirt / tests / msvcirt.c
blobb381b301c9e86f74c3bd1699672c9e1b3905325a
1 /*
2 * Copyright 2015 Iván Matellanes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <fcntl.h>
20 #include <io.h>
21 #include <stdio.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include "wine/test.h"
26 typedef void (*vtable_ptr)(void);
27 typedef LONG streamoff;
28 typedef LONG streampos;
29 typedef int filedesc;
31 typedef enum {
32 IOSTATE_goodbit = 0x0,
33 IOSTATE_eofbit = 0x1,
34 IOSTATE_failbit = 0x2,
35 IOSTATE_badbit = 0x4
36 } ios_io_state;
38 typedef enum {
39 OPENMODE_in = 0x1,
40 OPENMODE_out = 0x2,
41 OPENMODE_ate = 0x4,
42 OPENMODE_app = 0x8,
43 OPENMODE_trunc = 0x10,
44 OPENMODE_nocreate = 0x20,
45 OPENMODE_noreplace = 0x40,
46 OPENMODE_binary = 0x80
47 } ios_open_mode;
49 typedef enum {
50 SEEKDIR_beg = 0,
51 SEEKDIR_cur = 1,
52 SEEKDIR_end = 2
53 } ios_seek_dir;
55 typedef enum {
56 FLAGS_skipws = 0x1,
57 FLAGS_left = 0x2,
58 FLAGS_right = 0x4,
59 FLAGS_internal = 0x8,
60 FLAGS_dec = 0x10,
61 FLAGS_oct = 0x20,
62 FLAGS_hex = 0x40,
63 FLAGS_showbase = 0x80,
64 FLAGS_showpoint = 0x100,
65 FLAGS_uppercase = 0x200,
66 FLAGS_showpos = 0x400,
67 FLAGS_scientific = 0x800,
68 FLAGS_fixed = 0x1000,
69 FLAGS_unitbuf = 0x2000,
70 FLAGS_stdio = 0x4000
71 } ios_flags;
73 const int filebuf_sh_none = 0x800;
74 const int filebuf_sh_read = 0xa00;
75 const int filebuf_sh_write = 0xc00;
76 const int filebuf_openprot = 420;
77 const int filebuf_binary = _O_BINARY;
78 const int filebuf_text = _O_TEXT;
80 /* class streambuf */
81 typedef struct {
82 const vtable_ptr *vtable;
83 int allocated;
84 int unbuffered;
85 int stored_char;
86 char *base;
87 char *ebuf;
88 char *pbase;
89 char *pptr;
90 char *epptr;
91 char *eback;
92 char *gptr;
93 char *egptr;
94 int do_lock;
95 CRITICAL_SECTION lock;
96 } streambuf;
98 /* class filebuf */
99 typedef struct {
100 streambuf base;
101 filedesc fd;
102 int close;
103 } filebuf;
105 /* class ios */
106 struct _ostream;
107 typedef struct {
108 const vtable_ptr *vtable;
109 streambuf *sb;
110 ios_io_state state;
111 int special[4];
112 int delbuf;
113 struct _ostream *tie;
114 ios_flags flags;
115 int precision;
116 char fill;
117 int width;
118 int do_lock;
119 CRITICAL_SECTION lock;
120 } ios;
122 /* class ostream */
123 typedef struct _ostream {
124 const vtable_ptr *vtable;
125 } ostream;
127 #undef __thiscall
128 #ifdef __i386__
129 #define __thiscall __stdcall
130 #else
131 #define __thiscall __cdecl
132 #endif
134 static void* (__cdecl *p_operator_new)(unsigned int);
136 /* streambuf */
137 static streambuf* (*__thiscall p_streambuf_reserve_ctor)(streambuf*, char*, int);
138 static streambuf* (*__thiscall p_streambuf_ctor)(streambuf*);
139 static void (*__thiscall p_streambuf_dtor)(streambuf*);
140 static int (*__thiscall p_streambuf_allocate)(streambuf*);
141 static void (*__thiscall p_streambuf_clrclock)(streambuf*);
142 static int (*__thiscall p_streambuf_doallocate)(streambuf*);
143 static void (*__thiscall p_streambuf_gbump)(streambuf*, int);
144 static void (*__thiscall p_streambuf_lock)(streambuf*);
145 static int (*__thiscall p_streambuf_pbackfail)(streambuf*, int);
146 static void (*__thiscall p_streambuf_pbump)(streambuf*, int);
147 static int (*__thiscall p_streambuf_sbumpc)(streambuf*);
148 static void (*__thiscall p_streambuf_setb)(streambuf*, char*, char*, int);
149 static void (*__thiscall p_streambuf_setlock)(streambuf*);
150 static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int);
151 static int (*__thiscall p_streambuf_sgetc)(streambuf*);
152 static int (*__thiscall p_streambuf_snextc)(streambuf*);
153 static int (*__thiscall p_streambuf_sputc)(streambuf*, int);
154 static void (*__thiscall p_streambuf_stossc)(streambuf*);
155 static int (*__thiscall p_streambuf_sync)(streambuf*);
156 static void (*__thiscall p_streambuf_unlock)(streambuf*);
157 static int (*__thiscall p_streambuf_xsgetn)(streambuf*, char*, int);
158 static int (*__thiscall p_streambuf_xsputn)(streambuf*, const char*, int);
160 /* filebuf */
161 static filebuf* (*__thiscall p_filebuf_fd_ctor)(filebuf*, int);
162 static filebuf* (*__thiscall p_filebuf_fd_reserve_ctor)(filebuf*, int, char*, int);
163 static filebuf* (*__thiscall p_filebuf_ctor)(filebuf*);
164 static void (*__thiscall p_filebuf_dtor)(filebuf*);
165 static filebuf* (*__thiscall p_filebuf_attach)(filebuf*, filedesc);
166 static filebuf* (*__thiscall p_filebuf_open)(filebuf*, const char*, ios_open_mode, int);
167 static filebuf* (*__thiscall p_filebuf_close)(filebuf*);
168 static int (*__thiscall p_filebuf_setmode)(filebuf*, int);
169 static streambuf* (*__thiscall p_filebuf_setbuf)(filebuf*, char*, int);
170 static int (*__thiscall p_filebuf_sync)(filebuf*);
171 static int (*__thiscall p_filebuf_overflow)(filebuf*, int);
172 static int (*__thiscall p_filebuf_underflow)(filebuf*);
173 static streampos (*__thiscall p_filebuf_seekoff)(filebuf*, streamoff, ios_seek_dir, int);
175 /* ios */
176 static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
177 static ios* (*__thiscall p_ios_ctor)(ios*);
178 static ios* (*__thiscall p_ios_sb_ctor)(ios*, streambuf*);
179 static ios* (*__thiscall p_ios_assign)(ios*, const ios*);
180 static void (*__thiscall p_ios_init)(ios*, streambuf*);
181 static void (*__thiscall p_ios_dtor)(ios*);
182 static void (*__cdecl p_ios_clrlock)(ios*);
183 static void (*__cdecl p_ios_setlock)(ios*);
184 static void (*__cdecl p_ios_lock)(ios*);
185 static void (*__cdecl p_ios_unlock)(ios*);
186 static void (*__cdecl p_ios_lockbuf)(ios*);
187 static void (*__cdecl p_ios_unlockbuf)(ios*);
188 static CRITICAL_SECTION *p_ios_static_lock;
189 static void (*__cdecl p_ios_lockc)(void);
190 static void (*__cdecl p_ios_unlockc)(void);
191 static LONG (*__thiscall p_ios_flags_set)(ios*, LONG);
192 static LONG (*__thiscall p_ios_flags_get)(const ios*);
193 static LONG (*__thiscall p_ios_setf)(ios*, LONG);
194 static LONG (*__thiscall p_ios_setf_mask)(ios*, LONG, LONG);
195 static LONG (*__thiscall p_ios_unsetf)(ios*, LONG);
196 static int (*__thiscall p_ios_good)(const ios*);
197 static int (*__thiscall p_ios_bad)(const ios*);
198 static int (*__thiscall p_ios_eof)(const ios*);
199 static int (*__thiscall p_ios_fail)(const ios*);
200 static void (*__thiscall p_ios_clear)(ios*, int);
201 static LONG *p_ios_maxbit;
202 static LONG (*__cdecl p_ios_bitalloc)(void);
203 static int *p_ios_curindex;
204 static LONG *p_ios_statebuf;
205 static LONG* (*__thiscall p_ios_iword)(const ios*, int);
206 static void** (*__thiscall p_ios_pword)(const ios*, int);
207 static int (*__cdecl p_ios_xalloc)(void);
208 static int *p_ios_fLockcInit;
210 /* Emulate a __thiscall */
211 #ifdef __i386__
213 #include "pshpack1.h"
214 struct thiscall_thunk
216 BYTE pop_eax; /* popl %eax (ret addr) */
217 BYTE pop_edx; /* popl %edx (func) */
218 BYTE pop_ecx; /* popl %ecx (this) */
219 BYTE push_eax; /* pushl %eax */
220 WORD jmp_edx; /* jmp *%edx */
222 #include "poppack.h"
224 static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
225 static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
226 static void * (WINAPI *call_thiscall_func3)( void *func, void *this, const void *a, const void *b );
227 static void * (WINAPI *call_thiscall_func4)( void *func, void *this, const void *a, const void *b,
228 const void *c );
229 static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a, const void *b,
230 const void *c, const void *d );
232 static void init_thiscall_thunk(void)
234 struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
235 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
236 thunk->pop_eax = 0x58; /* popl %eax */
237 thunk->pop_edx = 0x5a; /* popl %edx */
238 thunk->pop_ecx = 0x59; /* popl %ecx */
239 thunk->push_eax = 0x50; /* pushl %eax */
240 thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
241 call_thiscall_func1 = (void *)thunk;
242 call_thiscall_func2 = (void *)thunk;
243 call_thiscall_func3 = (void *)thunk;
244 call_thiscall_func4 = (void *)thunk;
245 call_thiscall_func5 = (void *)thunk;
248 #define call_func1(func,_this) call_thiscall_func1(func,_this)
249 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
250 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b))
251 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),(const void*)(b), \
252 (const void*)(c))
253 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \
254 (const void*)(c), (const void *)(d))
256 #else
258 #define init_thiscall_thunk()
259 #define call_func1(func,_this) func(_this)
260 #define call_func2(func,_this,a) func(_this,a)
261 #define call_func3(func,_this,a,b) func(_this,a,b)
262 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
263 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
265 #endif /* __i386__ */
267 static HMODULE msvcrt, msvcirt;
268 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcirt,y)
269 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
270 static BOOL init(void)
272 msvcrt = LoadLibraryA("msvcrt.dll");
273 msvcirt = LoadLibraryA("msvcirt.dll");
274 if(!msvcirt) {
275 win_skip("msvcirt.dll not installed\n");
276 return FALSE;
279 if(sizeof(void*) == 8) { /* 64-bit initialization */
280 p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPEAX_K@Z");
282 SET(p_streambuf_reserve_ctor, "??0streambuf@@IEAA@PEADH@Z");
283 SET(p_streambuf_ctor, "??0streambuf@@IEAA@XZ");
284 SET(p_streambuf_dtor, "??1streambuf@@UEAA@XZ");
285 SET(p_streambuf_allocate, "?allocate@streambuf@@IEAAHXZ");
286 SET(p_streambuf_clrclock, "?clrlock@streambuf@@QEAAXXZ");
287 SET(p_streambuf_doallocate, "?doallocate@streambuf@@MEAAHXZ");
288 SET(p_streambuf_gbump, "?gbump@streambuf@@IEAAXH@Z");
289 SET(p_streambuf_lock, "?lock@streambuf@@QEAAXXZ");
290 SET(p_streambuf_pbackfail, "?pbackfail@streambuf@@UEAAHH@Z");
291 SET(p_streambuf_pbump, "?pbump@streambuf@@IEAAXH@Z");
292 SET(p_streambuf_sbumpc, "?sbumpc@streambuf@@QEAAHXZ");
293 SET(p_streambuf_setb, "?setb@streambuf@@IEAAXPEAD0H@Z");
294 SET(p_streambuf_setbuf, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z");
295 SET(p_streambuf_setlock, "?setlock@streambuf@@QEAAXXZ");
296 SET(p_streambuf_sgetc, "?sgetc@streambuf@@QEAAHXZ");
297 SET(p_streambuf_snextc, "?snextc@streambuf@@QEAAHXZ");
298 SET(p_streambuf_sputc, "?sputc@streambuf@@QEAAHH@Z");
299 SET(p_streambuf_stossc, "?stossc@streambuf@@QEAAXXZ");
300 SET(p_streambuf_sync, "?sync@streambuf@@UEAAHXZ");
301 SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ");
302 SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UEAAHPEADH@Z");
303 SET(p_streambuf_xsputn, "?xsputn@streambuf@@UEAAHPEBDH@Z");
305 SET(p_filebuf_fd_ctor, "??0filebuf@@QEAA@H@Z");
306 SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QEAA@HPEADH@Z");
307 SET(p_filebuf_ctor, "??0filebuf@@QEAA@XZ");
308 SET(p_filebuf_dtor, "??1filebuf@@UEAA@XZ");
309 SET(p_filebuf_attach, "?attach@filebuf@@QEAAPEAV1@H@Z");
310 SET(p_filebuf_open, "?open@filebuf@@QEAAPEAV1@PEBDHH@Z");
311 SET(p_filebuf_close, "?close@filebuf@@QEAAPEAV1@XZ");
312 SET(p_filebuf_setmode, "?setmode@filebuf@@QEAAHH@Z");
313 SET(p_filebuf_setbuf, "?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z");
314 SET(p_filebuf_sync, "?sync@filebuf@@UEAAHXZ");
315 SET(p_filebuf_overflow, "?overflow@filebuf@@UEAAHH@Z");
316 SET(p_filebuf_underflow, "?underflow@filebuf@@UEAAHXZ");
317 SET(p_filebuf_seekoff, "?seekoff@filebuf@@UEAAJJW4seek_dir@ios@@H@Z");
319 SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z");
320 SET(p_ios_ctor, "??0ios@@IEAA@XZ");
321 SET(p_ios_sb_ctor, "??0ios@@QEAA@PEAVstreambuf@@@Z");
322 SET(p_ios_assign, "??4ios@@IEAAAEAV0@AEBV0@@Z");
323 SET(p_ios_init, "?init@ios@@IEAAXPEAVstreambuf@@@Z");
324 SET(p_ios_dtor, "??1ios@@UEAA@XZ");
325 SET(p_ios_clrlock, "?clrlock@ios@@QEAAXXZ");
326 SET(p_ios_setlock, "?setlock@ios@@QEAAXXZ");
327 SET(p_ios_lock, "?lock@ios@@QEAAXXZ");
328 SET(p_ios_unlock, "?unlock@ios@@QEAAXXZ");
329 SET(p_ios_lockbuf, "?lockbuf@ios@@QEAAXXZ");
330 SET(p_ios_unlockbuf, "?unlockbuf@ios@@QEAAXXZ");
331 SET(p_ios_flags_set, "?flags@ios@@QEAAJJ@Z");
332 SET(p_ios_flags_get, "?flags@ios@@QEBAJXZ");
333 SET(p_ios_setf, "?setf@ios@@QEAAJJ@Z");
334 SET(p_ios_setf_mask, "?setf@ios@@QEAAJJJ@Z");
335 SET(p_ios_unsetf, "?unsetf@ios@@QEAAJJ@Z");
336 SET(p_ios_good, "?good@ios@@QEBAHXZ");
337 SET(p_ios_bad, "?bad@ios@@QEBAHXZ");
338 SET(p_ios_eof, "?eof@ios@@QEBAHXZ");
339 SET(p_ios_fail, "?fail@ios@@QEBAHXZ");
340 SET(p_ios_clear, "?clear@ios@@QEAAXH@Z");
341 SET(p_ios_iword, "?iword@ios@@QEBAAEAJH@Z");
342 SET(p_ios_pword, "?pword@ios@@QEBAAEAPEAXH@Z");
343 } else {
344 p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPAXI@Z");
346 SET(p_streambuf_reserve_ctor, "??0streambuf@@IAE@PADH@Z");
347 SET(p_streambuf_ctor, "??0streambuf@@IAE@XZ");
348 SET(p_streambuf_dtor, "??1streambuf@@UAE@XZ");
349 SET(p_streambuf_allocate, "?allocate@streambuf@@IAEHXZ");
350 SET(p_streambuf_clrclock, "?clrlock@streambuf@@QAEXXZ");
351 SET(p_streambuf_doallocate, "?doallocate@streambuf@@MAEHXZ");
352 SET(p_streambuf_gbump, "?gbump@streambuf@@IAEXH@Z");
353 SET(p_streambuf_lock, "?lock@streambuf@@QAEXXZ");
354 SET(p_streambuf_pbackfail, "?pbackfail@streambuf@@UAEHH@Z");
355 SET(p_streambuf_pbump, "?pbump@streambuf@@IAEXH@Z");
356 SET(p_streambuf_sbumpc, "?sbumpc@streambuf@@QAEHXZ");
357 SET(p_streambuf_setb, "?setb@streambuf@@IAEXPAD0H@Z");
358 SET(p_streambuf_setbuf, "?setbuf@streambuf@@UAEPAV1@PADH@Z");
359 SET(p_streambuf_setlock, "?setlock@streambuf@@QAEXXZ");
360 SET(p_streambuf_sgetc, "?sgetc@streambuf@@QAEHXZ");
361 SET(p_streambuf_snextc, "?snextc@streambuf@@QAEHXZ");
362 SET(p_streambuf_sputc, "?sputc@streambuf@@QAEHH@Z");
363 SET(p_streambuf_stossc, "?stossc@streambuf@@QAEXXZ");
364 SET(p_streambuf_sync, "?sync@streambuf@@UAEHXZ");
365 SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ");
366 SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UAEHPADH@Z");
367 SET(p_streambuf_xsputn, "?xsputn@streambuf@@UAEHPBDH@Z");
369 SET(p_filebuf_fd_ctor, "??0filebuf@@QAE@H@Z");
370 SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QAE@HPADH@Z");
371 SET(p_filebuf_ctor, "??0filebuf@@QAE@XZ");
372 SET(p_filebuf_dtor, "??1filebuf@@UAE@XZ");
373 SET(p_filebuf_attach, "?attach@filebuf@@QAEPAV1@H@Z");
374 SET(p_filebuf_open, "?open@filebuf@@QAEPAV1@PBDHH@Z");
375 SET(p_filebuf_close, "?close@filebuf@@QAEPAV1@XZ");
376 SET(p_filebuf_setmode, "?setmode@filebuf@@QAEHH@Z");
377 SET(p_filebuf_setbuf, "?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z");
378 SET(p_filebuf_sync, "?sync@filebuf@@UAEHXZ");
379 SET(p_filebuf_overflow, "?overflow@filebuf@@UAEHH@Z");
380 SET(p_filebuf_underflow, "?underflow@filebuf@@UAEHXZ");
381 SET(p_filebuf_seekoff, "?seekoff@filebuf@@UAEJJW4seek_dir@ios@@H@Z");
383 SET(p_ios_copy_ctor, "??0ios@@IAE@ABV0@@Z");
384 SET(p_ios_ctor, "??0ios@@IAE@XZ");
385 SET(p_ios_sb_ctor, "??0ios@@QAE@PAVstreambuf@@@Z");
386 SET(p_ios_assign, "??4ios@@IAEAAV0@ABV0@@Z");
387 SET(p_ios_init, "?init@ios@@IAEXPAVstreambuf@@@Z");
388 SET(p_ios_dtor, "??1ios@@UAE@XZ");
389 SET(p_ios_clrlock, "?clrlock@ios@@QAAXXZ");
390 SET(p_ios_setlock, "?setlock@ios@@QAAXXZ");
391 SET(p_ios_lock, "?lock@ios@@QAAXXZ");
392 SET(p_ios_unlock, "?unlock@ios@@QAAXXZ");
393 SET(p_ios_lockbuf, "?lockbuf@ios@@QAAXXZ");
394 SET(p_ios_unlockbuf, "?unlockbuf@ios@@QAAXXZ");
395 SET(p_ios_flags_set, "?flags@ios@@QAEJJ@Z");
396 SET(p_ios_flags_get, "?flags@ios@@QBEJXZ");
397 SET(p_ios_setf, "?setf@ios@@QAEJJ@Z");
398 SET(p_ios_setf_mask, "?setf@ios@@QAEJJJ@Z");
399 SET(p_ios_unsetf, "?unsetf@ios@@QAEJJ@Z");
400 SET(p_ios_good, "?good@ios@@QBEHXZ");
401 SET(p_ios_bad, "?bad@ios@@QBEHXZ");
402 SET(p_ios_eof, "?eof@ios@@QBEHXZ");
403 SET(p_ios_fail, "?fail@ios@@QBEHXZ");
404 SET(p_ios_clear, "?clear@ios@@QAEXH@Z");
405 SET(p_ios_iword, "?iword@ios@@QBEAAJH@Z");
406 SET(p_ios_pword, "?pword@ios@@QBEAAPAXH@Z");
408 SET(p_ios_static_lock, "?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A");
409 SET(p_ios_lockc, "?lockc@ios@@KAXXZ");
410 SET(p_ios_unlockc, "?unlockc@ios@@KAXXZ");
411 SET(p_ios_maxbit, "?x_maxbit@ios@@0JA");
412 SET(p_ios_bitalloc, "?bitalloc@ios@@SAJXZ");
413 SET(p_ios_curindex, "?x_curindex@ios@@0HA");
414 SET(p_ios_statebuf, "?x_statebuf@ios@@0PAJA");
415 SET(p_ios_xalloc, "?xalloc@ios@@SAHXZ");
416 SET(p_ios_fLockcInit, "?fLockcInit@ios@@0HA");
418 init_thiscall_thunk();
419 return TRUE;
422 static int overflow_count, underflow_count;
423 static streambuf *test_this;
424 static char test_get_buffer[24];
425 static int buffer_pos, get_end;
427 #ifdef __i386__
428 static int __thiscall test_streambuf_overflow(int ch)
429 #else
430 static int __thiscall test_streambuf_overflow(streambuf *this, int ch)
431 #endif
433 overflow_count++;
434 if (ch == 'L') /* simulate a failure */
435 return EOF;
436 if (!test_this->unbuffered)
437 test_this->pptr = test_this->pbase + 5;
438 return ch;
441 #ifdef __i386__
442 static int __thiscall test_streambuf_underflow(void)
443 #else
444 static int __thiscall test_streambuf_underflow(streambuf *this)
445 #endif
447 underflow_count++;
448 if (test_this->unbuffered) {
449 return (buffer_pos < 23) ? test_get_buffer[buffer_pos++] : EOF;
450 } else if (test_this->gptr < test_this->egptr) {
451 return *test_this->gptr;
452 } else {
453 return get_end ? EOF : *(test_this->gptr = test_this->eback);
457 struct streambuf_lock_arg
459 streambuf *sb;
460 HANDLE lock[4];
461 HANDLE test[4];
464 static DWORD WINAPI lock_streambuf(void *arg)
466 struct streambuf_lock_arg *lock_arg = arg;
467 call_func1(p_streambuf_lock, lock_arg->sb);
468 SetEvent(lock_arg->lock[0]);
469 WaitForSingleObject(lock_arg->test[0], INFINITE);
470 call_func1(p_streambuf_lock, lock_arg->sb);
471 SetEvent(lock_arg->lock[1]);
472 WaitForSingleObject(lock_arg->test[1], INFINITE);
473 call_func1(p_streambuf_lock, lock_arg->sb);
474 SetEvent(lock_arg->lock[2]);
475 WaitForSingleObject(lock_arg->test[2], INFINITE);
476 call_func1(p_streambuf_unlock, lock_arg->sb);
477 SetEvent(lock_arg->lock[3]);
478 WaitForSingleObject(lock_arg->test[3], INFINITE);
479 call_func1(p_streambuf_unlock, lock_arg->sb);
480 return 0;
483 static void test_streambuf(void)
485 streambuf sb, sb2, sb3, *psb;
486 vtable_ptr test_streambuf_vtbl[11];
487 struct streambuf_lock_arg lock_arg;
488 HANDLE thread;
489 char reserve[16];
490 int ret, i;
491 BOOL locked;
493 memset(&sb, 0xab, sizeof(streambuf));
494 memset(&sb2, 0xab, sizeof(streambuf));
495 memset(&sb3, 0xab, sizeof(streambuf));
497 /* constructors */
498 call_func1(p_streambuf_ctor, &sb);
499 ok(sb.allocated == 0, "wrong allocate value, expected 0 got %d\n", sb.allocated);
500 ok(sb.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", sb.unbuffered);
501 ok(sb.base == NULL, "wrong base pointer, expected %p got %p\n", NULL, sb.base);
502 ok(sb.ebuf == NULL, "wrong ebuf pointer, expected %p got %p\n", NULL, sb.ebuf);
503 ok(sb.lock.LockCount == -1, "wrong critical section state, expected -1 got %d\n", sb.lock.LockCount);
504 call_func3(p_streambuf_reserve_ctor, &sb2, reserve, 16);
505 ok(sb2.allocated == 0, "wrong allocate value, expected 0 got %d\n", sb2.allocated);
506 ok(sb2.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", sb2.unbuffered);
507 ok(sb2.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb2.base);
508 ok(sb2.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb2.ebuf);
509 ok(sb.lock.LockCount == -1, "wrong critical section state, expected -1 got %d\n", sb.lock.LockCount);
510 call_func1(p_streambuf_ctor, &sb3);
511 ok(sb3.allocated == 0, "wrong allocate value, expected 0 got %d\n", sb3.allocated);
512 ok(sb3.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", sb3.unbuffered);
513 ok(sb3.base == NULL, "wrong base pointer, expected %p got %p\n", NULL, sb3.base);
514 ok(sb3.ebuf == NULL, "wrong ebuf pointer, expected %p got %p\n", NULL, sb3.ebuf);
516 memcpy(test_streambuf_vtbl, sb.vtable, sizeof(test_streambuf_vtbl));
517 test_streambuf_vtbl[7] = (vtable_ptr)&test_streambuf_overflow;
518 test_streambuf_vtbl[8] = (vtable_ptr)&test_streambuf_underflow;
519 sb2.vtable = test_streambuf_vtbl;
520 sb3.vtable = test_streambuf_vtbl;
521 overflow_count = underflow_count = 0;
522 strcpy(test_get_buffer, "CompuGlobalHyperMegaNet");
523 buffer_pos = get_end = 0;
525 /* setlock */
526 ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock);
527 call_func1(p_streambuf_setlock, &sb);
528 ok(sb.do_lock == -2, "expected do_lock value -2, got %d\n", sb.do_lock);
529 call_func1(p_streambuf_setlock, &sb);
530 ok(sb.do_lock == -3, "expected do_lock value -3, got %d\n", sb.do_lock);
531 sb.do_lock = 3;
532 call_func1(p_streambuf_setlock, &sb);
533 ok(sb.do_lock == 2, "expected do_lock value 2, got %d\n", sb.do_lock);
535 /* clrlock */
536 sb.do_lock = -2;
537 call_func1(p_streambuf_clrclock, &sb);
538 ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock);
539 call_func1(p_streambuf_clrclock, &sb);
540 ok(sb.do_lock == 0, "expected do_lock value 0, got %d\n", sb.do_lock);
541 call_func1(p_streambuf_clrclock, &sb);
542 ok(sb.do_lock == 1, "expected do_lock value 1, got %d\n", sb.do_lock);
543 call_func1(p_streambuf_clrclock, &sb);
544 ok(sb.do_lock == 1, "expected do_lock value 1, got %d\n", sb.do_lock);
546 /* lock/unlock */
547 lock_arg.sb = &sb;
548 for (i = 0; i < 4; i++) {
549 lock_arg.lock[i] = CreateEventW(NULL, FALSE, FALSE, NULL);
550 ok(lock_arg.lock[i] != NULL, "CreateEventW failed\n");
551 lock_arg.test[i] = CreateEventW(NULL, FALSE, FALSE, NULL);
552 ok(lock_arg.test[i] != NULL, "CreateEventW failed\n");
555 sb.do_lock = 0;
556 thread = CreateThread(NULL, 0, lock_streambuf, (void*)&lock_arg, 0, NULL);
557 ok(thread != NULL, "CreateThread failed\n");
558 WaitForSingleObject(lock_arg.lock[0], INFINITE);
559 locked = TryEnterCriticalSection(&sb.lock);
560 ok(locked != 0, "could not lock the streambuf\n");
561 LeaveCriticalSection(&sb.lock);
563 sb.do_lock = 1;
564 SetEvent(lock_arg.test[0]);
565 WaitForSingleObject(lock_arg.lock[1], INFINITE);
566 locked = TryEnterCriticalSection(&sb.lock);
567 ok(locked != 0, "could not lock the streambuf\n");
568 LeaveCriticalSection(&sb.lock);
570 sb.do_lock = -1;
571 SetEvent(lock_arg.test[1]);
572 WaitForSingleObject(lock_arg.lock[2], INFINITE);
573 locked = TryEnterCriticalSection(&sb.lock);
574 ok(locked == 0, "the streambuf was not locked before\n");
576 sb.do_lock = 0;
577 SetEvent(lock_arg.test[2]);
578 WaitForSingleObject(lock_arg.lock[3], INFINITE);
579 locked = TryEnterCriticalSection(&sb.lock);
580 ok(locked == 0, "the streambuf was not locked before\n");
581 sb.do_lock = -1;
583 /* setb */
584 call_func4(p_streambuf_setb, &sb, reserve, reserve+16, 0);
585 ok(sb.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb.base);
586 ok(sb.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb.ebuf);
587 call_func4(p_streambuf_setb, &sb, reserve, reserve+16, 4);
588 ok(sb.allocated == 4, "wrong allocate value, expected 4 got %d\n", sb.allocated);
589 sb.allocated = 0;
590 call_func4(p_streambuf_setb, &sb, NULL, NULL, 3);
591 ok(sb.allocated == 3, "wrong allocate value, expected 3 got %d\n", sb.allocated);
593 /* setbuf */
594 psb = call_func3(p_streambuf_setbuf, &sb, NULL, 5);
595 ok(psb == &sb, "wrong return value, expected %p got %p\n", &sb, psb);
596 ok(sb.allocated == 3, "wrong allocate value, expected 3 got %d\n", sb.allocated);
597 ok(sb.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", sb.unbuffered);
598 ok(sb.base == NULL, "wrong base pointer, expected %p got %p\n", NULL, sb.base);
599 ok(sb.ebuf == NULL, "wrong ebuf pointer, expected %p got %p\n", NULL, sb.ebuf);
600 psb = call_func3(p_streambuf_setbuf, &sb, reserve, 0);
601 ok(psb == &sb, "wrong return value, expected %p got %p\n", &sb, psb);
602 ok(sb.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", sb.unbuffered);
603 ok(sb.base == NULL, "wrong base pointer, expected %p got %p\n", NULL, sb.base);
604 ok(sb.ebuf == NULL, "wrong ebuf pointer, expected %p got %p\n", NULL, sb.ebuf);
605 psb = call_func3(p_streambuf_setbuf, &sb, reserve, 16);
606 ok(psb == &sb, "wrong return value, expected %p got %p\n", &sb, psb);
607 ok(sb.allocated == 3, "wrong allocate value, expected 3 got %d\n", sb.allocated);
608 ok(sb.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", sb.unbuffered);
609 ok(sb.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb.base);
610 ok(sb.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb.ebuf);
611 psb = call_func3(p_streambuf_setbuf, &sb, NULL, 8);
612 ok(psb == NULL, "wrong return value, expected %p got %p\n", NULL, psb);
613 ok(sb.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", sb.unbuffered);
614 ok(sb.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb.base);
615 ok(sb.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb.ebuf);
617 /* allocate */
618 ret = (int) call_func1(p_streambuf_allocate, &sb);
619 ok(ret == 0, "wrong return value, expected 0 got %d\n", ret);
620 sb.base = NULL;
621 ret = (int) call_func1(p_streambuf_allocate, &sb);
622 ok(ret == 1, "wrong return value, expected 1 got %d\n", ret);
623 ok(sb.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb.allocated);
624 ok(sb.ebuf - sb.base == 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb.ebuf, sb.base);
626 /* doallocate */
627 ret = (int) call_func1(p_streambuf_doallocate, &sb2);
628 ok(ret == 1, "doallocate failed, got %d\n", ret);
629 ok(sb2.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb2.allocated);
630 ok(sb2.ebuf - sb2.base == 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb2.ebuf, sb2.base);
631 ret = (int) call_func1(p_streambuf_doallocate, &sb3);
632 ok(ret == 1, "doallocate failed, got %d\n", ret);
633 ok(sb3.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb3.allocated);
634 ok(sb3.ebuf - sb3.base == 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb3.ebuf, sb3.base);
636 /* sb: buffered, space available */
637 sb.eback = sb.gptr = sb.base;
638 sb.egptr = sb.base + 256;
639 sb.pbase = sb.pptr = sb.base + 256;
640 sb.epptr = sb.base + 512;
641 /* sb2: buffered, no space available */
642 sb2.eback = sb2.base;
643 sb2.gptr = sb2.egptr = sb2.base + 256;
644 sb2.pbase = sb2.base + 256;
645 sb2.pptr = sb2.epptr = sb2.base + 512;
646 /* sb3: unbuffered */
647 sb3.unbuffered = 1;
649 /* gbump */
650 call_func2(p_streambuf_gbump, &sb, 10);
651 ok(sb.gptr == sb.eback + 10, "advance get pointer failed, expected %p got %p\n", sb.eback + 10, sb.gptr);
652 call_func2(p_streambuf_gbump, &sb, -15);
653 ok(sb.gptr == sb.eback - 5, "advance get pointer failed, expected %p got %p\n", sb.eback - 5, sb.gptr);
654 sb.gptr = sb.eback;
656 /* pbump */
657 call_func2(p_streambuf_pbump, &sb, -2);
658 ok(sb.pptr == sb.pbase - 2, "advance put pointer failed, expected %p got %p\n", sb.pbase - 2, sb.pptr);
659 call_func2(p_streambuf_pbump, &sb, 20);
660 ok(sb.pptr == sb.pbase + 18, "advance put pointer failed, expected %p got %p\n", sb.pbase + 18, sb.pptr);
661 sb.pptr = sb.pbase;
663 /* sync */
664 ret = (int) call_func1(p_streambuf_sync, &sb);
665 ok(ret == EOF, "sync failed, expected EOF got %d\n", ret);
666 sb.gptr = sb.egptr;
667 ret = (int) call_func1(p_streambuf_sync, &sb);
668 ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
669 sb.gptr = sb.egptr + 1;
670 ret = (int) call_func1(p_streambuf_sync, &sb);
671 ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
672 sb.gptr = sb.eback;
673 ret = (int) call_func1(p_streambuf_sync, &sb2);
674 ok(ret == EOF, "sync failed, expected EOF got %d\n", ret);
675 sb2.pptr = sb2.pbase;
676 ret = (int) call_func1(p_streambuf_sync, &sb2);
677 ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
678 sb2.pptr = sb2.pbase - 1;
679 ret = (int) call_func1(p_streambuf_sync, &sb2);
680 ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
681 sb2.pptr = sb2.epptr;
682 ret = (int) call_func1(p_streambuf_sync, &sb3);
683 ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
685 /* sgetc */
686 strcpy(sb2.eback, "WorstTestEver");
687 test_this = &sb2;
688 ret = (int) call_func1(p_streambuf_sgetc, &sb2);
689 ok(ret == 'W', "expected 'W' got '%c'\n", ret);
690 ok(underflow_count == 1, "expected call to underflow\n");
691 ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char);
692 sb2.gptr++;
693 ret = (int) call_func1(p_streambuf_sgetc, &sb2);
694 ok(ret == 'o', "expected 'o' got '%c'\n", ret);
695 ok(underflow_count == 2, "expected call to underflow\n");
696 ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char);
697 sb2.gptr = sb2.egptr;
698 test_this = &sb3;
699 ret = (int) call_func1(p_streambuf_sgetc, &sb3);
700 ok(ret == 'C', "expected 'C' got '%c'\n", ret);
701 ok(underflow_count == 3, "expected call to underflow\n");
702 ok(sb3.stored_char == 'C', "wrong stored character, expected 'C' got %c\n", sb3.stored_char);
703 sb3.stored_char = 'b';
704 ret = (int) call_func1(p_streambuf_sgetc, &sb3);
705 ok(ret == 'b', "expected 'b' got '%c'\n", ret);
706 ok(underflow_count == 3, "no call to underflow expected\n");
707 ok(sb3.stored_char == 'b', "wrong stored character, expected 'b' got %c\n", sb3.stored_char);
709 /* sputc */
710 *sb.pbase = 'a';
711 ret = (int) call_func2(p_streambuf_sputc, &sb, 'c');
712 ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret);
713 ok(overflow_count == 0, "no call to overflow expected\n");
714 ok(*sb.pbase == 'c', "expected 'c' in the put area, got %c\n", *sb.pbase);
715 ok(sb.pptr == sb.pbase + 1, "wrong put pointer, expected %p got %p\n", sb.pbase + 1, sb.pptr);
716 test_this = &sb2;
717 ret = (int) call_func2(p_streambuf_sputc, &sb2, 'c');
718 ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret);
719 ok(overflow_count == 1, "expected call to overflow\n");
720 ok(sb2.pptr == sb2.pbase + 5, "wrong put pointer, expected %p got %p\n", sb2.pbase + 5, sb2.pptr);
721 test_this = &sb3;
722 ret = (int) call_func2(p_streambuf_sputc, &sb3, 'c');
723 ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret);
724 ok(overflow_count == 2, "expected call to overflow\n");
725 sb3.pbase = sb3.pptr = sb3.base;
726 sb3.epptr = sb3.ebuf;
727 ret = (int) call_func2(p_streambuf_sputc, &sb3, 'c');
728 ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret);
729 ok(overflow_count == 2, "no call to overflow expected\n");
730 ok(*sb3.pbase == 'c', "expected 'c' in the put area, got %c\n", *sb3.pbase);
731 sb3.pbase = sb3.pptr = sb3.epptr = NULL;
733 /* xsgetn */
734 sb2.gptr = sb2.egptr = sb2.eback + 13;
735 test_this = &sb2;
736 ret = (int) call_func3(p_streambuf_xsgetn, &sb2, reserve, 5);
737 ok(ret == 5, "wrong return value, expected 5 got %d\n", ret);
738 ok(!strncmp(reserve, "Worst", 5), "expected 'Worst' got %s\n", reserve);
739 ok(sb2.gptr == sb2.eback + 5, "wrong get pointer, expected %p got %p\n", sb2.eback + 5, sb2.gptr);
740 ok(underflow_count == 4, "expected call to underflow\n");
741 ret = (int) call_func3(p_streambuf_xsgetn, &sb2, reserve, 4);
742 ok(ret == 4, "wrong return value, expected 4 got %d\n", ret);
743 ok(!strncmp(reserve, "Test", 4), "expected 'Test' got %s\n", reserve);
744 ok(sb2.gptr == sb2.eback + 9, "wrong get pointer, expected %p got %p\n", sb2.eback + 9, sb2.gptr);
745 ok(underflow_count == 5, "expected call to underflow\n");
746 get_end = 1;
747 ret = (int) call_func3(p_streambuf_xsgetn, &sb2, reserve, 16);
748 ok(ret == 4, "wrong return value, expected 4 got %d\n", ret);
749 ok(!strncmp(reserve, "Ever", 4), "expected 'Ever' got %s\n", reserve);
750 ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr);
751 ok(underflow_count == 7, "expected 2 calls to underflow, got %d\n", underflow_count - 5);
752 test_this = &sb3;
753 ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 11);
754 ok(ret == 11, "wrong return value, expected 11 got %d\n", ret);
755 ok(!strncmp(reserve, "bompuGlobal", 11), "expected 'bompuGlobal' got %s\n", reserve);
756 ok(sb3.stored_char == 'H', "wrong stored character, expected 'H' got %c\n", sb3.stored_char);
757 ok(underflow_count == 18, "expected 11 calls to underflow, got %d\n", underflow_count - 7);
758 ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 16);
759 ok(ret == 12, "wrong return value, expected 12 got %d\n", ret);
760 ok(!strncmp(reserve, "HyperMegaNet", 12), "expected 'HyperMegaNet' got %s\n", reserve);
761 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
762 ok(underflow_count == 30, "expected 12 calls to underflow, got %d\n", underflow_count - 18);
763 ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 3);
764 ok(ret == 0, "wrong return value, expected 0 got %d\n", ret);
765 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
766 ok(underflow_count == 31, "expected call to underflow\n");
767 buffer_pos = 0;
768 ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 5);
769 ok(ret == 5, "wrong return value, expected 5 got %d\n", ret);
770 ok(!strncmp(reserve, "Compu", 5), "expected 'Compu' got %s\n", reserve);
771 ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char);
772 ok(underflow_count == 37, "expected 6 calls to underflow, got %d\n", underflow_count - 31);
774 /* xsputn */
775 ret = (int) call_func3(p_streambuf_xsputn, &sb, "Test\0ing", 8);
776 ok(ret == 8, "wrong return value, expected 8 got %d\n", ret);
777 ok(sb.pptr == sb.pbase + 9, "wrong put pointer, expected %p got %p\n", sb.pbase + 9, sb.pptr);
778 test_this = &sb2;
779 sb2.pptr = sb2.epptr - 7;
780 ret = (int) call_func3(p_streambuf_xsputn, &sb2, "Testing", 7);
781 ok(ret == 7, "wrong return value, expected 7 got %d\n", ret);
782 ok(sb2.pptr == sb2.epptr, "wrong put pointer, expected %p got %p\n", sb2.epptr, sb2.pptr);
783 ok(overflow_count == 2, "no call to overflow expected\n");
784 sb2.pptr = sb2.epptr - 5;
785 sb2.pbase[5] = 'a';
786 ret = (int) call_func3(p_streambuf_xsputn, &sb2, "Testing", 7);
787 ok(ret == 7, "wrong return value, expected 7 got %d\n", ret);
788 ok(sb2.pbase[5] == 'g', "expected 'g' got %c\n", sb2.pbase[5]);
789 ok(sb2.pptr == sb2.pbase + 6, "wrong put pointer, expected %p got %p\n", sb2.pbase + 6, sb2.pptr);
790 ok(overflow_count == 3, "expected call to overflow\n");
791 sb2.pptr = sb2.epptr - 4;
792 ret = (int) call_func3(p_streambuf_xsputn, &sb2, "TestLing", 8);
793 ok(ret == 4, "wrong return value, expected 4 got %d\n", ret);
794 ok(sb2.pptr == sb2.epptr, "wrong put pointer, expected %p got %p\n", sb2.epptr, sb2.pptr);
795 ok(overflow_count == 4, "expected call to overflow\n");
796 test_this = &sb3;
797 ret = (int) call_func3(p_streambuf_xsputn, &sb3, "Testing", 7);
798 ok(ret == 7, "wrong return value, expected 7 got %d\n", ret);
799 ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char);
800 ok(overflow_count == 11, "expected 7 calls to overflow, got %d\n", overflow_count - 4);
801 ret = (int) call_func3(p_streambuf_xsputn, &sb3, "TeLephone", 9);
802 ok(ret == 2, "wrong return value, expected 2 got %d\n", ret);
803 ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char);
804 ok(overflow_count == 14, "expected 3 calls to overflow, got %d\n", overflow_count - 11);
806 /* snextc */
807 strcpy(sb.eback, "Test");
808 ret = (int) call_func1(p_streambuf_snextc, &sb);
809 ok(ret == 'e', "expected 'e' got '%c'\n", ret);
810 ok(sb.gptr == sb.eback + 1, "wrong get pointer, expected %p got %p\n", sb.eback + 1, sb.gptr);
811 test_this = &sb2;
812 ret = (int) call_func1(p_streambuf_snextc, &sb2);
813 ok(ret == EOF, "expected EOF got '%c'\n", ret);
814 ok(sb2.gptr == sb2.egptr + 1, "wrong get pointer, expected %p got %p\n", sb2.egptr + 1, sb2.gptr);
815 ok(underflow_count == 39, "expected 2 calls to underflow, got %d\n", underflow_count - 37);
816 sb2.gptr = sb2.egptr - 1;
817 ret = (int) call_func1(p_streambuf_snextc, &sb2);
818 ok(ret == EOF, "expected EOF got '%c'\n", ret);
819 ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr);
820 ok(underflow_count == 40, "expected call to underflow\n");
821 get_end = 0;
822 ret = (int) call_func1(p_streambuf_snextc, &sb2);
823 ok(ret == 'o', "expected 'o' got '%c'\n", ret);
824 ok(sb2.gptr == sb2.eback + 1, "wrong get pointer, expected %p got %p\n", sb2.eback + 1, sb2.gptr);
825 ok(underflow_count == 41, "expected call to underflow\n");
826 sb2.gptr = sb2.egptr - 1;
827 ret = (int) call_func1(p_streambuf_snextc, &sb2);
828 ok(ret == 'W', "expected 'W' got '%c'\n", ret);
829 ok(sb2.gptr == sb2.eback, "wrong get pointer, expected %p got %p\n", sb2.eback, sb2.gptr);
830 ok(underflow_count == 42, "expected call to underflow\n");
831 sb2.gptr = sb2.egptr;
832 test_this = &sb3;
833 ret = (int) call_func1(p_streambuf_snextc, &sb3);
834 ok(ret == 'l', "expected 'l' got '%c'\n", ret);
835 ok(sb3.stored_char == 'l', "wrong stored character, expected 'l' got %c\n", sb3.stored_char);
836 ok(underflow_count == 43, "expected call to underflow\n");
837 buffer_pos = 22;
838 ret = (int) call_func1(p_streambuf_snextc, &sb3);
839 ok(ret == 't', "expected 't' got '%c'\n", ret);
840 ok(sb3.stored_char == 't', "wrong stored character, expected 't' got %c\n", sb3.stored_char);
841 ok(underflow_count == 44, "expected call to underflow\n");
842 ret = (int) call_func1(p_streambuf_snextc, &sb3);
843 ok(ret == EOF, "expected EOF got '%c'\n", ret);
844 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
845 ok(underflow_count == 45, "expected call to underflow\n");
846 buffer_pos = 0;
847 ret = (int) call_func1(p_streambuf_snextc, &sb3);
848 ok(ret == 'o', "expected 'o' got '%c'\n", ret);
849 ok(sb3.stored_char == 'o', "wrong stored character, expected 'o' got %c\n", sb3.stored_char);
850 ok(underflow_count == 47, "expected 2 calls to underflow, got %d\n", underflow_count - 45);
851 sb3.stored_char = EOF;
852 ret = (int) call_func1(p_streambuf_snextc, &sb3);
853 ok(ret == 'p', "expected 'p' got '%c'\n", ret);
854 ok(sb3.stored_char == 'p', "wrong stored character, expected 'p' got %c\n", sb3.stored_char);
855 ok(underflow_count == 49, "expected 2 calls to underflow, got %d\n", underflow_count - 47);
857 /* sbumpc */
858 ret = (int) call_func1(p_streambuf_sbumpc, &sb);
859 ok(ret == 'e', "expected 'e' got '%c'\n", ret);
860 ok(sb.gptr == sb.eback + 2, "wrong get pointer, expected %p got %p\n", sb.eback + 2, sb.gptr);
861 test_this = &sb2;
862 ret = (int) call_func1(p_streambuf_sbumpc, &sb2);
863 ok(ret == 'W', "expected 'W' got '%c'\n", ret);
864 ok(sb2.gptr == sb2.eback + 1, "wrong get pointer, expected %p got %p\n", sb2.eback + 1, sb2.gptr);
865 ok(underflow_count == 50, "expected call to underflow\n");
866 sb2.gptr = sb2.egptr - 1;
867 *sb2.gptr = 't';
868 ret = (int) call_func1(p_streambuf_sbumpc, &sb2);
869 ok(ret == 't', "expected 't' got '%c'\n", ret);
870 ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr);
871 ok(underflow_count == 50, "no call to underflow expected\n");
872 get_end = 1;
873 ret = (int) call_func1(p_streambuf_sbumpc, &sb2);
874 ok(ret == EOF, "expected EOF got '%c'\n", ret);
875 ok(sb2.gptr == sb2.egptr + 1, "wrong get pointer, expected %p got %p\n", sb2.egptr + 1, sb2.gptr);
876 ok(underflow_count == 51, "expected call to underflow\n");
877 sb2.gptr = sb2.egptr;
878 test_this = &sb3;
879 ret = (int) call_func1(p_streambuf_sbumpc, &sb3);
880 ok(ret == 'p', "expected 'p' got '%c'\n", ret);
881 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
882 ok(underflow_count == 51, "no call to underflow expected\n");
883 ret = (int) call_func1(p_streambuf_sbumpc, &sb3);
884 ok(ret == 'u', "expected 'u' got '%c'\n", ret);
885 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
886 ok(underflow_count == 52, "expected call to underflow\n");
887 buffer_pos = 23;
888 ret = (int) call_func1(p_streambuf_sbumpc, &sb3);
889 ok(ret == EOF, "expected EOF got '%c'\n", ret);
890 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
891 ok(underflow_count == 53, "expected call to underflow\n");
892 buffer_pos = 0;
893 ret = (int) call_func1(p_streambuf_sbumpc, &sb3);
894 ok(ret == 'C', "expected 'C' got '%c'\n", ret);
895 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
896 ok(underflow_count == 54, "expected call to underflow\n");
898 /* stossc */
899 call_func1(p_streambuf_stossc, &sb);
900 ok(sb.gptr == sb.eback + 3, "wrong get pointer, expected %p got %p\n", sb.eback + 3, sb.gptr);
901 test_this = &sb2;
902 call_func1(p_streambuf_stossc, &sb2);
903 ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr);
904 ok(underflow_count == 55, "expected call to underflow\n");
905 get_end = 0;
906 call_func1(p_streambuf_stossc, &sb2);
907 ok(sb2.gptr == sb2.eback + 1, "wrong get pointer, expected %p got %p\n", sb2.eback + 1, sb2.gptr);
908 ok(underflow_count == 56, "expected call to underflow\n");
909 sb2.gptr = sb2.egptr - 1;
910 call_func1(p_streambuf_stossc, &sb2);
911 ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr);
912 ok(underflow_count == 56, "no call to underflow expected\n");
913 test_this = &sb3;
914 call_func1(p_streambuf_stossc, &sb3);
915 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
916 ok(underflow_count == 57, "expected call to underflow\n");
917 sb3.stored_char = 'a';
918 call_func1(p_streambuf_stossc, &sb3);
919 ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char);
920 ok(underflow_count == 57, "no call to underflow expected\n");
922 /* pbackfail */
923 ret = (int) call_func2(p_streambuf_pbackfail, &sb, 'A');
924 ok(ret == 'A', "expected 'A' got '%c'\n", ret);
925 ok(sb.gptr == sb.eback + 2, "wrong get pointer, expected %p got %p\n", sb.eback + 2, sb.gptr);
926 ok(*sb.gptr == 'A', "expected 'A' in the get area, got %c\n", *sb.gptr);
927 ret = (int) call_func2(p_streambuf_pbackfail, &sb, EOF);
928 ok(ret == EOF, "expected EOF got '%c'\n", ret);
929 ok(sb.gptr == sb.eback + 1, "wrong get pointer, expected %p got %p\n", sb.eback + 1, sb.gptr);
930 ok((signed char)*sb.gptr == EOF, "expected EOF in the get area, got %c\n", *sb.gptr);
931 sb.gptr = sb.eback;
932 ret = (int) call_func2(p_streambuf_pbackfail, &sb, 'Z');
933 ok(ret == EOF, "expected EOF got '%c'\n", ret);
934 ok(sb.gptr == sb.eback, "wrong get pointer, expected %p got %p\n", sb.eback, sb.gptr);
935 ok(*sb.gptr == 'T', "expected 'T' in the get area, got %c\n", *sb.gptr);
936 ret = (int) call_func2(p_streambuf_pbackfail, &sb, EOF);
937 ok(ret == EOF, "expected EOF got '%c'\n", ret);
938 ok(sb.gptr == sb.eback, "wrong get pointer, expected %p got %p\n", sb.eback, sb.gptr);
939 ok(*sb.gptr == 'T', "expected 'T' in the get area, got %c\n", *sb.gptr);
940 sb2.gptr = sb2.egptr + 1;
941 ret = (int) call_func2(p_streambuf_pbackfail, &sb2, 'X');
942 ok(ret == 'X', "expected 'X' got '%c'\n", ret);
943 ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr);
944 ok(*sb2.gptr == 'X', "expected 'X' in the get area, got %c\n", *sb2.gptr);
946 SetEvent(lock_arg.test[3]);
947 WaitForSingleObject(thread, INFINITE);
949 call_func1(p_streambuf_dtor, &sb);
950 call_func1(p_streambuf_dtor, &sb2);
951 call_func1(p_streambuf_dtor, &sb3);
952 for (i = 0; i < 4; i++) {
953 CloseHandle(lock_arg.lock[i]);
954 CloseHandle(lock_arg.test[i]);
956 CloseHandle(thread);
959 struct filebuf_lock_arg
961 filebuf *fb1, *fb2, *fb3;
962 HANDLE lock;
963 HANDLE test;
966 static DWORD WINAPI lock_filebuf(void *arg)
968 struct filebuf_lock_arg *lock_arg = arg;
969 call_func1(p_streambuf_lock, &lock_arg->fb1->base);
970 call_func1(p_streambuf_lock, &lock_arg->fb2->base);
971 call_func1(p_streambuf_lock, &lock_arg->fb3->base);
972 SetEvent(lock_arg->lock);
973 WaitForSingleObject(lock_arg->test, INFINITE);
974 call_func1(p_streambuf_unlock, &lock_arg->fb1->base);
975 call_func1(p_streambuf_unlock, &lock_arg->fb2->base);
976 call_func1(p_streambuf_unlock, &lock_arg->fb3->base);
977 return 0;
980 static void test_filebuf(void)
982 filebuf fb1, fb2, fb3, *pret;
983 struct filebuf_lock_arg lock_arg;
984 HANDLE thread;
985 const char filename1[] = "test1";
986 const char filename2[] = "test2";
987 const char filename3[] = "test3";
988 char read_buffer[16];
989 int ret;
991 memset(&fb1, 0xab, sizeof(filebuf));
992 memset(&fb2, 0xab, sizeof(filebuf));
993 memset(&fb3, 0xab, sizeof(filebuf));
995 /* constructors */
996 call_func2(p_filebuf_fd_ctor, &fb1, 1);
997 ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
998 ok(fb1.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", fb1.base.unbuffered);
999 ok(fb1.fd == 1, "wrong fd, expected 1 got %d\n", fb1.fd);
1000 ok(fb1.close == 0, "wrong value, expected 0 got %d\n", fb1.close);
1001 call_func4(p_filebuf_fd_reserve_ctor, &fb2, 4, NULL, 0);
1002 ok(fb2.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb2.base.allocated);
1003 ok(fb2.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb2.base.unbuffered);
1004 ok(fb2.fd == 4, "wrong fd, expected 4 got %d\n", fb2.fd);
1005 ok(fb2.close == 0, "wrong value, expected 0 got %d\n", fb2.close);
1006 call_func1(p_filebuf_ctor, &fb3);
1007 ok(fb3.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb3.base.allocated);
1008 ok(fb3.base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", fb3.base.unbuffered);
1009 ok(fb3.fd == -1, "wrong fd, expected -1 got %d\n", fb3.fd);
1010 ok(fb3.close == 0, "wrong value, expected 0 got %d\n", fb3.close);
1012 lock_arg.fb1 = &fb1;
1013 lock_arg.fb2 = &fb2;
1014 lock_arg.fb3 = &fb3;
1015 lock_arg.lock = CreateEventW(NULL, FALSE, FALSE, NULL);
1016 ok(lock_arg.lock != NULL, "CreateEventW failed\n");
1017 lock_arg.test = CreateEventW(NULL, FALSE, FALSE, NULL);
1018 ok(lock_arg.test != NULL, "CreateEventW failed\n");
1019 thread = CreateThread(NULL, 0, lock_filebuf, (void*)&lock_arg, 0, NULL);
1020 ok(thread != NULL, "CreateThread failed\n");
1021 WaitForSingleObject(lock_arg.lock, INFINITE);
1023 /* setbuf */
1024 fb1.base.do_lock = 0;
1025 pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 16);
1026 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1027 ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
1028 ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
1029 ok(fb1.base.pbase == NULL, "wrong put area, expected %p got %p\n", NULL, fb1.base.pbase);
1030 fb1.base.pbase = fb1.base.pptr = fb1.base.base;
1031 fb1.base.epptr = fb1.base.ebuf;
1032 fb1.base.do_lock = -1;
1033 pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 16);
1034 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1035 ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
1036 ok(fb1.base.base == read_buffer, "wrong buffer, expected %p got %p\n", read_buffer, fb1.base.base);
1037 ok(fb1.base.pbase == read_buffer, "wrong put area, expected %p got %p\n", read_buffer, fb1.base.pbase);
1038 fb1.base.base = fb1.base.ebuf = NULL;
1039 fb1.base.do_lock = 0;
1040 pret = (filebuf*) call_func3(p_filebuf_setbuf, &fb1, read_buffer, 0);
1041 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1042 ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
1043 ok(fb1.base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", fb1.base.unbuffered);
1044 ok(fb1.base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, fb1.base.base);
1045 ok(fb1.base.pbase == read_buffer, "wrong put area, expected %p got %p\n", read_buffer, fb1.base.pbase);
1046 fb1.base.pbase = fb1.base.pptr = fb1.base.epptr = NULL;
1047 fb1.base.unbuffered = 0;
1048 fb1.base.do_lock = -1;
1050 /* attach */
1051 pret = (filebuf*) call_func2(p_filebuf_attach, &fb1, 2);
1052 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1053 ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
1054 ok(fb1.fd == 1, "wrong fd, expected 1 got %d\n", fb1.fd);
1055 fb2.fd = -1;
1056 fb2.base.do_lock = 0;
1057 pret = (filebuf*) call_func2(p_filebuf_attach, &fb2, 3);
1058 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1059 ok(fb2.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb2.base.allocated);
1060 ok(fb2.fd == 3, "wrong fd, expected 3 got %d\n", fb2.fd);
1061 fb2.base.do_lock = -1;
1062 fb3.base.do_lock = 0;
1063 pret = (filebuf*) call_func2(p_filebuf_attach, &fb3, 2);
1064 ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
1065 ok(fb3.base.allocated == 1, "wrong allocate value, expected 1 got %d\n", fb3.base.allocated);
1066 ok(fb3.fd == 2, "wrong fd, expected 2 got %d\n", fb3.fd);
1067 fb3.base.do_lock = -1;
1069 /* open modes */
1070 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out, filebuf_openprot);
1071 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1072 fb1.fd = -1;
1073 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1,
1074 OPENMODE_ate|OPENMODE_nocreate|OPENMODE_noreplace|OPENMODE_binary, filebuf_openprot);
1075 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1076 ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
1077 fb1.base.do_lock = 0;
1078 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out, filebuf_openprot);
1079 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1080 ok(fb1.base.allocated == 1, "wrong allocate value, expected 1 got %d\n", fb1.base.allocated);
1081 ok(_write(fb1.fd, "testing", 7) == 7, "_write failed\n");
1082 pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
1083 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1084 ok(fb1.fd == -1, "wrong fd, expected -1 got %d\n", fb1.fd);
1085 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out, filebuf_openprot);
1086 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1087 ok(_read(fb1.fd, read_buffer, 1) == -1, "file should not be open for reading\n");
1088 pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
1089 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1090 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_app, filebuf_openprot);
1091 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1092 ok(_read(fb1.fd, read_buffer, 1) == -1, "file should not be open for reading\n");
1093 ok(_write(fb1.fd, "testing", 7) == 7, "_write failed\n");
1094 ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
1095 ok(_write(fb1.fd, "append", 6) == 6, "_write failed\n");
1096 pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
1097 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1098 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out|OPENMODE_ate, filebuf_openprot);
1099 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1100 ok(_read(fb1.fd, read_buffer, 1) == -1, "file should not be open for reading\n");
1101 ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
1102 ok(_write(fb1.fd, "ate", 3) == 3, "_write failed\n");
1103 pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
1104 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1105 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in, filebuf_openprot);
1106 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1107 ok(_read(fb1.fd, read_buffer, 13) == 13, "read failed\n");
1108 read_buffer[13] = 0;
1109 ok(!strncmp(read_buffer, "atetingappend", 13), "wrong contents, expected 'atetingappend' got '%s'\n", read_buffer);
1110 pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
1111 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1112 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in|OPENMODE_trunc, filebuf_openprot);
1113 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1114 ok(_read(fb1.fd, read_buffer, 1) == 0, "read failed\n");
1115 ok(_write(fb1.fd, "file1", 5) == 5, "_write failed\n");
1116 pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
1117 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1118 pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in|OPENMODE_app, filebuf_openprot);
1119 ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
1120 ok(_write(fb1.fd, "app", 3) == 3, "_write failed\n");
1121 ok(_read(fb1.fd, read_buffer, 1) == 0, "read failed\n");
1122 ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
1123 ok(_read(fb1.fd, read_buffer, 8) == 8, "read failed\n");
1124 read_buffer[8] = 0;
1125 ok(!strncmp(read_buffer, "file1app", 8), "wrong contents, expected 'file1app' got '%s'\n", read_buffer);
1126 fb1.base.do_lock = -1;
1128 fb2.fd = -1;
1129 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_out|OPENMODE_nocreate, filebuf_openprot);
1130 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1131 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in|OPENMODE_nocreate, filebuf_openprot);
1132 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1133 fb2.base.do_lock = 0;
1134 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in, filebuf_openprot);
1135 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1136 ok(_read(fb1.fd, read_buffer, 1) == 0, "read failed\n");
1137 pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
1138 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1139 fb2.base.do_lock = -1;
1140 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in|OPENMODE_noreplace, filebuf_openprot);
1141 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1142 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_trunc|OPENMODE_noreplace, filebuf_openprot);
1143 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1144 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename3, OPENMODE_out|OPENMODE_nocreate|OPENMODE_noreplace, filebuf_openprot);
1145 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1147 /* open protection*/
1148 fb3.fd = -1;
1149 fb3.base.do_lock = 0;
1150 pret = (filebuf*) call_func4(p_filebuf_open, &fb3, filename3, OPENMODE_in|OPENMODE_out, filebuf_openprot);
1151 ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
1152 ok(_write(fb3.fd, "You wouldn't\nget this from\nany other guy", 40) == 40, "_write failed\n");
1153 fb2.base.do_lock = 0;
1154 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename3, OPENMODE_in|OPENMODE_out, filebuf_openprot);
1155 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1156 pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
1157 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1158 fb2.base.do_lock = -1;
1159 pret = (filebuf*) call_func1(p_filebuf_close, &fb3);
1160 ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
1161 pret = (filebuf*) call_func4(p_filebuf_open, &fb3, filename3, OPENMODE_in, filebuf_sh_none);
1162 ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
1163 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename3, OPENMODE_in, filebuf_openprot);
1164 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1165 fb3.base.do_lock = -1;
1167 /* setmode */
1168 fb1.base.do_lock = 0;
1169 fb1.base.pbase = fb1.base.pptr = fb1.base.base;
1170 fb1.base.epptr = fb1.base.ebuf;
1171 ret = (int) call_func2(p_filebuf_setmode, &fb1, filebuf_binary);
1172 ok(ret == filebuf_text, "wrong return, expected %d got %d\n", filebuf_text, ret);
1173 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1174 ret = (int) call_func2(p_filebuf_setmode, &fb1, filebuf_binary);
1175 ok(ret == filebuf_binary, "wrong return, expected %d got %d\n", filebuf_binary, ret);
1176 fb1.base.do_lock = -1;
1177 ret = (int) call_func2(p_filebuf_setmode, &fb1, 0x9000);
1178 ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
1179 fb2.base.do_lock = 0;
1180 ret = (int) call_func2(p_filebuf_setmode, &fb2, filebuf_text);
1181 ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
1182 fb2.base.do_lock = -1;
1184 /* sync */
1185 ret = (int) call_func1(p_filebuf_sync, &fb1);
1186 ok(ret == 0, "wrong return, expected 0 got %d\n", ret);
1187 fb1.base.eback = fb1.base.gptr = fb1.base.base;
1188 fb1.base.egptr = fb1.base.pbase = fb1.base.pptr = fb1.base.base + 256;
1189 fb1.base.epptr = fb1.base.ebuf;
1190 ret = (int) call_func3(p_streambuf_xsputn, &fb1.base, "We're no strangers to love\n", 27);
1191 ok(ret == 27, "wrong return, expected 27 got %d\n", ret);
1192 ret = (int) call_func1(p_filebuf_sync, &fb1);
1193 ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
1194 ok(fb1.base.gptr == fb1.base.base, "wrong get pointer, expected %p got %p\n", fb1.base.base, fb1.base.gptr);
1195 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1196 fb1.base.eback = fb1.base.gptr = fb1.base.egptr = NULL;
1197 fb1.base.pbase = fb1.base.pptr = fb1.base.base;
1198 fb1.base.epptr = fb1.base.ebuf;
1199 ret = (int) call_func3(p_streambuf_xsputn, &fb1.base, "You know the rules and so do I\n", 31);
1200 ok(ret == 31, "wrong return, expected 31 got %d\n", ret);
1201 ret = (int) call_func1(p_filebuf_sync, &fb1);
1202 ok(ret == 0, "wrong return, expected 0 got %d\n", ret);
1203 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1204 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1205 fb1.base.eback = fb1.base.base;
1206 fb1.base.gptr = fb1.base.base + 190;
1207 fb1.base.egptr = fb1.base.pbase = fb1.base.pptr = fb1.base.base + 256;
1208 fb1.base.epptr = fb1.base.ebuf;
1209 ret = (int) call_func1(p_filebuf_sync, &fb1);
1210 ok(ret == 0, "wrong return, expected 0 got %d\n", ret);
1211 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1212 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1213 ok(_tell(fb1.fd) == 0, "_tell failed\n");
1214 ret = (int) call_func1(p_filebuf_sync, &fb2);
1215 ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
1216 fb3.base.eback = fb3.base.base;
1217 fb3.base.gptr = fb3.base.egptr = fb3.base.pbase = fb3.base.pptr = fb3.base.base + 256;
1218 fb3.base.epptr = fb3.base.ebuf;
1219 ret = (int) call_func3(p_streambuf_xsputn, &fb3.base, "A full commitment's what I'm thinking of\n", 41);
1220 ok(ret == 41, "wrong return, expected 41 got %d\n", ret);
1221 ret = (int) call_func1(p_filebuf_sync, &fb3);
1222 ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
1223 ok(fb3.base.gptr == fb3.base.base + 256, "wrong get pointer, expected %p got %p\n", fb3.base.base + 256, fb3.base.gptr);
1224 ok(fb3.base.pptr == fb3.base.base + 297, "wrong put pointer, expected %p got %p\n", fb3.base.base + 297, fb3.base.pptr);
1225 fb3.base.eback = fb3.base.base;
1226 fb3.base.gptr = fb3.base.egptr = fb3.base.pbase = fb3.base.pptr = fb3.base.base + 256;
1227 fb3.base.epptr = fb3.base.ebuf;
1228 ret = (int) call_func1(p_filebuf_sync, &fb3);
1229 ok(ret == 0, "wrong return, expected 0 got %d\n", ret);
1230 ok(fb3.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb3.base.gptr);
1231 ok(fb3.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb3.base.pptr);
1232 fb3.base.eback = fb3.base.base;
1233 fb3.base.gptr = fb3.base.base + 216;
1234 fb3.base.egptr = fb3.base.pbase = fb3.base.pptr = fb3.base.base + 256;
1235 fb3.base.epptr = fb3.base.ebuf;
1236 ok(_read(fb3.fd, fb3.base.gptr, 42) == 40, "read failed\n");
1237 ret = (int) call_func1(p_filebuf_sync, &fb3);
1238 ok(ret == 0, "wrong return, expected 0 got %d\n", ret);
1239 ok(fb3.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb3.base.gptr);
1240 ok(fb3.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb3.base.pptr);
1241 ok(_tell(fb3.fd) == 0, "_tell failed\n");
1242 fb3.base.eback = fb3.base.gptr = fb3.base.egptr = NULL;
1243 fb3.base.pbase = fb3.base.pptr = fb3.base.epptr = NULL;
1245 /* overflow */
1246 ret = (int) call_func2(p_filebuf_overflow, &fb1, EOF);
1247 ok(ret == 1, "wrong return, expected 1 got %d\n", ret);
1248 fb1.base.pbase = fb1.base.pptr = fb1.base.epptr = NULL;
1249 fb1.base.eback = fb1.base.gptr = fb1.base.base;
1250 fb1.base.egptr = fb1.base.ebuf;
1251 ret = (int) call_func2(p_filebuf_overflow, &fb1, 'a');
1252 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1253 fb1.base.gptr = fb1.base.egptr = fb1.base.pbase = fb1.base.pptr = fb1.base.base + 256;
1254 fb1.base.epptr = fb1.base.ebuf;
1255 ret = (int) call_func3(p_streambuf_xsputn, &fb1.base, "I just want to tell you how I'm feeling", 39);
1256 ok(ret == 39, "wrong return, expected 39 got %d\n", ret);
1257 ret = (int) call_func2(p_filebuf_overflow, &fb1, '\n');
1258 ok(ret == 1, "wrong return, expected 1 got %d\n", ret);
1259 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1260 ok(fb1.base.pbase == fb1.base.base, "wrong put base, expected %p got %p\n", fb1.base.base, fb1.base.pbase);
1261 ok(fb1.base.pptr == fb1.base.base + 1, "wrong put pointer, expected %p got %p\n", fb1.base.base + 1, fb1.base.pptr);
1262 ok(fb1.base.epptr == fb1.base.ebuf, "wrong put end pointer, expected %p got %p\n", fb1.base.ebuf, fb1.base.epptr);
1263 ok(*fb1.base.pbase == '\n', "wrong character, expected '\\n' got '%c'\n", *fb1.base.pbase);
1264 ret = (int) call_func2(p_filebuf_overflow, &fb1, EOF);
1265 ok(ret == 1, "wrong return, expected 1 got %d\n", ret);
1266 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1267 ok(fb1.base.pbase == fb1.base.base, "wrong put base, expected %p got %p\n", fb1.base.base, fb1.base.pbase);
1268 ok(fb1.base.pptr == fb1.base.base, "wrong put pointer, expected %p got %p\n", fb1.base.base, fb1.base.pptr);
1269 ok(fb1.base.epptr == fb1.base.ebuf, "wrong put end pointer, expected %p got %p\n", fb1.base.ebuf, fb1.base.epptr);
1270 ret = (int) call_func2(p_filebuf_overflow, &fb2, EOF);
1271 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1272 fb2.base.do_lock = 0;
1273 pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in|OPENMODE_out, filebuf_openprot);
1274 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1275 fb2.base.do_lock = -1;
1276 ret = (int) call_func2(p_filebuf_overflow, &fb2, EOF);
1277 ok(ret == 1, "wrong return, expected 1 got %d\n", ret);
1279 /* underflow */
1280 ret = (int) call_func1(p_filebuf_underflow, &fb1);
1281 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1282 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1283 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1284 fb1.base.eback = fb1.base.gptr = fb1.base.base;
1285 fb1.base.egptr = fb1.base.pbase = fb1.base.pptr = fb1.base.base + 256;
1286 fb1.base.epptr = fb1.base.ebuf;
1287 *fb1.base.gptr = 'A';
1288 ret = (int) call_func1(p_filebuf_underflow, &fb1);
1289 ok(ret == 'A', "wrong return, expected 'A' got %d\n", ret);
1290 ok(fb1.base.gptr == fb1.base.base, "wrong get pointer, expected %p got %p\n", fb1.base.base, fb1.base.gptr);
1291 ok(fb1.base.pptr == fb1.base.base + 256, "wrong put pointer, expected %p got %p\n", fb1.base.base + 256, fb1.base.pptr);
1292 fb1.base.gptr = fb1.base.ebuf;
1293 ret = (int) call_func1(p_filebuf_underflow, &fb1);
1294 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1295 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1296 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1297 ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
1298 ret = (int) call_func1(p_filebuf_underflow, &fb1);
1299 ok(ret == 'f', "wrong return, expected 'f' got %d\n", ret);
1300 ok(fb1.base.eback == fb1.base.base, "wrong get base, expected %p got %p\n", fb1.base.base, fb1.base.eback);
1301 ok(fb1.base.gptr == fb1.base.base, "wrong get pointer, expected %p got %p\n", fb1.base.base, fb1.base.gptr);
1302 ok(fb1.base.egptr == fb1.base.base + 106, "wrong get end pointer, expected %p got %p\n", fb1.base.base + 106, fb1.base.egptr);
1303 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1304 ret = (int) call_func1(p_filebuf_underflow, &fb2);
1305 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1306 ok(_write(fb2.fd, "A\n", 2) == 2, "_write failed\n");
1307 ok(_lseek(fb2.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
1308 ret = (int) call_func1(p_filebuf_underflow, &fb2);
1309 ok(ret == 'A', "wrong return, expected 'A' got %d\n", ret);
1310 ret = (int) call_func1(p_filebuf_underflow, &fb2);
1311 ok(ret == '\n', "wrong return, expected '\\n' got %d\n", ret);
1312 fb2.base.do_lock = 0;
1313 pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
1314 ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
1315 fb2.base.do_lock = -1;
1316 ret = (int) call_func1(p_filebuf_underflow, &fb2);
1317 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1319 /* seekoff */
1320 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 5, SEEKDIR_beg, 0);
1321 ok(ret == 5, "wrong return, expected 5 got %d\n", ret);
1322 ok(fb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, fb1.base.gptr);
1323 ok(fb1.base.pptr == NULL, "wrong put pointer, expected %p got %p\n", NULL, fb1.base.pptr);
1324 fb1.base.eback = fb1.base.gptr = fb1.base.base;
1325 fb1.base.egptr = fb1.base.ebuf;
1326 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 0, SEEKDIR_beg, 0);
1327 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1328 fb1.base.eback = fb1.base.gptr = fb1.base.egptr = NULL;
1329 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 10, SEEKDIR_beg, OPENMODE_in|OPENMODE_out);
1330 ok(ret == 10, "wrong return, expected 10 got %d\n", ret);
1331 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 0, SEEKDIR_cur, 0);
1332 ok(ret == 10, "wrong return, expected 10 got %d\n", ret);
1333 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 200, SEEKDIR_cur, OPENMODE_in);
1334 ok(ret == 210, "wrong return, expected 210 got %d\n", ret);
1335 ret = (int) call_func4(p_filebuf_seekoff, &fb1, -60, SEEKDIR_cur, 0);
1336 ok(ret == 150, "wrong return, expected 150 got %d\n", ret);
1337 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 0, SEEKDIR_end, 0);
1338 ok(ret == 106, "wrong return, expected 106 got %d\n", ret);
1339 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 20, SEEKDIR_end, OPENMODE_out);
1340 ok(ret == 126, "wrong return, expected 126 got %d\n", ret);
1341 ret = (int) call_func4(p_filebuf_seekoff, &fb1, -150, SEEKDIR_end, -1);
1342 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1343 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 10, 3, 0);
1344 ok(ret == EOF, "wrong return, expected EOF got %d\n", ret);
1345 ret = (int) call_func4(p_filebuf_seekoff, &fb1, 16, SEEKDIR_beg, 0);
1346 ok(ret == 16, "wrong return, expected 16 got %d\n", ret);
1348 /* close */
1349 pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
1350 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1351 fb3.base.do_lock = 0;
1352 pret = (filebuf*) call_func1(p_filebuf_close, &fb3);
1353 ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
1354 ok(fb3.fd == -1, "wrong fd, expected -1 got %d\n", fb3.fd);
1355 fb3.fd = 5;
1356 pret = (filebuf*) call_func1(p_filebuf_close, &fb3);
1357 ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
1358 ok(fb3.fd == 5, "wrong fd, expected 5 got %d\n", fb3.fd);
1359 fb3.base.do_lock = -1;
1361 SetEvent(lock_arg.test);
1362 WaitForSingleObject(thread, INFINITE);
1364 /* destructor */
1365 call_func1(p_filebuf_dtor, &fb1);
1366 ok(fb1.fd == -1, "wrong fd, expected -1 got %d\n", fb1.fd);
1367 call_func1(p_filebuf_dtor, &fb2);
1368 call_func1(p_filebuf_dtor, &fb3);
1370 ok(_unlink(filename1) == 0, "Couldn't unlink file named '%s'\n", filename1);
1371 ok(_unlink(filename2) == 0, "Couldn't unlink file named '%s'\n", filename2);
1372 ok(_unlink(filename3) == 0, "Couldn't unlink file named '%s'\n", filename3);
1373 CloseHandle(lock_arg.lock);
1374 CloseHandle(lock_arg.test);
1375 CloseHandle(thread);
1378 struct ios_lock_arg
1380 ios *ios_obj;
1381 HANDLE lock;
1382 HANDLE release[3];
1385 static DWORD WINAPI lock_ios(void *arg)
1387 struct ios_lock_arg *lock_arg = arg;
1388 p_ios_lock(lock_arg->ios_obj);
1389 p_ios_lockbuf(lock_arg->ios_obj);
1390 p_ios_lockc();
1391 SetEvent(lock_arg->lock);
1392 WaitForSingleObject(lock_arg->release[0], INFINITE);
1393 p_ios_unlockc();
1394 WaitForSingleObject(lock_arg->release[1], INFINITE);
1395 p_ios_unlockbuf(lock_arg->ios_obj);
1396 WaitForSingleObject(lock_arg->release[2], INFINITE);
1397 p_ios_unlock(lock_arg->ios_obj);
1398 return 0;
1401 static void test_ios(void)
1403 ios ios_obj, ios_obj2;
1404 streambuf *psb;
1405 struct ios_lock_arg lock_arg;
1406 HANDLE thread;
1407 BOOL locked;
1408 LONG *pret, expected, ret;
1409 void **pret2;
1410 int i;
1412 memset(&ios_obj, 0xab, sizeof(ios));
1413 memset(&ios_obj2, 0xab, sizeof(ios));
1414 psb = p_operator_new(sizeof(streambuf));
1415 ok(psb != NULL, "failed to allocate streambuf object\n");
1416 call_func1(p_streambuf_ctor, psb);
1418 /* constructor/destructor */
1419 ok(*p_ios_fLockcInit == 4, "expected 4 got %d\n", *p_ios_fLockcInit);
1420 call_func2(p_ios_sb_ctor, &ios_obj, NULL);
1421 ok(ios_obj.sb == NULL, "expected %p got %p\n", NULL, ios_obj.sb);
1422 ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
1423 ok(ios_obj.special[0] == 0, "expected 0 got %d\n", ios_obj.special[0]);
1424 ok(ios_obj.special[1] == 0, "expected 0 got %d\n", ios_obj.special[1]);
1425 ok(ios_obj.delbuf == 0, "expected 0 got %d\n", ios_obj.delbuf);
1426 ok(ios_obj.tie == NULL, "expected %p got %p\n", NULL, ios_obj.tie);
1427 ok(ios_obj.flags == 0, "expected 0 got %x\n", ios_obj.flags);
1428 ok(ios_obj.precision == 6, "expected 6 got %d\n", ios_obj.precision);
1429 ok(ios_obj.fill == ' ', "expected ' ' got %d\n", ios_obj.fill);
1430 ok(ios_obj.width == 0, "expected 0 got %d\n", ios_obj.width);
1431 ok(ios_obj.do_lock == -1, "expected -1 got %d\n", ios_obj.do_lock);
1432 ok(ios_obj.lock.LockCount == -1, "expected -1 got %d\n", ios_obj.lock.LockCount);
1433 ok(*p_ios_fLockcInit == 5, "expected 5 got %d\n", *p_ios_fLockcInit);
1434 ios_obj.state = 0x8;
1435 call_func1(p_ios_dtor, &ios_obj);
1436 ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
1437 ok(*p_ios_fLockcInit == 4, "expected 4 got %d\n", *p_ios_fLockcInit);
1438 ios_obj.state = 0x8;
1439 call_func2(p_ios_sb_ctor, &ios_obj, psb);
1440 ok(ios_obj.sb == psb, "expected %p got %p\n", psb, ios_obj.sb);
1441 ok(ios_obj.state == IOSTATE_goodbit, "expected %x got %x\n", IOSTATE_goodbit, ios_obj.state);
1442 ok(ios_obj.delbuf == 0, "expected 0 got %d\n", ios_obj.delbuf);
1443 ok(*p_ios_fLockcInit == 5, "expected 5 got %d\n", *p_ios_fLockcInit);
1444 ios_obj.state = 0x8;
1445 call_func1(p_ios_dtor, &ios_obj);
1446 ok(ios_obj.sb == NULL, "expected %p got %p\n", NULL, ios_obj.sb);
1447 ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
1448 ok(*p_ios_fLockcInit == 4, "expected 4 got %d\n", *p_ios_fLockcInit);
1449 ios_obj.sb = psb;
1450 ios_obj.state = 0x8;
1451 call_func1(p_ios_ctor, &ios_obj);
1452 ok(ios_obj.sb == NULL, "expected %p got %p\n", NULL, ios_obj.sb);
1453 ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
1454 ok(*p_ios_fLockcInit == 5, "expected 5 got %d\n", *p_ios_fLockcInit);
1456 /* init */
1457 ios_obj.state |= 0x8;
1458 call_func2(p_ios_init, &ios_obj, psb);
1459 ok(ios_obj.sb == psb, "expected %p got %p\n", psb, ios_obj.sb);
1460 ok(ios_obj.state == 0x8, "expected %x got %x\n", 0x8, ios_obj.state);
1461 call_func2(p_ios_init, &ios_obj, NULL);
1462 ok(ios_obj.sb == NULL, "expected %p got %p\n", NULL, ios_obj.sb);
1463 ok(ios_obj.state == (0x8|IOSTATE_badbit), "expected %x got %x\n", (0x8|IOSTATE_badbit), ios_obj.state);
1464 ios_obj.sb = psb;
1465 ios_obj.delbuf = 0;
1466 call_func2(p_ios_init, &ios_obj, psb);
1467 ok(ios_obj.sb == psb, "expected %p got %p\n", psb, ios_obj.sb);
1468 ok(ios_obj.state == 0x8, "expected %x got %x\n", 0x8, ios_obj.state);
1469 call_func1(p_ios_dtor, &ios_obj);
1471 /* copy constructor */
1472 call_func2(p_ios_copy_ctor, &ios_obj, &ios_obj2);
1473 ok(ios_obj.sb == NULL, "expected %p got %p\n", NULL, ios_obj.sb);
1474 ok(ios_obj.state == (ios_obj2.state|IOSTATE_badbit), "expected %x got %x\n", (ios_obj2.state|IOSTATE_badbit), ios_obj.state);
1475 ok(ios_obj.delbuf == 0, "expected 0 got %d\n", ios_obj.delbuf);
1476 ok(ios_obj.tie == ios_obj2.tie, "expected %p got %p\n", ios_obj2.tie, ios_obj.tie);
1477 ok(ios_obj.flags == ios_obj2.flags, "expected %x got %x\n", ios_obj2.flags, ios_obj.flags);
1478 ok(ios_obj.precision == (char)0xab, "expected %d got %d\n", (char)0xab, ios_obj.precision);
1479 ok(ios_obj.fill == (char)0xab, "expected %d got %d\n", (char)0xab, ios_obj.fill);
1480 ok(ios_obj.width == (char)0xab, "expected %d got %d\n", (char)0xab, ios_obj.width);
1481 ok(ios_obj.do_lock == -1, "expected -1 got %d\n", ios_obj.do_lock);
1482 ok(*p_ios_fLockcInit == 5, "expected 5 got %d\n", *p_ios_fLockcInit);
1484 /* assignment */
1485 ios_obj.state = 0x8;
1486 ios_obj.delbuf = 2;
1487 ios_obj.tie = NULL;
1488 ios_obj.flags = 0;
1489 ios_obj.precision = 6;
1490 ios_obj.fill = ' ';
1491 ios_obj.width = 0;
1492 ios_obj.do_lock = 2;
1493 call_func2(p_ios_assign, &ios_obj, &ios_obj2);
1494 ok(ios_obj.sb == NULL, "expected %p got %p\n", NULL, ios_obj.sb);
1495 ok(ios_obj.state == (ios_obj2.state|IOSTATE_badbit), "expected %x got %x\n", (ios_obj2.state|IOSTATE_badbit), ios_obj.state);
1496 ok(ios_obj.delbuf == 2, "expected 2 got %d\n", ios_obj.delbuf);
1497 ok(ios_obj.tie == ios_obj2.tie, "expected %p got %p\n", ios_obj2.tie, ios_obj.tie);
1498 ok(ios_obj.flags == ios_obj2.flags, "expected %x got %x\n", ios_obj2.flags, ios_obj.flags);
1499 ok(ios_obj.precision == (char)0xab, "expected %d got %d\n", (char)0xab, ios_obj.precision);
1500 ok(ios_obj.fill == (char)0xab, "expected %d got %d\n", (char)0xab, ios_obj.fill);
1501 ok(ios_obj.width == (char)0xab, "expected %d got %d\n", (char)0xab, ios_obj.width);
1502 ok(ios_obj.do_lock == 2, "expected 2 got %d\n", ios_obj.do_lock);
1504 /* locking */
1505 ios_obj.sb = psb;
1506 ios_obj.do_lock = 1;
1507 ios_obj.sb->do_lock = 0;
1508 p_ios_clrlock(&ios_obj);
1509 ok(ios_obj.do_lock == 1, "expected 1 got %d\n", ios_obj.do_lock);
1510 ok(ios_obj.sb->do_lock == 1, "expected 1 got %d\n", ios_obj.sb->do_lock);
1511 ios_obj.do_lock = 0;
1512 p_ios_clrlock(&ios_obj);
1513 ok(ios_obj.do_lock == 1, "expected 1 got %d\n", ios_obj.do_lock);
1514 ok(ios_obj.sb->do_lock == 1, "expected 1 got %d\n", ios_obj.sb->do_lock);
1515 p_ios_setlock(&ios_obj);
1516 ok(ios_obj.do_lock == 0, "expected 0 got %d\n", ios_obj.do_lock);
1517 ok(ios_obj.sb->do_lock == 0, "expected 0 got %d\n", ios_obj.sb->do_lock);
1518 ios_obj.do_lock = -1;
1519 p_ios_setlock(&ios_obj);
1520 ok(ios_obj.do_lock == -2, "expected -2 got %d\n", ios_obj.do_lock);
1521 ok(ios_obj.sb->do_lock == -1, "expected -1 got %d\n", ios_obj.sb->do_lock);
1523 lock_arg.ios_obj = &ios_obj;
1524 lock_arg.lock = CreateEventW(NULL, FALSE, FALSE, NULL);
1525 ok(lock_arg.lock != NULL, "CreateEventW failed\n");
1526 lock_arg.release[0] = CreateEventW(NULL, FALSE, FALSE, NULL);
1527 ok(lock_arg.release[0] != NULL, "CreateEventW failed\n");
1528 lock_arg.release[1] = CreateEventW(NULL, FALSE, FALSE, NULL);
1529 ok(lock_arg.release[1] != NULL, "CreateEventW failed\n");
1530 lock_arg.release[2] = CreateEventW(NULL, FALSE, FALSE, NULL);
1531 ok(lock_arg.release[2] != NULL, "CreateEventW failed\n");
1532 thread = CreateThread(NULL, 0, lock_ios, (void*)&lock_arg, 0, NULL);
1533 ok(thread != NULL, "CreateThread failed\n");
1534 WaitForSingleObject(lock_arg.lock, INFINITE);
1536 locked = TryEnterCriticalSection(&ios_obj.lock);
1537 ok(locked == 0, "the ios object was not locked before\n");
1538 locked = TryEnterCriticalSection(&ios_obj.sb->lock);
1539 ok(locked == 0, "the streambuf was not locked before\n");
1540 locked = TryEnterCriticalSection(p_ios_static_lock);
1541 ok(locked == 0, "the static critical section was not locked before\n");
1543 /* flags */
1544 ios_obj.flags = 0x8000;
1545 ret = (LONG) call_func1(p_ios_flags_get, &ios_obj);
1546 ok(ret == 0x8000, "expected %x got %x\n", 0x8000, ret);
1547 ret = (LONG) call_func2(p_ios_flags_set, &ios_obj, 0x444);
1548 ok(ret == 0x8000, "expected %x got %x\n", 0x8000, ret);
1549 ok(ios_obj.flags == 0x444, "expected %x got %x\n", 0x444, ios_obj.flags);
1550 ret = (LONG) call_func2(p_ios_flags_set, &ios_obj, 0);
1551 ok(ret == 0x444, "expected %x got %x\n", 0x444, ret);
1552 ok(ios_obj.flags == 0, "expected %x got %x\n", 0, ios_obj.flags);
1554 /* setf */
1555 ios_obj.do_lock = 0;
1556 ios_obj.flags = 0x8400;
1557 ret = (LONG) call_func2(p_ios_setf, &ios_obj, 0x444);
1558 ok(ret == 0x8400, "expected %x got %x\n", 0x8400, ret);
1559 ok(ios_obj.flags == 0x8444, "expected %x got %x\n", 0x8444, ios_obj.flags);
1560 ret = (LONG) call_func3(p_ios_setf_mask, &ios_obj, 0x111, 0);
1561 ok(ret == 0x8444, "expected %x got %x\n", 0x8444, ret);
1562 ok(ios_obj.flags == 0x8444, "expected %x got %x\n", 0x8444, ios_obj.flags);
1563 ret = (LONG) call_func3(p_ios_setf_mask, &ios_obj, 0x111, 0x105);
1564 ok(ret == 0x8444, "expected %x got %x\n", 0x8444, ret);
1565 ok(ios_obj.flags == 0x8541, "expected %x got %x\n", 0x8541, ios_obj.flags);
1567 /* unsetf */
1568 ret = (LONG) call_func2(p_ios_unsetf, &ios_obj, 0x1111);
1569 ok(ret == 0x8541, "expected %x got %x\n", 0x8541, ret);
1570 ok(ios_obj.flags == 0x8440, "expected %x got %x\n", 0x8440, ios_obj.flags);
1571 ret = (LONG) call_func2(p_ios_unsetf, &ios_obj, 0x8008);
1572 ok(ret == 0x8440, "expected %x got %x\n", 0x8440, ret);
1573 ok(ios_obj.flags == 0x440, "expected %x got %x\n", 0x440, ios_obj.flags);
1574 ios_obj.do_lock = -1;
1576 /* state */
1577 ios_obj.state = 0x8;
1578 ret = (LONG) call_func1(p_ios_good, &ios_obj);
1579 ok(ret == 0, "expected 0 got %d\n", ret);
1580 ios_obj.state = IOSTATE_goodbit;
1581 ret = (LONG) call_func1(p_ios_good, &ios_obj);
1582 ok(ret == 1, "expected 1 got %d\n", ret);
1583 ret = (LONG) call_func1(p_ios_bad, &ios_obj);
1584 ok(ret == 0, "expected 0 got %d\n", ret);
1585 ios_obj.state = (IOSTATE_eofbit|IOSTATE_badbit);
1586 ret = (LONG) call_func1(p_ios_bad, &ios_obj);
1587 ok(ret == IOSTATE_badbit, "expected 4 got %d\n", ret);
1588 ret = (LONG) call_func1(p_ios_eof, &ios_obj);
1589 ok(ret == IOSTATE_eofbit, "expected 1 got %d\n", ret);
1590 ios_obj.state = 0x8;
1591 ret = (LONG) call_func1(p_ios_eof, &ios_obj);
1592 ok(ret == 0, "expected 0 got %d\n", ret);
1593 ret = (LONG) call_func1(p_ios_fail, &ios_obj);
1594 ok(ret == 0, "expected 0 got %d\n", ret);
1595 ios_obj.state = IOSTATE_badbit;
1596 ret = (LONG) call_func1(p_ios_fail, &ios_obj);
1597 ok(ret == IOSTATE_badbit, "expected 4 got %d\n", ret);
1598 ios_obj.state = (IOSTATE_eofbit|IOSTATE_failbit);
1599 ret = (LONG) call_func1(p_ios_fail, &ios_obj);
1600 ok(ret == IOSTATE_failbit, "expected 2 got %d\n", ret);
1601 ios_obj.state = (IOSTATE_eofbit|IOSTATE_failbit|IOSTATE_badbit);
1602 ret = (LONG) call_func1(p_ios_fail, &ios_obj);
1603 ok(ret == (IOSTATE_failbit|IOSTATE_badbit), "expected 6 got %d\n", ret);
1604 ios_obj.do_lock = 0;
1605 call_func2(p_ios_clear, &ios_obj, 0);
1606 ok(ios_obj.state == IOSTATE_goodbit, "expected 0 got %d\n", ios_obj.state);
1607 call_func2(p_ios_clear, &ios_obj, 0x8|IOSTATE_eofbit);
1608 ok(ios_obj.state == (0x8|IOSTATE_eofbit), "expected 9 got %d\n", ios_obj.state);
1609 ios_obj.do_lock = -1;
1611 SetEvent(lock_arg.release[0]);
1613 /* bitalloc */
1614 expected = 0x10000;
1615 for (i = 0; i < 20; i++) {
1616 ret = p_ios_bitalloc();
1617 ok(ret == expected, "expected %x got %x\n", expected, ret);
1618 ok(*p_ios_maxbit == expected, "expected %x got %x\n", expected, *p_ios_maxbit);
1619 expected <<= 1;
1622 /* xalloc/pword/iword */
1623 ok(*p_ios_curindex == -1, "expected -1 got %d\n", *p_ios_curindex);
1624 expected = 0;
1625 for (i = 0; i < 8; i++) {
1626 ret = p_ios_xalloc();
1627 ok(ret == expected, "expected %d got %d\n", expected, ret);
1628 ok(*p_ios_curindex == expected, "expected %d got %d\n", expected, *p_ios_curindex);
1629 pret = (LONG*) call_func2(p_ios_iword, &ios_obj, ret);
1630 ok(pret == &p_ios_statebuf[ret], "expected %p got %p\n", &p_ios_statebuf[ret], pret);
1631 ok(*pret == 0, "expected 0 got %d\n", *pret);
1632 pret2 = (void**) call_func2(p_ios_pword, &ios_obj, ret);
1633 ok(pret2 == (void**)&p_ios_statebuf[ret], "expected %p got %p\n", (void**)&p_ios_statebuf[ret], pret2);
1634 expected++;
1636 ret = p_ios_xalloc();
1637 ok(ret == -1, "expected -1 got %d\n", ret);
1638 ok(*p_ios_curindex == 7, "expected 7 got %d\n", *p_ios_curindex);
1640 SetEvent(lock_arg.release[1]);
1641 SetEvent(lock_arg.release[2]);
1642 WaitForSingleObject(thread, INFINITE);
1644 ios_obj.delbuf = 1;
1645 call_func1(p_ios_dtor, &ios_obj);
1646 ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
1647 ok(*p_ios_fLockcInit == 4, "expected 4 got %d\n", *p_ios_fLockcInit);
1648 CloseHandle(lock_arg.lock);
1649 CloseHandle(lock_arg.release[0]);
1650 CloseHandle(lock_arg.release[1]);
1651 CloseHandle(lock_arg.release[2]);
1652 CloseHandle(thread);
1655 START_TEST(msvcirt)
1657 if(!init())
1658 return;
1660 test_streambuf();
1661 test_filebuf();
1662 test_ios();
1664 FreeLibrary(msvcrt);
1665 FreeLibrary(msvcirt);