Byte[] to ruby string

Hello,

I’m struggling with converting a byte array into a ruby binary string.
Does anybody know how to make something like this pass?

require ‘test/unit’
include System::IO
class Binstring < Test::Unit::TestCase

def test_binstring_bytea
fileName = ‘flowers.jpg’

 #Ruby way
 data1 = File.read(fileName)

 #.Net
 fs = FileStream.new(fileName, FileMode.Open, FileAccess.Read);
 br = BinaryReader.new(fs);
 numBytes = FileInfo.new(fileName).Length;
 buff = br.ReadBytes(numBytes);
 data2 = System::Text::ASCIIEncoding.new.GetString(buff).to_s

 assert data1 == data2

end

end

Regards,

Håkon


Håkon Clausen
Nosyko AS

“Nobody will ever need more than 640k RAM!” - Bill Gates, 1981.

File.open(filename, 'rb:BINARY) { |f| f.read } might help not sure
though.

You can also look into the unpack method of a string that is used for
returning a bunch of different serialization formats.
http://www.ruby-doc.org/core/classes/String.html#M000760


Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

I don’t even get that far. When I do a File.read or a
System::IO::File.read_all_bytes from IronRuby (iirb.exe), I get this
(works OK in MRI):

C:>iirb
irb(main):001:0> File.read(“c:\temp\clickhere.png”)
File.read(“c:\temp\clickhere.png”)
IOError: Not enough storage is available to process this command.

    from mscorlib:0:in `WinIOError'
    from mscorlib:0:in `Write'
    from :0:in `write'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:302:in `output_value'
    from :0:in `printf'
    from :0:in `printf'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:151:in `eval_input'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:263:in `signal_status'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:147:in `eval_input'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:146:in `eval_input'
    from :0:in `loop'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:70:in `start'
    from c:/IronRuby/lib/ruby/1.8/irb.rb:69:in `start'
    from :0:in `catch'
    from c:/IronRuby/bin/iirb:13
    from :0:in `catch'

irb(main):002:0>

you can just skip my email… I tried my things now and none of them
work.

Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

On Fri, Oct 23, 2009 at 12:13 AM, Nathan Stults
<[email protected]

The current implementation of to_s is inherited from IList because
byte[] implements IList interface:

a = System::Array[System::Byte].new(10)
=> [0 (Byte), 0 (Byte), 0 (Byte), 0 (Byte), 0 (Byte), 0 (Byte), 0
(Byte), 0 (Byte), 0 (Byte), 0 (Byte)]
a.to_s
=> “0000000000”
a.method(:to_s)
=> #<Method: System::Byte#to_s>
a.method(:to_s).clr_members
=> [IronRuby.Builtins.MutableString
Join(IronRuby.Runtime.ConversionStorage`1[IronRuby.Builtins.MutableString],
System.Collections.IList)]

Which is not very useful for byte[]. However to keep this consistent
with other arrays it’s better to keep it as is.
To enable creating strings from byte[] I’ll add an overload to
String.new that takes a byte[].

a = System::Array[System::Byte].new(10)
=> [0 (Byte), 0 (Byte), 0 (Byte), 0 (Byte), 0 (Byte), 0 (Byte), 0
(Byte), 0 (Byte), 0 (Byte), 0 (Byte)]
a[4] = ?A
=> 65
String.new(a)
=> “\000\000\000\000A\000\000\000\000\000”

You can also go to MutableString class directly like so:

String.CreateBinary(a)
=> “\000\000\000\000A\000\000\000\000\000”

or

String.CreateBinary().Append(a, 3, 3)
=> “\000A\000”

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Ivan Porto
Carrero
Sent: Thursday, October 22, 2009 4:14 PM
To: [email protected]
Subject: Re: [Ironruby-core] byte[] to ruby string

you can just skip my email… I tried my things now and none of them
work.


Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

On Fri, Oct 23, 2009 at 12:13 AM, Nathan Stults
<[email protected]mailto:[email protected]> wrote:
I don’t even get that far. When I do a File.read or a
System::IO::File.read_all_bytes from IronRuby (iirb.exe), I get this
(works OK in MRI):

C:>iirb
irb(main):001:0> File.read(“c:\temp\clickhere.png”)
File.read(“c:\temp\clickhere.png”)
IOError: Not enough storage is available to process this command.

   from mscorlib:0:in `WinIOError'
   from mscorlib:0:in `Write'
   from :0:in `write'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:302:in `output_value'
   from :0:in `printf'
   from :0:in `printf'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:151:in `eval_input'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:263:in `signal_status'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:147:in `eval_input'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:146:in `eval_input'
   from :0:in `loop'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:70:in `start'
   from c:/IronRuby/lib/ruby/1.8/irb.rb:69:in `start'
   from :0:in `catch'
   from c:/IronRuby/bin/iirb:13
   from :0:in `catch'

irb(main):002:0>

Thanks,
CreateBinary made the picture file pass the test.
I’m having some trouble with some plain text and newlines. Any idea why
“test_3” don’t pass?

require ‘test/unit’
include System::IO
class Binstring < Test::Unit::TestCase

def test_1
fileName = ‘flowers.jpg’

 #Ruby
 data1 = File.read(fileName)

 #.Net
 fs = FileStream.new(fileName, FileMode.Open, FileAccess.Read)
 br = BinaryReader.new(fs)
 numBytes = FileInfo.new(fileName).Length
 buff = br.ReadBytes(numBytes)
 data2 = String.CreateBinary(buff)

 assert data1 == data2

end

def test_2
fileName = ‘flowers.jpg’

 #Ruby
 data1 = File.read(fileName)

 #.Net
 fs = FileStream.new(fileName, FileMode.Open, FileAccess.Read)
 data2 = "".Append(fs, fs.length)

 assert data1 == data2

end

def test_3
data0 = “This is a test\n”
File.open(‘test.txt’, ‘w’) {|f| f.write(data0) }
data1 = File.read(‘test.txt’)
fs = FileStream.new(‘test.txt’, FileMode.Open, FileAccess.Read)
br = BinaryReader.new(fs)
numBytes = FileInfo.new(‘test.txt’).Length
buff = br.ReadBytes(numBytes)
data2 = String.CreateBinary(buff)

 assert_equal data0, data1
 assert_equal data0, data2
 assert_equal data1, data2

end
end


Loaded suite binstring
Started
…F
Finished in 0.46875 seconds.

  1. Failure:
    test_3(Binstring)
    [binstring.rb:45:in test_3' c:/Ironruby/lib/IronRuby/test/unit/testcase.rb:79:inrun’
    :0:in send' testrunner.rb:66:instart_mediator’
    :0:in `each’]:
    <“This is a test\n”> expected but was
    <“This is a test\r\n”>.

3 tests, 4 assertions, 1 failures, 0 errors

On Fri, 23 Oct 2009 03:56:38 +0200, Tomas M.

In this particular case, I would recommend to use .NET API:

include System::IO
=> Object

stream = FileStream.new(“c:\temp\a.txt”, FileMode.Open, FileAccess.Read)
=> System.IO.FileStream

“”.Append(stream, stream.Length)
=> “hello”

Tomas

<“This is a test\n”> expected but was
<“This is a test\r\n”>.
windows default is to use CRLF for a new line and the CLR inherits that
But for ruby the new line constant is a LF which ruby inherits from *nix
based systems

the dirty workaround is

either specify data0 = “This is a test\r\n”
or
data1.gsub! /\n/, “\r\n”
or
data2.gsub! /\r\n/, “\n”

AFAIK there is no way to override the Environment.NewLine constant in a
way
the CLR will pick it up.


Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

You need to use ‘wb’ mode to prevent Ruby from transforming eolns.

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Ivan Porto
Carrero
Sent: Friday, October 23, 2009 5:47 AM
To: [email protected]; [email protected]
Subject: Re: [Ironruby-core] byte[] to ruby string

<“This is a test\n”> expected but was
<“This is a test\r\n”>.

windows default is to use CRLF for a new line and the CLR inherits that
But for ruby the new line constant is a LF which ruby inherits from *nix
based systems

the dirty workaround is

either specify data0 = “This is a test\r\n”
or
data1.gsub! /\n/, “\r\n”
or
data2.gsub! /\r\n/, “\n”

AFAIK there is no way to override the Environment.NewLine constant in a
way the CLR will pick it up.


Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

On Fri, Oct 23, 2009 at 2:31 PM, HÃ¥kon Clausen
<[email protected]mailto:[email protected]> wrote:
Thanks,
CreateBinary made the picture file pass the test.
I’m having some trouble with some plain text and newlines. Any idea why
“test_3” don’t pass?

require ‘test/unit’
include System::IO
class Binstring < Test::Unit::TestCase
def test_1
fileName = ‘flowers.jpg’

Ruby

data1 = File.read(fileName)

#.Net
fs = FileStream.new(fileName, FileMode.Open, FileAccess.Read)
br = BinaryReader.new(fs)
numBytes = FileInfo.new(fileName).Length
buff = br.ReadBytes(numBytes)
data2 = String.CreateBinary(buff)

assert data1 == data2
end

def test_2
fileName = ‘flowers.jpg’

Ruby

data1 = File.read(fileName)

#.Net
fs = FileStream.new(fileName, FileMode.Open, FileAccess.Read)
data2 = “”.Append(fs, fs.length)

assert data1 == data2
end

def test_3
data0 = “This is a test\n”
File.open(‘test.txt’, ‘w’) {|f| f.write(data0) }
data1 = File.read(‘test.txt’)
fs = FileStream.new(‘test.txt’, FileMode.Open, FileAccess.Read)
br = BinaryReader.new(fs)
numBytes = FileInfo.new(‘test.txt’).Length
buff = br.ReadBytes(numBytes)
data2 = String.CreateBinary(buff)

assert_equal data0, data1
assert_equal data0, data2
assert_equal data1, data2
end
end


Loaded suite binstring
Started
…F
Finished in 0.46875 seconds.

  1. Failure:
    test_3(Binstring)
    [binstring.rb:45:in `test_3’
    c:/Ironruby/lib/IronRuby/test/unit/testcase.rb:79:in `run’
    :0:in `send’
    testrunner.rb:66:in `start_mediator’
    :0:in `each’]:
    <“This is a test\n”> expected but was
    <“This is a test\r\n”>.

3 tests, 4 assertions, 1 failures, 0 errors

On Fri, 23 Oct 2009 03:56:38 +0200, Tomas M.
<[email protected]mailto:[email protected]>
wrote:
In this particular case, I would recommend to use .NET API:
include System::IO
=> Object
stream = FileStream.new(“c:\temp\a.txt”, FileMode.Open,
FileAccess.Read)
=> System.IO.FileStream
“”.Append(stream, stream.Length)
=> “hello”

Tomas


Ironruby-core mailing list
[email protected]mailto:[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core