static long s_inetRecv( PHB_SOCKET_STRUCT socket, char * buffer, long size, HB_BOOL readahead ) { long rec = 0; if( readahead && socket->inbuffer == 0 && socket->readahead > size ) { if( socket->buffer == NULL ) socket->buffer = ( char * ) hb_xgrab( socket->readahead ); socket->posbuffer = 0; if( socket->recvFunc ) rec = socket->recvFunc( socket->stream, socket->sd, socket->buffer, socket->readahead, socket->iTimeout ); else rec = hb_socketRecv( socket->sd, socket->buffer, socket->readahead, 0, socket->iTimeout ); socket->inbuffer = HB_MAX( 0, rec ); } else readahead = HB_FALSE; if( socket->inbuffer > 0 ) { rec = HB_MIN( size, socket->inbuffer ); memcpy( buffer, socket->buffer + socket->posbuffer, rec ); socket->posbuffer += rec; socket->inbuffer -= rec; if( size > rec && ! readahead ) { if( socket->recvFunc ) rec = socket->recvFunc( socket->stream, socket->sd, buffer + rec, size - rec, socket->iTimeout ); else size = hb_socketRecv( socket->sd, buffer + rec, size - rec, 0, 0 ); if( size > 0 ) rec += size; } } else if( ! readahead ) { if( socket->recvFunc ) rec = socket->recvFunc( socket->stream, socket->sd, buffer, size, socket->iTimeout ); else rec = hb_socketRecv( socket->sd, buffer, size, 0, socket->iTimeout ); } return rec; }
static long s_sockexRead( PHB_SOCKEX pSock, void * data, long len, HB_MAXINT timeout ) { long lRead = HB_MIN( pSock->inbuffer, len ); if( lRead > 0 ) { memcpy( data, pSock->buffer + pSock->posbuffer, lRead ); pSock->inbuffer -= lRead; if( pSock->inbuffer ) pSock->posbuffer += lRead; else pSock->posbuffer = 0; len -= lRead; if( len == 0 || pSock->sd == HB_NO_SOCKET ) return lRead; data = ( HB_BYTE * ) data + lRead; timeout = 0; } else if( pSock->sd == HB_NO_SOCKET ) { hb_socketSetError( HB_SOCKET_ERR_INVALIDHANDLE ); return -1; } len = pSock->cargo ? hb_znetRead( HB_ZNET_GET( pSock ), pSock->sd, data, len, timeout ) : hb_socketRecv( pSock->sd, data, len, 0, timeout ); return lRead > 0 ? HB_MAX( len, 0 ) + lRead : len; }
static HB_SIZE s_fileRead( PHB_FILE pFile, void * data, HB_SIZE nSize, HB_MAXINT timeout ) { HB_ERRCODE errcode = 0; long lRead = 0; if( ! pFile->fEof ) { lRead = nSize > LONG_MAX ? LONG_MAX : ( long ) nSize; if( timeout == -1 ) timeout = pFile->timeout; lRead = hb_socketRecv( pFile->sd, data, lRead, 0, timeout ); errcode = hb_socketGetError(); if( lRead <= 0 ) { switch( errcode ) { case HB_SOCKET_ERR_TIMEOUT: case HB_SOCKET_ERR_AGAIN: case HB_SOCKET_ERR_TRYAGAIN: break; default: pFile->fEof = HB_TRUE; break; } lRead = 0; } } hb_fsSetError( errcode ); return lRead; }
static long s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lRead = 0, l; HB_MAXUINT end_timer; end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; while( lRead < len && ! conn->stop ) { if( conn->zstream ) l = hb_znetRead( conn->zstream, conn->sd, ptr + lRead, len - lRead, 1000 ); else l = hb_socketRecv( conn->sd, ptr + lRead, len - lRead, 0, 1000 ); if( l <= 0 ) { if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || hb_vmRequestQuery() != 0 || ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) break; } else { lRead += l; conn->rd_count += l; } } return lRead; }
/* read data from extended socket, check internal readahead buffer first */ static long s_sockexRead( PHB_SOCKEX pSock, void * data, long len, HB_MAXINT timeout ) { long lRead = HB_MIN( pSock->inbuffer, len ); if( lRead > 0 ) { memcpy( data, pSock->buffer + pSock->posbuffer, lRead ); pSock->inbuffer -= lRead; if( pSock->inbuffer ) pSock->posbuffer += lRead; else pSock->posbuffer = 0; return lRead; } if( pSock->sd == HB_NO_SOCKET ) { hb_socketSetError( HB_SOCKET_ERR_INVALIDHANDLE ); return -1; } return hb_socketRecv( pSock->sd, data, len, 0, timeout ); }
HB_BOOL hb_lppRecv( PHB_LPP pSocket, void ** data, HB_SIZE * len, HB_MAXINT timeout ) { HB_MAXINT nTime = 0; long lRecv; if( ! pSocket->pRecvBuffer ) { pSocket->pRecvBuffer = ( char * ) hb_xgrab( 4 ); pSocket->nRecvLen = 0; pSocket->fRecvHasSize = HB_FALSE; } if( timeout > 0 ) nTime = ( HB_MAXINT ) hb_dateMilliSeconds() + timeout; for( ;; ) { if( ! pSocket->fRecvHasSize ) { lRecv = ( long ) ( 4 - pSocket->nRecvLen ); lRecv = hb_socketRecv( pSocket->sd, pSocket->pRecvBuffer + pSocket->nRecvLen, lRecv, 0, timeout ); if( lRecv == -1 ) { pSocket->iError = hb_socketGetError(); return HB_FALSE; } else if( lRecv == 0 ) { /* peer closed connection */ pSocket->iError = 0; return HB_FALSE; } pSocket->nRecvLen += lRecv; if( pSocket->nRecvLen < 4 ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; } pSocket->nRecvSize = HB_GET_UINT32( pSocket->pRecvBuffer ); if( pSocket->nLimit && pSocket->nRecvSize > pSocket->nLimit ) { /* protection against remote memory exhaust attack */ pSocket->iError = HB_LPP_ERR_TOOLARGE; hb_xfree( pSocket->pRecvBuffer ); pSocket->pRecvBuffer = NULL; return HB_FALSE; } pSocket->nRecvLen = 0; pSocket->fRecvHasSize = HB_TRUE; if( pSocket->nRecvSize != 4 ) pSocket->pRecvBuffer = ( char * ) hb_xrealloc( pSocket->pRecvBuffer, pSocket->nRecvSize ); } if( pSocket->nRecvSize - pSocket->nRecvLen < ( HB_SIZE ) LONG_MAX ) lRecv = ( long ) ( pSocket->nRecvSize - pSocket->nRecvLen ); else lRecv = LONG_MAX; lRecv = hb_socketRecv( pSocket->sd, pSocket->pRecvBuffer + pSocket->nRecvLen, lRecv, 0, timeout ); if( lRecv == -1 ) { pSocket->iError = hb_socketGetError(); return HB_FALSE; } else if( lRecv == 0 ) { /* peer closed connection */ pSocket->iError = 0; return HB_FALSE; } pSocket->nRecvLen += lRecv; if( pSocket->nRecvSize == pSocket->nRecvLen ) { * data = pSocket->pRecvBuffer; * len = pSocket->nRecvLen; pSocket->pRecvBuffer = NULL; pSocket->iError = 0; return HB_TRUE; } if( timeout == 0 || ( timeout > 0 && ( timeout = nTime - ( HB_MAXINT ) hb_dateMilliSeconds() ) <= 0 ) ) { pSocket->iError = HB_SOCKET_ERR_TIMEOUT; return HB_FALSE; } } }
/* read data using stream structure */ long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len, HB_MAXINT timeout ) { long rec = 0; pStream->rd.next_out = ( Bytef * ) buffer; pStream->rd.avail_out = ( uInt ) len; pStream->err = Z_OK; while( pStream->rd.avail_out ) { if( pStream->rd.avail_in == 0 && pStream->err == Z_BUF_ERROR ) { if( pStream->skip_in ) { pStream->rd.next_in += pStream->skip_in; pStream->skip_in = 0; } if( pStream->crypt_in && pStream->rd.next_in > pStream->inbuf ) memmove( pStream->inbuf, pStream->rd.next_in, pStream->crypt_in ); pStream->rd.next_in = pStream->inbuf; if( ! pStream->crypt || pStream->crypt_in < 8 ) { if( pStream->rd.avail_out != ( uInt ) len ) timeout = 0; rec = hb_socketRecv( sd, pStream->inbuf + pStream->crypt_in, HB_ZNET_BUFSIZE - pStream->crypt_in, 0, timeout ); if( rec <= 0 ) break; } if( pStream->crypt ) { pStream->crypt_in += rec; if( pStream->crypt_size == 0 ) { if( pStream->crypt_in >= 8 ) { hb_znetDecrypt( pStream, pStream->rd.next_in ); pStream->crypt_size = HB_GET_BE_UINT16( pStream->rd.next_in ); pStream->rd.next_in += 2; pStream->crypt_in -= 8; rec = HB_MIN( pStream->crypt_size, 6 ); pStream->crypt_size -= ( uInt ) rec; pStream->rd.avail_in += ( uInt ) rec; pStream->skip_in = ( uInt ) ( 6 - rec ); rec = 0; } } if( pStream->skip_in == 0 ) { long l = ( pStream->crypt_size + 0x07 ) & ~0x07; rec = pStream->crypt_in & ~0x07; if( rec > l ) rec = l; /* decrypt the buffer */ for( l = 0; l < rec; l += 8 ) hb_znetDecrypt( pStream, pStream->rd.next_in + pStream->rd.avail_in + l ); pStream->crypt_in -= rec; if( ( uInt ) rec > pStream->crypt_size ) { pStream->skip_in = rec - pStream->crypt_size; rec = pStream->crypt_size; } pStream->crypt_size -= rec; } } pStream->rd.avail_in += ( uInt ) rec; if( pStream->rd.avail_in == 0 ) break; rec = 0; } pStream->err = inflate( &pStream->rd, Z_SYNC_FLUSH ); /* if( pStream->err == Z_STREAM_END && pStream->rd.avail_in == 0 ) pStream->err = Z_BUF_ERROR; */ if( pStream->err != Z_OK && ! ( pStream->err == Z_BUF_ERROR && pStream->rd.avail_in == 0 ) ) break; } len -= pStream->rd.avail_out; return len == 0 ? rec : len; }