require 'ndr_support/utf8_encoding' module UTF8Encoding # Allows any supported object to have control characters # escaped, using standard replacement scheme. module ControlCharacters # The range of characters we consider: CONTROL_CHARACTERS = /[\x00-\x1f]|\x7f/ # Exceptions that are allowed: ALLOWED_CONTROL_CHARACTERS = %W( \x09 \x0a \x0d ) # Recursively escape any control characters in `object`. def escape_control_chars_in_object!(object) case object when String escape_control_chars!(object) when Hash escape_control_chars_in_hash!(object) when Array escape_control_chars_in_array!(object) else object end end # Returns a copy of `string`, with any control characters escaped. def escape_control_chars(string) escape_control_chars!(string.dup) end # Escapes in-place any control characters in `string`, before returning it. def escape_control_chars!(string) string.gsub!(CONTROL_CHARACTERS) do |character| if ALLOWED_CONTROL_CHARACTERS.include?(character) character else UTF8Encoding::REPLACEMENT_SCHEME[character] end end string end # Escape control characters in values of the given `hash`. def escape_control_chars_in_hash!(hash) hash.each_value { |value| escape_control_chars_in_object!(value) } end # Escape control characters in elements of the given `array`. def escape_control_chars_in_array!(array) array.each { |element| escape_control_chars_in_object!(element) } end end end