#include "infoindx.h" #include "diskpane.h" #include "keyboard.h" #include "mouse.h" #include #include #include #define DEFAULT_INFO_HEIGHT 512 #define MAX_LINE_LENGTH 512 const int info_index_id = -8098; //---------------------------- info_node ------------------------------- info_file_index empty_index; info_node empty_node; info_node:: info_node() { start = 0; height = 0; viewing_position = 0; } info_node & info_node::operator=( const info_node & model ) { file_name = model.file_name; node_name = model.node_name; start = model.start; height = model.height; viewing_position = model.viewing_position; return *this; } bool info_node::operator==( const info_node & other ) { return this -> node_name == other.node_name && this -> file_name == other.file_name; } bool info_node::operator!=( const info_node & other ) { return this -> node_name != other.node_name || this -> file_name != other.file_name; } //------------------------- info_file_index ---------------------------- info_file_index:: info_file_index() { _node_count = 0; _actual_height = 0; _node_array = 0; } info_file_index:: info_file_index( const info_file_index & model ) { _node_count = 0; _actual_height = 0; _node_array = 0; *this = model; } info_file_index:: ~info_file_index() { if( _node_array ) delete [] _node_array; } info_file_index & info_file_index:: operator=( const info_file_index & other ) { resize( other._node_count ); int i = 0; while( i < other._node_count ) { _node_array[i] = other._node_array[i]; i++; } return *this; } info_file_index & info_file_index:: operator+=( const info_file_index & other ) { int original_count = _node_count; resize( _node_count + other._node_count ); int i = 0; while( i < other._node_count ) { _node_array[i + original_count] = other._node_array[i]; i++; } return *this; } info_file_index & info_file_index:: operator+=( const info_node & new_entry ) { resize( _node_count + 1 ); _node_array[_node_count - 1] = new_entry; return *this; } bool info_file_index:: resize( int new_height ) { if( new_height < 0 ) { return true; } if( new_height < _node_count ) { int i = new_height; while( i < _node_count ) { _node_array[i] = empty_node; i++; } _node_count = new_height; return false; } if( new_height <= _actual_height ) { _node_count = new_height; return false; } int new_actual_height = 2 * _actual_height; if( new_actual_height == 0 ) new_actual_height = DEFAULT_INFO_HEIGHT; if( new_actual_height < new_height ) new_actual_height = new_height; info_node * temp = new info_node[new_actual_height]; if( !temp ) return true; if( _node_array ) { int max = _node_count; if( max > new_height ) max = new_height; int i = 0; while( i < max ) { temp[i] = _node_array[i]; i++; } delete [] _node_array; } _actual_height = new_actual_height; _node_count = new_height; _node_array = temp; return false; } info_file_index build_file_index( const char * full_path_name ) { info_file_index node_index; string_array whole_file; string_array file_list; bool error = whole_file.read_file( full_path_name ); if( error ) { perror( full_path_name ); key.get(); return empty_index; } String info_path = full_path_name; info_path = info_path.through( DIRSLASH, -1 ); String file_name = full_path_name; file_name = file_name.after( DIRSLASH, -1 ); file_list += file_name; file_list += get_file_parts( whole_file ); int i = 0; while( i < file_list.height() ) { node_index += build_file_part_index( info_path + file_list[i] ); i++; } return node_index; } info_file_index build_file_part_index( const char * full_path_name ) { string_array whole_file; bool error = whole_file.read_file( full_path_name ); if( error ) { String error_message = "build_file_part_index - error reading file "; error_message += full_path_name; perror( error_message ); key.get(); return empty_index; } info_file_index node_index; info_node new_node; new_node.file_name = full_path_name; new_node.file_name = new_node.file_name.after( DIRSLASH, -1 ); new_node.file_name.downcase(); int node_end; int file_height = whole_file.height(); int n = 0; int i = 1; while( i < file_height ) { if( whole_file[i-1].length() == 1 && whole_file[i-1][0] == '' && whole_file[i].contains( "File: ", 0 ) ) { new_node.start = i; new_node.node_name = whole_file[i].after( "Node: " ); new_node.node_name = new_node.node_name.before( ',' ); new_node.node_name.gsub( RXwhite, ' ' ); node_index += new_node; node_end = whole_file.index( '', 0, i+1 ).y; if( node_end == not_found ) node_index[n].height = whole_file.height() - i; else node_index[n].height = node_end - i; n++; } i++; } return node_index; } string_array get_file_parts( string_array & top_file ) { string_array parts; int height = top_file.height(); int i = 1; while( i < height ) { if( top_file[i-1].length() == 1 && top_file[i-1][0] == '' && top_file[i].contains( "Indirect:", 0 ) ) { i++; while( i < height && ( top_file[i].length() != 1 || top_file[i][0] != '' ) ) { parts += (String)top_file[i].before( ':' ); i++; } } i++; } return parts; } bool info_file_index:: write_file( const char * file_name ) { FILE * stream = fopen( file_name, "wb" ); if( !stream ) return true; if( (int)fwrite( &info_index_id, sizeof(int), 1, stream ) == -1 || (int)fwrite( &_node_count, sizeof(int), 1, stream ) == -1 ) { fclose( stream ); return true; } int i = 0; while( i < _node_count ) { if( (int)fwrite( &_node_array[i].start, sizeof(int), 1, stream ) == -1 ) break; if( (int)fwrite( &_node_array[i].height, sizeof(int), 1, stream ) == -1 ) break; if( fputs( _node_array[i].file_name+'\n', stream ) <= 0 ) break; if( fputs( _node_array[i].node_name+'\n', stream ) <= 0 ) break; i++; } fclose( stream ); if( i != _node_count ) { fprintf(stderr,"info index write not completed. \n"); key.get(); return true; } else return false; } bool info_file_index:: read_file( const char * file_name ) { if( !is_a_file( file_name ) ) return true; FILE * stream = fopen( file_name, "rb" ); if( !stream ) return true; int id_word; int new_node_count; if( (int)fread( &id_word, sizeof(int), 1, stream ) == -1 || id_word != info_index_id || (int)fread( &new_node_count, sizeof(int), 1, stream ) == -1 ) { fclose( stream ); return true; } resize( new_node_count ); char buffer[MAX_LINE_LENGTH]; int i = 0; while( i < new_node_count ) { if( (int)fread( &_node_array[i].start, sizeof(int), 1, stream ) == -1 ) break; if( (int)fread( &_node_array[i].height, sizeof(int), 1, stream ) == -1 ) break; if( !fgets( buffer, MAX_LINE_LENGTH, stream ) ) break; _node_array[i].file_name = buffer; _node_array[i].file_name = _node_array[i].file_name.before( '\n' ); if( !fgets( buffer, MAX_LINE_LENGTH, stream ) ) break; _node_array[i].node_name = buffer; _node_array[i].node_name = _node_array[i].node_name.before( '\n' ); i++; } fclose( stream ); if( i != new_node_count ) { fprintf(stderr,"info index read not completed. \n"); key.get(); return true; } else return false; } int info_file_index:: size() { int size = 2 * sizeof(int); int i = 0; while( i < node_count() ) { size += _node_array[i].file_name.length() + 1; size += _node_array[i].node_name.length() + 1; size += 2 * sizeof(int); i++; } return size; }