Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Bitstuct and binary files

Reply
Thread Tools

Bitstuct and binary files

 
 
Rob Lee
Guest
Posts: n/a
 
      10-24-2006
Hi,

I've been working with modifying a binary file to replace some meta-data
included within. I've had some discussions previously
(http://www.ruby-forum.com/topic/85591) about this but couldn't get to a
satisfactory conclusion. Basically I need to encode an integer value
into 3 bytes as part of a binary file - Bitstruct was suggested as one
of the solutions, however I haven't been able to get it to work for
values larger than 1024 :

require 'bit-struct'

class Audio < BitStruct
signed :aheader, 8, :endian => :little
unsigned :alength, 3*8, :endian => :little
signed :afooter, 8, :endian => :little
end

audio = Audio.new
audio.aheader = 1
audio.alength = 3027
audio.afooter = 1
f = open("testfile","wb")
f.write(audio)
f.close
f = open("testfile","rb")
f.pos=0
puts f.read(1).unpack("c").first.to_s
puts f.read(3).unpack('H6').first.to_i(16)
puts f.read(1).unpack("c").first.to_s
f.close

In the application above, if the value of audio.alength is set to equal
or below 1024 then the output for f.read(3).unpack('H6').first.to_i(16)
matches, however if set above this then the value printed doesn't match.

Can anybody tell me why setting an audio.alength>=1024 breaks the output
and provide a way to fix it ...

Thanks

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Joel VanderWerf
Guest
Posts: n/a
 
      10-24-2006
Rob Lee wrote:
> puts f.read(3).unpack('H6').first.to_i(16)


I think you want 'h' instead of 'H', and you need to reverse the nibbles:

puts f.read(3).unpack('h6').first.reverse.to_i(16)

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

 
Reply With Quote
 
 
 
 
Ben Nagy
Guest
Posts: n/a
 
      10-24-2006
> -----Original Message-----
[...]
> Can anybody tell me why setting an audio.alength>=1024 breaks
> the output
> and provide a way to fix it ...


---borked---
num=359447
f.write(num.to_s(16)[0..2].instance_eval {(self.reverse + '0' * (6 -
self.length)).reverse}.scan(/../).inject('') {|s,byte| s <<
byte.to_i(16)})
---

My code is broken. Where I said [0..2] I meant [0..5], I added it in at the
last minute as an overflow check without testing - I was thinking 3 raw hex
bytes but the string after the conversion is a 6 byte 'friendly' hex string.

Sorry.

ben


 
Reply With Quote
 
Rob Lee
Guest
Posts: n/a
 
      10-24-2006
Joel VanderWerf wrote:
> Rob Lee wrote:
>> puts f.read(3).unpack('H6').first.to_i(16)

>
> I think you want 'h' instead of 'H', and you need to reverse the
> nibbles:
>
> puts f.read(3).unpack('h6').first.reverse.to_i(16)


Ah, OK that works with my example script - thanks. However, that means
the Bitstruct definition I gave is incorrect. The binary file I'm
trying to modify correctly unpacks the integer using :

f.read(3).unpack('H6').first.to_i(16)

However, I'm really confused over what the Bitstruct definition should
be to support this - do you have any suggestions ?

Thanks

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Rob Lee
Guest
Posts: n/a
 
      10-24-2006

>
> My code is broken. Where I said [0..2] I meant [0..5], I added it in at
> the
> last minute as an overflow check without testing - I was thinking 3 raw
> hex
> bytes but the string after the conversion is a 6 byte 'friendly' hex
> string.
>
> Sorry.
>
> ben


No problem ! I've just modified the code and it works great - thanks
I'm investigating bitstruct as well but it's always nice to have
alternatives ...

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Joel VanderWerf
Guest
Posts: n/a
 
      10-24-2006
Rob Lee wrote:
> Joel VanderWerf wrote:
>> Rob Lee wrote:
>>> puts f.read(3).unpack('H6').first.to_i(16)

>> I think you want 'h' instead of 'H', and you need to reverse the
>> nibbles:
>>
>> puts f.read(3).unpack('h6').first.reverse.to_i(16)

>
> Ah, OK that works with my example script - thanks. However, that means
> the Bitstruct definition I gave is incorrect. The binary file I'm
> trying to modify correctly unpacks the integer using :
>
> f.read(3).unpack('H6').first.to_i(16)
>
> However, I'm really confused over what the Bitstruct definition should
> be to support this - do you have any suggestions ?
>
> Thanks
>


Then probably your data is in big endian order--I should have grokked
that from your code. Try this:

class Audio < BitStruct
signed :aheader, 8
unsigned :alength, 3*8
signed :afooter, 8
end

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

 
Reply With Quote
 
Rob Lee
Guest
Posts: n/a
 
      10-24-2006
>
> Then probably your data is in big endian order--I should have grokked
> that from your code. Try this:
>
> class Audio < BitStruct
> signed :aheader, 8
> unsigned :alength, 3*8
> signed :afooter, 8
> end


Excellent - thank you. It all works - if you're interested I'm working
on a Ruby proxy for the Nabaztag (wifi bunny rabbit) and I'm trying to
extend some of it's audio capabilities

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Newbie: working with binary files/extract png from a binary file Jim Ruby 6 12-24-2013 08:09 AM
(8-bit binary to two digit bcd) or (8-bit binary to two digit seven segment) Fangs VHDL 3 10-26-2008 06:41 AM
Advantages of Binary Files over Text files in Search and read utab C++ 3 11-28-2006 03:09 PM
Uploading files with cgi - binary-files are truncated !? dermoon Python 0 10-08-2003 10:21 PM
Re: ostreams, ios::binary, endian, mixed binary-ascii Marc Schellens C++ 8 07-15-2003 12:27 PM



Advertisments