本人纯java程序员,最近看了论坛的作品后对lua非常感兴趣。因为看游泳的鱼的代码中提到“lua本身对二进制文件处理的支持不够”,又碰巧看到了lua中进行这种操作的代码,顺手kiang了过来。我本人对各位大虾非常敬仰,纯学术研究而已。实际上这是我第一段正式的lua程序,大家见笑。私下里的意思是,希望lua的代码越多越好,C的代码越少越好,因为我不会VC,至今不知道哪里能下载到VC6。
local create = Byte.create;
Byte.create = function(size)
local str = {};
str.value = string.rep(string.char(0), size);
return str;
end
local bloadfile = Byte.loadfile;
Byte.loadfile = function(b,filename,start,length)
local INF = assert(io.open(filename, "rb"));
local _;
_, b.value = INF:read(start, length);
io.close(INF);
end
local savefile = Byte.savefile;
Byte.savefile = function(b,filename,start,length)
local INF = assert(io.open(filename, "rb"));
local _previous, _, _next = INF:read(start, length, "*all");
io.close(INF);
INF = assert(io.open(filename, "wb"));
INF:write(_previous or "", b.value , string.rep(string.char(0), length - string.len(b.value)), _next or "");
io.close(INF);
end
local cache = {};
local getnum = function(b,start, size, unsign)
local str = string.sub(b.value, start + 1, start + size);
if not cache[str] then
local sum = 0
for i = size, 1, -1 do
sum = sum * 256 + string.byte(str, i)
end
-- test for negative number
if not unsign and string.byte(str, size) > 127 then
sum = sum - math.ldexp(1, 8 * size)
end
cache[str] = sum;
end
return cache[str];
end
local setnum = function(b,start,va, size, unsign)
local v = ""
local x = math.floor(va);
if unsign or x >= 0 then
for i = 1, size do
v = v..string.char(x % 256); x = math.floor(x / 256)
end
else-- x < 0
x = -x
local carry = 1
for i = 1, size do
local c = 255 - (x % 256) + carry
if c == 256 then c = 0; carry = 1 else carry = 0 end
v = v..string.char(c); x = math.floor(x / 256)
end
end
b.value = string.sub(b.value, 1, start).. v ..string.sub(b.value, start + size + 1)
end
local get16 = Byte.get16;
Byte.get16 = function(b,start)
return getnum(b,start,2);
end
local set16 = Byte.set16;
Byte.set16 = function(b,start,v)
setnum(b,start,v, 2);
end
local getu16 = Byte.getu16;
Byte.getu16 = function(b,start)
return getnum(b,start,2, true);
end
local setu16 = Byte.setu16;
Byte.setu16 = function(b,start,v)
setnum(b,start,v, 2, true);
end
local get32 = Byte.get32;
Byte.get32 = function(b,start)
return getnum(b,start,4);
end
local set32 = Byte.set32;
Byte.set32 = function(b,start,v)
setnum(b,start,v, 4);
end
local getstr = Byte.getstr;
Byte.getstr = function(b,start,length)
return string.sub(b.value,start + 1, start + length);
end
local setstr = Byte.setstr;
Byte.setstr = function(b,start,length,str)
b.value = string.sub(b.value, 1, start).. string.sub(str, 1, length) ..string.sub(b.value, start + length + 1)
end
运行方法是加到jymodify.lua的SetModify函数里,只在JY_SDL_Lua_0.6_release上测过,如果没什么变化其他版本应该也可以吧。
附件是我自己测试的小文件,可以用 "lua5.1 jyelse.lua"单独测试。
要注意的是测试的时候那个文件(名字就是"filename")得自己先建好,哪怕是空的也行。没有文件的话,lua会报错。暂时没查到lua怎么检测文件时候存在和touch文件的方法,大虾们可以给我指条明路。如果os.execute的话可以做到,但是要和系统不相关的话估计很难。
深入讨论的话,有一点是里面的getnum我加了缓存,不知道时间长了会不会内存溢出,一开始的写法如下
local getnum = function(b,start, size, unsign)
local sum = 0
for i = size, 1, -1 do
sum = sum * 256 + string.byte(b.value, start + i)
end
-- test for negative number
if not unsign and string.byte(b.value, start + size) > 127 then
sum = sum - math.ldexp(1, 8 * size)
end
return sum
end
大同小异了。
其实可以评测一下原版,lua版,不加缓存lua版的性能哪个好一些,暂时没有做。
|