1if not modules then modules = { } end modules ['data-tar'] = {
2 version = 1.001,
3 comment = "companion to luat-lib.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local format, find, match = string.format, string.find, string.match
10
11local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
12
13local report_tar = logs.reporter("resolvers","tar")
14
15
16
17
18
19
20local resolvers = resolvers
21local findfile = resolvers.findfile
22local registerfile = resolvers.registerfile
23local splitmethod = resolvers.splitmethod
24local starttiming = resolvers.starttiming
25local stoptiming = resolvers.stoptiming
26
27local urlquery = url.query
28
29
30
31local tar = utilities.tar or { }
32utilities.tar = tar
33
34local archives = tar.archives or { }
35tar.archives = archives
36
37local registeredfiles = tar.registeredfiles or { }
38tar.registeredfiles = registeredfiles
39
40
41
42
43
44local hashtar, fetchtar, wipetar do
45
46 local suffix = file.suffix
47
48 local tarfiles = utilities.tar.file
49 local tarstrings = utilities.tar.string
50
51 local hashtarfile = tar.files.hash
52 local fetchtarfile = tar.files.fetch
53
54 local hashtarstring = tar.strings.hash
55 local fetchtarstring = tar.strings.fetch
56
57 local register = resolvers.decompressors.register
58
59 hashtar = function(archive,strip)
60 local a = register(archive)
61 if a then
62 return hashtarstring(a,archive)
63 else
64 return hashtarfile(archive,archive)
65 end
66 end
67
68 fetchtar = function(archive,filename,list)
69 local a = register(archive)
70 if a then
71 return fetchtarstring(a,filename,list)
72 else
73 return fetchtarfile(archive,filename,list)
74 end
75 end
76
77 wipetar = resolvers.decompressors.unregister
78
79end
80
81local function validfile(archive,name)
82 return archive[name]
83end
84
85local function openarchive(name)
86 if not name or name == "" then
87 return nil
88 else
89 local arch = archives[name]
90 if not arch then
91 local full = findfile(name) or ""
92 arch = full ~= "" and hashtar(full,name) or false
93 archives[name] = arch
94 end
95 return arch
96 end
97end
98
99local function closearchive(name)
100 if not name or (name == "" and archives[name]) then
101 archives[name] = nil
102 wipetar(name)
103 end
104end
105
106tar.openarchive = openarchive
107tar.closearchive = closearchive
108
109function resolvers.locators.tar(specification)
110 local archive = specification.filename
111 local tarfile = archive and archive ~= "" and openarchive(archive)
112 if trace_locating then
113 if tarfile then
114 report_tar("locator: archive %a found",archive)
115 else
116 report_tar("locator: archive %a not found",archive)
117 end
118 end
119end
120
121function resolvers.concatinators.tar(tarfile,path,name)
122 if not path or path == "" then
123 return format('%s?name=%s',tarfile,name)
124 else
125 return format('%s?name=%s/%s',tarfile,path,name)
126 end
127end
128
129local finders = resolvers.finders
130local notfound = finders.notfound
131
132function finders.tar(specification)
133 local original = specification.original
134 local archive = specification.filename
135 if archive then
136 local query = urlquery(specification.query)
137 local queryname = query.name
138 if queryname then
139 local tfile = openarchive(archive)
140 if tfile then
141 if trace_locating then
142 report_tar("finder: archive %a found",archive)
143 end
144 if validfile(tfile,queryname) then
145 if trace_locating then
146 report_tar("finder: file %a found",queryname)
147 end
148 return specification.original
149 elseif trace_locating then
150 report_tar("finder: file %a not found",queryname)
151 end
152 elseif trace_locating then
153 report_tar("finder: unknown archive %a",archive)
154 end
155 end
156 end
157 if trace_locating then
158 report_tar("finder: %a not found",original)
159 end
160 return notfound()
161end
162
163local openers = resolvers.openers
164local notfound = openers.notfound
165local textopener = openers.helpers.textopener
166
167function openers.tar(specification)
168 local original = specification.original
169 local archive = specification.filename
170 if archive then
171 local query = urlquery(specification.query)
172 local queryname = query.name
173 if queryname then
174 local tfile = openarchive(archive)
175 if tfile then
176 if trace_locating then
177 report_tar("opener; archive %a opened",archive)
178 end
179 local data = fetchtar(archive,queryname,tfile)
180 if data then
181 if trace_locating then
182 report_tar("opener: file %a found",queryname)
183 end
184 return textopener('tar',original,data)
185 elseif trace_locating then
186 report_tar("opener: file %a not found",queryname)
187 end
188 elseif trace_locating then
189 report_tar("opener: unknown archive %a",archive)
190 end
191 end
192 end
193 if trace_locating then
194 report_tar("opener: %a not found",original)
195 end
196 return notfound()
197end
198
199loaders = resolvers.loaders
200local notfound = loaders.notfound
201
202function loaders.tar(specification)
203 local original = specification.original
204 local archive = specification.filename
205 if archive then
206 local query = urlquery(specification.query)
207 local queryname = query.name
208 if queryname then
209 local tfile = openarchive(archive)
210 if tfile then
211 if trace_locating then
212 report_tar("loader: archive %a opened",archive)
213 end
214 local data = fetchtar(archive,queryname,tfile)
215 if data then
216 if trace_locating then
217 report_tar("loader; file %a loaded",original)
218 end
219 return true, data, #data
220 elseif trace_locating then
221 report_tar("loader: file %a not found",queryname)
222 end
223 elseif trace_locating then
224 report_tar("loader; unknown archive %a",archive)
225 end
226 end
227 end
228 if trace_locating then
229 report_tar("loader: %a not found",original)
230 end
231 return notfound()
232end
233 |