This commit is contained in:
Ryan Ward 2019-02-05 16:03:16 -05:00
parent c069a981cd
commit 68c156c518
6 changed files with 777 additions and 47 deletions

View File

@ -1,3 +1,4 @@
local bin = require("bin")
local base64={}
local bs = { [0] =
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
@ -27,4 +28,13 @@ function base64.decode(s)
end
return r:sub(1,-(cc+1))
end
function bin.newFromBase91(data)
return bin.new(bin.fromBase91(data))
end
function bin.toBase91(s)
return base91.encode(s)
end
function bin.fromBase91(s)
return base91.decode(s)
end
return base64

View File

@ -1,3 +1,4 @@
local bin = require("bin")
local base91={}
local b91enc={[0]=
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
@ -69,4 +70,13 @@ function base91.encode(d)
end
return o
end
function bin.newFromBase64(data)
return bin.new(bin.fromBase64(data))
end
function bin.toBase64(s)
return base64.encode(s)
end
function bin.fromBase64(s)
return base64.decode(s)
end
return base91

View File

@ -1,3 +1,4 @@
local bin = require("bin")
local md5 = {
_VERSION = "md5.lua 1.1.0",
_DESCRIPTION = "MD5 computation in Lua (5.1-3, LuaJIT)",
@ -373,5 +374,21 @@ end
function md5.sumhexa(s)
return md5.tohex(md5.sum(s))
end
bin.md5 = md5
function bin:getMD5Hash()
self:setSeek(1)
local len=self:getSize()
local md5=bin.md5.new()
local SIZE=2048
if len>SIZE then
local dat=self:read(SIZE)
while dat~=nil do
md5:update(dat)
dat=self:read(SIZE)
end
return bin.md5.tohex(md5:finish()):upper()
else
return bin.md5.sumhexa(self:getData()):upper()
end
end
return md5

View File

@ -1,5 +1,5 @@
bin={}
bin.Version={5,1,0}
bin.Version={6,0,0}
bin.stage='stable'
bin.data=''
bin.t='bin'
@ -12,7 +12,135 @@ bin.streams={}
function bin.getVersion()
return bin.Version[1]..'.'..bin.Version[2]..'.'..bin.Version[3]
end
require("bin.support.utils")
function table.print(tbl, indent)
if not indent then indent = 0 end
for k, v in pairs(tbl) do
formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then
print(formatting)
table.print(v, indent+1)
elseif type(v) == 'boolean' then
print(formatting .. tostring(v))
else
print(formatting .. tostring(v))
end
end
end
function table.flip(t)
local tt={}
for i,v in pairs(t) do
tt[v]=i
end
return tt
end
function toFraction(n)
local w,p=math.modf(n)
if p~=0 then
p=tonumber(tostring(p):sub(3))
end
return w,p
end
function io.cleanName(name)
name=name:gsub("\\","")
name=name:gsub("/","")
name=name:gsub(":","")
name=name:gsub("*","")
name=name:gsub("%?","")
name=name:gsub("\"","''")
name=name:gsub("<","")
name=name:gsub(">","")
name=name:gsub("|","")
return name
end
function math.numfix(n,x)
local str=tostring(n)
if #str<x then
str=('0'):rep(x-#str)..str
end
return str
end
function bin.stripFileName(path)
path=path:gsub("\\","/")
local npath=path:reverse()
a=npath:find("/",1,true)
npath=npath:sub(a)
npath=npath:reverse()
return npath
end
function bin._trim(str)
return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
function io.dirExists(strFolderName)
strFolderName = strFolderName or io.getDir()
local fileHandle, strError = io.open(strFolderName..'\\*.*','r')
if fileHandle ~= nil then
io.close(fileHandle)
return true
else
if string.match(strError,'No such file or directory') then
return false
else
return true
end
end
end
function bin.fileExists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
function bin.randomName(n,ext)
n=n or math.random(7,15)
if ext then
a,b=ext:find('.',1,true)
if a and b then
ext=ext:sub(2)
end
end
local str,h = '',0
strings = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
for i=1,n do
h = math.random(1,#strings)
str = str..''..strings[h]
end
return str..'.'..(ext or 'tmp')
end
function bin.trimNul(str)
return str:match("(.-)[%z]*$")
end
function io.mkDir(dirname)
os.execute('mkdir "' .. dirname..'"')
end
function string.lines(str)
local t = {}
local function helper(line) table.insert(t, line) return '' end
helper((str:gsub('(.-)\r?\n', helper)))
return t
end
function log(data,name,fmt)
if name then
name=io.cleanName(name)
end
if not bin.logger then
bin.logger = bin.stream(name or 'lua.log',false)
elseif bin.logger and name then
bin.logger:close()
bin.logger = bin.stream(name or 'lua.log',false)
end
local d=os.date('*t',os.time())
bin.logger:tackE((fmt or '['..math.numfix(d.month,2)..'-'..math.numfix(d.day,2)..'-'..d.year..'|'..math.numfix(d.hour,2)..':'..math.numfix(d.min,2)..':'..math.numfix(d.sec,2)..']\t')..data..'\r\n')
end
function table.max(t)
if #t == 0 then return end
local value = t[1]
for i = 2, #t do
if (value < t[i]) then
value = t[i]
end
end
return value
end
local bit
if jit then
bit=require("bit")
elseif bit32 then
@ -20,15 +148,445 @@ elseif bit32 then
else
bit=require("bin.numbers.no_jit_bit")
end
base64=require("bin.converters.base64")
base91=require("bin.converters.base91")
bin.lzw=require("bin.compressors.lzw") -- A WIP
bits=require("bin.numbers.bits")
infinabits=require("bin.numbers.infinabits") -- like the bits library but works past 32 bits for 32bit lua and 64 bits for 64 bit lua.
bin.md5=require("bin.hashes.md5")
randomGen=require("bin.numbers.random")
local bits={}
bin.bits = 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
local floor,insert = math.floor, table.insert
function bits.newBitBuffer(n)
--
end
function bits.newConverter(bitsIn,bitsOut)
local c={}
--
end
function basen(n,b)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
local sign = ""
if n < 0 then
sign = "-"
n = -n
end
repeat
local d = n % b + 1
n = n / b
insert(t, 1, digits:sub(d,d))
until n == 0
return sign .. table.concat(t,"")
end
bits.ref={}
function bits.newByte(d)
local c={}
if type(d)=="string" then
if #d>1 or #d<1 then
error("A byte must be one character!")
else
c.data=string.byte(d)
end
elseif type(d)=="number" then
if d>255 or d<0 then
error("A byte must be between 0 and 255!")
else
c.data=d
end
else
error("cannot use type "..type(d).." as an argument! Takes only strings or numbers!")
end
c.__index=function(self,k)
if k>=0 and k<9 then
if self.data==0 then
return 0
elseif self.data==255 then
return 1
else
return bits.ref[self.data][k]
end
end
end
c.__tostring=function(self)
return bits.ref[tostring(self.data)]
end
setmetatable(c,c)
return c
end
function bits.newByteArray(s)
local c={}
if type(s)~="string" then
error("Must be a string type or bin/buffer type")
elseif type(s)=="table" then
if s.t=="sink" or s.t=="buffer" or s.t=="bin" then
local data=s:getData()
for i=1,#data do
c[#c+1]=bits.newByte(data:sub(i,i))
end
else
error("Must be a string type or bin/buffer type")
end
else
for i=1,#s do
c[#c+1]=bits.newByte(s:sub(i,i))
end
end
return c
end
function bits.new(n,binary)
local temp={}
temp.t="bits"
temp.Type="bits"
if type(n)=="string" then
if binary then
temp.data=n:match("[10]+")
else
local t={}
for i=#n,1,-1 do
table.insert(t,bits:conv(string.byte(n,i)))
end
temp.data=table.concat(t)
end
elseif type(n)=="number" or type(n)=="table" then
temp.data=basen(n,2)
end
if #temp.data%8~=0 then
temp.data=string.rep('0',8-#temp.data%8)..temp.data
end
setmetatable(temp, bits)
return temp
end
for i=0,255 do
local d=bits.new(i).data
bits.ref[i]={d:match("(%d)(%d)(%d)(%d)(%d)(%d)(%d)(%d)")}
bits.ref[tostring(i)]=d
bits.ref[d]=i
bits.ref["\255"..string.char(i)]=d
end
function bits.numToBytes(n,fit,func)
local num=string.reverse(bits.new(n):toSbytes())
local ref={["num"]=num,["fit"]=fit}
if fit then
if fit<#num then
if func then
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
func(ref)
else
print("Warning: attempting to store a number that takes up more space than allotted!")
end
return ref.num:sub(1,ref.fit)
elseif fit==#num then
return string.reverse(num)
else
return string.reverse(string.rep("\0",fit-#num)..num)
end
else
return string.reverse(num)
end
end
function bits:conv(n)
local tab={}
while n>=1 do
table.insert(tab,n%2)
n=math.floor(n/2)
end
local str=string.reverse(table.concat(tab))
if #str%8~=0 or #str==0 then
str=string.rep('0',8-#str%8)..str
end
return str
end
function bits:tonumber(s,e)
if s==0 then
return tonumber(self.data,2)
end
s=s or 1
return tonumber(string.sub(self.data,(8*(s-1))+1,8*s),2) or error('Bounds!')
end
function bits:isover()
return #self.data>8
end
function bits:flipbits()
tab={}
for i=1,#self.data do
if string.sub(self.data,i,i)=='1' then
table.insert(tab,'0')
else
table.insert(tab,'1')
end
end
self.data=table.concat(tab)
end
function bits:tobytes()
local tab={}
for i=self:getbytes(),1,-1 do
table.insert(tab,string.char(self:tonumber(i)))
end
return bin.new(table.concat(tab))
end
function bits:toSbytes()
local tab={}
for i=self:getbytes(),1,-1 do
table.insert(tab,string.char(self:tonumber(i)))
end
return table.concat(tab)
end
function bits:getBin()
return self.data
end
function bits:getbytes()
return #self.data/8
end
local binNum=require("bin.numbers.BigNum")
local infinabits={}
bin.infinabits = 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
local floor,insert = math.floor, table.insert
function basen(n,b)
n=BigNum.new(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
local sign = ""
if n < BigNum.new(0) then
sign = "-"
n = -n
end
repeat
local d = tonumber(tostring(n % b)) + 1
n = n / b
insert(t, 1, digits:sub(d,d))
until n == BigNum.new(0)
return sign .. table.concat(t,"")
end
function base2to10(num)
local n=BigNum.new(0)
for i = #num-1,0,-1 do
nn=BigNum.new(num:sub(i+1,i+1))*(BigNum.new(2)^((#num-i)-1))
n=n+nn
end
return n
end
function infinabits.newBitBuffer(n)
-- WIP
end
function infinabits.newConverter(bitsIn,bitsOut)
local c={}
-- WIP
end
infinabits.ref={}
function infinabits.newByte(d)-- WIP
local c={}
if type(d)=="string" then
if #d>1 or #d<1 then
error("A byte must be one character!")
else
c.data=string.byte(d)
end
elseif type(d)=="number" then
if d>255 or d<0 then
error("A byte must be between 0 and 255!")
else
c.data=d
end
else
error("cannot use type "..type(d).." as an argument! Takes only strings or numbers!")
end
c.__index=function(self,k)
if k>=0 and k<9 then
if self.data==0 then
return 0
elseif self.data==255 then
return 1
else
return infinabits.ref[self.data][k]
end
end
end
c.__tostring=function(self)
return infinabits.ref[tostring(self.data)]
end
setmetatable(c,c)
return c
end
function infinabits.newByteArray(s)-- WIP
local c={}
if type(s)~="string" then
error("Must be a string type or bin/buffer type")
elseif type(s)=="table" then
if s.t=="sink" or s.t=="buffer" or s.t=="bin" then
local data=s:getData()
for i=1,#data do
c[#c+1]=infinabits.newByte(data:sub(i,i))
end
else
error("Must be a string type or bin/buffer type")
end
else
for i=1,#s do
c[#c+1]=infinabits.newByte(s:sub(i,i))
end
end
return c
end
function infinabits.new(n,binary)
local temp={}
temp.t="infinabits"
temp.Type="infinabits"
if type(n)=="string" then
if binary then
temp.data=n:match("[10]+")
else
local t={}
for i=#n,1,-1 do
table.insert(t,infinabits:conv(string.byte(n,i)))
end
temp.data=table.concat(t)
end
elseif type(n)=="number" or type(n)=="table" then
temp.data=basen(tostring(n),2)
end
if #temp.data%8~=0 then
temp.data=string.rep('0',8-#temp.data%8)..temp.data
end
setmetatable(temp, infinabits)
return temp
end
for i=0,255 do
local d=infinabits.new(i).data
infinabits.ref[i]={d:match("(%d)(%d)(%d)(%d)(%d)(%d)(%d)(%d)")}
infinabits.ref[tostring(i)]=d
infinabits.ref[d]=i
infinabits.ref["\255"..string.char(i)]=d
end
function infinabits.numToBytes(n,fit,func)
local num=string.reverse(infinabits.new(BigNum.new(n)):toSbytes())
local ref={["num"]=num,["fit"]=fit}
if fit then
if fit<#num then
if func then
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
func(ref)
else
print("Warning: attempting to store a number that takes up more space than allotted!")
end
return ref.num:sub(1,ref.fit)
elseif fit==#num then
return string.reverse(num)
else
return string.reverse(string.rep("\0",fit-#num)..num)
end
else
return string.reverse(num)
end
end
function infinabits.numToBytes(n,fit,fmt,func)
if fmt=="%e" then
local num=string.reverse(infinabits.new(BigNum.new(n)):toSbytes())
local ref={["num"]=num,["fit"]=fit}
if fit then
if fit<#num then
if func then
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
func(ref)
else
print("Warning: attempting to store a number that takes up more space than allotted!")
end
return ref.num:sub(1,ref.fit)
elseif fit==#num then
return num
else
return string.rep("\0",fit-#num)..num
end
else
return num
end
else
local num=string.reverse(infinabits.new(BigNum.new(n)):toSbytes())
local ref={["num"]=num,["fit"]=fit}
if fit then
if fit<#num then
if func then
print("Warning: attempting to store a number that takes up more space than allotted! Using provided method!")
func(ref)
else
print("Warning: attempting to store a number that takes up more space than allotted!")
end
return ref.num:sub(1,ref.fit)
elseif fit==#num then
return string.reverse(num)
else
return string.reverse(string.rep("\0",fit-#num)..num)
end
else
return string.reverse(num)
end
end
end
function infinabits:conv(n)
local tab={}
local one=BigNum.new(1)
local n=BigNum.new(n)
while n>=one do
table.insert(tab,tonumber(tostring(n%2)))
n=n/2
end
local str=string.reverse(table.concat(tab))
if #str%8~=0 or #str==0 then
str=string.rep('0',8-#str%8)..str
end
return str
end
function infinabits:tonumber(s)
if s==0 then
return tonumber(self.data,2)
end
s=s or 1
return tonumber(tostring(base2to10(string.sub(self.data,(8*(s-1))+1,8*s)))) or error('Bounds!')
end
function infinabits:isover()
return #self.data>8
end
function infinabits:flipbits()
tab={}
local s=self.data
s=s:gsub("1","_")
s=s:gsub("0","1")
s=s:gsub("_","0")
self.data=s
end
function infinabits:tobytes()
local tab={}
for i=self:getbytes(),1,-1 do
table.insert(tab,string.char(self:tonumber(i)))
end
return bin.new(table.concat(tab))
end
function infinabits:toSbytes()
local tab={}
for i=self:getbytes(),1,-1 do
table.insert(tab,string.char(self:tonumber(i)))
end
return table.concat(tab)
end
function infinabits:getBin()
return self.data
end
function infinabits:getbytes()
return #self.data/8
end
local randomGen=require("bin.numbers.random")
function bin.setBitsInterface(int)
bin.defualtBit=int or bits
bin.defualtBit=int or infinabits
end
bin.setBitsInterface()
function bin.normalizeData(data) -- unified function to allow for all types to string
@ -108,18 +666,7 @@ function bin.fromHex(str)
return string.char(tonumber(cc, 16))
end))
end
function bin.toBase64(s)
return base64.encode(s)
end
function bin.fromBase64(s)
return base64.decode(s)
end
function bin.toBase91(s)
return base91.encode(s)
end
function bin.fromBase91(s)
return base91.decode(s)
end
-- Constructors
function bin.new(data)
data=bin.normalizeData(data)
@ -132,12 +679,7 @@ function bin.new(data)
c.stream=false
return c
end
function bin.newFromBase64(data)
return bin.new(bin.fromBase64(data))
end
function bin.newFromBase91(data)
return bin.new(bin.fromBase91(data))
end
function bin.newFromHex(data)
return bin.new(bin.fromHex(data))
end
@ -571,22 +1113,6 @@ function bin:toDataBuffer()
end
return buf
end
function bin:getMD5Hash()
self:setSeek(1)
local len=self:getSize()
local md5=bin.md5.new()
local SIZE=2048
if len>SIZE then
local dat=self:read(SIZE)
while dat~=nil do
md5:update(dat)
dat=self:read(SIZE)
end
return bin.md5.tohex(md5:finish()):upper()
else
return bin.md5.sumhexa(self:getData()):upper()
end
end
function bin:getHash()
if self:getSize()==0 then
return "NaN"
@ -676,7 +1202,152 @@ function bin:fullTrim(empty)
self:wipe()
self:write(table.concat(t,"\n"))
end
require("bin.support.extraBlocks") -- registered blocks that you can use
local __CURRENTVERSION=2
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)>__CURRENTVERSION 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 _dat=ref:read(2)
if _dat==nil then break end
local it,dt=_dat: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("d")
n=n+8
elseif dt=="I" then
tab[ind]=math.huge
ref:getBlock("n",4)
n=n+4
elseif dt=="i" then
tab[ind]=-math.huge
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:setSeek(cur)
ref:read(4)
if size==7 then
tab[ind]={}
ref:read(7)
n=n+11
else
local data=bin.new(ref:read(size))
local dat=data:getBlock("t")
if dat.__RECURSIVE then
tab[ind]=tab
else
tab[ind]=dat
end
n=n+data:getSize()+4
end
end
if n==len then break end
end
return bin.resolveType(tab)
end,function(d,fit,fmt,self,rec,tabsaw)
-- INGORE FIT WE ARE CREATING A STRUCT!!!
-- fmt will apply to all numbers
local __rem=nil
if not tabsaw then rem=true end
local tabsaw=tabsaw or {}
if rem then
table.insert(tabsaw,d)
end
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
if v==math.huge then
tp="I"
v=0
elseif v==-math.huge then
tp="i"
v=0
end
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
local temp=bin.new()
temp:addBlock(v,nil,"d")
table.insert(bData,temp.data)
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...
if tabsaw[1]==v then
v={__RECURSIVE=i}
else
tabsaw[i]=v
end
local data=rec(v,nil,"t",self,rec,tabsaw)
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"..string.char(__CURRENTVERSION)..bin.defualtBit.numToBytes(#data,4)..data
end)
bin.registerBlock("b",function(SIZE_OR_NIL,ref)
return ({["\255"]=true,["\0"]=false})[ref:read(1)]
end,function(d)
return ({[true]="\255",[false]="\0"})[d]
end)
bin.registerBlock("f",function(SIZE_OR_NIL,ref)
local nn=ref:getBlock("n",4)
return loadstring(ref:read(nn))
end,function(d)
local dump=string.dump(d)
return bin.defualtBit.numToBytes(#dump,4)..dump
end)
bin.registerBlock("d",function(SIZE_OR_NIL,ref)
local w,p=ref:getBlock("n",4),ref:getBlock("n",4)
p=tonumber("0."..tostring(p))
return w+p
end,function(d,fit,fmt,self,rec,tabsaw)
local w,p = toFraction(d)
local temp=bin.new()
temp:addBlock(w,4)
temp:addBlock(p,4)
return temp.data
end)
if love then
function bin.load(file,s,r)
content, size = love.filesystem.read(file)
@ -684,10 +1355,30 @@ if love then
temp.filepath=file
return temp
end
function bin.fileExists(name)
return love.filesystem.getInfo(name)
end
function bin:tofile(filename)
if not(filename) or self.Stream then return nil end
love.filesystem.write(filename,self.data)
end
function bin.loadS(path,s,r)
local path = love.filesystem.getSaveDirectory( ).."\\"..path
if type(path) ~= "string" then error("Path must be a string!") end
local f = io.open(path, 'rb')
local content = f:read('*a')
f:close()
return bin.new(content)
end
function bin:tofileS(filename)
if self.stream then return end
local filename = love.filesystem.getSaveDirectory( ).."\\"..filename
print(#self.data,filename)
if not filename then error("Must include a filename to save as!") end
file = io.open(filename, "wb")
file:write(self.data)
file:close()
end
function bin.stream(file)
return bin.newStreamFileObject(love.filesystem.newFile(file))
end
@ -737,3 +1428,4 @@ if love then
self.workingfile:close()
end
end
return bin

View File

@ -0,0 +1 @@
local bin = require("bin")