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