[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Newbie question - how to write out specific bytes to an IO stream?

Collin VanDyck

11/7/2007 12:42:00 AM

Hello -- I'm trying to write out specific byte sequences over the
wire / to a file / etc. Let's say for example that I wanted to write
out

99 111 108 108 105 110

as a simple, six byte sequence to a file. In Java, I might use the
byte primitive, but it seems that in Ruby you have Fixnum and then a
Float for fractions. If I simply create a Fixnum using the 99
literal, I think that that will create more than an 8-bit sequence
when I write out to the file.

Any ideas on how to do this?

6 Answers

Todd Benson

11/7/2007 1:32:00 AM

0

On 11/6/07, Collin VanDyck <gluedtomyseat@gmail.com> wrote:
> Hello -- I'm trying to write out specific byte sequences over the
> wire / to a file / etc. Let's say for example that I wanted to write
> out
>
> 99 111 108 108 105 110
>
> as a simple, six byte sequence to a file. In Java, I might use the
> byte primitive, but it seems that in Ruby you have Fixnum and then a
> Float for fractions. If I simply create a Fixnum using the 99
> literal, I think that that will create more than an 8-bit sequence
> when I write out to the file.
>
> Any ideas on how to do this?

String objects are arrays of bytes, so you could simply do...

num_string = "99 111 108 108 105 110"
byte_string = num_string.split.map! {|word| word.to_i.chr}.join

# Now, to illustrate...

byte_string.class
# gives String

byte[0]
# gives 99, the base 10 representation of 1100011
# note that each byte can store numbers up to 255

puts byte_string
# gives collin

If you want to store the 1's and 0's as a text string, you can use the
Integer#to_s(2) method.

hth,
Todd

yermej

11/7/2007 1:51:00 AM

0

On Nov 6, 6:42 pm, Collin VanDyck <gluedtomys...@gmail.com> wrote:
> Hello -- I'm trying to write out specific byte sequences over the
> wire / to a file / etc. Let's say for example that I wanted to write
> out
>
> 99 111 108 108 105 110
>
> as a simple, six byte sequence to a file. In Java, I might use the
> byte primitive, but it seems that in Ruby you have Fixnum and then a
> Float for fractions. If I simply create a Fixnum using the 99
> literal, I think that that will create more than an 8-bit sequence
> when I write out to the file.
>
> Any ideas on how to do this?

I *think* you'll want to use Array#pack. E.g., to write them out in
big-endian order:

> a = [99, 111, 108, 108, 105, 110].pack 'n*'
=> "\000c\000o\000l\000l\000i\000n"
> file.write a

If you want little-endian, use 's*' (or 'S*' for unsigned) instead of
'n*'. See http://ruby-doc... and check Array#pack for more
details on the directives.

Todd Benson

11/7/2007 2:27:00 AM

0

On 11/6/07, yermej <yermej@gmail.com> wrote:
> On Nov 6, 6:42 pm, Collin VanDyck <gluedtomys...@gmail.com> wrote:
> > Hello -- I'm trying to write out specific byte sequences over the
> > wire / to a file / etc. Let's say for example that I wanted to write
> > out
> >
> > 99 111 108 108 105 110
> >
> > as a simple, six byte sequence to a file. In Java, I might use the
> > byte primitive, but it seems that in Ruby you have Fixnum and then a
> > Float for fractions. If I simply create a Fixnum using the 99
> > literal, I think that that will create more than an 8-bit sequence
> > when I write out to the file.
> >
> > Any ideas on how to do this?
>
> I *think* you'll want to use Array#pack. E.g., to write them out in
> big-endian order:
>
> > a = [99, 111, 108, 108, 105, 110].pack 'n*'
> => "\000c\000o\000l\000l\000i\000n"
> > file.write a
>
> If you want little-endian, use 's*' (or 'S*' for unsigned) instead of
> 'n*'. See http://ruby-doc... and check Array#pack for more
> details on the directives.

Hmm, I was thinking about #pack, but your example creates 12 bytes.

Collin VanDyck

11/7/2007 2:33:00 AM

0

Thank you for your replies!

Both methods seem to work equally well, but I'm seeming to favor the
pack method because i can just push in my random bytes (0-255) into an
array. I decided to use pack "C*" though, because I think that the C*
directive will limit the packed members to 8 bits, if I'm not mistaken.

Todd Benson

11/7/2007 3:24:00 AM

0

On 11/6/07, Collin VanDyck <gluedtomyseat@gmail.com> wrote:
> Thank you for your replies!
>
> Both methods seem to work equally well, but I'm seeming to favor the
> pack method because i can just push in my random bytes (0-255) into an
> array. I decided to use pack "C*" though, because I think that the C*
> directive will limit the packed members to 8 bits, if I'm not mistaken.

Good choice!

Todd

Alex Young

11/7/2007 10:29:00 AM

0

Todd Benson wrote:
> On 11/6/07, yermej <yermej@gmail.com> wrote:
>> On Nov 6, 6:42 pm, Collin VanDyck <gluedtomys...@gmail.com> wrote:
>>> Hello -- I'm trying to write out specific byte sequences over the
>>> wire / to a file / etc. Let's say for example that I wanted to write
>>> out
>>>
>>> 99 111 108 108 105 110
>>>
>>> as a simple, six byte sequence to a file. In Java, I might use the
>>> byte primitive, but it seems that in Ruby you have Fixnum and then a
>>> Float for fractions. If I simply create a Fixnum using the 99
>>> literal, I think that that will create more than an 8-bit sequence
>>> when I write out to the file.
>>>
>>> Any ideas on how to do this?
>> I *think* you'll want to use Array#pack. E.g., to write them out in
>> big-endian order:
>>
>>> a = [99, 111, 108, 108, 105, 110].pack 'n*'
>> => "\000c\000o\000l\000l\000i\000n"
>>> file.write a
>> If you want little-endian, use 's*' (or 'S*' for unsigned) instead of
>> 'n*'. See http://ruby-doc... and check Array#pack for more
>> details on the directives.
>
> Hmm, I was thinking about #pack, but your example creates 12 bytes.
>
That's because n isn't the code for a byte - you want c or C, for signed
or unsigned char:

irb(main):004:0> a = [1, 2, 3, 4, 5, 6].pack 'C*'
=> "\001\002\003\004\005\006"

--
Alex