-
Notifications
You must be signed in to change notification settings - Fork 495
Expand file tree
/
Copy pathlar.lua
More file actions
executable file
·218 lines (200 loc) · 6.09 KB
/
Copy pathlar.lua
File metadata and controls
executable file
·218 lines (200 loc) · 6.09 KB
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
-----------------------------------------------------------------------------
-- LAR - Lua ARchives
--
-- Support code to use lar files as a virtual file system.
-- Currently using the ZIP or tar.gz formats.
--
-- Version 1.0 (28/04/2004)
--
-- Redefines the following I/O operations:
-- io.open
-- loadfile
-- dofile
-- require
--
-- Usage:
-- call lar.init(format, extension)
-- use I/O operations assuming the original directory structure
--
-- Author: André Carregal ([email protected])
--
-- Copyright (c) 2004 Kepler Project
-----------------------------------------------------------------------------
local Public = {}
local Private = {}
lar = Public
local larExtension = ""
-----------------------------------------------------------------------------
-- Inits the LAR library
-- @param format the compression format ("ZIP" or "TAR.GZ", default is "ZIP")
-- @param extension the lar file extension (default is "lar")
-----------------------------------------------------------------------------
Public.init = function(format, extension)
larExtension = extension or "lar"
format = format or "ZIP"
if format == "ZIP" then
if not zip then require "zip" end
Public.open = Private.openzip
Public.close = zip.close
elseif format == "TAR.GZ" then
if not tar then require "tar" end
Public.open = Private.opentar
Public.close = tar.close
else
error("Uknown LAR format")
end
Private.openedFiles = {} -- file caching
-- redefines the global I/O functions
io.open = Private.ioopen
loadfile = Private.loadfile
dofile = Private.dofile
require = Private.require
end
-----------------------------------------------------------------------------
-- Opens a LAR file using tar.gz format.
-----------------------------------------------------------------------------
Private.opentar = function (filepath, mode)
-- tries to find a lar in the file path
local current = ""
local remain = filepath
local pos
while remain and remain ~= "" do
pos = string.find(remain, "/")
if (pos) then
current = current..string.sub(remain, 1, pos - 1)
remain = string.sub(remain, pos + 1)
local filename = current.."."..larExtension
if Private.openedFiles[filename] then
return Private.openedFiles[filename]
else
local gfile = gzip.open(filename, "rb")
if gfile then
local tarfile = tar.open(gfile)
if tarfile then
local file = tarfile:open(remain)
Private.openedFiles[filepath] = file
return file
end
else
current = current.."/"
end
end
else
current = current..remain
remain = ""
end
end
end
-----------------------------------------------------------------------------
-- Opens a LAR file using ZIP format (default)
-----------------------------------------------------------------------------
Private.openzip = function (filepath, mode)
-- tries to find a lar in the file path
local current = ""
local remain = filepath
local pos
while remain and remain ~= "" do
pos = string.find(remain, "/")
if (pos) then
current = current..string.sub(remain, 1, pos - 1)
remain = string.sub(remain, pos + 1)
local filename = current.."."..larExtension
if Private.openedFiles[filepath] then
return Private.openedFiles[filepath]
else
local zfile = zip.open(filename)
if zfile then
local file = zfile:open(remain)
Private.openedFiles[filepath] = file
zip.close(filename)
return file
else
current = current.."/"
end
end
else
current = current..remain
remain = ""
end
end
end
local openLars = {}
-----------------------------------------------------------------------------
-- Redefines io.open to handle LAR files.
-----------------------------------------------------------------------------
local open = io.open
Private.ioopen = function (filename, mode)
local fh, msg = open(filename, mode)
openLars[filename] = "IO"
if fh == nil then
local fh2, msg2 = Public.open(filename, mode)
openLars[filename] = "LAR"
if fh2 then
fh = fh2
msg = msg2
end
end
return fh, msg
end
-----------------------------------------------------------------------------
-- Redefines io.close to handle LAR files.
-----------------------------------------------------------------------------
local close = io.close
Private.ioclose = function (filename)
if openLars[filename] == "LAR" then
Public.close(filename)
else
close(filename)
end
end
-----------------------------------------------------------------------------
-- Redefines loadfile to accept LAR files.
-----------------------------------------------------------------------------
local _loadfile = loadfile
Private.loadfile = function (filename)
local fh, chunk, msg
chunk, msg = _loadfile(filename)
if chunk == nil then
fh, msg = Public.open(filename)
if fh ~= nil then
local contents = fh:read("*a")
fh:close()
if contents then
chunk, msg = loadstring(contents)
end
end
end
return chunk, msg
end
-----------------------------------------------------------------------------
-- Redefines loadfile to accept LAR files.
-----------------------------------------------------------------------------
local _dofile = dofile
Private.dofile = function (filename)
local chunk, msg, ret
chunk, msg = loadfile(filename)
if chunk then
ret = chunk()
end
return ret
end
-----------------------------------------------------------------------------
-- Redefines require to accept LAR files.
-----------------------------------------------------------------------------
local _require = require
Private.require = function (packagename)
local status, ret = pcall(_require, packagename)
if status then
return ret
end
local filepath = string.gsub("?;?.lua", "?", packagename)
for p in string.gfind(filepath, "([^;]+)") do
local chunk, msg = loadfile(p)
if chunk then
res = chunk() or true
package.loaded[packagename] = res
end
end
return res
end
Public.init("TAR.GZ")