#ifndef USEFUL_FUNCTIONS_H // prohibiting multiple file inclusion #define USEFUL_FUNCTIONS_H /* useful_functions.h (c) 1997-2001 Kari Laitinen 02.10.1997 file created. 11.09.1998 find_smallest_object_in_array and sort_to_ascending_order ( function templates ) added. 17.09.1998 string_terminates_string added 28.05.1999 constants were removed from this file. 13.08.2001 Function print_binary was added. 27.09.2001 last modification This is an includable file containing general purpose functions. */ bool character_is_in_string( char given_character, char given_string[] ) { int character_index = 0 ; bool return_code = false ; while ( given_string[ character_index ] != 0 && return_code == false ) { if ( given_string[ character_index ] == given_character ) { return_code = true ; } character_index ++ ; } return return_code ; } // Note that the functions below work only with English/American // alphabet where letters have ASCII codes that are less than 7FH. bool character_is_visible( char character_code ) { return ( character_code >= 0x20 && character_code <= 0x7E ) ; } bool character_is_letter( char ascii_code ) { return ( ( ascii_code >= 'A' && ascii_code <= 'Z' ) || ( ascii_code >= 'a' && ascii_code <= 'z' ) ) ; } bool character_is_digit( char ascii_code ) { return ( ascii_code >= '0' && ascii_code <= '9' ) ; } bool character_is_letter_or_digit( char ascii_code ) { return ( character_is_letter( ascii_code ) || character_is_digit( ascii_code ) ) ; } double degrees_to_radians( int given_degrees, int given_minutes ) { return ( (double) (( given_degrees * 60 ) + given_minutes ) / (double) ( 360 * 60 ) ) * 2.0 * 3.14159 ; } int get_string_length( char given_string[] ) { // This function is the same as strlen in "string.h". // This is rewritten here because we want to keep this // file independent of other includable files. int calculated_string_length = 0 ; while ( given_string[ calculated_string_length ] != 0 ) { calculated_string_length ++ ; } return calculated_string_length ; } bool equal_strings( char first_string [], char second_string [] ) { int character_index = 0 ; while ( first_string[ character_index ] == second_string[ character_index ] && first_string[ character_index ] != 0 && second_string[ character_index ] != 0 ) { character_index ++ ; } return ( first_string[ character_index ] == 0 && second_string[ character_index ] == 0 ) ; } bool equal_memory_blocks( char first_block[], char second_block[], int block_length_in_bytes ) { // Note: blocks of zero length are considered equal. int byte_index = 0 ; bool return_code = true ; while ( byte_index < block_length_in_bytes && return_code == true ) { if ( first_block[ byte_index ] != second_block[ byte_index ] ) { return_code = false ; } byte_index ++ ; } return return_code ; } bool string_includes_string( char longer_string[], char shorter_string[] ) { /* Note: any string is considered to include a zero string. This function works in somewhat similar way as strstr. This does not return a pointer to the found string. */ bool return_code = false ; int shorter_string_length = get_string_length( shorter_string ) ; char* substring_in_longer_string = longer_string ; while ( get_string_length( substring_in_longer_string ) >= shorter_string_length && return_code == false ) { if ( equal_memory_blocks( substring_in_longer_string, shorter_string, shorter_string_length ) ) { return_code = true ; } else { substring_in_longer_string ++ ; } } return return_code ; } bool string_includes_strings( char longer_string[], char first_shorter_string[], char second_shorter_string[] ) { return ( string_includes_string( longer_string, first_shorter_string ) && string_includes_string( longer_string, second_shorter_string ) ) ; } bool string_terminates_string( char possible_terminating_string[], char longer_string[] ) { int length_of_terminating_string = get_string_length( possible_terminating_string ) ; int length_of_longer_string = get_string_length( longer_string ) ; return ( length_of_terminating_string <= length_of_longer_string && equal_strings( possible_terminating_string, &longer_string[ length_of_longer_string - length_of_terminating_string ] ) ) ; } int ascii_to_integer( char number_as_string[], int number_of_digits ) { int resulting_integer = 0 ; int digit_multiplier = 1 ; /* This function works in the same way as standard function atoi in stdlib.h but here number_as_string does not need to be terminated by NULL. */ while ( number_of_digits > 0 ) { number_of_digits -- ; resulting_integer = resulting_integer + ( ( number_as_string[ number_of_digits ] - 0x30 ) * digit_multiplier ) ; digit_multiplier = digit_multiplier * 10 ; } return resulting_integer ; } void move_bytes ( unsigned int byte_count, char *source, char *destination ) { if ( ( source == 0 || destination == 0 ) && ( byte_count > 0 ) ) { cout << "\n\n e r r o r in move_bytes ....\n\n" ; return ; } /* This function moves bytes in memory so that no memory contents is lost. Standard functions strcpy and strncpy may overwrite important data if memory blocks being moved overlap. */ if ( source < destination ) { while ( byte_count > 0 ) { byte_count -- ; *( destination + byte_count ) = *(source + byte_count ) ; } } else if ( source > destination ) { while ( byte_count > 0 ) { *destination = *source ; byte_count -- ; destination ++ ; source ++ ; } } } template void move_objects ( unsigned int number_of_objects_to_move, Type array_of_source_objects[], Type array_of_destination_objects[] ) { if ( array_of_source_objects < array_of_destination_objects ) { while ( number_of_objects_to_move > 0 ) { number_of_objects_to_move -- ; array_of_destination_objects[ number_of_objects_to_move ] = array_of_source_objects[ number_of_objects_to_move ] ; } } else if ( array_of_source_objects > array_of_destination_objects ) { for ( unsigned int object_index = 0 ; object_index < number_of_objects_to_move ; object_index ++ ) { array_of_destination_objects[ object_index ] = array_of_source_objects[ object_index ] ; } } } template void find_smallest_object_in_array( Type array_of_objects[], int number_of_objects_in_array, Type& smallest_object, int& index_of_smallest_object ) { smallest_object = array_of_objects[ 0 ] ; index_of_smallest_object = 0 ; for ( int object_index = 1 ; object_index < number_of_objects_in_array ; object_index ++ ) { if ( array_of_objects[ object_index ] < smallest_object ) { smallest_object = array_of_objects[ object_index ] ; index_of_smallest_object = object_index ; } } } template void sort_to_ascending_order( Type array_of_objects[], int number_of_objects_in_array ) { Type smallest_object ; int index_of_smallest_object ; for ( int object_index = 0 ; object_index < number_of_objects_in_array - 1 ; object_index ++ ) { find_smallest_object_in_array( &array_of_objects[ object_index ], number_of_objects_in_array - object_index, smallest_object, index_of_smallest_object ) ; index_of_smallest_object += object_index ; // Now we simply put the object in current array // position to where the smallest object is, and // then put the smallest object in current position. array_of_objects[ index_of_smallest_object ] = array_of_objects[ object_index ] ; array_of_objects[ object_index ] = smallest_object ; } } void print_binary( char given_byte ) { unsigned char bit_mask = 0x80 ; unsigned char one_bit_in_given_byte ; for ( int bit_counter = 0 ; bit_counter < 8 ; bit_counter ++ ) { one_bit_in_given_byte = given_byte & bit_mask ; if ( one_bit_in_given_byte == 0 ) { cout << "0" ; } else { cout << "1" ; } bit_mask = bit_mask >> 1 ; } } void print_hexadecimal( char a_byte_to_print ) { // This function prints bytes always with two digits. char hexadecimal_digits[] = "0123456789ABCDEF" ; short higher_order_nibble = a_byte_to_print & 0x00F0 ; higher_order_nibble = higher_order_nibble >> 4 ; short lower_order_nibble = a_byte_to_print & 0x000F ; cout << hexadecimal_digits[ higher_order_nibble ] ; cout << hexadecimal_digits[ lower_order_nibble ] ; } void print_hexadecimal( unsigned char a_byte_to_print ) { print_hexadecimal( (char) a_byte_to_print ) ; } void print_hexadecimal( long long_integer ) { // Here we suppose that the least significant byte of // a long variable has the smallest memory address. char* a_byte_in_long_integer = (char*) &long_integer ; int number_of_bytes_to_print = sizeof( long ) ; while ( number_of_bytes_to_print > 0 ) { number_of_bytes_to_print -- ; print_hexadecimal( *( a_byte_in_long_integer + number_of_bytes_to_print ) ) ; } } /* The following function exists also in program memory.cpp. Both functions work in the same way, but the function below has a slightly different internal implementation. */ void print_memory_contents( void* memory_address, int number_of_bytes_to_print ) { char* a_byte_in_memory = (char*) memory_address ; long current_memory_address = (long) a_byte_in_memory ; int number_of_bytes_on_this_line = 0 ; char bytes_of_this_line[ 20 ] ; cout << "\n" ; print_hexadecimal( current_memory_address ) ; cout << " " ; while ( number_of_bytes_to_print > 0 ) { if ( number_of_bytes_on_this_line == 16 ) { bytes_of_this_line[ number_of_bytes_on_this_line ] = 0 ; cout << " " << bytes_of_this_line ; current_memory_address = (long) a_byte_in_memory ; cout << "\n" ; print_hexadecimal( current_memory_address ) ; cout << " " ; number_of_bytes_on_this_line = 0 ; } cout << " " ; print_hexadecimal( *a_byte_in_memory ) ; // bytes_of_this_line contains all printable characters if ( *a_byte_in_memory > 0x1F && *a_byte_in_memory < 0x7F ) { bytes_of_this_line[ number_of_bytes_on_this_line ] = *a_byte_in_memory ; } else { bytes_of_this_line[ number_of_bytes_on_this_line ] = ' ' ; } number_of_bytes_on_this_line ++ ; number_of_bytes_to_print -- ; a_byte_in_memory ++ ; } /* The last line of memory contents may contain less than 16 bytes. Next we print that line. */ if ( number_of_bytes_on_this_line > 0 ) { while ( number_of_bytes_on_this_line < 16 ) { cout << " " ; bytes_of_this_line[ number_of_bytes_on_this_line ] = ' ' ; number_of_bytes_on_this_line ++ ; } bytes_of_this_line[ number_of_bytes_on_this_line ] = 0 ; cout << " " << bytes_of_this_line ; } } #endif // end of include guard