From 7094656723017cad8830751f4592544f4cdfd09d Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 3 Aug 2017 00:22:47 -0400 Subject: [PATCH] getting closer! --- BinRewrite.md | 18 ++--- rewritedata/bin/bits.lua | 1 + rewritedata/bin/extraBlocks.lua | 82 +++++++++++++++++++ rewritedata/bin/infinabits.lua | 1 + rewritedata/bin/init.lua | 22 +++-- rewritedata/test_Bin.lua | 137 ++++++++++++++++++++++++++++++++ 6 files changed, 240 insertions(+), 21 deletions(-) create mode 100644 rewritedata/bin/extraBlocks.lua create mode 100644 rewritedata/test_Bin.lua diff --git a/BinRewrite.md b/BinRewrite.md index f117985..05acd6e 100644 --- a/BinRewrite.md +++ b/BinRewrite.md @@ -1,7 +1,7 @@ # Bin Rewrite Progress! My vision for the bin library is to provide great and consistant support for binary minipulation... The old version was not consistant with how I wanted things to work. Great things to come! **Note: A lot breaks (Almost everything)** -Progress: [====- - - - - - 20% - - - - - - - - -] +Progress: [=====- - - - - 25% - - - - - - - - -] ### List of new methods - [x] bin.newFromBase64(data) - [x] bin.newFromBase91(data) @@ -31,7 +31,7 @@ Progress: [====- - - - - - 20% - - - - - - - - -] - [x] bin:tackE(data) -- tacks data onto the end of a file - [x] bin:tofile(path) - [ ] bin.loadVFS(path) -- [ ] bin:newDataBuffer(s) +- [x] bin:newDataBuffer(size,fill) - [ ] bin.bufferToBin(b) - [ ] bin.binToBuffer(b) - [ ] bin:getDataBuffer(a,b) @@ -40,19 +40,19 @@ Progress: [====- - - - - - 20% - - - - - - - - -] - [ ] bin.loadNamedBlock(path) - [ ] bin.namedBlockManager(arg) - [ ] bin.randomName(n,ext) -- [ ] bin.NumtoHEX(n) -- [ ] bin.HEXtoBin(s) -- [ ] bin.HEXtoStr(s) +- [ ] ~~bin.NumtoHEX(n)~~ +- [ ] ~~bin.HEXtoBin(s)~~ +- [ ] ~~bin.HEXtoStr(s)~~ - [x] bin.tohex(s) - [x] bin.fromhex(s) - [x] bin.endianflop(data) - [x] bin.getVersion() - [ ] bin.escapeStr(str) -- [ ] bin.ToStr(tab) -- [ ] bin.packLLIB(name,tab,ext) -- [ ] bin.unpackLLIB(name,exe,todir,over,ext) +- [ ] ~~bin.ToStr(tab)~~ +- [ ] ~~bin.packLLIB(name,tab,ext)~~ +- [ ] ~~bin.unpackLLIB(name,exe,todir,over,ext)~~ - [ ] ~~bin.fileExist(path)~~ NOW io.fileExists(path) -- [ ] bin.closeto(a,b,v) +- [ ] ~~bin.closeto(a,b,v)~~ - [ ] bin.textToBinary(txt) - [ ] bin.decodeBits(bindata) - [ ] bin.trimNul(s) diff --git a/rewritedata/bin/bits.lua b/rewritedata/bin/bits.lua index 675bf3d..21824ea 100644 --- a/rewritedata/bin/bits.lua +++ b/rewritedata/bin/bits.lua @@ -1,6 +1,7 @@ local bits={} bits.data='' bits.t='bits' +bits.Type='bits' bits.__index = bits bits.__tostring=function(self) return self.data end bits.__len=function(self) return (#self.data)/8 end diff --git a/rewritedata/bin/extraBlocks.lua b/rewritedata/bin/extraBlocks.lua new file mode 100644 index 0000000..85f7512 --- /dev/null +++ b/rewritedata/bin/extraBlocks.lua @@ -0,0 +1,82 @@ +bin.registerBlock("t",function(SIZE_OR_NIL,ref) + local header=ref:read(3) + if not header:match("(LT.)") then error("Not a valid table struct!") end + if bin.defualtBit.new(header:sub(3,3)):tonumber(1)~=0 then error("Incompatible Version of LuaTable!") end + local len=ref:getBlock("n",4) -- hehe lets make life easier + local tab={} + local ind + local n=0 + while true do + local it,dt=ref:read(2):match("(.)(.)") + n=n+2 + if it=="N" then -- get the index stuff out of the way first + ind=ref:getBlock("n",4) + n=n+4 + else + indL=ref:getBlock("n",1) + n=n+1+indL + ind=ref:read(indL) + end + if dt=="N" then + tab[ind]=ref:getBlock("n",4) + n=n+4 + elseif dt=="S" then + local nn=ref:getBlock("n",4) + tab[ind]=ref:read(nn) + n=n+4+nn + elseif dt=="B" then + tab[ind]=({["\255"]=true,["\0"]=false})[ref:read(1)] + n=n+1 + elseif dt=="F" then + local nn=ref:getBlock("n",4) + tab[ind]=loadstring(ref:read(nn)) + n=n+4+nn + elseif dt=="T" then + local cur=ref:getSeek() + local size=ref:getBlock("n",4) + ref:seekSet(cur) + ref:read(4) + local data=bin.new(ref:read(size)) + local dat=data:getBlock("t") + tab[ind]=dat + n=n+data:getSize()+4 + end + if n==len then break end + end + return tab +end,function(d,fit,fmt,self,rec) + -- INGORE FIT WE ARE CREATING A STRUCT!!! + -- fmt will apply to all numbers + local bData={} + for i,v in pairs(d) do -- this is for tables, all but userdata is fine. Depending on where you are using lua functions may or may not work + local tp=type(v):sub(1,1):upper() -- uppercase of datatype + if type(i)=="number" then -- Lets handle indexies + table.insert(bData,"N"..tp..bin.defualtBit.numToBytes(i,4)) -- number index? + elseif type(i)=="string" then + if #i>255 then error("A string index cannot be larger than 255 bytes!") end + table.insert(bData,"S"..tp..bin.defualtBit.numToBytes(#i,1)..i) -- string index? + else + error("Only numbers and strings can be a table index!") -- throw error? + end + if type(v)=="number" then + -- How do we handle number data + table.insert(bData,bin.defualtBit.numToBytes(v,4)) + elseif type(v)=="string" then + -- Lets work on strings + table.insert(bData,bin.defualtBit.numToBytes(#v,4)) -- add length of string + table.insert(bData,v) -- add string + elseif type(v)=="boolean" then -- bools are easy :D + table.insert(bData,({[true]="\255",[false]="\0"})[v]) + elseif type(v)=="function" then -- should we allow this? why not... + local dump=string.dump(v) + table.insert(bData,bin.defualtBit.numToBytes(#dump,4)) -- add length of dumped string + table.insert(bData,dump) -- add it + elseif type(v)=="table" then -- tables... + local data=rec(v,nil,"t",self,rec) + table.insert(bData,bin.defualtBit.numToBytes(#data,4)) -- add length of string + table.insert(bData,data) -- add string + end + end + local data=table.concat(bData) + return "LT\0"..bin.defualtBit.numToBytes(#data,4)..data +end) diff --git a/rewritedata/bin/infinabits.lua b/rewritedata/bin/infinabits.lua index b49f248..954d75d 100644 --- a/rewritedata/bin/infinabits.lua +++ b/rewritedata/bin/infinabits.lua @@ -2,6 +2,7 @@ local binNum=require("bin.BigNum") local infinabits={} infinabits.data='' infinabits.t='infinabits' +infinabits.Type='infinabits' infinabits.__index = infinabits infinabits.__tostring=function(self) return self.data end infinabits.__len=function(self) return (#self.data)/8 end diff --git a/rewritedata/bin/init.lua b/rewritedata/bin/init.lua index bf82b4d..19bb44c 100644 --- a/rewritedata/bin/init.lua +++ b/rewritedata/bin/init.lua @@ -33,12 +33,10 @@ bin.setBitsInterface() function bin.normalizeData(data) -- unified function to allow if type(data)=="string" then return data end if type(data)=="table" then - if data.Type=="bin" or data.Type=="streamable" then + if data.Type=="bin" or data.Type=="streamable" or data.Type=="buffer" then return data:getData() - elseif data.Type=="bits" then + elseif data.Type=="bits" or data.Type=="infinabits" then return data:toSbytes() - elseif data.Type=="buffer" then - -- LATER elseif data.Type=="sink" then -- LATER else @@ -267,7 +265,7 @@ function bin:getSize(fmt) len=#self.data end if fmt=="%b" then - --return bin.toB64() -- LATER + return bin.toB64() elseif fmt then return string.format(fmt, len) else @@ -308,13 +306,6 @@ function bin:tofile(name) file:write(self.data) file:close() end -function bin.getnumber(num,len,fmt,func) - local num=bits.numToBytes(num,len,func) - if fmt=="%B" then - return bin.endianflop(num) - end - return num -end function bin:close() if self.stream then if bin.streams[self.file][2]==1 then @@ -344,6 +335,12 @@ function bin:getBlock(t,n) local big=numB:tonumber(0) if t=="%E" then return big + elseif t=="%X" then + return bin.toHex(data):upper() + elseif t=="%x" then + return bin.toHex(data):lower() + elseif t=="%b" then + return bin.toB64(data) elseif t=="%e" then return little end @@ -377,3 +374,4 @@ bin.registerBlocks={} function bin.registerBlock(t,funcG,funcA) bin.registerBlocks[t]={funcG,funcA} end +require("bin.extraBlocks") -- registered blocks that you can use diff --git a/rewritedata/test_Bin.lua b/rewritedata/test_Bin.lua new file mode 100644 index 0000000..9c4ba8c --- /dev/null +++ b/rewritedata/test_Bin.lua @@ -0,0 +1,137 @@ +package.path="?/init.lua;"..package.path +require("bin") +--~ test=bin.new() +--~ test:addBlock({ +--~ test=134534, +--~ 23452, +--~ 65723, +--~ 45744, +--~ 523463, +--~ test2=6234562, +--~ test3="HELLO WORLD!", +--~ test4=true, +--~ test5=false, +--~ test6={a=1,b=2,3,4}, +--~ test6={c=1345,d=2345,3567,4789,{1,true,false,"HI"},c={1,2,3,"HI2"}}, +--~ test7=function() print("Hello World!") end +--~ },nil,"t") +--~ test:addBlock(1234,4) +--~ test:tofile("test.dat") +--~ test2=bin.load("test.dat") +--~ t=test2:getBlock("t") +--~ table.print(t) +--~ print("-----") +--~ print(test2:getBlock("n",4)) + +--~ print("bfType:",test:getBlock("s",2)) +--~ print("bfSize:",test:getBlock("%E",4)) +--~ print("bfReserved1:",test:getBlock("%E",2)) +--~ print("bfReserved2:",test:getBlock("%E",2)) +--~ print("bfOffBits:",test:getBlock("%E",4)) +--~ print("biSize:",test:getBlock("%E",4)) +--~ print("biWidth:",test:getBlock("%E",4)) +--~ print("biHeight:",test:getBlock("%E",4)) +--~ print("biPlanes:",test:getBlock("%E",2)) +--~ print("biBitCount:",test:getBlock("%E",2)) +--~ print("biCompression:",test:getBlock("%E",4)) +--~ print("biSizeImage:",test:getBlock("%E",4)) +--~ print("biXPelsPerMeter:",test:getBlock("%E",4)) +--~ print("biYPelsPerMeter:",test:getBlock("%E",4)) +--~ print("biClrUsed:",test:getBlock("%E",4)) +--~ print("biClrImportant:",test:getBlock("%E",4)) + +-- allocate space in a file and work with it directly. No need to worry about seeking and such! +function bin:newDataBufferFromBin(size,fill) -- fills with \0 or nul or with what you enter IF the nothing exists inside the bin file. + -- +end +function bin.newDataBuffer(size,fill) -- fills with \0 or nul or with what you enter + local c={} + local fill=fill or "\0" + c.data={self=c} + c.Type="buffer" + c.size=size or 0 -- 0 means an infinite buffer, sometimes useful + for i=1,size do + c.data[i]=fill + end + local mt={ + __index=function(t,k) + if type(k)=="number" then + local data=t.data[k] + if data then + return string.byte(data) + else + error("Index out of range!") + end + elseif type(k)=="string" then + local num=tonumber(k) + if num then + local data=t.data[num] + if data then + return data + else + error("Index out of range!") + end + else + error("Only number-strings and numbers can be indexed!") + end + else + error("Only number-strings and numbers can be indexed!") + end + end, + __newindex=function(t,k,v) + if type(k)~="number" then error("Can only set a buffers data with a numeric index!") end + local data="" + if type(v)=="string" then + data=v + elseif type(v)=="number" then + data=string.char(v) + else + -- try to normalize the data of type v + data=bin.normalizeData(v) + end + t:fillBuffer(k,data) + end, + __tostring=function(t) + return t:getData() + end, + } + function c:fillBuffer(a,data) + local len=#data + if len==1 then + self.data[a]=data + else + local i=a-1 + for d in data:gmatch(".") do + i=i+1 + if i>c.size then + return #data-i+a + end + self.data[i]=d + end + return #data-i+(a-1) + end + end + function c:getData(a,b,fmt) -- LATER + local dat=bin.new(table.concat(self.data,"",a,b)) + local n=dat:getSize() + return dat:getBlock(fmt or "s",n) + end + function c:getSize() + return #self:getData() + end + setmetatable(c,mt) + return c +end +test=bin.newDataBuffer(16) +test[1]=bits.numToBytes(1234,2,"%E") +test[5]=bin.new("Hello") +test[10]=24 +print(test:getData(1,4,"n")) +print(test["5"]) +print(test["6"]) +print(test["7"]) +print(test["8"]) +print(test["9"]) +print(test[10]) +print(test) +print(test:getSize())