Method: String#formatted

Defined in:
lib/openc3/core_ext/string.rb

#formatted(word_size = 1, words_per_line = 16, word_separator = ' ', indent = 0, show_address = true, address_separator = ': ', show_ascii = true, ascii_separator = ' ', unprintable_character = ' ', line_separator = "\n") ⇒ Object

Displays a String containing binary data in a human readable format by converting each byte to the hex representation.

Parameters:

  • word_size (Integer) (defaults to: 1)

    How many bytes compose a word. Words are grouped together without spaces in between

  • words_per_line (Integer) (defaults to: 16)

    The number of words to display on a single formatted line

  • word_separator (String) (defaults to: ' ')

    The string to place between words

  • indent (Integer) (defaults to: 0)

    The amount of spaces to put in front of each formatted line

  • show_address (Boolean) (defaults to: true)

    Whether to show the hex address of the first byte in the formatted output

  • address_separator (String) (defaults to: ': ')

    The string to put after the hex address. Only used if show_address is true.

  • show_ascii (Boolean) (defaults to: true)

    Whether to interpret the binary data as ASCII characters and display the printable characters to the right of the formatted line

  • ascii_separator (String) (defaults to: ' ')

    The string to put between the formatted line and the ASCII characters. Only used if show_ascii is true.

  • unprintable_character (String) (defaults to: ' ')

    The string to output when data in the binary String does not result in a printable ASCII character. Only used if show_ascii is true.

  • line_separator (String) (defaults to: "\n")

    The string used to end a line. Normaly newline.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/openc3/core_ext/string.rb', line 67

def formatted(
  word_size = 1,
  words_per_line = 16,
  word_separator = ' ',
  indent = 0,
  show_address = true,
  address_separator = ': ',
  show_ascii = true,
  ascii_separator = '  ',
  unprintable_character = ' ',
  line_separator = "\n"
)
  string = ''
  byte_offset = 0
  bytes_per_line = word_size * words_per_line
  indent_string = ' ' * indent
  ascii_line = ''

  self.each_byte do |byte|
    if byte_offset % bytes_per_line == 0
      # Create the indentation at the beginning of each line
      string << indent_string

      # Add the address if requested
      string << sprintf("%08X%s", byte_offset, address_separator) if show_address
    end

    # Add the byte
    string << sprintf("%02X", byte)

    # Create the ASCII representation if requested
    if show_ascii
      if PRINTABLE_RANGE.include?(byte)
        ascii_line << [byte].pack('C')
      else
        ascii_line << unprintable_character
      end
    end

    # Move to next byte
    byte_offset += 1

    # If we're at the end of the line we output the ascii if requested
    if byte_offset % bytes_per_line == 0
      if show_ascii
        string << "#{ascii_separator}#{ascii_line}"
        ascii_line = ''
      end
      string << line_separator

    # If we're at a word junction then output the word_separator
    elsif (byte_offset % word_size == 0) and byte_offset != self.length
      string << word_separator
    end
  end

  # We're done printing all the bytes. Now check to see if we ended in the
  # middle of a line. If so we have to print out the final ASCII if
  # requested.
  if byte_offset % bytes_per_line != 0
    if show_ascii
      num_word_separators = ((byte_offset % bytes_per_line) - 1) / word_size
      existing_length = (num_word_separators * word_separator.length) + ((byte_offset % bytes_per_line) * 2)
      full_line_length = (bytes_per_line * 2) + ((words_per_line - 1) * word_separator.length)
      filler = ' ' * (full_line_length - existing_length)
      ascii_filler = ' ' * (bytes_per_line - ascii_line.length)
      string << "#{filler}#{ascii_separator}#{ascii_line}#{ascii_filler}"
      ascii_line = ''
    end
    string << line_separator
  end
  string
end