pretty_format.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "pretty_format.h"
  2. #include <core/check.h>
  3. #include <core/core_defines.h>
  4. #define PRETTY_FORMAT_MAX_CANONICAL_DATA_SIZE 256U
  5. void pretty_format_bytes_hex_canonical(
  6. FuriString* result,
  7. size_t num_places,
  8. const char* line_prefix,
  9. const uint8_t* data,
  10. size_t data_size) {
  11. furi_assert(data);
  12. bool is_truncated = false;
  13. if(data_size > PRETTY_FORMAT_MAX_CANONICAL_DATA_SIZE) {
  14. data_size = PRETTY_FORMAT_MAX_CANONICAL_DATA_SIZE;
  15. is_truncated = true;
  16. }
  17. /* Only num_places byte(s) can be on a single line, therefore: */
  18. const size_t line_count =
  19. data_size / num_places + (data_size % num_places != 0 ? 1 : 0) + (is_truncated ? 2 : 0);
  20. /* Line length = Prefix length + 3 * num_places (2 hex digits + space) + 1 * num_places +
  21. + 1 pipe character + 1 newline character */
  22. const size_t line_length = (line_prefix ? strlen(line_prefix) : 0) + 4 * num_places + 2;
  23. /* Reserve memory in adance in order to avoid unnecessary reallocs */
  24. furi_string_reset(result);
  25. furi_string_reserve(result, line_count * line_length);
  26. for(size_t i = 0; i < data_size; i += num_places) {
  27. if(line_prefix) {
  28. furi_string_cat(result, line_prefix);
  29. }
  30. const size_t begin_idx = i;
  31. const size_t end_idx = MIN(i + num_places, data_size);
  32. for(size_t j = begin_idx; j < end_idx; j++) {
  33. furi_string_cat_printf(result, "%02X ", data[j]);
  34. }
  35. furi_string_push_back(result, '|');
  36. for(size_t j = begin_idx; j < end_idx; j++) {
  37. const char c = data[j];
  38. const char sep = ((j < end_idx - 1) ? ' ' : '\n');
  39. const char* fmt = ((j < data_size - 1) ? "%c%c" : "%c");
  40. furi_string_cat_printf(result, fmt, (c > 0x1f && c < 0x7f) ? c : '.', sep);
  41. }
  42. }
  43. if(is_truncated) {
  44. furi_string_cat_printf(
  45. result, "\n(Data is too big. Showing only the first %zu bytes.)", data_size);
  46. }
  47. }