2019-05-02 18:17:27 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-07-31 06:02:18 -04:00
|
|
|
require 'rchardet'
|
2018-07-27 13:41:53 -04:00
|
|
|
|
|
|
|
module Encodings
|
2018-07-31 06:02:18 -04:00
|
|
|
def self.to_utf8(string)
|
|
|
|
result = CharDet.detect(string)
|
2018-07-27 13:41:53 -04:00
|
|
|
|
2018-07-31 06:02:18 -04:00
|
|
|
encoded_string = try_utf8(string, result['encoding']) if result && result['encoding']
|
|
|
|
encoded_string = force_utf8(string) if encoded_string.nil?
|
|
|
|
encoded_string
|
2018-07-27 13:41:53 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.try_utf8(string, source_encoding)
|
|
|
|
encoded = string.encode(Encoding::UTF_8, source_encoding)
|
|
|
|
encoded&.valid_encoding? ? delete_bom!(encoded) : nil
|
|
|
|
rescue Encoding::InvalidByteSequenceError,
|
|
|
|
Encoding::UndefinedConversionError,
|
|
|
|
Encoding::ConverterNotFoundError
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2018-07-31 06:02:18 -04:00
|
|
|
def self.force_utf8(string)
|
|
|
|
encoded_string = string.encode(Encoding::UTF_8,
|
|
|
|
undef: :replace,
|
|
|
|
invalid: :replace,
|
|
|
|
replace: '')
|
|
|
|
delete_bom!(encoded_string)
|
|
|
|
end
|
|
|
|
|
2018-07-27 13:41:53 -04:00
|
|
|
def self.delete_bom!(string)
|
|
|
|
string.sub!(/\A\xEF\xBB\xBF/, '') unless string.blank?
|
|
|
|
string
|
|
|
|
end
|
|
|
|
end
|