best DRY solution for this task

A

anansi

Hi,
I have a certain problem here and can't find a proper DRY solution for
this so I wondered if someone here has an idea and could help me.

I'm reading a file byte for byte. This file is structured and I try to
give out each structures element and the meaning of it. So let's pretend
the file content would be this in bytes (you get it e.g. with
file.read(7)): 1 3d 0 233 0 1 2f


now I wanna read the file byte for byte and output if the first 3 bytes
are equal 1 3d 0:
startflag : good (1 3d 0)
or if the check fails
startflag : bad (2 3d 0)
now the fourth byte is read and if it is 1
debg_mode : on
if it is 0 : out and if it is 233 : don't know ...


My problem with a DRY solution is that some bytes in this file are
grouped together and have just together a meaning as the first three
starting bytes: 1 3d 0 at the beginning and some bytes have alone a
meaning as the fourth byte 233 in the example.
And that everything has another ouput. So the first three bytes meaning
is another than the one of the fourt or the fifth byte.

My solution until now:


target = open('testfile.txt','r')

startflag = target.read(3)
print("startflag: ")
if startflag == $startflag # here I took a global var because
"\x13d0" didn't work
print(" good")
else
print(" bad")
end
startflag.each_byte do |x|
printf("%x ",x)
end
puts ""


dbg_mode = target.read(1)
printf("dbg_mode: ")
if dbg_mode == "\x1"
print(" on")
elseif dbg_mode == "\x255"
print("don't know")
else
print(" bad")
end
dbg_mode.each_byte {|x| printf("%x ",x) }
puts ""

and so on and on and on...

so how can I do this check and outputting better? Because there are many
bytes with many different meanings and as said sometimes I need to read
in 4 bytes then just one then again 2 bytes... is this at all possible
to do dry-like?

thanks
 
P

Phrogz

I'm reading a file byte for byte. This file is structured and I try to
give out each structures element and the meaning of it. So let's pretend
the file content would be this in bytes (you get it e.g. with
file.read(7)): 1 3d 0 233 0 1 2f

a) You might want to look into the BitStruct library.
b) See the following. It's up to you how much work you want to put in
the common 'eat' method, versus how much you want to leave up to the
proc for each particular matcher.

# Just for no-file testing
require 'stringio'
bytes = [ 1, 0x3d, 0, 233, 0, 1, 0x2f ]
byte_string = StringIO.new( bytes.map{ |b| b.chr }.join )

class ByteEater
def initialize( title, num_bytes, &block )
@title = title
@num_bytes = num_bytes
@proc = block
end
def eat( file )
bytes = file.read( @num_bytes )
print( "#@title: " )
@proc.call( bytes )
bytes.each_byte{ |x| print "%x" % x }
puts ""
end
end

structure = [
ByteEater.new( 'startflag', 3 ){ |bytes|
if bytes == "\01\x3d\0"
print " good"
else
print " bad"
end
},
ByteEater.new( 'dbg_mode', 1 ){ |bytes|
case bytes
when 1.chr
print " on"
when 255.chr
print "don't know"
else
print "bad"
end
},
]

structure.each{ |eater|
eater.eat( byte_string )
}

#=> startflag: good13d0
#=> dbg_mode: bade9
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top