wininet: Add a new NETCON_query_data_available function.

Use it to implement the behaviour where InternetReadFileExA does a 
synchronous request if the data is available and asynchronous otherwise.
This commit is contained in:
Rob Shearman 2007-05-28 11:16:06 +01:00 committed by Alexandre Julliard
parent 76507d475b
commit 56267608f1
3 changed files with 65 additions and 17 deletions

View File

@ -1855,26 +1855,32 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu
return FALSE;
}
/* FIXME: native only does it asynchronously if the amount of data
* requested isn't available. See NtReadFile. */
/* FIXME: IRF_ASYNC may not be the right thing to test here;
* hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC is probably better, but
* we should implement the above first */
* hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC is probably better */
if (dwFlags & IRF_ASYNC)
{
WORKREQUEST workRequest;
struct WORKREQ_INTERNETREADFILEEXA *req;
DWORD dwDataAvailable = 0;
workRequest.asyncproc = AsyncInternetReadFileExProc;
workRequest.hdr = WININET_AddRef( lpwh );
req = &workRequest.u.InternetReadFileExA;
req->lpBuffersOut = lpBuffersOut;
if (lpwh->htype == WH_HHTTPREQ)
NETCON_query_data_available(&((LPWININETHTTPREQW)lpwh)->netConnection,
&dwDataAvailable);
retval = INTERNET_AsyncCall(&workRequest);
if (!retval) return FALSE;
if (!dwDataAvailable)
{
WORKREQUEST workRequest;
struct WORKREQ_INTERNETREADFILEEXA *req;
INTERNET_SetLastError(ERROR_IO_PENDING);
return FALSE;
workRequest.asyncproc = AsyncInternetReadFileExProc;
workRequest.hdr = WININET_AddRef( lpwh );
req = &workRequest.u.InternetReadFileExA;
req->lpBuffersOut = lpBuffersOut;
retval = INTERNET_AsyncCall(&workRequest);
if (!retval) return FALSE;
INTERNET_SetLastError(ERROR_IO_PENDING);
return FALSE;
}
}
retval = INTERNET_ReadFile(lpwh, lpBuffersOut->lpvBuffer,
@ -3258,15 +3264,24 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
switch (lpwhr->hdr.htype)
{
case WH_HHTTPREQ:
if (!NETCON_recv(&lpwhr->netConnection, buffer,
if (NETCON_query_data_available(&lpwhr->netConnection,
lpdwNumberOfBytesAvailble))
{
if (!*lpdwNumberOfBytesAvailble &&
!NETCON_recv(&lpwhr->netConnection, buffer,
min(sizeof(buffer), lpwhr->dwContentLength - lpwhr->dwContentRead),
MSG_PEEK, (int *)lpdwNumberOfBytesAvailble))
{
INTERNET_SetLastError(ERROR_NO_MORE_FILES);
retval = FALSE;
}
retval = TRUE;
}
else
{
INTERNET_SetLastError(ERROR_NO_MORE_FILES);
retval = FALSE;
}
else
retval = TRUE;
break;
default:

View File

@ -459,6 +459,7 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
int *sent /* out */);
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
int *recvd /* out */);
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available);
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer);
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection);
BOOL NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value);

View File

@ -33,6 +33,9 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@ -569,6 +572,35 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
}
}
/******************************************************************************
* NETCON_query_data_available
* Returns the number of bytes of peeked data plus the number of bytes of
* queued, but unread data.
*/
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available)
{
if (!NETCON_connected(connection))
return FALSE;
if (connection->peek_msg)
*available = connection->peek_len;
else
*available = 0;
#ifdef FIONREAD
if (!connection->useSSL)
{
int unread;
int retval = ioctl(connection->socketFD, FIONREAD, &unread);
if (!retval)
{
TRACE("%d bytes of queued, but unread data\n", unread);
*available += unread;
}
}
#endif
return TRUE;
}
/******************************************************************************
* NETCON_getNextLine
*/