parse binary of an file in lua

Viewed 380

i need your help. Ive got an file with binary in it. I know that one packet starts with 0x7E. I want to have one big table of the file and then split the table into tables which each table starts with 0x7E. I now started with converting the binary into hex and worked with that but i think it would be easier to work with binary but i do not know how to do this. For example a line of the binary file:

I already can read in the file, convert it to hex and find the amount of 0x7E in the file. Plus the length of the file. But the amount and the length is not nessesary. Also i think working with strings is wrong because of the bytelength.Can you help me parsing the file? I also thought about using a callback function but i dont know how to do it. I am new to this. Thats my code at the moment:

local function read_file(path) --function read_file
 local file = io.open(path, "rb") -- r read mode and b binary mode
 if not file then return nil end
 local content = file:read "*all" -- *all reads the whole file
 file:close()
 return content
end

function string.tohex(str)
 return (str:gsub('.',function(c)
  return string.format('%02X',string.byte(c))
 end))
end

local fileContent = read_file("H:/wireshark/rstp_dtc_0.dat"); --passes file content to function read_file
inhalt = (fileContent):tohex()

s=inhalt
t={}
for k in s:gmatch"(%x%x)" do 
 table.insert(t,tonumber(k,16))
end 

function tablelength(T)
 local count = 0
 for _ in pairs (T) do count = count +1 end 
 return count 
end 

length = tablelength(t)
print(length)

counter = 0

local items = t
for _, v in pairs(items) do 
 if v == 0x7E then   
  counter = counter+1
 end 
end 

print(counter)

Thank you for your help!

2 Answers

A solution is to use string.gmatch to extract substrings from your file content that begin with "\x7e"

local packets = {}
for packetstr in data:gmatch("\x7e[^\x7e]+") do
  table.insert(packets, {packetstr:byte(1, #packetstr)})
end

That way you can use the pattern matching facilities of Lua so you don't have to write your own packet logic.

I found another answer for my question.

function print_table(tab)
 print("Table:") 
  for key, value in pairs(tab) do
      io.write(string.format("%02X ", value))  
  end
 print("\n") 
end

local function read_file(path, callback) 
 local file = io.open(path, "rb") 
  if not file then 
     return nil
  end
 local t = {} 
 repeat
    local str = file:read(4 * 1024)   
    for c in (str or ''):gmatch('.') do  
        if c:byte() == 0x7E then 
            callback(t) -- function print_table
            t = {}
        else
            table.insert(t, c:byte())  
        end
    end
 until not str
 file:close() 
 return t 
 end

local result = {}
function add_to_table_of_tables(t)
 table.insert(result, t) 
end

local fileContent = read_file("file.dat", print_table)
Related