From 776717a7293feaf881672ecf9a6941fd8cb86670 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:52:40 +0100 Subject: [PATCH] HPA_DCO_009 Continuation of HPA/DCO integration. Changed the way percentage is calculated. As we are dealing with large numbers and for some reason printf prints a double that is 99.99999999999 as 100.00 when a precision of two is specified I wrote a function that creates a percentage string such that 99.99999999999 is displayed as 99.99%. This is important in the report as a disc with one hidden sector will now correctly show as 99.99% erased and not 100.00% erased. --- src/create_pdf.c | 65 +++++++++------------------------------------ src/miscellaneous.c | 26 ++++++++++++++++++ src/miscellaneous.h | 24 ++++++++++++++--- 3 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/create_pdf.c b/src/create_pdf.c index b778843..c3a9369 100644 --- a/src/create_pdf.c +++ b/src/create_pdf.c @@ -72,6 +72,7 @@ int create_pdf( nwipe_context_t* ptr ) char HPA_size_text[50] = ""; char errors[50] = ""; char throughput_txt[50] = ""; + char bytes_percent_str[7] = ""; int status_icon; @@ -453,11 +454,11 @@ int create_pdf( nwipe_context_t* ptr ) if( c->device_type == NWIPE_DEVICE_NVME || c->device_type == NWIPE_DEVICE_VIRT || c->HPA_status == HPA_NOT_APPLICABLE ) { - snprintf( bytes_erased, - sizeof( bytes_erased ), - "%lli, (%.1f%%)", - c->bytes_erased, - (float) ( (float) c->bytes_erased / (float) ( (float) c->device_size ) ) * 100 ); + convert_double_to_string( bytes_percent_str, + (double) ( (double) c->bytes_erased / (double) c->device_size ) * 100 ); + + snprintf( bytes_erased, sizeof( bytes_erased ), "%lli, (%s%%)", c->bytes_erased, bytes_percent_str ); + if( c->bytes_erased == c->device_size ) { pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN ); @@ -469,13 +470,13 @@ int create_pdf( nwipe_context_t* ptr ) } else { - snprintf( bytes_erased, - sizeof( bytes_erased ), - "%lli, %lli, (%.1f%%)", - c->bytes_erased, - c->Calculated_real_max_size_in_bytes, - (double) ( (double) c->bytes_erased / (double) ( (double) c->Calculated_real_max_size_in_bytes ) ) - * 100 ); + + convert_double_to_string( + bytes_percent_str, + (double) ( (double) c->bytes_erased / (double) c->Calculated_real_max_size_in_bytes ) * 100 ); + + snprintf( bytes_erased, sizeof( bytes_erased ), "%lli, (%s%%)", c->bytes_erased, bytes_percent_str ); + if( c->bytes_erased == c->Calculated_real_max_size_in_bytes ) { pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN ); @@ -485,46 +486,6 @@ int create_pdf( nwipe_context_t* ptr ) pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_RED ); } } - -#if 0 - /* Use real max sectors taken from DCO if not zero */ - if( c->DCO_reported_real_max_sectors != 0 ) - { - snprintf( - bytes_erased, - sizeof( bytes_erased ), - "%lli (%.1f%%)", - c->bytes_erased, - (double) ( (double) c->bytes_erased / (double) ( (double) c->DCO_reported_real_max_sectors * c->device_sector_size ) ) - * 100 ); - if( c->bytes_erased == ( c->DCO_reported_real_max_sectors * c->device_sector_size ) ) - { - pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN ); - } - else - { - pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_RED ); - } - } - else - { - /* else use the reported size which will be less if there is a enabled HPA */ - snprintf( bytes_erased, - sizeof( bytes_erased ), - "%lli (%.1f%%)", - c->bytes_erased, - (double) ( (double) c->bytes_erased / (double) c->device_size ) * 100 ); - - if( c->bytes_erased == c->device_size ) - { - pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN ); - } - else - { - pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_RED ); - } - } -#endif } pdf_set_font( pdf, "Helvetica" ); diff --git a/src/miscellaneous.c b/src/miscellaneous.c index 4afa71f..bf36630 100644 --- a/src/miscellaneous.c +++ b/src/miscellaneous.c @@ -241,3 +241,29 @@ void replace_non_alphanumeric( char* str, char replacement_char ) i++; } } + +void convert_double_to_string( char* output_str, double value ) +{ + int idx = 0; + int idx2; + int idx3 = 0; + + char percstr[512] = ""; + + snprintf( percstr, sizeof( percstr ), "%5.32lf", value ); + printf( "percstr=%s%%", percstr ); + + while( percstr[idx] != 0 ) + { + if( percstr[idx] == '.' ) + { + for( idx2 = 0; idx2 < 3; idx2++ ) + { + output_str[idx3++] = percstr[idx++]; + } + break; + } + output_str[idx3++] = percstr[idx++]; + } + output_str[idx3] = 0; +} diff --git a/src/miscellaneous.h b/src/miscellaneous.h index 9245b67..a0ad0a7 100644 --- a/src/miscellaneous.h +++ b/src/miscellaneous.h @@ -63,10 +63,28 @@ int nwipe_strip_path( char*, char* ); * char str[] = 18:21:56; * calling the function replace_non_alphanumeric( &str, '_' ) * would result in str changing from 18:21:56 to 18_21_56 - * @param character pointer to the string to be processed - * @param replacement_char the character used to replace non alpha-numeric characters + * @param char* pointer to the string to be processed + * @param char the character used to replace non alpha-numeric characters * @return void */ -void replace_non_alphanumeric( char* str, char replacement_char ); +void replace_non_alphanumeric( char*, char ); + +/** + * I found this function necessary when converting a double of say + * 99.999999999999999999 to text using printf. I only wanted 99.99 + * printed but if you specified a precision of %.2f in printf i.e 2 digits + * after the decimal point you get 100.00 and not 99.99 If you increase + * the precision to %.10f then you get 99.9999999999 but I only want + * two significant digits displayed.i.e 99.99% not 100% + * So this function converts to double retaining sufficient precision + * so that a 30TB disc with one hidden sector will display as 99.99% erased + * As an example if the double value to be converted is 99.999999999999999987 + * this function will always output 99.99 unlike printf which outputs 100.00 + * @param char* pointer to the string we write our percentage to. Needs to be + * a minimum of 7 bytes, i.e 100.00 plus null terminator. + * @param double the floating point value to be converted to a string. + * @return void + */ +void convert_double_to_string( char*, double ); #endif /* HPA_DCO_H_ */