2019-05-03 06:17:27 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-07-31 18:02:18 +08:00
|
|
|
require "rchardet"
|
2018-07-28 01:41:53 +08:00
|
|
|
|
|
|
|
module Encodings
|
2018-07-31 18:02:18 +08:00
|
|
|
def self.to_utf8(string)
|
|
|
|
result = CharDet.detect(string)
|
2018-07-28 01:41:53 +08:00
|
|
|
|
2018-07-31 18:02:18 +08: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-28 01:41:53 +08: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 18:02:18 +08: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-28 01:41:53 +08:00
|
|
|
def self.delete_bom!(string)
|
2024-05-27 18:27:13 +08:00
|
|
|
string.sub!(/\A\xEF\xBB\xBF/, "") if string.present?
|
2018-07-28 01:41:53 +08:00
|
|
|
string
|
|
|
|
end
|
|
|
|
end
|