Wednesday, January 25, 2012
99 ways to program a hex, Part 17: Lua, recursion, runtime type checking
Since Lua is a dynamically typed language (“values have types, not variables”) we can check the type of a variable at runtime and behave accordingly. Before, we were restricted with just dumping a file, but we could also dump strings (which in Lua can be pure binary data). So today's version checks what type the input is; if it's a file, we read data from there, otherwise if the input is a string, we pull the next blob of data out of it.
Granted, we don't actually use that feature here, but we can
more easily reuse do_dump()
elsewhere.
#!/usr/bin/env lua -- *************************************************************** -- -- Copyright 2010 by Sean Conner. All Rights Reserved. -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. -- -- Comments, questions and criticisms can be sent to: sean@conman.org -- -- ******************************************************************** -- Style: Lua 5.1, recursion, runtime type checking function do_dump(fpin,fpout,offset) local line if type(fpin) == 'string' then if offset > string.len(fpin) then return end line = fpin:sub(offset + 1,offset + 16) else line = fpin:read(16) if line == nil then return end end fpout:write( string.format("%08X: ",offset), line:gsub(".",function(c) return string.format("%02X ",c:byte()) end), string.rep(" ",3 * (16 - line:len())), line:gsub("%c","."), "\n" ) return do_dump(fpin,fpout,offset + 16) end -- ********************************************************************** if #arg == 0 then print("-----stdin-----") do_dump(io.stdin,io.stdout,0) else for i = 1 , #arg do local f = io.open(arg[1],"r") io.stdout:write("-----",arg[1],"-----","\n") do_dump(f,io.stdout,0) f:close() end end os.exit(0)