2025-01-07 21:43 UTC+0100 Emanuele Zavallone (emanuele.zavallone gmail.com)

* contrib/hbcurl/easy.c
  * contrib/hbcurl/hbcurl.ch
    + added multi interface implementation
This commit is contained in:
Emanuele Zavallone
2025-01-07 21:43:38 +01:00
committed by Aleksander Czajczynski
parent cb9888c76d
commit 60663791e1
3 changed files with 249 additions and 0 deletions

View File

@@ -7,6 +7,11 @@
Entries may not always be in chronological/commit order.
See license at the end of file. */
2025-01-07 21:43 UTC+0100 Emanuele Zavallone (emanuele.zavallone gmail.com)
* contrib/hbcurl/easy.c
* contrib/hbcurl/hbcurl.ch
+ added multi interface implementation
2025-01-07 12:24 UTC+0100 Aleksander Czajczynski (hb fki.pl)
* src/common/hbver.c
* indent cleanup

View File

@@ -2499,6 +2499,222 @@ HB_FUNC( CURL_GETDATE )
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* Multi interface */
/* ----------------- */
typedef struct _HB_CURLM
{
CURLM * curlm;
} HB_CURLM, * PHB_CURLM;
/* Constructor/Destructor */
/* ---------------------- */
static void PHB_CURLM_free( PHB_CURLM hb_curlm )
{
curl_multi_cleanup( hb_curlm->curlm );
hb_xfree( hb_curlm );
}
static PHB_CURLM PHB_CURLM_create( )
{
CURLM * curlm = curl_multi_init();
if( curlm )
{
PHB_CURLM hb_curlm = ( PHB_CURLM ) hb_xgrab( sizeof( HB_CURLM ) );
memset( hb_curlm, 0, sizeof( HB_CURLM ) );
hb_curlm->curlm = curlm;
return hb_curlm;
}
else
return NULL;
}
static HB_GARBAGE_FUNC( PHB_CURLM_release )
{
PHB_CURLM * hb_curlm_ptr = ( PHB_CURLM * ) Cargo;
/* Check if pointer is not NULL to avoid multiple freeing */
if( hb_curlm_ptr && *hb_curlm_ptr )
{
/* Destroy the object */
PHB_CURLM_free( *hb_curlm_ptr );
*hb_curlm_ptr = NULL;
}
}
static const HB_GC_FUNCS s_gcCURLMFuncs =
{
PHB_CURLM_release,
hb_gcDummyMark
};
static void PHB_CURLM_ret()
{
void ** ph = ( void ** ) hb_gcAllocate( sizeof( PHB_CURLM ), &s_gcCURLMFuncs );
*ph = PHB_CURLM_create( );
hb_retptrGC( ph );
}
static void * PHB_CURLM_is( int iParam )
{
return hb_parptrGC( &s_gcCURLMFuncs, iParam );
}
static PHB_CURLM PHB_CURLM_par( int iParam )
{
void ** ph = ( void ** ) hb_parptrGC( &s_gcCURLMFuncs, iParam );
return ph ? ( PHB_CURLM ) *ph : NULL;
}
/* Harbour interface */
/* ----------------- */
HB_FUNC( CURL_MULTI_INIT )
{
PHB_CURLM_ret( );
}
HB_FUNC( CURL_MULTI_CLEANUP )
{
if( PHB_CURLM_is( 1 ) )
{
void ** ph = ( void ** ) hb_parptrGC( &s_gcCURLMFuncs, 1 );
if( ph && *ph )
{
/* Destroy the object */
PHB_CURLM_free( ( PHB_CURLM ) *ph );
*ph = NULL;
}
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
HB_FUNC( CURL_MULTI_ADD_HANDLE )
{
if( PHB_CURLM_is( 1 ) && PHB_CURL_is( 2 ) )
{
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
PHB_CURL hb_curl = PHB_CURL_par( 2 );
hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_add_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_INTERNAL_ERROR );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
HB_FUNC( CURL_MULTI_REMOVE_HANDLE )
{
if( PHB_CURLM_is( 1 ) && PHB_CURL_is( 2 ) )
{
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
PHB_CURL hb_curl = PHB_CURL_par( 2 );
hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_remove_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_INTERNAL_ERROR );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
HB_FUNC( CURL_MULTI_PERFORM )
{
if( PHB_CURLM_is( 1 ) && HB_ISBYREF( 2 ) )
{
CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR;
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
if ( hb_curlm )
{
int running_handles = 0;
res = curl_multi_perform( hb_curlm->curlm, &running_handles);
hb_stornl( running_handles, 2);
}
hb_retnl( ( long ) res );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
HB_FUNC( CURL_MULTI_POLL )
{
if( PHB_CURLM_is( 1 ) && HB_ISNUM( 2 ) )
{
CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR;
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
if ( hb_curlm )
{
res = curl_multi_poll( hb_curlm->curlm,
NULL,
0,
hb_parni(2),
NULL );
}
hb_retnl( ( long ) res );
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
HB_FUNC( CURL_MULTI_INFO_READ )
{
if( PHB_CURLM_is( 1 ) )
{
PHB_ITEM pReturn = NULL;
PHB_CURLM hb_curlm = PHB_CURLM_par( 1 );
if ( hb_curlm )
{
int msgs_in_queue = 0;
struct CURLMsg *msg = curl_multi_info_read( hb_curlm->curlm, &msgs_in_queue );
if ( msg )
{
CURLcode res = ( CURLcode ) HB_CURLE_ERROR;
long response_code = 0;
res = curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code );
pReturn = hb_itemArrayNew( HB_CURLMSG_RESP_LAST );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_LEN, ( long ) msgs_in_queue );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESPONSE_CODE, ( long ) response_code );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_MSG, ( long ) msg->msg );
hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESULT, ( long ) msg->data.result );
}
}
if ( pReturn )
hb_itemReturnRelease( pReturn );
else
hb_ret();
}
else
hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* Harbour interface (session independent) */
/* NOTE: Obsolete, superceded by curl_easy_escape() */

View File

@@ -578,4 +578,32 @@
#define HB_CURLE_FTP_BAD_FILE_LIST 87 /* unable to parse FTP file list */
#define HB_CURLE_CHUNK_FAILED 88 /* chunk callback reported error */
/* curl multi result codes. */
#define HB_CURLM_CALL_MULTI_PERFORM -1 /* please call curl_multi_perform() or curl_multi_socket*() soon */
#define HB_CURLM_OK 0
#define HB_CURLM_BAD_HANDLE 1 /* the passed-in handle is not a valid CURLM handle */
#define HB_CURLM_BAD_EASY_HANDLE 2 /* an easy handle was not good/valid */
#define HB_CURLM_OUT_OF_MEMORY 3 /* if you ever get this, you're in deep sh*t */
#define HB_CURLM_INTERNAL_ERROR 4 /* this is a libcurl bug */
#define HB_CURLM_BAD_SOCKET 5 /* the passed in socket argument did not match */
#define HB_CURLM_UNKNOWN_OPTION 6 /* curl_multi_setopt() with unsupported option */
#define HB_CURLM_ADDED_ALREADY 7 /* an easy handle already added to a multi handle was attempted to get added - again */
#define HB_CURLM_RECURSIVE_API_CALL 8 /* an api function was called from inside a callback */
#define HB_CURLM_WAKEUP_FAILURE 9 /* wakeup is unavailable or failed */
#define HB_CURLM_BAD_FUNCTION_ARGUMENT 10 /* function called with a bad parameter */
#define HB_CURLM_ABORTED_BY_CALLBACK 11
#define HB_CURLM_UNRECOVERABLE_POLL 12
/* curl_multi_info_read result codes. */
#define HB_CURLMSG_NONE 0 /* first, not used */
#define HB_CURLMSG_DONE 1 /* This easy handle has completed. 'result' contains the CURLcode of the transfer */
#define HB_CURLMSG_RESP_LEN 1 /* queue len */
#define HB_CURLMSG_RESP_RESPONSE_CODE 2 /* curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE ) */
#define HB_CURLMSG_RESP_MSG 3 /* CURLMSG */
#define HB_CURLMSG_RESP_RESULT 4 /* CURLcode */
#define HB_CURLMSG_RESP_LAST HB_CURLMSG_RESP_RESULT
#endif /* HBCURL_CH_ */