1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE ../shared/a_modes.inc}
16 // database of file hashes (md5)
19 interface
21 uses
26 type
28 public
38 private
41 type
48 // used in directory scanner
52 private
60 private
70 public
75 // doesn't automatically rescans
78 // doesn't clear base path
81 // (re)scans base path and all its subdirs
82 // returns `true` if db was changed
83 // you'd better call it after loading a database
86 // those throws
88 // this clears existing data
91 // returns file name relative to base path or empty string
93 // returns `true` if something was changed
94 // name is relative to base
99 implementation
103 //result := joaatHashPtr(@k, sizeof(TMD5Digest));
104 //k8: use first 4 bytes of k as a hash instead? it should be good enough
107 class function THashKeyMD5.equ (const a, b: TMD5Digest): Boolean; inline; begin result := MD5Match(a, b); end;
111 //==========================================================================
112 //
113 // fixSlashes
114 //
115 // fixes all slashes; adds a final one too
116 //
117 //==========================================================================
119 var
121 begin
124 if (addFinal) and (length(result) > 0) and (result[length(result)] <> '/') then result := result+'/';
128 //==========================================================================
129 //
130 // TFileHashDB.appendOneDir
131 //
132 //==========================================================================
134 var
137 begin
142 begin
151 begin
158 //==========================================================================
159 //
160 // TFileHashDB.setup
161 //
162 //==========================================================================
164 var
166 begin
169 begin
182 //==========================================================================
183 //
184 // TFileHashDB.Create
185 //
186 //==========================================================================
188 begin
193 //==========================================================================
194 //
195 // TFileHashDB.Create
196 //
197 //==========================================================================
199 var
202 begin
209 //==========================================================================
210 //
211 // TFileHashDB.appendMoreDirs
212 //
213 //==========================================================================
215 var
217 begin
222 //==========================================================================
223 //
224 // TFileHashDB.Destroy
225 //
226 //==========================================================================
228 begin
238 //==========================================================================
239 //
240 // TFileHashDB.clear
241 //
242 // doesn't clear base path
243 //
244 //==========================================================================
246 begin
250 //SetLength(mPathList, 0);
255 //==========================================================================
256 //
257 // TFileHashDB.saveTo
258 //
259 //==========================================================================
261 var
264 begin
270 begin
280 //==========================================================================
281 //
282 // TFileHashDB.loadFrom
283 //
284 //==========================================================================
286 var
291 begin
293 try
299 if (count < 0) or (count > 1024*1024) then raise Exception.Create('invalid database file count');
301 begin
314 except
315 begin
323 //==========================================================================
324 //
325 // TFileHashDB.removeIndex
326 //
327 //==========================================================================
329 begin
330 if (idx < 0) or (idx > High(mFileList)) or (length(mFileList[idx].name) = 0) then exit; // nothing to do
339 //==========================================================================
340 //
341 // TFileHashDB.allocIndex
342 //
343 //==========================================================================
345 begin
348 begin
350 end
351 else
352 begin
359 //==========================================================================
360 //
361 // TFileHashDB.scanDir
362 //
363 //==========================================================================
365 var
374 begin
375 //writeln('TFileHashDB.scanDir(000): [', path, ']');
377 begin
379 exit;
381 //writeln('TFileHashDB.scanDir(001): [', path, ']');
382 try
383 repeat
385 begin
386 // directory
388 end
390 begin
391 // file
393 // build internal file name
395 //Delete(hfn, 1, length(mBasePath)); // remove prefix
396 // find file in hash
398 // check if we already have this file
401 begin
402 // do we need to update this file?
404 begin
405 needUpdate :=
408 end
409 else
410 begin
413 // recalc md5 and update file entry, if necessary
415 begin
417 try
420 except
423 begin
425 // remove old hash -> index mapping
427 // update
437 end
438 else
439 begin
440 // update failed, remove this entry
444 end
445 else
446 begin
449 end
450 else
451 begin
452 // remove this file if we don't have it anymore
456 end
457 else
458 begin
460 // build internal file name
463 // find file in hash
465 begin
471 finally
477 //==========================================================================
478 //
479 // TFileHashDB.scanFiles
480 //
481 // scans base path and all its subdirs
482 // returns `true` if db was changed
483 //
484 //==========================================================================
486 var
488 begin
491 //scanDir(mBasePath, result);
492 //writeln('TFileHashDB.scanFiles: dll=', length(mPathList));
494 // remove all unseen files
497 begin
504 //==========================================================================
505 //
506 // TFileHashDB.findByHash
507 //
508 // returns file name relative to base path or empty string
509 //
510 //==========================================================================
512 var
514 begin
520 //==========================================================================
521 //
522 // TFileHashDB.addWithHash
523 //
524 // returns `true` if something was changed
525 // name is *NOT* relative to base
526 //
527 //==========================================================================
529 var
535 begin
537 //if (length(fdiskname) > length(mBasePath)) and strEquCI1251(mBasePath, Copy(fdiskname, 1, length(mBasePath))) then Delete(fdiskname, 1, Length(mBasePath));
539 //fn := mBasePath+fdiskname;
542 // get age
545 // get size
551 // find old file, if any
552 //Delete(fn, 1, length(mBasePath));
554 // check for changes
556 begin
557 if (mFileList[idx].size = size) and (mFileList[idx].age = age) and (MD5Match(mFileList[idx].hash, md5)) then exit;