-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathfileExtend.lua
150 lines (139 loc) · 4.71 KB
/
fileExtend.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
if not love.filesystem then
LOG("FILE lib is not loaded (need love.filesystem)")
return setmetatable({},{
__index=function(_,k)
error("attempt to use FILE."..k..", but FILE lib is not loaded (need love.filesystem)")
end
})
end
local fs=love.filesystem
local FILE={}
---Check if a file exists
---@param path string
---@param filterType? love.FileType
function FILE.exist(path,filterType)
return not not fs.getInfo(path,filterType)
end
---Check if a file is safe to read/write (not in save directory)
---@param file string
function FILE.isSafe(file)
return fs.getRealDirectory(file)~=fs.getSaveDirectory()
end
---Load a file with a specified mode
---(Auto detect if mode not given, not accurate)
---@param path string
---@param args? string | '-luaon' | '-lua' | '-json' | '-string' | '-canskip'
---@param venv? table Used as environment for LuaON
---@return any
function FILE.load(path,args,venv)
if not args then args='' end
if fs.getInfo(path) then
local F=fs.newFile(path)
assert(F:open'r',"FILE.load: Open error")
local s=F:read()
F:close()
local mode=
STRING.sArg(args,'-luaon') and 'luaon' or
STRING.sArg(args,'-lua') and 'lua' or
STRING.sArg(args,'-json') and 'json' or
STRING.sArg(args,'-string') and 'string' or
s:sub(1,9):find('return%s*%{') and 'luaon' or
(s:sub(1,1)=='[' and s:sub(-1)==']' or s:sub(1,1)=='{' and s:sub(-1)=='}') and 'json' or
'string'
if mode=='luaon' then
local lackReturn=s:match("^%s*[{]")
local func,err_mes=loadstring("--[["..STRING.simplifyPath(path)..(lackReturn and ']]return' or ']]')..s)
if func then
setfenv(func,venv or {})
local res=func()
return assert(res,"FILE.load: Decode error")
else
error("FILE.load: Decode error: "..err_mes)
end
elseif mode=='lua' then
local func,err_mes=loadstring("--[["..STRING.simplifyPath(path)..']]'..s)
if func then
local res=func()
return assert(res,"FILE.load: run error")
else
error("FILE.load: Compile error: "..err_mes)
end
elseif mode=='json' then
local suc,res=pcall(JSON.decode,s)
return suc and res or error("FILE.load: Decode error")
elseif mode=='string' then
return s
else
error("FILE.load: Unknown mode")
end
elseif not STRING.sArg(args,'-canskip') then
errorf("FILE.load: file '%s' doesn't exist",path)
end
end
---Save a file with a specified mode
---(Default to JSON, then LuaON, then string)
---@param data any
---@param path string
---@param args? string | '-d' | '-luaon' | '-expand'
function FILE.save(data,path,args)
if not args then args='' end
assert(not (STRING.sArg(args,'-d') and fs.getInfo(path)),"FILE.save: File already exist")
if type(data)=='table' then
if STRING.sArg(args,'-luaon') then
if STRING.sArg(args,'-expand') then
data=TABLE.dump(data)
else
data='return'..TABLE.dumpDeflate(data)
end
if not data then
error("FILE.save: Luaon-encoding error")
end
else
local suc
suc,data=pcall(JSON.encode,data)
assert(suc,"FILE.save: Json-encoding error")
end
else
data=tostring(data)
end
local F=fs.newFile(path)
assert(F:open('w'),"FILE.save: Open error")
F:write(data)
F:flush()
F:close()
end
---Clear a directory
---@param path string
function FILE.clear(path)
if not FILE.isSafe(path) and fs.getInfo(path).type=='directory' then
for _,name in next,fs.getDirectoryItems(path) do
name=path..'/'..name
if not FILE.isSafe(name) then
local t=fs.getInfo(name).type
if t=='file' then
fs.remove(name)
end
end
end
end
end
---Delete a directory recursively
---@param path string | ''
function FILE.clear_s(path)
if path=='' or (not FILE.isSafe(path) and fs.getInfo(path).type=='directory') then
for _,name in next,fs.getDirectoryItems(path) do
name=path..'/'..name
if not FILE.isSafe(name) then
local t=fs.getInfo(name).type
if t=='file' then
fs.remove(name)
elseif t=='directory' then
FILE.clear_s(name)
fs.remove(name)
end
end
end
fs.remove(path)
end
end
return FILE