char* xi_str_dup( const char* s ) { // PRECONDITIONS assert( s != 0 ); size_t len = strlen( s ); char * ret = xi_alloc( len + 1 ); if( ret == 0 ) { return 0; } memcpy( ret, s, len + 1 ); return ret; }
xi_context_t* xi_create_context( xi_protocol_t protocol, const char* api_key , int32_t feed_id ) { // allocate the structure to store new context xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) ); XI_CHECK_MEMORY( ret ); // copy given numeric parameters as is ret->protocol = protocol; ret->feed_id = feed_id; // copy string parameters carefully if( api_key ) { // duplicate the string ret->api_key = xi_str_dup( api_key ); XI_CHECK_MEMORY( ret->api_key ); } else { ret->api_key = 0; } return ret; err_handling: if( ret ) { XI_SAFE_FREE( ret ); } return 0; }
xi_context_t* xi_create_context( xi_protocol_t protocol, const char* api_key , xi_feed_id_t feed_id ) { // allocate the structure to store new context xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) ); XI_CHECK_MEMORY( ret ); // copy given numeric parameters as is ret->protocol = protocol; ret->feed_id = feed_id; // copy string parameters carefully if( api_key ) { // duplicate the string ret->api_key = xi_str_dup( api_key ); XI_CHECK_MEMORY( ret->api_key ); } else { ret->api_key = 0; } switch( protocol ) { case XI_HTTP: { // @TODO make a configurable pool of these // static structures allocated statically static http_layer_data_t http_layer_data; static csv_layer_data_t csv_layer_data; static xi_response_t xi_response; // clean the structures memset( &http_layer_data, 0, sizeof( http_layer_data_t ) ); memset( &csv_layer_data, 0, sizeof( csv_layer_data_t ) ); memset( &xi_response, 0, sizeof( xi_response_t ) ); // the response pointer http_layer_data.response = &xi_response; csv_layer_data.response = &xi_response; // prepare user data description void* user_datas[] = { 0, ( void* ) &http_layer_data, ( void* ) &csv_layer_data }; // create and connect layers store the information in layer_chain member ret->layer_chain = create_and_connect_layers( CONNECTION_SCHEME_1, user_datas, CONNECTION_SCHEME_LENGTH( CONNECTION_SCHEME_1 ) ); } break; default: goto err_handling; } return ret; err_handling: if( ret ) { if( ret->api_key ) { XI_SAFE_FREE( ret->api_key ); } XI_SAFE_FREE( ret ); } return 0; }
layer_state_t posix_asynch_io_layer_init( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { XI_UNUSED( hint ); XI_UNUSED( data ); // PRECONDITIONS assert( context != 0 ); xi_debug_logger( "[posix_io_layer_init]" ); layer_t* layer = ( layer_t* ) context->self; posix_asynch_data_t* posix_asynch_data = xi_alloc( sizeof( posix_asynch_data_t ) ); XI_CHECK_MEMORY( posix_asynch_data ); layer->user_data = ( void* ) posix_asynch_data; xi_debug_logger( "Creating socket..." ); posix_asynch_data->socket_fd = socket( AF_INET, SOCK_STREAM, 0 ); if( posix_asynch_data->socket_fd == -1 ) { xi_debug_logger( "Socket creation [failed]" ); xi_set_err( XI_SOCKET_INITIALIZATION_ERROR ); return 0; } xi_debug_logger( "Setting socket non blocking behaviour..." ); int flags = fcntl( posix_asynch_data->socket_fd, F_GETFL, 0 ); if( flags == -1 ) { xi_debug_logger( "Socket non blocking behaviour [failed]" ); xi_set_err( XI_SOCKET_INITIALIZATION_ERROR ); goto err_handling; } if( fcntl( posix_asynch_data->socket_fd, F_SETFL, flags | O_NONBLOCK ) == -1 ) { xi_debug_logger( "Socket non blocking behaviour [failed]" ); xi_set_err( XI_SOCKET_INITIALIZATION_ERROR ); goto err_handling; } xi_debug_logger( "Socket creation [ok]" ); // POSTCONDITIONS assert( layer->user_data != 0 ); assert( posix_asynch_data->socket_fd != -1 ); return LAYER_STATE_OK; err_handling: // cleanup the memory if( posix_asynch_data ) { close( posix_asynch_data->socket_fd ); } if( layer->user_data ) { XI_SAFE_FREE( layer->user_data ); } return LAYER_STATE_ERROR; }