l-md5.lua /size: 3414 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['l-md5'] = {
2    version   = 1.001,
3    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
4    copyright = "PRAGMA ADE / ConTeXt Development Team",
5    license   = "see context related readme files"
6}
7
8-- This also provides file checksums and checkers.
9
10if not md5 then
11    md5 = optionalrequire("md5")
12end
13
14if not md5 then
15    md5 = {
16        sum     = function(str) print("error: md5 is not loaded (sum     ignored)") return str end,
17        sumhexa = function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
18    }
19end
20
21local md5, file = md5, file
22local gsub = string.gsub
23local modification, isfile, touch = lfs.modification, lfs.isfile, lfs.touch
24local loaddata, savedata = io.loaddata, io.savedata
25
26-- local gsub, format, byte = string.gsub, string.format, string.byte
27--
28-- local function convert(str,fmt)
29--     return (gsub(md5sum(str),".",function(chr) return format(fmt,byte(chr)) end))
30-- end
31--
32-- if not md5.HEX then function md5.HEX(str) return convert(str,"%02X") end end
33-- if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
34-- if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
35
36do
37
38    local patterns = lpeg and lpeg.patterns
39
40    if patterns then
41
42        local bytestoHEX = patterns.bytestoHEX
43        local bytestohex = patterns.bytestohex
44        local bytestodec = patterns.bytestodec
45
46        local lpegmatch = lpeg.match
47        local md5sum    = md5.sum
48
49        if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
50        if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
51        if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
52
53        md5.sumhexa = md5.hex
54        md5.sumHEXA = md5.HEX
55
56    end
57
58end
59
60local md5HEX = md5.HEX
61
62function file.needsupdating(oldname,newname,threshold) -- size modification access change
63    local oldtime = modification(oldname)
64    if oldtime then
65        local newtime = modification(newname)
66        if not newtime then
67            return true -- no new file, so no updating needed
68        elseif newtime >= oldtime then
69            return false -- new file definitely needs updating
70        elseif oldtime - newtime < (threshold or 1) then
71            return false -- new file is probably still okay
72        else
73            return true -- new file has to be updated
74        end
75    else
76        return false -- no old file, so no updating needed
77    end
78end
79
80file.needs_updating = file.needsupdating
81
82function file.syncmtimes(oldname,newname)
83    local oldtime = modification(oldname)
84    if oldtime and isfile(newname) then
85        touch(newname,oldtime,oldtime)
86    end
87end
88
89local function checksum(name)
90    if md5 then
91        local data = loaddata(name)
92        if data then
93            return md5HEX(data)
94        end
95    end
96    return nil
97end
98
99file.checksum = checksum
100
101function file.loadchecksum(name)
102    if md5 then
103        local data = loaddata(name .. ".md5")
104        return data and (gsub(data,"%s",""))
105    end
106    return nil
107end
108
109function file.savechecksum(name,checksum)
110    if not checksum then checksum = checksum(name) end
111    if checksum then
112        savedata(name .. ".md5",checksum)
113        return checksum
114    end
115    return nil
116end
117