File.open( "binary.bin", "wb" ) do |io|
obj = BinData::String.new(:initial_value => "Binary file start-point").write(io)
obj = BinData::Uint32be.new(:initial_value => 0).write(io)
obj = BinData::Bit16.new(:initial_value => 0).write(io)
obj = BinData::Uint24be.new(:initial_value => @fragments.size).write(io)
for fragment in @fragments do
obj = BinData::Uint8be.new(:initial_value => fragment.encoding).write(io)
obj = BinData::Uint8be.new(:initial_value => fragment.atype).write(io)
obj = BinData::String.new(:initial_value => fragment.content).write(io)
end
end
Refactorings
No refactoring yet !
Martin Plöger
March 5, 2010, March 05, 2010 20:51, permalink
I don't know much about binary-files. Hope, my solution works and is not too cryptic.
I put each Type and the corresponding data in an Array. So I can call the #new-method and hand in the value at the end.
Hope this gives rise to some more succinct and more readable solutions... I don't know BinData at all.
BTW: You don't need to assign and reassign the obj-variable each time.
File.open 'binary.bin', 'wb' do |file|
b = BinData
head = b::String, 'Binary file start-point', b::Uint32be, 0, b::Bit16,0, b::Uint24be, @fragments.size
data = @fragments.collect { |f| [b::Uint8be, f.encoding, b::Uint8be, f.atype, b::String, f.content] }.flatten
(head + data).each_slice(2) {|type, value| type.new(:initial_value => value).write file }
end
podcaster
March 11, 2010, March 11, 2010 07:38, permalink
Hi, thanks so much for the re-factoring. Everything worked fine. However I'm struggling to adapt one loop I didn't actually mention.
This one:
@@offset = 0
@fragments.each do |fragment|
obj = BinData::Uint32be.new(:initial_value => fragment.id).write(io)
obj = BinData::Uint32be.new(:initial_value => @@offset).write(io)
@@offset = @@offset + fragment.content.size + 2
end
Introducing the offset value change for each fragment iteration causes the problem. I can't get the correct offset value when I try to create a similar loop.
podcaster
March 11, 2010, March 11, 2010 13:18, permalink
I managed to fix the offset issue with the code below. Not sure if it is optimal though.
headerloop = @fragments.enum_for(:each_with_index).collect { |f, i| [b::Uint32be, f.id, b::Uint32be, offset((f.content.size) ,i)]}.flatten
#Then calculating the offset outside that block
@@lastOffset = 0
def offset(value, index)
@@offset += @@lastOffset
@@lastOffset = value + 2
return @@offset
end
Hi, I'm currently using Bindata gem to create a binary file. I think my code could be improved, probably in two ways. One way would be to make more general use of write(io). Other way could probably make a more advanced use of the Bindata features. I would appreciate any hints how to improve my current piece of code.
Cheers.