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
22 #include "wine/test.h"
24 typedef void (*vtable_ptr
)(void);
28 const vtable_ptr
*vtable
;
41 CRITICAL_SECTION lock
;
46 #define __thiscall __stdcall
48 #define __thiscall __cdecl
52 static streambuf
* (*__thiscall p_streambuf_reserve_ctor
)(streambuf
*, char*, int);
53 static streambuf
* (*__thiscall p_streambuf_ctor
)(streambuf
*);
54 static void (*__thiscall p_streambuf_dtor
)(streambuf
*);
55 static int (*__thiscall p_streambuf_allocate
)(streambuf
*);
56 static void (*__thiscall p_streambuf_clrclock
)(streambuf
*);
57 static int (*__thiscall p_streambuf_doallocate
)(streambuf
*);
58 static void (*__thiscall p_streambuf_gbump
)(streambuf
*, int);
59 static void (*__thiscall p_streambuf_lock
)(streambuf
*);
60 static void (*__thiscall p_streambuf_pbump
)(streambuf
*, int);
61 static int (*__thiscall p_streambuf_sbumpc
)(streambuf
*);
62 static void (*__thiscall p_streambuf_setb
)(streambuf
*, char*, char*, int);
63 static void (*__thiscall p_streambuf_setlock
)(streambuf
*);
64 static streambuf
* (*__thiscall p_streambuf_setbuf
)(streambuf
*, char*, int);
65 static int (*__thiscall p_streambuf_sgetc
)(streambuf
*);
66 static int (*__thiscall p_streambuf_snextc
)(streambuf
*);
67 static int (*__thiscall p_streambuf_sputc
)(streambuf
*, int);
68 static int (*__thiscall p_streambuf_sync
)(streambuf
*);
69 static void (*__thiscall p_streambuf_unlock
)(streambuf
*);
70 static int (*__thiscall p_streambuf_xsgetn
)(streambuf
*, char*, int);
71 static int (*__thiscall p_streambuf_xsputn
)(streambuf
*, const char*, int);
73 /* Emulate a __thiscall */
79 BYTE pop_eax
; /* popl %eax (ret addr) */
80 BYTE pop_edx
; /* popl %edx (func) */
81 BYTE pop_ecx
; /* popl %ecx (this) */
82 BYTE push_eax
; /* pushl %eax */
83 WORD jmp_edx
; /* jmp *%edx */
87 static void * (WINAPI
*call_thiscall_func1
)( void *func
, void *this );
88 static void * (WINAPI
*call_thiscall_func2
)( void *func
, void *this, const void *a
);
89 static void * (WINAPI
*call_thiscall_func3
)( void *func
, void *this, const void *a
, const void *b
);
90 static void * (WINAPI
*call_thiscall_func4
)( void *func
, void *this, const void *a
, const void *b
,
92 static void * (WINAPI
*call_thiscall_func5
)( void *func
, void *this, const void *a
, const void *b
,
93 const void *c
, const void *d
);
95 static void init_thiscall_thunk(void)
97 struct thiscall_thunk
*thunk
= VirtualAlloc( NULL
, sizeof(*thunk
),
98 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
99 thunk
->pop_eax
= 0x58; /* popl %eax */
100 thunk
->pop_edx
= 0x5a; /* popl %edx */
101 thunk
->pop_ecx
= 0x59; /* popl %ecx */
102 thunk
->push_eax
= 0x50; /* pushl %eax */
103 thunk
->jmp_edx
= 0xe2ff; /* jmp *%edx */
104 call_thiscall_func1
= (void *)thunk
;
105 call_thiscall_func2
= (void *)thunk
;
106 call_thiscall_func3
= (void *)thunk
;
107 call_thiscall_func4
= (void *)thunk
;
108 call_thiscall_func5
= (void *)thunk
;
111 #define call_func1(func,_this) call_thiscall_func1(func,_this)
112 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
113 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b))
114 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),(const void*)(b), \
116 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \
117 (const void*)(c), (const void *)(d))
121 #define init_thiscall_thunk()
122 #define call_func1(func,_this) func(_this)
123 #define call_func2(func,_this,a) func(_this,a)
124 #define call_func3(func,_this,a,b) func(_this,a,b)
125 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
126 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
128 #endif /* __i386__ */
130 static HMODULE msvcirt
;
131 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcirt,y)
132 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
133 static BOOL
init(void)
135 msvcirt
= LoadLibraryA("msvcirt.dll");
137 win_skip("msvcirt.dll not installed\n");
141 if(sizeof(void*) == 8) { /* 64-bit initialization */
142 SET(p_streambuf_reserve_ctor
, "??0streambuf@@IEAA@PEADH@Z");
143 SET(p_streambuf_ctor
, "??0streambuf@@IEAA@XZ");
144 SET(p_streambuf_dtor
, "??1streambuf@@UEAA@XZ");
145 SET(p_streambuf_allocate
, "?allocate@streambuf@@IEAAHXZ");
146 SET(p_streambuf_clrclock
, "?clrlock@streambuf@@QEAAXXZ");
147 SET(p_streambuf_doallocate
, "?doallocate@streambuf@@MEAAHXZ");
148 SET(p_streambuf_gbump
, "?gbump@streambuf@@IEAAXH@Z");
149 SET(p_streambuf_lock
, "?lock@streambuf@@QEAAXXZ");
150 SET(p_streambuf_pbump
, "?pbump@streambuf@@IEAAXH@Z");
151 SET(p_streambuf_sbumpc
, "?sbumpc@streambuf@@QEAAHXZ");
152 SET(p_streambuf_setb
, "?setb@streambuf@@IEAAXPEAD0H@Z");
153 SET(p_streambuf_setbuf
, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z");
154 SET(p_streambuf_setlock
, "?setlock@streambuf@@QEAAXXZ");
155 SET(p_streambuf_sgetc
, "?sgetc@streambuf@@QEAAHXZ");
156 SET(p_streambuf_snextc
, "?snextc@streambuf@@QEAAHXZ");
157 SET(p_streambuf_sputc
, "?sputc@streambuf@@QEAAHH@Z");
158 SET(p_streambuf_sync
, "?sync@streambuf@@UEAAHXZ");
159 SET(p_streambuf_unlock
, "?unlock@streambuf@@QEAAXXZ");
160 SET(p_streambuf_xsgetn
, "?xsgetn@streambuf@@UEAAHPEADH@Z");
161 SET(p_streambuf_xsputn
, "?xsputn@streambuf@@UEAAHPEBDH@Z");
163 SET(p_streambuf_reserve_ctor
, "??0streambuf@@IAE@PADH@Z");
164 SET(p_streambuf_ctor
, "??0streambuf@@IAE@XZ");
165 SET(p_streambuf_dtor
, "??1streambuf@@UAE@XZ");
166 SET(p_streambuf_allocate
, "?allocate@streambuf@@IAEHXZ");
167 SET(p_streambuf_clrclock
, "?clrlock@streambuf@@QAEXXZ");
168 SET(p_streambuf_doallocate
, "?doallocate@streambuf@@MAEHXZ");
169 SET(p_streambuf_gbump
, "?gbump@streambuf@@IAEXH@Z");
170 SET(p_streambuf_lock
, "?lock@streambuf@@QAEXXZ");
171 SET(p_streambuf_pbump
, "?pbump@streambuf@@IAEXH@Z");
172 SET(p_streambuf_sbumpc
, "?sbumpc@streambuf@@QAEHXZ");
173 SET(p_streambuf_setb
, "?setb@streambuf@@IAEXPAD0H@Z");
174 SET(p_streambuf_setbuf
, "?setbuf@streambuf@@UAEPAV1@PADH@Z");
175 SET(p_streambuf_setlock
, "?setlock@streambuf@@QAEXXZ");
176 SET(p_streambuf_sgetc
, "?sgetc@streambuf@@QAEHXZ");
177 SET(p_streambuf_snextc
, "?snextc@streambuf@@QAEHXZ");
178 SET(p_streambuf_sputc
, "?sputc@streambuf@@QAEHH@Z");
179 SET(p_streambuf_sync
, "?sync@streambuf@@UAEHXZ");
180 SET(p_streambuf_unlock
, "?unlock@streambuf@@QAEXXZ");
181 SET(p_streambuf_xsgetn
, "?xsgetn@streambuf@@UAEHPADH@Z");
182 SET(p_streambuf_xsputn
, "?xsputn@streambuf@@UAEHPBDH@Z");
185 init_thiscall_thunk();
189 static int overflow_count
, underflow_count
;
190 static streambuf
*test_this
;
191 static char test_get_buffer
[24];
192 static int buffer_pos
, get_end
;
195 static int __thiscall
test_streambuf_overflow(int ch
)
197 static int __thiscall
test_streambuf_overflow(streambuf
*this, int ch
)
201 if (ch
== 'L') /* simulate a failure */
203 if (!test_this
->unbuffered
)
204 test_this
->pptr
= test_this
->pbase
+ 5;
209 static int __thiscall
test_streambuf_underflow(void)
211 static int __thiscall
test_streambuf_underflow(streambuf
*this)
215 if (test_this
->unbuffered
) {
216 return (buffer_pos
< 23) ? test_get_buffer
[buffer_pos
++] : EOF
;
217 } else if (test_this
->gptr
< test_this
->egptr
) {
218 return *test_this
->gptr
;
220 return get_end
? EOF
: *(test_this
->gptr
= test_this
->eback
);
224 struct streambuf_lock_arg
231 static DWORD WINAPI
lock_streambuf(void *arg
)
233 struct streambuf_lock_arg
*lock_arg
= arg
;
234 call_func1(p_streambuf_lock
, lock_arg
->sb
);
235 SetEvent(lock_arg
->lock
[0]);
236 WaitForSingleObject(lock_arg
->test
[0], INFINITE
);
237 call_func1(p_streambuf_lock
, lock_arg
->sb
);
238 SetEvent(lock_arg
->lock
[1]);
239 WaitForSingleObject(lock_arg
->test
[1], INFINITE
);
240 call_func1(p_streambuf_lock
, lock_arg
->sb
);
241 SetEvent(lock_arg
->lock
[2]);
242 WaitForSingleObject(lock_arg
->test
[2], INFINITE
);
243 call_func1(p_streambuf_unlock
, lock_arg
->sb
);
244 SetEvent(lock_arg
->lock
[3]);
245 WaitForSingleObject(lock_arg
->test
[3], INFINITE
);
246 call_func1(p_streambuf_unlock
, lock_arg
->sb
);
250 static void test_streambuf(void)
252 streambuf sb
, sb2
, sb3
, *psb
;
253 vtable_ptr test_streambuf_vtbl
[11];
254 struct streambuf_lock_arg lock_arg
;
260 memset(&sb
, 0xab, sizeof(streambuf
));
261 memset(&sb2
, 0xab, sizeof(streambuf
));
262 memset(&sb3
, 0xab, sizeof(streambuf
));
265 call_func1(p_streambuf_ctor
, &sb
);
266 ok(sb
.allocated
== 0, "wrong allocate value, expected 0 got %d\n", sb
.allocated
);
267 ok(sb
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb
.unbuffered
);
268 ok(sb
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb
.base
);
269 ok(sb
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb
.ebuf
);
270 ok(sb
.lock
.LockCount
== -1, "wrong critical section state, expected -1 got %d\n", sb
.lock
.LockCount
);
271 call_func3(p_streambuf_reserve_ctor
, &sb2
, reserve
, 16);
272 ok(sb2
.allocated
== 0, "wrong allocate value, expected 0 got %d\n", sb2
.allocated
);
273 ok(sb2
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb2
.unbuffered
);
274 ok(sb2
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb2
.base
);
275 ok(sb2
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb2
.ebuf
);
276 ok(sb
.lock
.LockCount
== -1, "wrong critical section state, expected -1 got %d\n", sb
.lock
.LockCount
);
277 call_func1(p_streambuf_ctor
, &sb3
);
278 ok(sb3
.allocated
== 0, "wrong allocate value, expected 0 got %d\n", sb3
.allocated
);
279 ok(sb3
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb3
.unbuffered
);
280 ok(sb3
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb3
.base
);
281 ok(sb3
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb3
.ebuf
);
283 memcpy(test_streambuf_vtbl
, sb
.vtable
, sizeof(test_streambuf_vtbl
));
284 test_streambuf_vtbl
[7] = (vtable_ptr
)&test_streambuf_overflow
;
285 test_streambuf_vtbl
[8] = (vtable_ptr
)&test_streambuf_underflow
;
286 sb2
.vtable
= test_streambuf_vtbl
;
287 sb3
.vtable
= test_streambuf_vtbl
;
288 overflow_count
= underflow_count
= 0;
289 strcpy(test_get_buffer
, "CompuGlobalHyperMegaNet");
290 buffer_pos
= get_end
= 0;
293 ok(sb
.do_lock
== -1, "expected do_lock value -1, got %d\n", sb
.do_lock
);
294 call_func1(p_streambuf_setlock
, &sb
);
295 ok(sb
.do_lock
== -2, "expected do_lock value -2, got %d\n", sb
.do_lock
);
296 call_func1(p_streambuf_setlock
, &sb
);
297 ok(sb
.do_lock
== -3, "expected do_lock value -3, got %d\n", sb
.do_lock
);
299 call_func1(p_streambuf_setlock
, &sb
);
300 ok(sb
.do_lock
== 2, "expected do_lock value 2, got %d\n", sb
.do_lock
);
304 call_func1(p_streambuf_clrclock
, &sb
);
305 ok(sb
.do_lock
== -1, "expected do_lock value -1, got %d\n", sb
.do_lock
);
306 call_func1(p_streambuf_clrclock
, &sb
);
307 ok(sb
.do_lock
== 0, "expected do_lock value 0, got %d\n", sb
.do_lock
);
308 call_func1(p_streambuf_clrclock
, &sb
);
309 ok(sb
.do_lock
== 1, "expected do_lock value 1, got %d\n", sb
.do_lock
);
310 call_func1(p_streambuf_clrclock
, &sb
);
311 ok(sb
.do_lock
== 1, "expected do_lock value 1, got %d\n", sb
.do_lock
);
315 for (i
= 0; i
< 4; i
++) {
316 lock_arg
.lock
[i
] = CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
317 ok(lock_arg
.lock
[i
] != NULL
, "CreateEventW failed\n");
318 lock_arg
.test
[i
] = CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
319 ok(lock_arg
.test
[i
] != NULL
, "CreateEventW failed\n");
323 thread
= CreateThread(NULL
, 0, lock_streambuf
, (void*)&lock_arg
, 0, NULL
);
324 ok(thread
!= NULL
, "CreateThread failed\n");
325 WaitForSingleObject(lock_arg
.lock
[0], INFINITE
);
326 locked
= TryEnterCriticalSection(&sb
.lock
);
327 ok(locked
!= 0, "could not lock the streambuf\n");
328 LeaveCriticalSection(&sb
.lock
);
331 SetEvent(lock_arg
.test
[0]);
332 WaitForSingleObject(lock_arg
.lock
[1], INFINITE
);
333 locked
= TryEnterCriticalSection(&sb
.lock
);
334 ok(locked
!= 0, "could not lock the streambuf\n");
335 LeaveCriticalSection(&sb
.lock
);
338 SetEvent(lock_arg
.test
[1]);
339 WaitForSingleObject(lock_arg
.lock
[2], INFINITE
);
340 locked
= TryEnterCriticalSection(&sb
.lock
);
341 ok(locked
== 0, "the streambuf was not locked before\n");
344 SetEvent(lock_arg
.test
[2]);
345 WaitForSingleObject(lock_arg
.lock
[3], INFINITE
);
346 locked
= TryEnterCriticalSection(&sb
.lock
);
347 ok(locked
== 0, "the streambuf was not locked before\n");
351 call_func4(p_streambuf_setb
, &sb
, reserve
, reserve
+16, 0);
352 ok(sb
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb
.base
);
353 ok(sb
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb
.ebuf
);
354 call_func4(p_streambuf_setb
, &sb
, reserve
, reserve
+16, 4);
355 ok(sb
.allocated
== 4, "wrong allocate value, expected 4 got %d\n", sb
.allocated
);
357 call_func4(p_streambuf_setb
, &sb
, NULL
, NULL
, 3);
358 ok(sb
.allocated
== 3, "wrong allocate value, expected 3 got %d\n", sb
.allocated
);
361 psb
= call_func3(p_streambuf_setbuf
, &sb
, NULL
, 5);
362 ok(psb
== &sb
, "wrong return value, expected %p got %p\n", &sb
, psb
);
363 ok(sb
.allocated
== 3, "wrong allocate value, expected 3 got %d\n", sb
.allocated
);
364 ok(sb
.unbuffered
== 1, "wrong unbuffered value, expected 1 got %d\n", sb
.unbuffered
);
365 ok(sb
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb
.base
);
366 ok(sb
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb
.ebuf
);
367 psb
= call_func3(p_streambuf_setbuf
, &sb
, reserve
, 0);
368 ok(psb
== &sb
, "wrong return value, expected %p got %p\n", &sb
, psb
);
369 ok(sb
.unbuffered
== 1, "wrong unbuffered value, expected 1 got %d\n", sb
.unbuffered
);
370 ok(sb
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb
.base
);
371 ok(sb
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb
.ebuf
);
372 psb
= call_func3(p_streambuf_setbuf
, &sb
, reserve
, 16);
373 ok(psb
== &sb
, "wrong return value, expected %p got %p\n", &sb
, psb
);
374 ok(sb
.allocated
== 3, "wrong allocate value, expected 3 got %d\n", sb
.allocated
);
375 ok(sb
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb
.unbuffered
);
376 ok(sb
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb
.base
);
377 ok(sb
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb
.ebuf
);
378 psb
= call_func3(p_streambuf_setbuf
, &sb
, NULL
, 8);
379 ok(psb
== NULL
, "wrong return value, expected %p got %p\n", NULL
, psb
);
380 ok(sb
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb
.unbuffered
);
381 ok(sb
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb
.base
);
382 ok(sb
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb
.ebuf
);
385 ret
= (int) call_func1(p_streambuf_allocate
, &sb
);
386 ok(ret
== 0, "wrong return value, expected 0 got %d\n", ret
);
388 ret
= (int) call_func1(p_streambuf_allocate
, &sb
);
389 ok(ret
== 1, "wrong return value, expected 1 got %d\n", ret
);
390 ok(sb
.allocated
== 1, "wrong allocate value, expected 1 got %d\n", sb
.allocated
);
391 ok(sb
.ebuf
- sb
.base
== 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb
.ebuf
, sb
.base
);
394 ret
= (int) call_func1(p_streambuf_doallocate
, &sb2
);
395 ok(ret
== 1, "doallocate failed, got %d\n", ret
);
396 ok(sb2
.allocated
== 1, "wrong allocate value, expected 1 got %d\n", sb2
.allocated
);
397 ok(sb2
.ebuf
- sb2
.base
== 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb2
.ebuf
, sb2
.base
);
398 ret
= (int) call_func1(p_streambuf_doallocate
, &sb3
);
399 ok(ret
== 1, "doallocate failed, got %d\n", ret
);
400 ok(sb3
.allocated
== 1, "wrong allocate value, expected 1 got %d\n", sb3
.allocated
);
401 ok(sb3
.ebuf
- sb3
.base
== 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb3
.ebuf
, sb3
.base
);
403 /* sb: buffered, space available */
404 sb
.eback
= sb
.gptr
= sb
.base
;
405 sb
.egptr
= sb
.base
+ 256;
406 sb
.pbase
= sb
.pptr
= sb
.base
+ 256;
407 sb
.epptr
= sb
.base
+ 512;
408 /* sb2: buffered, no space available */
409 sb2
.eback
= sb2
.base
;
410 sb2
.gptr
= sb2
.egptr
= sb2
.base
+ 256;
411 sb2
.pbase
= sb2
.base
+ 256;
412 sb2
.pptr
= sb2
.epptr
= sb2
.base
+ 512;
413 /* sb3: unbuffered */
417 call_func2(p_streambuf_gbump
, &sb
, 10);
418 ok(sb
.gptr
== sb
.eback
+ 10, "advance get pointer failed, expected %p got %p\n", sb
.eback
+ 10, sb
.gptr
);
419 call_func2(p_streambuf_gbump
, &sb
, -15);
420 ok(sb
.gptr
== sb
.eback
- 5, "advance get pointer failed, expected %p got %p\n", sb
.eback
- 5, sb
.gptr
);
424 call_func2(p_streambuf_pbump
, &sb
, -2);
425 ok(sb
.pptr
== sb
.pbase
- 2, "advance put pointer failed, expected %p got %p\n", sb
.pbase
- 2, sb
.pptr
);
426 call_func2(p_streambuf_pbump
, &sb
, 20);
427 ok(sb
.pptr
== sb
.pbase
+ 18, "advance put pointer failed, expected %p got %p\n", sb
.pbase
+ 18, sb
.pptr
);
431 ret
= (int) call_func1(p_streambuf_sync
, &sb
);
432 ok(ret
== EOF
, "sync failed, expected EOF got %d\n", ret
);
434 ret
= (int) call_func1(p_streambuf_sync
, &sb
);
435 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
436 sb
.gptr
= sb
.egptr
+ 1;
437 ret
= (int) call_func1(p_streambuf_sync
, &sb
);
438 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
440 ret
= (int) call_func1(p_streambuf_sync
, &sb2
);
441 ok(ret
== EOF
, "sync failed, expected EOF got %d\n", ret
);
442 sb2
.pptr
= sb2
.pbase
;
443 ret
= (int) call_func1(p_streambuf_sync
, &sb2
);
444 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
445 sb2
.pptr
= sb2
.pbase
- 1;
446 ret
= (int) call_func1(p_streambuf_sync
, &sb2
);
447 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
448 sb2
.pptr
= sb2
.epptr
;
449 ret
= (int) call_func1(p_streambuf_sync
, &sb3
);
450 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
453 strcpy(sb2
.eback
, "WorstTestEver");
455 ret
= (int) call_func1(p_streambuf_sgetc
, &sb2
);
456 ok(ret
== 'W', "expected 'W' got '%c'\n", ret
);
457 ok(underflow_count
== 1, "expected call to underflow\n");
458 ok(sb2
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb2
.stored_char
);
460 ret
= (int) call_func1(p_streambuf_sgetc
, &sb2
);
461 ok(ret
== 'o', "expected 'o' got '%c'\n", ret
);
462 ok(underflow_count
== 2, "expected call to underflow\n");
463 ok(sb2
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb2
.stored_char
);
464 sb2
.gptr
= sb2
.egptr
;
466 ret
= (int) call_func1(p_streambuf_sgetc
, &sb3
);
467 ok(ret
== 'C', "expected 'C' got '%c'\n", ret
);
468 ok(underflow_count
== 3, "expected call to underflow\n");
469 ok(sb3
.stored_char
== 'C', "wrong stored character, expected 'C' got %c\n", sb3
.stored_char
);
470 sb3
.stored_char
= 'b';
471 ret
= (int) call_func1(p_streambuf_sgetc
, &sb3
);
472 ok(ret
== 'b', "expected 'b' got '%c'\n", ret
);
473 ok(underflow_count
== 3, "no call to underflow expected\n");
474 ok(sb3
.stored_char
== 'b', "wrong stored character, expected 'b' got %c\n", sb3
.stored_char
);
478 ret
= (int) call_func2(p_streambuf_sputc
, &sb
, 'c');
479 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
480 ok(overflow_count
== 0, "no call to overflow expected\n");
481 ok(*sb
.pbase
== 'c', "expected 'c' in the put area, got %c\n", *sb
.pbase
);
482 ok(sb
.pptr
== sb
.pbase
+ 1, "wrong put pointer, expected %p got %p\n", sb
.pbase
+ 1, sb
.pptr
);
484 ret
= (int) call_func2(p_streambuf_sputc
, &sb2
, 'c');
485 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
486 ok(overflow_count
== 1, "expected call to overflow\n");
487 ok(sb2
.pptr
== sb2
.pbase
+ 5, "wrong put pointer, expected %p got %p\n", sb2
.pbase
+ 5, sb2
.pptr
);
489 ret
= (int) call_func2(p_streambuf_sputc
, &sb3
, 'c');
490 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
491 ok(overflow_count
== 2, "expected call to overflow\n");
492 sb3
.pbase
= sb3
.pptr
= sb3
.base
;
493 sb3
.epptr
= sb3
.ebuf
;
494 ret
= (int) call_func2(p_streambuf_sputc
, &sb3
, 'c');
495 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
496 ok(overflow_count
== 2, "no call to overflow expected\n");
497 ok(*sb3
.pbase
== 'c', "expected 'c' in the put area, got %c\n", *sb3
.pbase
);
498 sb3
.pbase
= sb3
.pptr
= sb3
.epptr
= NULL
;
501 sb2
.gptr
= sb2
.egptr
= sb2
.eback
+ 13;
503 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb2
, reserve
, 5);
504 ok(ret
== 5, "wrong return value, expected 5 got %d\n", ret
);
505 ok(!strncmp(reserve
, "Worst", 5), "expected 'Worst' got %s\n", reserve
);
506 ok(sb2
.gptr
== sb2
.eback
+ 5, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 5, sb2
.gptr
);
507 ok(underflow_count
== 4, "expected call to underflow\n");
508 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb2
, reserve
, 4);
509 ok(ret
== 4, "wrong return value, expected 4 got %d\n", ret
);
510 ok(!strncmp(reserve
, "Test", 4), "expected 'Test' got %s\n", reserve
);
511 ok(sb2
.gptr
== sb2
.eback
+ 9, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 9, sb2
.gptr
);
512 ok(underflow_count
== 5, "expected call to underflow\n");
514 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb2
, reserve
, 16);
515 ok(ret
== 4, "wrong return value, expected 4 got %d\n", ret
);
516 ok(!strncmp(reserve
, "Ever", 4), "expected 'Ever' got %s\n", reserve
);
517 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
518 ok(underflow_count
== 7, "expected 2 calls to underflow, got %d\n", underflow_count
- 5);
520 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 11);
521 ok(ret
== 11, "wrong return value, expected 11 got %d\n", ret
);
522 ok(!strncmp(reserve
, "bompuGlobal", 11), "expected 'bompuGlobal' got %s\n", reserve
);
523 ok(sb3
.stored_char
== 'H', "wrong stored character, expected 'H' got %c\n", sb3
.stored_char
);
524 ok(underflow_count
== 18, "expected 11 calls to underflow, got %d\n", underflow_count
- 7);
525 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 16);
526 ok(ret
== 12, "wrong return value, expected 12 got %d\n", ret
);
527 ok(!strncmp(reserve
, "HyperMegaNet", 12), "expected 'HyperMegaNet' got %s\n", reserve
);
528 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
529 ok(underflow_count
== 30, "expected 12 calls to underflow, got %d\n", underflow_count
- 18);
530 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 3);
531 ok(ret
== 0, "wrong return value, expected 0 got %d\n", ret
);
532 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
533 ok(underflow_count
== 31, "expected call to underflow\n");
535 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 5);
536 ok(ret
== 5, "wrong return value, expected 5 got %d\n", ret
);
537 ok(!strncmp(reserve
, "Compu", 5), "expected 'Compu' got %s\n", reserve
);
538 ok(sb3
.stored_char
== 'G', "wrong stored character, expected 'G' got %c\n", sb3
.stored_char
);
539 ok(underflow_count
== 37, "expected 6 calls to underflow, got %d\n", underflow_count
- 31);
542 ret
= (int) call_func3(p_streambuf_xsputn
, &sb
, "Test\0ing", 8);
543 ok(ret
== 8, "wrong return value, expected 8 got %d\n", ret
);
544 ok(sb
.pptr
== sb
.pbase
+ 9, "wrong put pointer, expected %p got %p\n", sb
.pbase
+ 9, sb
.pptr
);
546 sb2
.pptr
= sb2
.epptr
- 7;
547 ret
= (int) call_func3(p_streambuf_xsputn
, &sb2
, "Testing", 7);
548 ok(ret
== 7, "wrong return value, expected 7 got %d\n", ret
);
549 ok(sb2
.pptr
== sb2
.epptr
, "wrong put pointer, expected %p got %p\n", sb2
.epptr
, sb2
.pptr
);
550 ok(overflow_count
== 2, "no call to overflow expected\n");
551 sb2
.pptr
= sb2
.epptr
- 5;
553 ret
= (int) call_func3(p_streambuf_xsputn
, &sb2
, "Testing", 7);
554 ok(ret
== 7, "wrong return value, expected 7 got %d\n", ret
);
555 ok(sb2
.pbase
[5] == 'g', "expected 'g' got %c\n", sb2
.pbase
[5]);
556 ok(sb2
.pptr
== sb2
.pbase
+ 6, "wrong put pointer, expected %p got %p\n", sb2
.pbase
+ 6, sb2
.pptr
);
557 ok(overflow_count
== 3, "expected call to overflow\n");
558 sb2
.pptr
= sb2
.epptr
- 4;
559 ret
= (int) call_func3(p_streambuf_xsputn
, &sb2
, "TestLing", 8);
560 ok(ret
== 4, "wrong return value, expected 4 got %d\n", ret
);
561 ok(sb2
.pptr
== sb2
.epptr
, "wrong put pointer, expected %p got %p\n", sb2
.epptr
, sb2
.pptr
);
562 ok(overflow_count
== 4, "expected call to overflow\n");
564 ret
= (int) call_func3(p_streambuf_xsputn
, &sb3
, "Testing", 7);
565 ok(ret
== 7, "wrong return value, expected 7 got %d\n", ret
);
566 ok(sb3
.stored_char
== 'G', "wrong stored character, expected 'G' got %c\n", sb3
.stored_char
);
567 ok(overflow_count
== 11, "expected 7 calls to overflow, got %d\n", overflow_count
- 4);
568 ret
= (int) call_func3(p_streambuf_xsputn
, &sb3
, "TeLephone", 9);
569 ok(ret
== 2, "wrong return value, expected 2 got %d\n", ret
);
570 ok(sb3
.stored_char
== 'G', "wrong stored character, expected 'G' got %c\n", sb3
.stored_char
);
571 ok(overflow_count
== 14, "expected 3 calls to overflow, got %d\n", overflow_count
- 11);
574 strcpy(sb
.eback
, "Test");
575 ret
= (int) call_func1(p_streambuf_snextc
, &sb
);
576 ok(ret
== 'e', "expected 'e' got '%c'\n", ret
);
577 ok(sb
.gptr
== sb
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 1, sb
.gptr
);
579 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
580 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
581 ok(sb2
.gptr
== sb2
.egptr
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.egptr
+ 1, sb2
.gptr
);
582 ok(underflow_count
== 39, "expected 2 calls to underflow, got %d\n", underflow_count
- 37);
583 sb2
.gptr
= sb2
.egptr
- 1;
584 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
585 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
586 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
587 ok(underflow_count
== 40, "expected call to underflow\n");
589 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
590 ok(ret
== 'o', "expected 'o' got '%c'\n", ret
);
591 ok(sb2
.gptr
== sb2
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 1, sb2
.gptr
);
592 ok(underflow_count
== 41, "expected call to underflow\n");
593 sb2
.gptr
= sb2
.egptr
- 1;
594 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
595 ok(ret
== 'W', "expected 'W' got '%c'\n", ret
);
596 ok(sb2
.gptr
== sb2
.eback
, "wrong get pointer, expected %p got %p\n", sb2
.eback
, sb2
.gptr
);
597 ok(underflow_count
== 42, "expected call to underflow\n");
598 sb2
.gptr
= sb2
.egptr
;
600 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
601 ok(ret
== 'l', "expected 'l' got '%c'\n", ret
);
602 ok(sb3
.stored_char
== 'l', "wrong stored character, expected 'l' got %c\n", sb3
.stored_char
);
603 ok(underflow_count
== 43, "expected call to underflow\n");
605 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
606 ok(ret
== 't', "expected 't' got '%c'\n", ret
);
607 ok(sb3
.stored_char
== 't', "wrong stored character, expected 't' got %c\n", sb3
.stored_char
);
608 ok(underflow_count
== 44, "expected call to underflow\n");
609 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
610 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
611 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
612 ok(underflow_count
== 45, "expected call to underflow\n");
614 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
615 ok(ret
== 'o', "expected 'o' got '%c'\n", ret
);
616 ok(sb3
.stored_char
== 'o', "wrong stored character, expected 'o' got %c\n", sb3
.stored_char
);
617 ok(underflow_count
== 47, "expected 2 calls to underflow, got %d\n", underflow_count
- 45);
618 sb3
.stored_char
= EOF
;
619 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
620 ok(ret
== 'p', "expected 'p' got '%c'\n", ret
);
621 ok(sb3
.stored_char
== 'p', "wrong stored character, expected 'p' got %c\n", sb3
.stored_char
);
622 ok(underflow_count
== 49, "expected 2 calls to underflow, got %d\n", underflow_count
- 47);
625 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb
);
626 ok(ret
== 'e', "expected 'e' got '%c'\n", ret
);
627 ok(sb
.gptr
== sb
.eback
+ 2, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 2, sb
.gptr
);
629 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb2
);
630 ok(ret
== 'W', "expected 'W' got '%c'\n", ret
);
631 ok(sb2
.gptr
== sb2
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 1, sb2
.gptr
);
632 ok(underflow_count
== 50, "expected call to underflow\n");
633 sb2
.gptr
= sb2
.egptr
- 1;
635 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb2
);
636 ok(ret
== 't', "expected 't' got '%c'\n", ret
);
637 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
638 ok(underflow_count
== 50, "no call to underflow expected\n");
640 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb2
);
641 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
642 ok(sb2
.gptr
== sb2
.egptr
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.egptr
+ 1, sb2
.gptr
);
643 ok(underflow_count
== 51, "expected call to underflow\n");
644 sb2
.gptr
= sb2
.egptr
;
646 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
647 ok(ret
== 'p', "expected 'p' got '%c'\n", ret
);
648 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
649 ok(underflow_count
== 51, "no call to underflow expected\n");
650 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
651 ok(ret
== 'u', "expected 'u' got '%c'\n", ret
);
652 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
653 ok(underflow_count
== 52, "expected call to underflow\n");
655 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
656 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
657 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
658 ok(underflow_count
== 53, "expected call to underflow\n");
660 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
661 ok(ret
== 'C', "expected 'C' got '%c'\n", ret
);
662 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
663 ok(underflow_count
== 54, "expected call to underflow\n");
665 SetEvent(lock_arg
.test
[3]);
666 WaitForSingleObject(thread
, INFINITE
);
668 call_func1(p_streambuf_dtor
, &sb
);
669 call_func1(p_streambuf_dtor
, &sb2
);
670 call_func1(p_streambuf_dtor
, &sb3
);
671 for (i
= 0; i
< 4; i
++) {
672 CloseHandle(lock_arg
.lock
[i
]);
673 CloseHandle(lock_arg
.test
[i
]);
685 FreeLibrary(msvcirt
);