Skip to content

Commit

Permalink
2025-01-07 21:43 UTC+0100 Emanuele Zavallone (emanuele.zavallone gmai…
Browse files Browse the repository at this point in the history
…l.com)

  * contrib/hbcurl/easy.c
  * contrib/hbcurl/hbcurl.ch
    + added multi interface implementation
  • Loading branch information
emazv72 authored and alcz committed Jan 7, 2025
1 parent cb9888c commit 6066379
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 0 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
216 changes: 216 additions & 0 deletions contrib/hbcurl/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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() */
Expand Down
28 changes: 28 additions & 0 deletions contrib/hbcurl/hbcurl.ch
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */

0 comments on commit 6066379

Please sign in to comment.