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 int (*__thiscall p_streambuf_pbackfail
)(streambuf
*, int);
61 static void (*__thiscall p_streambuf_pbump
)(streambuf
*, int);
62 static int (*__thiscall p_streambuf_sbumpc
)(streambuf
*);
63 static void (*__thiscall p_streambuf_setb
)(streambuf
*, char*, char*, int);
64 static void (*__thiscall p_streambuf_setlock
)(streambuf
*);
65 static streambuf
* (*__thiscall p_streambuf_setbuf
)(streambuf
*, char*, int);
66 static int (*__thiscall p_streambuf_sgetc
)(streambuf
*);
67 static int (*__thiscall p_streambuf_snextc
)(streambuf
*);
68 static int (*__thiscall p_streambuf_sputc
)(streambuf
*, int);
69 static void (*__thiscall p_streambuf_stossc
)(streambuf
*);
70 static int (*__thiscall p_streambuf_sync
)(streambuf
*);
71 static void (*__thiscall p_streambuf_unlock
)(streambuf
*);
72 static int (*__thiscall p_streambuf_xsgetn
)(streambuf
*, char*, int);
73 static int (*__thiscall p_streambuf_xsputn
)(streambuf
*, const char*, int);
75 /* Emulate a __thiscall */
81 BYTE pop_eax
; /* popl %eax (ret addr) */
82 BYTE pop_edx
; /* popl %edx (func) */
83 BYTE pop_ecx
; /* popl %ecx (this) */
84 BYTE push_eax
; /* pushl %eax */
85 WORD jmp_edx
; /* jmp *%edx */
89 static void * (WINAPI
*call_thiscall_func1
)( void *func
, void *this );
90 static void * (WINAPI
*call_thiscall_func2
)( void *func
, void *this, const void *a
);
91 static void * (WINAPI
*call_thiscall_func3
)( void *func
, void *this, const void *a
, const void *b
);
92 static void * (WINAPI
*call_thiscall_func4
)( void *func
, void *this, const void *a
, const void *b
,
94 static void * (WINAPI
*call_thiscall_func5
)( void *func
, void *this, const void *a
, const void *b
,
95 const void *c
, const void *d
);
97 static void init_thiscall_thunk(void)
99 struct thiscall_thunk
*thunk
= VirtualAlloc( NULL
, sizeof(*thunk
),
100 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
101 thunk
->pop_eax
= 0x58; /* popl %eax */
102 thunk
->pop_edx
= 0x5a; /* popl %edx */
103 thunk
->pop_ecx
= 0x59; /* popl %ecx */
104 thunk
->push_eax
= 0x50; /* pushl %eax */
105 thunk
->jmp_edx
= 0xe2ff; /* jmp *%edx */
106 call_thiscall_func1
= (void *)thunk
;
107 call_thiscall_func2
= (void *)thunk
;
108 call_thiscall_func3
= (void *)thunk
;
109 call_thiscall_func4
= (void *)thunk
;
110 call_thiscall_func5
= (void *)thunk
;
113 #define call_func1(func,_this) call_thiscall_func1(func,_this)
114 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
115 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b))
116 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),(const void*)(b), \
118 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \
119 (const void*)(c), (const void *)(d))
123 #define init_thiscall_thunk()
124 #define call_func1(func,_this) func(_this)
125 #define call_func2(func,_this,a) func(_this,a)
126 #define call_func3(func,_this,a,b) func(_this,a,b)
127 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
128 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
130 #endif /* __i386__ */
132 static HMODULE msvcirt
;
133 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcirt,y)
134 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
135 static BOOL
init(void)
137 msvcirt
= LoadLibraryA("msvcirt.dll");
139 win_skip("msvcirt.dll not installed\n");
143 if(sizeof(void*) == 8) { /* 64-bit initialization */
144 SET(p_streambuf_reserve_ctor
, "??0streambuf@@IEAA@PEADH@Z");
145 SET(p_streambuf_ctor
, "??0streambuf@@IEAA@XZ");
146 SET(p_streambuf_dtor
, "??1streambuf@@UEAA@XZ");
147 SET(p_streambuf_allocate
, "?allocate@streambuf@@IEAAHXZ");
148 SET(p_streambuf_clrclock
, "?clrlock@streambuf@@QEAAXXZ");
149 SET(p_streambuf_doallocate
, "?doallocate@streambuf@@MEAAHXZ");
150 SET(p_streambuf_gbump
, "?gbump@streambuf@@IEAAXH@Z");
151 SET(p_streambuf_lock
, "?lock@streambuf@@QEAAXXZ");
152 SET(p_streambuf_pbackfail
, "?pbackfail@streambuf@@UEAAHH@Z");
153 SET(p_streambuf_pbump
, "?pbump@streambuf@@IEAAXH@Z");
154 SET(p_streambuf_sbumpc
, "?sbumpc@streambuf@@QEAAHXZ");
155 SET(p_streambuf_setb
, "?setb@streambuf@@IEAAXPEAD0H@Z");
156 SET(p_streambuf_setbuf
, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z");
157 SET(p_streambuf_setlock
, "?setlock@streambuf@@QEAAXXZ");
158 SET(p_streambuf_sgetc
, "?sgetc@streambuf@@QEAAHXZ");
159 SET(p_streambuf_snextc
, "?snextc@streambuf@@QEAAHXZ");
160 SET(p_streambuf_sputc
, "?sputc@streambuf@@QEAAHH@Z");
161 SET(p_streambuf_stossc
, "?stossc@streambuf@@QEAAXXZ");
162 SET(p_streambuf_sync
, "?sync@streambuf@@UEAAHXZ");
163 SET(p_streambuf_unlock
, "?unlock@streambuf@@QEAAXXZ");
164 SET(p_streambuf_xsgetn
, "?xsgetn@streambuf@@UEAAHPEADH@Z");
165 SET(p_streambuf_xsputn
, "?xsputn@streambuf@@UEAAHPEBDH@Z");
167 SET(p_streambuf_reserve_ctor
, "??0streambuf@@IAE@PADH@Z");
168 SET(p_streambuf_ctor
, "??0streambuf@@IAE@XZ");
169 SET(p_streambuf_dtor
, "??1streambuf@@UAE@XZ");
170 SET(p_streambuf_allocate
, "?allocate@streambuf@@IAEHXZ");
171 SET(p_streambuf_clrclock
, "?clrlock@streambuf@@QAEXXZ");
172 SET(p_streambuf_doallocate
, "?doallocate@streambuf@@MAEHXZ");
173 SET(p_streambuf_gbump
, "?gbump@streambuf@@IAEXH@Z");
174 SET(p_streambuf_lock
, "?lock@streambuf@@QAEXXZ");
175 SET(p_streambuf_pbackfail
, "?pbackfail@streambuf@@UAEHH@Z");
176 SET(p_streambuf_pbump
, "?pbump@streambuf@@IAEXH@Z");
177 SET(p_streambuf_sbumpc
, "?sbumpc@streambuf@@QAEHXZ");
178 SET(p_streambuf_setb
, "?setb@streambuf@@IAEXPAD0H@Z");
179 SET(p_streambuf_setbuf
, "?setbuf@streambuf@@UAEPAV1@PADH@Z");
180 SET(p_streambuf_setlock
, "?setlock@streambuf@@QAEXXZ");
181 SET(p_streambuf_sgetc
, "?sgetc@streambuf@@QAEHXZ");
182 SET(p_streambuf_snextc
, "?snextc@streambuf@@QAEHXZ");
183 SET(p_streambuf_sputc
, "?sputc@streambuf@@QAEHH@Z");
184 SET(p_streambuf_stossc
, "?stossc@streambuf@@QAEXXZ");
185 SET(p_streambuf_sync
, "?sync@streambuf@@UAEHXZ");
186 SET(p_streambuf_unlock
, "?unlock@streambuf@@QAEXXZ");
187 SET(p_streambuf_xsgetn
, "?xsgetn@streambuf@@UAEHPADH@Z");
188 SET(p_streambuf_xsputn
, "?xsputn@streambuf@@UAEHPBDH@Z");
191 init_thiscall_thunk();
195 static int overflow_count
, underflow_count
;
196 static streambuf
*test_this
;
197 static char test_get_buffer
[24];
198 static int buffer_pos
, get_end
;
201 static int __thiscall
test_streambuf_overflow(int ch
)
203 static int __thiscall
test_streambuf_overflow(streambuf
*this, int ch
)
207 if (ch
== 'L') /* simulate a failure */
209 if (!test_this
->unbuffered
)
210 test_this
->pptr
= test_this
->pbase
+ 5;
215 static int __thiscall
test_streambuf_underflow(void)
217 static int __thiscall
test_streambuf_underflow(streambuf
*this)
221 if (test_this
->unbuffered
) {
222 return (buffer_pos
< 23) ? test_get_buffer
[buffer_pos
++] : EOF
;
223 } else if (test_this
->gptr
< test_this
->egptr
) {
224 return *test_this
->gptr
;
226 return get_end
? EOF
: *(test_this
->gptr
= test_this
->eback
);
230 struct streambuf_lock_arg
237 static DWORD WINAPI
lock_streambuf(void *arg
)
239 struct streambuf_lock_arg
*lock_arg
= arg
;
240 call_func1(p_streambuf_lock
, lock_arg
->sb
);
241 SetEvent(lock_arg
->lock
[0]);
242 WaitForSingleObject(lock_arg
->test
[0], INFINITE
);
243 call_func1(p_streambuf_lock
, lock_arg
->sb
);
244 SetEvent(lock_arg
->lock
[1]);
245 WaitForSingleObject(lock_arg
->test
[1], INFINITE
);
246 call_func1(p_streambuf_lock
, lock_arg
->sb
);
247 SetEvent(lock_arg
->lock
[2]);
248 WaitForSingleObject(lock_arg
->test
[2], INFINITE
);
249 call_func1(p_streambuf_unlock
, lock_arg
->sb
);
250 SetEvent(lock_arg
->lock
[3]);
251 WaitForSingleObject(lock_arg
->test
[3], INFINITE
);
252 call_func1(p_streambuf_unlock
, lock_arg
->sb
);
256 static void test_streambuf(void)
258 streambuf sb
, sb2
, sb3
, *psb
;
259 vtable_ptr test_streambuf_vtbl
[11];
260 struct streambuf_lock_arg lock_arg
;
266 memset(&sb
, 0xab, sizeof(streambuf
));
267 memset(&sb2
, 0xab, sizeof(streambuf
));
268 memset(&sb3
, 0xab, sizeof(streambuf
));
271 call_func1(p_streambuf_ctor
, &sb
);
272 ok(sb
.allocated
== 0, "wrong allocate value, expected 0 got %d\n", sb
.allocated
);
273 ok(sb
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb
.unbuffered
);
274 ok(sb
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb
.base
);
275 ok(sb
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb
.ebuf
);
276 ok(sb
.lock
.LockCount
== -1, "wrong critical section state, expected -1 got %d\n", sb
.lock
.LockCount
);
277 call_func3(p_streambuf_reserve_ctor
, &sb2
, reserve
, 16);
278 ok(sb2
.allocated
== 0, "wrong allocate value, expected 0 got %d\n", sb2
.allocated
);
279 ok(sb2
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb2
.unbuffered
);
280 ok(sb2
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb2
.base
);
281 ok(sb2
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb2
.ebuf
);
282 ok(sb
.lock
.LockCount
== -1, "wrong critical section state, expected -1 got %d\n", sb
.lock
.LockCount
);
283 call_func1(p_streambuf_ctor
, &sb3
);
284 ok(sb3
.allocated
== 0, "wrong allocate value, expected 0 got %d\n", sb3
.allocated
);
285 ok(sb3
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb3
.unbuffered
);
286 ok(sb3
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb3
.base
);
287 ok(sb3
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb3
.ebuf
);
289 memcpy(test_streambuf_vtbl
, sb
.vtable
, sizeof(test_streambuf_vtbl
));
290 test_streambuf_vtbl
[7] = (vtable_ptr
)&test_streambuf_overflow
;
291 test_streambuf_vtbl
[8] = (vtable_ptr
)&test_streambuf_underflow
;
292 sb2
.vtable
= test_streambuf_vtbl
;
293 sb3
.vtable
= test_streambuf_vtbl
;
294 overflow_count
= underflow_count
= 0;
295 strcpy(test_get_buffer
, "CompuGlobalHyperMegaNet");
296 buffer_pos
= get_end
= 0;
299 ok(sb
.do_lock
== -1, "expected do_lock value -1, got %d\n", sb
.do_lock
);
300 call_func1(p_streambuf_setlock
, &sb
);
301 ok(sb
.do_lock
== -2, "expected do_lock value -2, got %d\n", sb
.do_lock
);
302 call_func1(p_streambuf_setlock
, &sb
);
303 ok(sb
.do_lock
== -3, "expected do_lock value -3, got %d\n", sb
.do_lock
);
305 call_func1(p_streambuf_setlock
, &sb
);
306 ok(sb
.do_lock
== 2, "expected do_lock value 2, 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
);
312 call_func1(p_streambuf_clrclock
, &sb
);
313 ok(sb
.do_lock
== 0, "expected do_lock value 0, got %d\n", sb
.do_lock
);
314 call_func1(p_streambuf_clrclock
, &sb
);
315 ok(sb
.do_lock
== 1, "expected do_lock value 1, got %d\n", sb
.do_lock
);
316 call_func1(p_streambuf_clrclock
, &sb
);
317 ok(sb
.do_lock
== 1, "expected do_lock value 1, got %d\n", sb
.do_lock
);
321 for (i
= 0; i
< 4; i
++) {
322 lock_arg
.lock
[i
] = CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
323 ok(lock_arg
.lock
[i
] != NULL
, "CreateEventW failed\n");
324 lock_arg
.test
[i
] = CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
325 ok(lock_arg
.test
[i
] != NULL
, "CreateEventW failed\n");
329 thread
= CreateThread(NULL
, 0, lock_streambuf
, (void*)&lock_arg
, 0, NULL
);
330 ok(thread
!= NULL
, "CreateThread failed\n");
331 WaitForSingleObject(lock_arg
.lock
[0], INFINITE
);
332 locked
= TryEnterCriticalSection(&sb
.lock
);
333 ok(locked
!= 0, "could not lock the streambuf\n");
334 LeaveCriticalSection(&sb
.lock
);
337 SetEvent(lock_arg
.test
[0]);
338 WaitForSingleObject(lock_arg
.lock
[1], INFINITE
);
339 locked
= TryEnterCriticalSection(&sb
.lock
);
340 ok(locked
!= 0, "could not lock the streambuf\n");
341 LeaveCriticalSection(&sb
.lock
);
344 SetEvent(lock_arg
.test
[1]);
345 WaitForSingleObject(lock_arg
.lock
[2], INFINITE
);
346 locked
= TryEnterCriticalSection(&sb
.lock
);
347 ok(locked
== 0, "the streambuf was not locked before\n");
350 SetEvent(lock_arg
.test
[2]);
351 WaitForSingleObject(lock_arg
.lock
[3], INFINITE
);
352 locked
= TryEnterCriticalSection(&sb
.lock
);
353 ok(locked
== 0, "the streambuf was not locked before\n");
357 call_func4(p_streambuf_setb
, &sb
, reserve
, reserve
+16, 0);
358 ok(sb
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb
.base
);
359 ok(sb
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb
.ebuf
);
360 call_func4(p_streambuf_setb
, &sb
, reserve
, reserve
+16, 4);
361 ok(sb
.allocated
== 4, "wrong allocate value, expected 4 got %d\n", sb
.allocated
);
363 call_func4(p_streambuf_setb
, &sb
, NULL
, NULL
, 3);
364 ok(sb
.allocated
== 3, "wrong allocate value, expected 3 got %d\n", sb
.allocated
);
367 psb
= call_func3(p_streambuf_setbuf
, &sb
, NULL
, 5);
368 ok(psb
== &sb
, "wrong return value, expected %p got %p\n", &sb
, psb
);
369 ok(sb
.allocated
== 3, "wrong allocate value, expected 3 got %d\n", sb
.allocated
);
370 ok(sb
.unbuffered
== 1, "wrong unbuffered value, expected 1 got %d\n", sb
.unbuffered
);
371 ok(sb
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb
.base
);
372 ok(sb
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb
.ebuf
);
373 psb
= call_func3(p_streambuf_setbuf
, &sb
, reserve
, 0);
374 ok(psb
== &sb
, "wrong return value, expected %p got %p\n", &sb
, psb
);
375 ok(sb
.unbuffered
== 1, "wrong unbuffered value, expected 1 got %d\n", sb
.unbuffered
);
376 ok(sb
.base
== NULL
, "wrong base pointer, expected %p got %p\n", NULL
, sb
.base
);
377 ok(sb
.ebuf
== NULL
, "wrong ebuf pointer, expected %p got %p\n", NULL
, sb
.ebuf
);
378 psb
= call_func3(p_streambuf_setbuf
, &sb
, reserve
, 16);
379 ok(psb
== &sb
, "wrong return value, expected %p got %p\n", &sb
, psb
);
380 ok(sb
.allocated
== 3, "wrong allocate value, expected 3 got %d\n", sb
.allocated
);
381 ok(sb
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb
.unbuffered
);
382 ok(sb
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb
.base
);
383 ok(sb
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb
.ebuf
);
384 psb
= call_func3(p_streambuf_setbuf
, &sb
, NULL
, 8);
385 ok(psb
== NULL
, "wrong return value, expected %p got %p\n", NULL
, psb
);
386 ok(sb
.unbuffered
== 0, "wrong unbuffered value, expected 0 got %d\n", sb
.unbuffered
);
387 ok(sb
.base
== reserve
, "wrong base pointer, expected %p got %p\n", reserve
, sb
.base
);
388 ok(sb
.ebuf
== reserve
+16, "wrong ebuf pointer, expected %p got %p\n", reserve
+16, sb
.ebuf
);
391 ret
= (int) call_func1(p_streambuf_allocate
, &sb
);
392 ok(ret
== 0, "wrong return value, expected 0 got %d\n", ret
);
394 ret
= (int) call_func1(p_streambuf_allocate
, &sb
);
395 ok(ret
== 1, "wrong return value, expected 1 got %d\n", ret
);
396 ok(sb
.allocated
== 1, "wrong allocate value, expected 1 got %d\n", sb
.allocated
);
397 ok(sb
.ebuf
- sb
.base
== 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb
.ebuf
, sb
.base
);
400 ret
= (int) call_func1(p_streambuf_doallocate
, &sb2
);
401 ok(ret
== 1, "doallocate failed, got %d\n", ret
);
402 ok(sb2
.allocated
== 1, "wrong allocate value, expected 1 got %d\n", sb2
.allocated
);
403 ok(sb2
.ebuf
- sb2
.base
== 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb2
.ebuf
, sb2
.base
);
404 ret
= (int) call_func1(p_streambuf_doallocate
, &sb3
);
405 ok(ret
== 1, "doallocate failed, got %d\n", ret
);
406 ok(sb3
.allocated
== 1, "wrong allocate value, expected 1 got %d\n", sb3
.allocated
);
407 ok(sb3
.ebuf
- sb3
.base
== 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb3
.ebuf
, sb3
.base
);
409 /* sb: buffered, space available */
410 sb
.eback
= sb
.gptr
= sb
.base
;
411 sb
.egptr
= sb
.base
+ 256;
412 sb
.pbase
= sb
.pptr
= sb
.base
+ 256;
413 sb
.epptr
= sb
.base
+ 512;
414 /* sb2: buffered, no space available */
415 sb2
.eback
= sb2
.base
;
416 sb2
.gptr
= sb2
.egptr
= sb2
.base
+ 256;
417 sb2
.pbase
= sb2
.base
+ 256;
418 sb2
.pptr
= sb2
.epptr
= sb2
.base
+ 512;
419 /* sb3: unbuffered */
423 call_func2(p_streambuf_gbump
, &sb
, 10);
424 ok(sb
.gptr
== sb
.eback
+ 10, "advance get pointer failed, expected %p got %p\n", sb
.eback
+ 10, sb
.gptr
);
425 call_func2(p_streambuf_gbump
, &sb
, -15);
426 ok(sb
.gptr
== sb
.eback
- 5, "advance get pointer failed, expected %p got %p\n", sb
.eback
- 5, sb
.gptr
);
430 call_func2(p_streambuf_pbump
, &sb
, -2);
431 ok(sb
.pptr
== sb
.pbase
- 2, "advance put pointer failed, expected %p got %p\n", sb
.pbase
- 2, sb
.pptr
);
432 call_func2(p_streambuf_pbump
, &sb
, 20);
433 ok(sb
.pptr
== sb
.pbase
+ 18, "advance put pointer failed, expected %p got %p\n", sb
.pbase
+ 18, sb
.pptr
);
437 ret
= (int) call_func1(p_streambuf_sync
, &sb
);
438 ok(ret
== EOF
, "sync failed, expected EOF got %d\n", ret
);
440 ret
= (int) call_func1(p_streambuf_sync
, &sb
);
441 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
442 sb
.gptr
= sb
.egptr
+ 1;
443 ret
= (int) call_func1(p_streambuf_sync
, &sb
);
444 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
446 ret
= (int) call_func1(p_streambuf_sync
, &sb2
);
447 ok(ret
== EOF
, "sync failed, expected EOF got %d\n", ret
);
448 sb2
.pptr
= sb2
.pbase
;
449 ret
= (int) call_func1(p_streambuf_sync
, &sb2
);
450 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
451 sb2
.pptr
= sb2
.pbase
- 1;
452 ret
= (int) call_func1(p_streambuf_sync
, &sb2
);
453 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
454 sb2
.pptr
= sb2
.epptr
;
455 ret
= (int) call_func1(p_streambuf_sync
, &sb3
);
456 ok(ret
== 0, "sync failed, expected 0 got %d\n", ret
);
459 strcpy(sb2
.eback
, "WorstTestEver");
461 ret
= (int) call_func1(p_streambuf_sgetc
, &sb2
);
462 ok(ret
== 'W', "expected 'W' got '%c'\n", ret
);
463 ok(underflow_count
== 1, "expected call to underflow\n");
464 ok(sb2
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb2
.stored_char
);
466 ret
= (int) call_func1(p_streambuf_sgetc
, &sb2
);
467 ok(ret
== 'o', "expected 'o' got '%c'\n", ret
);
468 ok(underflow_count
== 2, "expected call to underflow\n");
469 ok(sb2
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb2
.stored_char
);
470 sb2
.gptr
= sb2
.egptr
;
472 ret
= (int) call_func1(p_streambuf_sgetc
, &sb3
);
473 ok(ret
== 'C', "expected 'C' got '%c'\n", ret
);
474 ok(underflow_count
== 3, "expected call to underflow\n");
475 ok(sb3
.stored_char
== 'C', "wrong stored character, expected 'C' got %c\n", sb3
.stored_char
);
476 sb3
.stored_char
= 'b';
477 ret
= (int) call_func1(p_streambuf_sgetc
, &sb3
);
478 ok(ret
== 'b', "expected 'b' got '%c'\n", ret
);
479 ok(underflow_count
== 3, "no call to underflow expected\n");
480 ok(sb3
.stored_char
== 'b', "wrong stored character, expected 'b' got %c\n", sb3
.stored_char
);
484 ret
= (int) call_func2(p_streambuf_sputc
, &sb
, 'c');
485 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
486 ok(overflow_count
== 0, "no call to overflow expected\n");
487 ok(*sb
.pbase
== 'c', "expected 'c' in the put area, got %c\n", *sb
.pbase
);
488 ok(sb
.pptr
== sb
.pbase
+ 1, "wrong put pointer, expected %p got %p\n", sb
.pbase
+ 1, sb
.pptr
);
490 ret
= (int) call_func2(p_streambuf_sputc
, &sb2
, 'c');
491 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
492 ok(overflow_count
== 1, "expected call to overflow\n");
493 ok(sb2
.pptr
== sb2
.pbase
+ 5, "wrong put pointer, expected %p got %p\n", sb2
.pbase
+ 5, sb2
.pptr
);
495 ret
= (int) call_func2(p_streambuf_sputc
, &sb3
, 'c');
496 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
497 ok(overflow_count
== 2, "expected call to overflow\n");
498 sb3
.pbase
= sb3
.pptr
= sb3
.base
;
499 sb3
.epptr
= sb3
.ebuf
;
500 ret
= (int) call_func2(p_streambuf_sputc
, &sb3
, 'c');
501 ok(ret
== 'c', "wrong return value, expected 'c' got %d\n", ret
);
502 ok(overflow_count
== 2, "no call to overflow expected\n");
503 ok(*sb3
.pbase
== 'c', "expected 'c' in the put area, got %c\n", *sb3
.pbase
);
504 sb3
.pbase
= sb3
.pptr
= sb3
.epptr
= NULL
;
507 sb2
.gptr
= sb2
.egptr
= sb2
.eback
+ 13;
509 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb2
, reserve
, 5);
510 ok(ret
== 5, "wrong return value, expected 5 got %d\n", ret
);
511 ok(!strncmp(reserve
, "Worst", 5), "expected 'Worst' got %s\n", reserve
);
512 ok(sb2
.gptr
== sb2
.eback
+ 5, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 5, sb2
.gptr
);
513 ok(underflow_count
== 4, "expected call to underflow\n");
514 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb2
, reserve
, 4);
515 ok(ret
== 4, "wrong return value, expected 4 got %d\n", ret
);
516 ok(!strncmp(reserve
, "Test", 4), "expected 'Test' got %s\n", reserve
);
517 ok(sb2
.gptr
== sb2
.eback
+ 9, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 9, sb2
.gptr
);
518 ok(underflow_count
== 5, "expected call to underflow\n");
520 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb2
, reserve
, 16);
521 ok(ret
== 4, "wrong return value, expected 4 got %d\n", ret
);
522 ok(!strncmp(reserve
, "Ever", 4), "expected 'Ever' got %s\n", reserve
);
523 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
524 ok(underflow_count
== 7, "expected 2 calls to underflow, got %d\n", underflow_count
- 5);
526 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 11);
527 ok(ret
== 11, "wrong return value, expected 11 got %d\n", ret
);
528 ok(!strncmp(reserve
, "bompuGlobal", 11), "expected 'bompuGlobal' got %s\n", reserve
);
529 ok(sb3
.stored_char
== 'H', "wrong stored character, expected 'H' got %c\n", sb3
.stored_char
);
530 ok(underflow_count
== 18, "expected 11 calls to underflow, got %d\n", underflow_count
- 7);
531 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 16);
532 ok(ret
== 12, "wrong return value, expected 12 got %d\n", ret
);
533 ok(!strncmp(reserve
, "HyperMegaNet", 12), "expected 'HyperMegaNet' got %s\n", reserve
);
534 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
535 ok(underflow_count
== 30, "expected 12 calls to underflow, got %d\n", underflow_count
- 18);
536 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 3);
537 ok(ret
== 0, "wrong return value, expected 0 got %d\n", ret
);
538 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
539 ok(underflow_count
== 31, "expected call to underflow\n");
541 ret
= (int) call_func3(p_streambuf_xsgetn
, &sb3
, reserve
, 5);
542 ok(ret
== 5, "wrong return value, expected 5 got %d\n", ret
);
543 ok(!strncmp(reserve
, "Compu", 5), "expected 'Compu' got %s\n", reserve
);
544 ok(sb3
.stored_char
== 'G', "wrong stored character, expected 'G' got %c\n", sb3
.stored_char
);
545 ok(underflow_count
== 37, "expected 6 calls to underflow, got %d\n", underflow_count
- 31);
548 ret
= (int) call_func3(p_streambuf_xsputn
, &sb
, "Test\0ing", 8);
549 ok(ret
== 8, "wrong return value, expected 8 got %d\n", ret
);
550 ok(sb
.pptr
== sb
.pbase
+ 9, "wrong put pointer, expected %p got %p\n", sb
.pbase
+ 9, sb
.pptr
);
552 sb2
.pptr
= sb2
.epptr
- 7;
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
.pptr
== sb2
.epptr
, "wrong put pointer, expected %p got %p\n", sb2
.epptr
, sb2
.pptr
);
556 ok(overflow_count
== 2, "no call to overflow expected\n");
557 sb2
.pptr
= sb2
.epptr
- 5;
559 ret
= (int) call_func3(p_streambuf_xsputn
, &sb2
, "Testing", 7);
560 ok(ret
== 7, "wrong return value, expected 7 got %d\n", ret
);
561 ok(sb2
.pbase
[5] == 'g', "expected 'g' got %c\n", sb2
.pbase
[5]);
562 ok(sb2
.pptr
== sb2
.pbase
+ 6, "wrong put pointer, expected %p got %p\n", sb2
.pbase
+ 6, sb2
.pptr
);
563 ok(overflow_count
== 3, "expected call to overflow\n");
564 sb2
.pptr
= sb2
.epptr
- 4;
565 ret
= (int) call_func3(p_streambuf_xsputn
, &sb2
, "TestLing", 8);
566 ok(ret
== 4, "wrong return value, expected 4 got %d\n", ret
);
567 ok(sb2
.pptr
== sb2
.epptr
, "wrong put pointer, expected %p got %p\n", sb2
.epptr
, sb2
.pptr
);
568 ok(overflow_count
== 4, "expected call to overflow\n");
570 ret
= (int) call_func3(p_streambuf_xsputn
, &sb3
, "Testing", 7);
571 ok(ret
== 7, "wrong return value, expected 7 got %d\n", ret
);
572 ok(sb3
.stored_char
== 'G', "wrong stored character, expected 'G' got %c\n", sb3
.stored_char
);
573 ok(overflow_count
== 11, "expected 7 calls to overflow, got %d\n", overflow_count
- 4);
574 ret
= (int) call_func3(p_streambuf_xsputn
, &sb3
, "TeLephone", 9);
575 ok(ret
== 2, "wrong return value, expected 2 got %d\n", ret
);
576 ok(sb3
.stored_char
== 'G', "wrong stored character, expected 'G' got %c\n", sb3
.stored_char
);
577 ok(overflow_count
== 14, "expected 3 calls to overflow, got %d\n", overflow_count
- 11);
580 strcpy(sb
.eback
, "Test");
581 ret
= (int) call_func1(p_streambuf_snextc
, &sb
);
582 ok(ret
== 'e', "expected 'e' got '%c'\n", ret
);
583 ok(sb
.gptr
== sb
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 1, sb
.gptr
);
585 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
586 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
587 ok(sb2
.gptr
== sb2
.egptr
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.egptr
+ 1, sb2
.gptr
);
588 ok(underflow_count
== 39, "expected 2 calls to underflow, got %d\n", underflow_count
- 37);
589 sb2
.gptr
= sb2
.egptr
- 1;
590 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
591 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
592 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
593 ok(underflow_count
== 40, "expected call to underflow\n");
595 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
596 ok(ret
== 'o', "expected 'o' got '%c'\n", ret
);
597 ok(sb2
.gptr
== sb2
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 1, sb2
.gptr
);
598 ok(underflow_count
== 41, "expected call to underflow\n");
599 sb2
.gptr
= sb2
.egptr
- 1;
600 ret
= (int) call_func1(p_streambuf_snextc
, &sb2
);
601 ok(ret
== 'W', "expected 'W' got '%c'\n", ret
);
602 ok(sb2
.gptr
== sb2
.eback
, "wrong get pointer, expected %p got %p\n", sb2
.eback
, sb2
.gptr
);
603 ok(underflow_count
== 42, "expected call to underflow\n");
604 sb2
.gptr
= sb2
.egptr
;
606 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
607 ok(ret
== 'l', "expected 'l' got '%c'\n", ret
);
608 ok(sb3
.stored_char
== 'l', "wrong stored character, expected 'l' got %c\n", sb3
.stored_char
);
609 ok(underflow_count
== 43, "expected call to underflow\n");
611 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
612 ok(ret
== 't', "expected 't' got '%c'\n", ret
);
613 ok(sb3
.stored_char
== 't', "wrong stored character, expected 't' got %c\n", sb3
.stored_char
);
614 ok(underflow_count
== 44, "expected call to underflow\n");
615 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
616 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
617 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
618 ok(underflow_count
== 45, "expected call to underflow\n");
620 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
621 ok(ret
== 'o', "expected 'o' got '%c'\n", ret
);
622 ok(sb3
.stored_char
== 'o', "wrong stored character, expected 'o' got %c\n", sb3
.stored_char
);
623 ok(underflow_count
== 47, "expected 2 calls to underflow, got %d\n", underflow_count
- 45);
624 sb3
.stored_char
= EOF
;
625 ret
= (int) call_func1(p_streambuf_snextc
, &sb3
);
626 ok(ret
== 'p', "expected 'p' got '%c'\n", ret
);
627 ok(sb3
.stored_char
== 'p', "wrong stored character, expected 'p' got %c\n", sb3
.stored_char
);
628 ok(underflow_count
== 49, "expected 2 calls to underflow, got %d\n", underflow_count
- 47);
631 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb
);
632 ok(ret
== 'e', "expected 'e' got '%c'\n", ret
);
633 ok(sb
.gptr
== sb
.eback
+ 2, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 2, sb
.gptr
);
635 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb2
);
636 ok(ret
== 'W', "expected 'W' got '%c'\n", ret
);
637 ok(sb2
.gptr
== sb2
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 1, sb2
.gptr
);
638 ok(underflow_count
== 50, "expected call to underflow\n");
639 sb2
.gptr
= sb2
.egptr
- 1;
641 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb2
);
642 ok(ret
== 't', "expected 't' got '%c'\n", ret
);
643 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
644 ok(underflow_count
== 50, "no call to underflow expected\n");
646 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb2
);
647 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
648 ok(sb2
.gptr
== sb2
.egptr
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.egptr
+ 1, sb2
.gptr
);
649 ok(underflow_count
== 51, "expected call to underflow\n");
650 sb2
.gptr
= sb2
.egptr
;
652 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
653 ok(ret
== 'p', "expected 'p' got '%c'\n", ret
);
654 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
655 ok(underflow_count
== 51, "no call to underflow expected\n");
656 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
657 ok(ret
== 'u', "expected 'u' got '%c'\n", ret
);
658 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
659 ok(underflow_count
== 52, "expected call to underflow\n");
661 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
662 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
663 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
664 ok(underflow_count
== 53, "expected call to underflow\n");
666 ret
= (int) call_func1(p_streambuf_sbumpc
, &sb3
);
667 ok(ret
== 'C', "expected 'C' got '%c'\n", ret
);
668 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
669 ok(underflow_count
== 54, "expected call to underflow\n");
672 call_func1(p_streambuf_stossc
, &sb
);
673 ok(sb
.gptr
== sb
.eback
+ 3, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 3, sb
.gptr
);
675 call_func1(p_streambuf_stossc
, &sb2
);
676 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
677 ok(underflow_count
== 55, "expected call to underflow\n");
679 call_func1(p_streambuf_stossc
, &sb2
);
680 ok(sb2
.gptr
== sb2
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb2
.eback
+ 1, sb2
.gptr
);
681 ok(underflow_count
== 56, "expected call to underflow\n");
682 sb2
.gptr
= sb2
.egptr
- 1;
683 call_func1(p_streambuf_stossc
, &sb2
);
684 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
685 ok(underflow_count
== 56, "no call to underflow expected\n");
687 call_func1(p_streambuf_stossc
, &sb3
);
688 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
689 ok(underflow_count
== 57, "expected call to underflow\n");
690 sb3
.stored_char
= 'a';
691 call_func1(p_streambuf_stossc
, &sb3
);
692 ok(sb3
.stored_char
== EOF
, "wrong stored character, expected EOF got %c\n", sb3
.stored_char
);
693 ok(underflow_count
== 57, "no call to underflow expected\n");
696 ret
= (int) call_func2(p_streambuf_pbackfail
, &sb
, 'A');
697 ok(ret
== 'A', "expected 'A' got '%c'\n", ret
);
698 ok(sb
.gptr
== sb
.eback
+ 2, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 2, sb
.gptr
);
699 ok(*sb
.gptr
== 'A', "expected 'A' in the get area, got %c\n", *sb
.gptr
);
700 ret
= (int) call_func2(p_streambuf_pbackfail
, &sb
, EOF
);
701 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
702 ok(sb
.gptr
== sb
.eback
+ 1, "wrong get pointer, expected %p got %p\n", sb
.eback
+ 1, sb
.gptr
);
703 ok(*sb
.gptr
== EOF
, "expected EOF in the get area, got %c\n", *sb
.gptr
);
705 ret
= (int) call_func2(p_streambuf_pbackfail
, &sb
, 'Z');
706 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
707 ok(sb
.gptr
== sb
.eback
, "wrong get pointer, expected %p got %p\n", sb
.eback
, sb
.gptr
);
708 ok(*sb
.gptr
== 'T', "expected 'T' in the get area, got %c\n", *sb
.gptr
);
709 ret
= (int) call_func2(p_streambuf_pbackfail
, &sb
, EOF
);
710 ok(ret
== EOF
, "expected EOF got '%c'\n", ret
);
711 ok(sb
.gptr
== sb
.eback
, "wrong get pointer, expected %p got %p\n", sb
.eback
, sb
.gptr
);
712 ok(*sb
.gptr
== 'T', "expected 'T' in the get area, got %c\n", *sb
.gptr
);
713 sb2
.gptr
= sb2
.egptr
+ 1;
714 ret
= (int) call_func2(p_streambuf_pbackfail
, &sb2
, 'X');
715 ok(ret
== 'X', "expected 'X' got '%c'\n", ret
);
716 ok(sb2
.gptr
== sb2
.egptr
, "wrong get pointer, expected %p got %p\n", sb2
.egptr
, sb2
.gptr
);
717 ok(*sb2
.gptr
== 'X', "expected 'X' in the get area, got %c\n", *sb2
.gptr
);
719 SetEvent(lock_arg
.test
[3]);
720 WaitForSingleObject(thread
, INFINITE
);
722 call_func1(p_streambuf_dtor
, &sb
);
723 call_func1(p_streambuf_dtor
, &sb2
);
724 call_func1(p_streambuf_dtor
, &sb3
);
725 for (i
= 0; i
< 4; i
++) {
726 CloseHandle(lock_arg
.lock
[i
]);
727 CloseHandle(lock_arg
.test
[i
]);
739 FreeLibrary(msvcirt
);