From: Rob Lee Date: 2006-10-23T20:05:52+09:00 Subject: Re: Binary file modification Ben Nagy wrote: >> -----Original Message----- >> From: list-bounce@example.com >> [mailto:list-bounce@example.com] On Behalf Of Rob Lee > [...] >> I've been reading the content-length data from >> the file >> using something similar to : >> >> f=open(config[:file],"rb") >> f.pos=AUDIO_CONTENT_HEADER_OFFSET >> length=f.read(3).unpack("H2H2H2").hex.to_i > > That should die because Array#hex doesn't exist, but I get the idea. If > you > do this kind of thing a lot with different kinds of data then you should > note that to_i and to_s both take optional base arguments, so > foo.unpack('H*').first.to_i(16) should work Thanks for pointing that out, it's strange as the code definately works (it returns correct content lengths repeatedly for different files) but as you say Array#hex doesn't exist - I'll look into this ... > > [...] >> I'd like to be able to reverse this process and take any an integer >> value (1024 in the case shown below) and write it to a binary >> file with >> some header and footer data - something like : > [...] >> mydata += ["1024"].pack("someformat") > [...] >> However I'm a bit stuck on how to pack the data (if this is >> the correct >> solution). > > Here's the problem - if you need exactly three bytes then you are going > to > have to apply your own padding, since the pack routines will only pack > directly as a long or a short which will mostly be 4 and 2 bytes - both > of > which could cause you problems. My hacks always involve <<'ing a single > byte > integer onto a string. In your case, here is a horrible oneliner which > you > should not use because it is gross. > > num=1024 > num.to_s(16)[0..2].instance_eval {(self.reverse + '0' * (6 - > self.length)).reverse}.scan(/../).inject('') {|s,byte| s << > byte.to_i(16)} > I'm intrigued by this, I can see you are repacking the int value into three bytes but I'm still unclear as to how you would then add this to the file. I guess it needs to be packed as 3 bytes - my guess was num=1024 newpacket += [num].pack("3C") However this doesn't seem to work using the reading scheme above. Could you tell me where I'm going wrong ? > You could also try googling BitStruct, which is a ruby library that > might > help by defining these headers and footers as structure objects. > I'm looking at using bitstruct for the next version of the project, but as I've almost got this working now I'd like to avoid a re-write at this stage if possible ! > Cheers, > > ben Thanks for all the help - you've saved me hours of work already ! -- Posted via http://www.ruby-forum.com/.