Esempio n. 1
0
ERROR_CODE decode_bencoding_file(char *file_path, struct type_t **type_pointer) {
    /* allocates space for the general (temporary) variables
    to be used durring the parsing of the file */
    ERROR_CODE return_value;
    size_t file_size;
    unsigned char *file_buffer;
    struct bencoding_engine_t *bencoding_engine;
    struct bencoding_handler_t *bencoding_handler;

    /* 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
        );
    }

    /* starts the bencoding engine, starting all of its internal
    structures and then runs an engine tick parsing the complete
    file buffer (it's completely available) */
    _start_bencoding_engine(&bencoding_engine);
    _run_bencoding_engine(bencoding_engine, file_buffer, file_size);

    /* retieves the handler associated with the engine and then
    uses it to retrieve the top type of the parsed structure */
    bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context;
    *type_pointer = bencoding_handler->top;

    /* stops the bencoding engine releasing all of its internal
    structures, the top type is still defined */
    _stop_bencoding_engine(bencoding_engine);

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

    /* raises no error */
    RAISE_NO_ERROR;
}
Esempio n. 2
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;
}