def check_encoding(str)
      if str.valid_encoding?
        # Get rid of the Unicode BOM if possible
        # Shortcut for UTF-8 which might be the majority case
        if str.encoding == Encoding::UTF_8
          return str.gsub(/\A\uFEFF/, '')
        elsif str.encoding.name =~ /^UTF-(16|32)(BE|LE)?$/
          return str.gsub(Regexp.new("\\A\uFEFF".encode(str.encoding)), '')
        else
          return str
        end
      end

      encoding = str.encoding
      newlines = Regexp.new("\r\n|\r|\n".encode(encoding).force_encoding(Encoding::ASCII_8BIT))
      str.force_encoding(Encoding::ASCII_8BIT).split(newlines).each_with_index do |line, i|
        begin
          line.encode(encoding)
        rescue Encoding::UndefinedConversionError => e
          yield <<MSG.rstrip, i + 1
Invalid #{encoding.name} character #{e.error_char.dump}
MSG
        end
      end
      return str
    end
def check_encoding(str)
      if str.valid_encoding?
        # Get rid of the Unicode BOM if possible
        # Shortcut for UTF-8 which might be the majority case
        if str.encoding == Encoding::UTF_8
          return str.gsub(/\A\uFEFF/, '')
        elsif str.encoding.name =~ /^UTF-(16|32)(BE|LE)?$/
          return str.gsub(Regexp.new("\\A\uFEFF".encode(str.encoding)), '')
        else
          return str
        end
      end

      encoding = str.encoding
      newlines = Regexp.new("\r\n|\r|\n".encode(encoding).force_encoding(Encoding::ASCII_8BIT))
      str.force_encoding(Encoding::ASCII_8BIT).split(newlines).each_with_index do |line, i|
        begin
          line.encode(encoding)
        rescue Encoding::UndefinedConversionError => e
          yield <<MSG.rstrip, i + 1
Invalid #{encoding.name} character #{e.error_char.dump}
MSG
        end
      end
      return str
    end
Checks that the encoding of a string is valid
 and cleans up potential encoding gotchas like the UTF-8 BOM.
 If it's not, yields an error string describing the invalid character
 and the line on which it occurs.

 @param str [String] The string of which to check the encoding
 @yield [msg] A block in which an encoding error can be raised.
   Only yields if there is an encoding error
 @yieldparam msg [String] The error message to be raised
 @return [String] `str`, potentially with encoding gotchas like BOMs removed