From: Robert Klemme Date: 2005-12-20T18:22:47+09:00 Subject: Re: Better way to read data from IO into packets? Levin Alexander wrote: > On 12/18/05, Joel VanderWerf wrote: > >>> I have a small program, that reads data from a serial port and chops >>> it into packets. A Packet has the following format: >>> >>> [0x65, 0xEB, , , , data:length>, >>> ] >> >> Why not read enough bytes to make sure you get the length byte: > > Because the application may be started in the middle of a packet or > the stream may be corrupted due to transmission errors. > > But you are right, I should optimize that and only read single bytes > if I need to resynchronize. > >> s = io.sysread(5) >> len = s[4] >> s << io.sysread(len+2) >> ary = s.unpack "C5a#{len}n" >> >> Or is the problem that there may be a variable number of "start >> bytes"? In that case, maybe you could tell from the first 5 bytes >> how many start bytes there are, and then read enough to capture the >> length byte. > > Hmm, maybe I can use regular expressions to check for the correct > format: > > buffer = "bad data" << [0x65,0xEB,0,4,65,66,67,68,00,00].pack("C*") > buffer.scan( / > \x65\xEB # startbytes > (.) # type > (.) # length-byte > (.*) # data > (..) # checksum > /x ) > > I would need a way to discard old or bad data from the buffer, > probably need to think about it more Why not just use a regexp to verify the initial sequence and use their offsets. Or do something like buffer.gsub!(/\A.*?(\x65\xEB)/, '\\1') > (btw: is there a way to use the length-byte in the regular expression > itself? Something like /(.)(.{\1})/) No. Kind regards robert