ERROR_CODE _bencoding_list_start_callback(struct bencoding_engine_t *bencoding_engine) { /* allocates space for the linked list and for the type structure that will encapsulate it */ struct linked_list_t *list; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* creates a new linked list for the new structure (sequence) context and then creates the respective type for the list */ create_linked_list(&list); create_type(&type, LIST_TYPE); *type = list_type(list); /* adds the sequence type to the sequence stack and then adds the current handler key to the key stack, then updates the current sequence reference and the current key in the handler */ append_value_linked_list(bencoding_handler->sequence_stack, (void *) type); append_value_linked_list(bencoding_handler->key_stack, (void *) bencoding_handler->key); bencoding_handler->sequence = type; bencoding_handler->key = NULL; /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* unsets the next key flag to avoid any possible misbehavior, colliding with the hash map structure */ bencoding_handler->next_key = 0; /* raises no error */ RAISE_NO_ERROR; }
ERROR_CODE _bencoding_dictionary_start_callback(struct bencoding_engine_t *bencoding_engine) { /* allocates space for the hash map and for the type structure that will encapsulate it */ struct hash_map_t *hash_map; struct sort_map_t *sort_map; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* switchs over the "target" map type to be used to store conceptual maps in the bencoding structure */ switch(bencoding_engine->map_type) { case MAP_TYPE: /* creates a new hash map for the new structure (sequence) context and then creates the respective type for the map */ create_hash_map(&hash_map, 0); create_type(&type, MAP_TYPE); *type = map_type(hash_map); case SORT_MAP_TYPE: /* creates a new sort map for the new structure (sequence) context and then creates the respective type for the map */ create_sort_map(&sort_map, 0); create_type(&type, SORT_MAP_TYPE); *type = sort_map_type(sort_map); default: /* creates a new sort map for the new structure (sequence) context and then creates the respective type for the map */ create_sort_map(&sort_map, 0); create_type(&type, SORT_MAP_TYPE); *type = sort_map_type(sort_map); } /* adds the sequence type to the sequence stack and then adds the current handler key to the key stack, then updates the current sequence reference and the current key in the handler */ append_value_linked_list(bencoding_handler->sequence_stack, (void *) type); append_value_linked_list(bencoding_handler->key_stack, (void *) bencoding_handler->key); bencoding_handler->sequence = type; bencoding_handler->key = NULL; /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* sets the next key flag so that in the next iteration the string is "accepted" as the current key value */ bencoding_handler->next_key = 1; /* raises no error */ RAISE_NO_ERROR; }
void insert_task_thread_pool(struct thread_pool_t *thread_pool, struct thread_pool_task_t *thread_pool_task) { /* locks the task condition lock */ CONDITION_LOCK(thread_pool->task_condition, thread_pool->task_condition_lock); /* adds the the thread pool task to the task queue */ append_value_linked_list(thread_pool->task_queue, thread_pool_task); /* signals the task condition */ CONDITION_SIGNAL(thread_pool->task_condition); /* unlock the task condition lock */ CONDITION_UNLOCK(thread_pool->task_condition, thread_pool->task_condition_lock); }
void create_thread_pool_element(struct thread_pool_t *thread_pool) { /* allocates space for the thread id */ THREAD_IDENTIFIER thread_id; /* retrieves the thread pool element size */ size_t thread_pool_element_size = sizeof(struct thread_pool_element_t); /* allocates space for the thread pool element */ struct thread_pool_element_t *thread_pool_element = (struct thread_pool_element_t *) MALLOC(thread_pool_element_size); /* creates the engine runnner thread */ THREAD_HANDLE thread_handle = THREAD_CREATE_BASE(thread_id, pool_runner_thread, (THREAD_ARGUMENTS) thread_pool); /* sets the thread pool element attributes */ thread_pool_element->thread_handle = thread_handle; thread_pool_element->thread_id = thread_id; /* adds the thread pool element to the thread pool worker threads list */ append_value_linked_list(thread_pool->worker_threads_list, (void *) thread_pool_element); /* increments the current number of threads */ thread_pool->current_number_threads++; }
ERROR_CODE _bencoding_sequence_end_callback(struct bencoding_engine_t *bencoding_engine) { /* allocates space for the map key for the sequence type and for the current type */ unsigned char *key; struct type_t *sequence; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* pops the current key in the stack and the current sequence in the stack (these are the current values), then peeks the current sequence in the stack (in case it exists) it should represent the sequence to be set in use for the current context */ pop_top_value_linked_list(bencoding_handler->key_stack, (void **) &key, 1); pop_top_value_linked_list(bencoding_handler->sequence_stack, (void **) &sequence, 1); peek_top_value_linked_list(bencoding_handler->sequence_stack, (void **) &type); bencoding_handler->sequence = type; /* in case the current (previous) sequence is a map, must do some garbage collection to avoid leeks */ if(sequence->type == MAP_TYPE || sequence->type == SORT_MAP_TYPE) { /* in case there is a key currently defined in the handler must release its memory (to avoid any leaks) */ if(bencoding_handler->key != NULL) { FREE(bencoding_handler->key); } bencoding_handler->key = NULL; } /* in case there is no sequence defined for the current handler context no need to continue the processing (nothing to be assiciated) this is typical for the top level of parsing */ if(bencoding_handler->sequence == NULL) { RAISE_NO_ERROR; } /* swithces over the sequence type to take the appropriate action of setting the lower (previous) context in the upper (current) context */ switch(bencoding_handler->sequence->type) { case LIST_TYPE: /* adds the lower value to the upper list appending it to the back of the lis */ append_value_linked_list(bencoding_handler->sequence->value.value_list, (void *) sequence); /* unsets the next key flag to avoid any unexpected string parsing behavior (hash map only) */ bencoding_handler->next_key = 0; /* breaks the switch */ break; case MAP_TYPE: /* sets the lower value in the upper map for the current key this is the lower upper layer association */ set_value_string_hash_map(bencoding_handler->sequence->value.value_map, key, (void *) sequence); /* sets the retrieved key as the current key and sets the next key flag to force the retrieval of key */ bencoding_handler->key = key; bencoding_handler->next_key = 1; /* breaks the switch */ break; case SORT_MAP_TYPE: /* sets the lower value in the upper map for the current key this is the lower upper layer association */ set_value_string_sort_map(bencoding_handler->sequence->value.value_sort_map, key, (void *) sequence); /* sets the retrieved key as the current key and sets the next key flag to force the retrieval of key */ bencoding_handler->key = key; bencoding_handler->next_key = 1; /* breaks the switch */ break; default: /* breaks the switch */ break; } /* raises no error */ RAISE_NO_ERROR; }
ERROR_CODE _bencoding_string_end_callback(struct bencoding_engine_t *bencoding_engine, const unsigned char *pointer, size_t size) { /* allocates space for the reference to the type structure to hold the string */ struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* allocates memory for the string and then copies the source pointer data into the string buffer for the provided size and then closes it */ char *string = MALLOC(size + 1); memcpy(string, pointer, size); string[size] = '\0'; /* in case the next key flag is active must set the current key as the just retrieved string */ if(bencoding_handler->next_key == 1) { /* in case there's a key pending to be release must release it to avoid memory leaks, then sets the current string as the key and unsets the next key flag to save the value */ if(bencoding_handler->key != NULL) { FREE(bencoding_handler->key); } bencoding_handler->key = (unsigned char *) string; bencoding_handler->next_key = 0; } /* otherwise in case the sequence type is defined the string must be a value and must be associated with the sequence */ else if(bencoding_handler->sequence != NULL) { /* creates a new type structure for the string and sets it with the correct string value */ create_type(&type, STRING_TYPE); *type = buffer_type(string, size); /* switches over the type of current sequence to execute the proper operations */ switch(bencoding_handler->sequence->type) { case LIST_TYPE: /* adds the current type to the list sequence */ append_value_linked_list( bencoding_handler->sequence->value.value_list, (void *) type ); /* breaks the switch */ break; case MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_hash_map( bencoding_handler->sequence->value.value_map, bencoding_handler->key, (void *) type ); bencoding_handler->next_key = 1; /* breaks the switch */ break; case SORT_MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_sort_map( bencoding_handler->sequence->value.value_sort_map, bencoding_handler->key, (void *) type ); bencoding_handler->next_key = 1; /* breaks the switch */ break; default: /* breaks the switch */ break; } } /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* raises no error */ RAISE_NO_ERROR; }
ERROR_CODE _bencoding_integer_end_callback(struct bencoding_engine_t *bencoding_engine, const unsigned char *pointer, size_t size) { /* allocates space for the integer value and for the type that will encapsulate it */ int _integer; struct type_t *type; /* retrieves the bencoding handler from the template engine context then uses it to store the (current) value */ struct bencoding_handler_t *bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context; /* allocates space for the integer string value and then copies the data buffer into it and terminates the null string */ char *integer = MALLOC(size + 1); memcpy(integer, pointer, size); integer[size] = '\0'; /* in case the sequence type is defined the integer must be a value and must be associated with the sequence */ if(bencoding_handler->sequence != NULL) { /* converts the integer string into an integer value, then creates the type structure for the integer and sets it as an integer value */ _integer = atoi(integer); create_type(&type, INTEGER_TYPE); *type = integer_type(_integer); /* switches over the type of current sequence to execute the proper operations */ switch(bencoding_handler->sequence->type) { case LIST_TYPE: /* adds the current type to the list sequence */ append_value_linked_list(bencoding_handler->sequence->value.value_list, (void *) type); /* breaks the switch */ break; case MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_hash_map(bencoding_handler->sequence->value.value_map, bencoding_handler->key, (void *) type); bencoding_handler->next_key = 1; /* breaks the switch */ break; case SORT_MAP_TYPE: /* sets the value in the map for the current key and sets the next key flag so that the next string is saved as a key */ set_value_string_sort_map(bencoding_handler->sequence->value.value_sort_map, bencoding_handler->key, (void *) type); bencoding_handler->next_key = 1; /* breaks the switch */ break; default: /* breaks the switch */ break; } } /* in case there is no top type defined for the handler sets the current type as the top type (base type) */ if(bencoding_handler->top == NULL) { bencoding_handler->top = type; } /* releases the memory associated with the intger string value in order to avoid memory leaks */ FREE(integer); /* raises no error */ RAISE_NO_ERROR; }