Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
ERROR_CODE parameters_http_c(char *buffer, size_t size, size_t count, ...) {
    /* allocates space for the variable list of arguments
    provided as arguments to this function and tha should
    contain sequences of key, value and length */
    va_list arguments;

    /* allocates space for the various indexes to be
    used in the iteration including the sequence offset
    and the global index counter */
    size_t index;
    size_t index_g;
    size_t offset;

    /* allocates space for the three components of the
    parameter the key, the value and the length of the
    provided value buffer (it's not null terminated) */
    char *key_s;
    char *buffer_s;
    size_t length_s;

    /* allocates space for the pointer to the buffer that
    will hold the created parameters string */
    char *params_buffer;
    size_t params_size;

    /* creates space for the pointer to the map that will
    contain all the arranjed sequence of keys and values
    representing the various parameters */
    struct hash_map_t *parameters_map;

    /* statically allocates space in the stack for the various
    value strings representing the parameter values */
    struct string_t strings[256];

    /* in case the number of tuples provided as arguments is
    more that the space available for the value strings must
    fail with an error otherwise a buffer overflow occurs */
    if(count > 256) {
        RAISE_ERROR_M(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Problem creating parameters"
        );
    }

    /* sets the inial key string value as null so that the
    value is started initialized, required for safe execution */
    key_s = NULL;

    /* multiplies the count by three as it must contain
    the real number of arguments and not just the number
    of tuples of three in it */
    count *= 3;

    /* creates the hash map that is going to be used to
    temporarly store the various key value associations */
    create_hash_map(&parameters_map, 0);

    /* iterates over the sequence of dynamic arguments
    provided to the function to retrieve them as sequences
    of key, value and length, then sets them in the map
    representing the various parameters */
    va_start(arguments, count);
    for(index = 0; index < count; index++) {
        offset = index % 3;
        index_g = index / 3;

        switch(offset) {
            case 0:
                key_s = va_arg(arguments, char *);
                break;

            case 1:
                buffer_s = va_arg(arguments, char *);
                strings[index_g].buffer = (unsigned char *) buffer_s;
                break;

            case 2:
                length_s = va_arg(arguments, size_t);
                strings[index_g].length = length_s;

                set_value_string_hash_map(
                    parameters_map,
                    (unsigned char *) key_s,
                    (void *) &strings[index_g]
                );

                break;
        }
    }
    va_end(arguments);

    /* generates the (get) parameters for an http request
    from the provided hash map of key values, the returned
    buffer is owned by the caller and must be released */
    parameters_http(
        parameters_map,
        (unsigned char **) &params_buffer,
        &params_size
    );
    delete_hash_map(parameters_map);

    /* in case the amount of bytes to be copied from the
    dynamically created params buffer to the buffer is
    greater than the size provided raises an error */
    if(params_size > size - 1) {
        FREE(params_buffer);
        RAISE_ERROR_M(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Problem creating parameters"
        );
    }

    /* copies the generated params buffer into the final
    buffer defined in the parameters structure, then closes
    the string with the final character and releases the
    temporary buffer (params buffer) */
    memcpy(buffer, params_buffer, params_size);
    buffer[params_size] = '\0';
    FREE(params_buffer);

    /* raises no error as the creation of the parameters
    buffer has completed with success */
    RAISE_NO_ERROR;
}