示例#1
0
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;
}
示例#2
0
ERROR_CODE _ini_value_end_callback(struct ini_engine_t *ini_engine, const unsigned char *pointer, size_t size) {
    /* allocates space for the sort map reference to
    hold the reference to the current section configuration */
    struct sort_map_t *section_configuration;

    /* retrieves the ini handler from the template engine context
    then uses it to store the (current) value */
    struct ini_handler_t *ini_handler = (struct ini_handler_t *) ini_engine->context;
    size_t offset = ini_handler->remove_spaces ? leading_offset((char *) pointer, size) : 0;
    size_t _size = size - offset;
    char *value = MALLOC(_size + 1);
    memcpy(value, pointer + offset, _size);
    value[_size] = '\0';

    /* tries to retrieve the current section configuration from the
    configuration in case it's not possible to retrieve it a new
    configuration map must be created */
    get_value_string_sort_map(ini_handler->configuration, (unsigned char *) ini_handler->section, (void **) &section_configuration);
    if(section_configuration == NULL) {
        /* creates a new sort map to contain the section configuration
        and sets it under the current configuration variable in the ini
        handler for the current section name */
        create_sort_map(&section_configuration, 0);
        set_value_string_sort_map(ini_handler->configuration, (unsigned char *) ini_handler->section, section_configuration);
    }

    /* sets the current key and value under the current section configuration
    this is the main handler action */
    set_value_string_sort_map(section_configuration, (unsigned char *) ini_handler->key, value);

    /* raises no error */
    RAISE_NO_ERROR;
}
示例#3
0
ERROR_CODE process_ini_file(char *file_path, struct sort_map_t **configuration_pointer) {
    /* allocates space for the general (temporary) variables
    to be used durring the parsing of the file */
    ERROR_CODE return_value;
    size_t index;
    size_t file_size;
    unsigned char *file_buffer;
    unsigned char character;
    enum ini_state_e state;

    /* allocates the mark variables used to locate
    the part of context changing durring the parsing */
    unsigned char *pointer = 0;
    unsigned char *section_end_mark = 0;
    unsigned char *comment_end_mark = 0;
    unsigned char *key_end_mark = 0;
    unsigned char *value_end_mark = 0;

    /* allocates space for the settings to be used by
    the engine for the engine instance itself and for
    the handler to be used to "catch" the events, then
    retrieves the pointers to these structures*/
    struct ini_settings_t ini_settings_s;
    struct ini_engine_t ini_engine_s;
    struct ini_handler_t ini_handler_s;
    struct ini_settings_t *ini_settings = &ini_settings_s;
    struct ini_engine_t *ini_engine = &ini_engine_s;
    struct ini_handler_t *ini_handler = &ini_handler_s;

    /* allocates space for the sort map to be used for
    the configuration to be created */
    struct sort_map_t *configuration;

    /* creates the sort map that will hold the various
    arguments, then updates the configuration pointer
    with the created configuration sort map */
    create_sort_map(&configuration, 0);
    *configuration_pointer = configuration;

    /* sets the various handlers for the ini settings
    parsing, they will be used to correctly update the
    provided configuration sort map */
    ini_settings_s.on_section_start = NULL;
    ini_settings_s.on_section_end = _ini_section_end_callback;
    ini_settings_s.on_comment_start = NULL;
    ini_settings_s.on_comment_end = _ini_comment_end_callback;
    ini_settings_s.on_key_start = NULL;
    ini_settings_s.on_key_end = _ini_key_end_callback;
    ini_settings_s.on_value_start = NULL;
    ini_settings_s.on_value_end = _ini_value_end_callback;

    /* sets the configuration reference in the ini handler
    so that it may be updatd and then sets the handler in
    the ini engine instance to be used for parsing */
    ini_handler_s.configuration = configuration;
    ini_engine_s.context = ini_handler;

    /* sets the flag that controls if the trailing space
    characters should be removesd from key and values */
    ini_handler_s.remove_spaces = 1;

    /* reads the file contained in the provided file path
    and then tests the error code for error, in case there is an
    error prints it to the error stream output */
    return_value = read_file(file_path, &file_buffer, &file_size);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_ERROR_F(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Problem reading file %s",
            file_path
        );
    }

    /* sets the initial state for the parsing process this
    is considered to be the "general loop" state */
    state = INI_ENGINE_NORMAL;

    /* iterates over the byte range of the file, all the bytes
    should be contained in the buffer "under" iteration */
    for(index = 0; index < file_size; index++) {
        /* retrieves the current character from the
        file buffer and the retrieves the pointer to
        its position */
        character = file_buffer[index];
        pointer = &file_buffer[index];

        switch(state) {
            case INI_ENGINE_NORMAL:
                if(character == '[') {
                    state = INI_ENGINE_SECTION;

                    INI_MARK_N(section_end, -1);
                    INI_CALLBACK(section_start);
                } else if(character == ';') {
                    state = INI_ENGINE_COMMENT;

                    INI_MARK_N(comment_end, -1);
                    INI_CALLBACK(comment_start);
                } else if(character == '\n' || character == '\r') {
                    state = INI_ENGINE_NORMAL;
                } else {
                    state = INI_ENGINE_KEY;

                    INI_MARK(key_end);
                    INI_CALLBACK(key_start);
                }

                break;

            case INI_ENGINE_SECTION:
                if(character == ']') {
                    state = INI_ENGINE_NORMAL;

                    INI_CALLBACK_DATA(section_end);
                }

                break;

            case INI_ENGINE_COMMENT:
                if(character == '\n' || character == '\r') {
                    state = INI_ENGINE_NORMAL;

                    INI_CALLBACK_DATA(comment_end);
                }

                break;

            case INI_ENGINE_KEY:
                if(character == '=') {
                    state = INI_ENGINE_VALUE;

                    INI_MARK_N(value_end, -1);
                    INI_CALLBACK_DATA(key_end);
                    INI_CALLBACK(value_start);
                }

                break;

            case INI_ENGINE_VALUE:
                if(character == '\n' || character == '\r') {
                    state = INI_ENGINE_NORMAL;

                    INI_CALLBACK_DATA(value_end);
                }

                break;
        }
    }

    /* releases the buffer used durring the parsing of
    the configuration file (avoids leaks) */
    FREE(file_buffer);

    /* raises no error */
    RAISE_NO_ERROR;
}