diff --git a/spec/ruby/core/io/set_encoding_by_bom_spec.rb b/spec/ruby/core/io/set_encoding_by_bom_spec.rb index c551042beea3..4239fbf0768e 100644 --- a/spec/ruby/core/io/set_encoding_by_bom_spec.rb +++ b/spec/ruby/core/io/set_encoding_by_bom_spec.rb @@ -67,5 +67,11 @@ -> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding is set to UTF-8 already') end + + it 'returns exception if encoding conversion is already set' do + @io.set_encoding(nil, Encoding::UTF_8) + + -> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding conversion is set') + end end end diff --git a/spec/tags/core/io/set_encoding_by_bom_tags.txt b/spec/tags/core/io/set_encoding_by_bom_tags.txt deleted file mode 100644 index 301ccace30c7..000000000000 --- a/spec/tags/core/io/set_encoding_by_bom_tags.txt +++ /dev/null @@ -1,8 +0,0 @@ -fails:IO#set_encoding_by_bom returns the result encoding if found BOM UTF-8 sequence -fails:IO#set_encoding_by_bom returns the result encoding if found BOM UTF_16LE sequence -fails:IO#set_encoding_by_bom returns the result encoding if found BOM UTF_16BE sequence -fails:IO#set_encoding_by_bom returns nil if found BOM sequence not provided -fails:IO#set_encoding_by_bom returns exception if io not in binary mode -fails:IO#set_encoding_by_bom returns exception if encoding already set -fails:IO#set_encoding_by_bom returns the result encoding if found BOM UTF_32LE sequence -fails:IO#set_encoding_by_bom returns the result encoding if found BOM UTF_32BE sequence diff --git a/src/main/ruby/truffleruby/core/io.rb b/src/main/ruby/truffleruby/core/io.rb index f7efc581e808..29397b883246 100644 --- a/src/main/ruby/truffleruby/core/io.rb +++ b/src/main/ruby/truffleruby/core/io.rb @@ -2158,6 +2158,25 @@ def set_encoding(external, internal=nil, options=undefined) self end + def set_encoding_by_bom + unless binmode? + raise ArgumentError, 'ASCII incompatible encoding needs binmode' + end + + if internal_encoding + raise ArgumentError, 'encoding conversion is set' + end + + if external_encoding && external_encoding != Encoding::ASCII_8BIT + raise ArgumentError, "encoding is set to #{external_encoding} already" + end + + external = strip_bom + if external + @external = Encoding.find(external) + end + end + private def strip_bom mode = Truffle::POSIX.truffleposix_fstat_mode(Primitive.io_fd(self)) return unless Truffle::StatOperations.file?(mode)