📄 abarctyp.pas
字号:
function TAbArchive.FindFile(const aFileName : string): Integer; {find the index of the specified file}begin Result := FItemList.Find(aFileName);end;{ -------------------------------------------------------------------------- }function TAbArchive.FindItem(aItem : TAbArchiveItem): Integer; {find the index of the specified item}begin Result := FItemList.Find(aItem.FileName);end;{ -------------------------------------------------------------------------- }function TAbArchive.FixName(Value : string) : string;begin {$IFDEF MSWINDOWS} if DOSMode then begin {Add the base directory to the filename before converting } {the file spec to the short filespec format. } if BaseDirectory <> '' then begin {Does the filename contain a drive or a leading backslash? } if not ((Pos(':', Value) = 2) or (Pos(AbPathDelim, Value) = 1)) then {If not, add the BaseDirectory to the filename.} Value := AbAddBackSlash(BaseDirectory) + Value; {!!.04} end; Value := AbGetShortFileSpec(Value); end; {$ENDIF} {strip drive stuff} if soStripDrive in StoreOptions then AbStripDrive(Value); {check for a leading backslash} if Value[1] = AbPathDelim then System.Delete(Value, 1, 1); if soStripPath in StoreOptions then begin Value := ExtractFileName(Value); end; if soRemoveDots in StoreOptions then AbStripDots(Value); Result := Value;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Freshen(aItem : TAbArchiveItem); {freshen the item}var Index : Integer;begin CheckValid; Index := FindItem(aItem); if Index <> -1 then FreshenAt(Index);end;{ -------------------------------------------------------------------------- }procedure TAbArchive.FreshenAt(Index : Integer); {freshen item at index}var Confirm : Boolean; FR : Boolean; ErrorClass : TAbErrorClass; ErrorCode : Integer;begin CheckValid; SaveIfNeeded(FItemList[Index]); Lock; try GetFreshenTarget(FItemList[Index]); FR := False; try FR := FreshenRequired(FItemList[Index]); except on E : Exception do begin AbConvertException(E, ErrorClass, ErrorCode); DoProcessItemFailure(FItemList[Index], ptFreshen, ErrorClass, ErrorCode); end; end; if not FR then Exit; DoConfirmProcessItem(FItemList[Index], ptFreshen, Confirm); if not Confirm then Exit; TAbArchiveItem(FItemList[Index]).Action := aaFreshen; FIsDirty := True; if AutoSave then Save; finally Unlock; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.FreshenFiles(const FileMask : string); {freshen all items that match the file mask}begin FreshenFilesEx(FileMask, '');end;{ -------------------------------------------------------------------------- }procedure TAbArchive.FreshenFilesEx(const FileMask, ExclusionMask : string); {freshen all items that match the file mask}var i : Integer;begin CheckValid; if Count > 0 then begin for i := pred(Count) downto 0 do begin with TAbArchiveItem(FItemList[i]) do if MatchesStoredNameEx(FileMask) then if not MatchesStoredNameEx(ExclusionMask) then FreshenAt(i); end; end;end;{ -------------------------------------------------------------------------- }function TAbArchive.FreshenRequired(Item : TAbArchiveItem) : Boolean;type DW = packed record Lo : Word; Hi : Word; end;var FS : TFileStream; DateTime : LongInt; FileTime : Word; FileDate : Word; Matched : Boolean; SaveDir : string;begin GetDir(0, SaveDir); if BaseDirectory <> '' then ChDir(BaseDirectory); try FS := TFileStream.Create(Item.DiskFileName, fmOpenRead or fmShareDenyWrite); try DateTime := FileGetDate(FS.Handle); FileTime := DW(DateTime).Lo; FileDate := DW(DateTime).Hi; Matched := (Item.LastModFileDate = FileDate) and (Item.LastModFileTime = FileTime); Result := not Matched; finally FS.Free; end; finally if BaseDirectory <> '' then ChDir(SaveDir); end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.FreshenTaggedItems; {freshen all tagged items}var i : Integer;begin CheckValid; if Count > 0 then begin for i := pred(Count) downto 0 do begin with TAbArchiveItem(FItemList[i]) do if Tagged then FreshenAt(i); end; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.GetFreshenTarget(Item : TAbArchiveItem);var PathType : TAbPathType; Files : TStrings; SaveDir : string; DName : string;begin PathType := AbGetPathType(Item.FileName); if (soRecurse in StoreOptions) and (PathType = ptNone) then begin GetDir(0, SaveDir); if BaseDirectory <> '' then ChDir(BaseDirectory); try Files := TStringList.Create; try AbFindFiles(Item.FileName, faAnyFile and not faDirectory, Files, True); if Files.Count > 0 then begin DName := AbAddBackSlash(BaseDirectory) + Files[0]; {!!.04} AbUnfixName(DName); Item.DiskFileName := DName; end else Item.DiskFileName := ''; finally Files.Free; end; finally if BaseDirectory <> '' then ChDir(SaveDir); end; end else begin if (BaseDirectory <> '') then DName := AbAddBackSlash(BaseDirectory) + Item.FileName {!!.04} else DName := Item.FileName; AbUnfixName(DName); Item.DiskFileName := DName; end;end;{ -------------------------------------------------------------------------- }function TAbArchive.GetSpanningThreshold : Longint;begin Result := FSpanningThreshold;end;{ -------------------------------------------------------------------------- }function TAbArchive.GetItemCount : Integer;begin if Assigned(FItemList) then Result := FItemList.Count else Result := 0;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Init;begin FIsDirty := False; FAutoSave := False; FItemList := TAbArchiveList.Create; FPadLock := TAbPadLock.Create; StoreOptions := []; ExtractOptions := []; FStatus := asIdle;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Load; {load the archive}begin Lock; try LoadArchive; FStatus := asIdle; finally DoLoad; Unlock; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Lock;begin FPadLock.Locked := True; FStatus := asBusy;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.MakeLogEntry(const FN: string; LT : TAbLogType);var Buf : array[0..255] of Char;begin if Assigned(FLogStream) then begin case LT of ltAdd : StrPCopy(Buf, FN + AbStrRes(AbLtAdd) + DateTimeToStr(Now) + CRLF); ltDelete : StrPCopy(Buf, FN + AbStrRes(AbLtDelete) + DateTimeToStr(Now) + CRLF); ltExtract : StrPCopy(Buf, FN + AbStrRes(AbLtExtract) + DateTimeToStr(Now) + CRLF); ltFreshen : StrPCopy(Buf, FN + AbStrRes(AbLtFreshen) + DateTimeToStr(Now) + CRLF); ltMove : StrPCopy(Buf, FN + AbStrRes(AbLtMove) + DateTimeToStr(Now) + CRLF); ltReplace : StrPCopy(Buf, FN + AbStrRes(AbLtReplace) + DateTimeToStr(Now) + CRLF); ltStart : StrPCopy(Buf, FN + AbStrRes(AbLtStart) + DateTimeToStr(Now) + CRLF); ltFoundUnhandled : StrPCopy(Buf, FN + AbStrRes(AbUnhandledEntity) + DateTimeToStr(Now) + CRLF); end; FLogStream.Write(Buf, StrLen(Buf)); end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Move(aItem : TAbArchiveItem; NewStoredPath : string);var Confirm : Boolean; Found : Boolean; i : Integer;begin CheckValid; Found := False; if Count > 0 then for i := 0 to pred(Count) do with TAbArchiveItem(FItemList[i]) do begin if CompareText(FixName(NewStoredPath), FileName) = 0 then if Action <> aaDelete then begin Found := True; break; end; end; if Found then begin DoProcessItemFailure(aItem, ptMove, ecAbbrevia, AbDuplicateName); {even if something gets done in the AddItemFailure, we don't want to continue...} Exit; end; SaveIfNeeded(aItem); Lock; try DoConfirmProcessItem(aItem, ptMove, Confirm); if not Confirm then Exit; with aItem do begin FileName := FixName(NewStoredPath); Action := aaMove; end; FIsDirty := True; if AutoSave then Save; finally Unlock; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Replace(aItem : TAbArchiveItem); {replace the item}var Index : Integer;begin CheckValid; Index := FindItem(aItem); if Index <> -1 then ReplaceAt(Index);end;{ -------------------------------------------------------------------------- }procedure TAbArchive.ReplaceAt(Index : Integer); {replace item at Index}var Confirm : Boolean;begin CheckValid; SaveIfNeeded(FItemList[Index]); Lock; try GetFreshenTarget(FItemList[Index]); DoConfirmProcessItem(FItemList[Index], ptReplace, Confirm); if not Confirm then Exit; TAbArchiveItem(FItemList[Index]).Action := aaReplace; FIsDirty := True; if AutoSave then Save; finally Unlock; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Save; {save the archive}var Confirm : Boolean;begin if Status = asInvalid then Exit; if (not FIsDirty) and (Count > 0) then Exit; Lock; try DoConfirmSave(Confirm); if not Confirm then Exit; SaveArchive; FIsDirty := False; DoSave; finally Unlock; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.SaveIfNeeded(aItem : TAbArchiveItem);begin if (aItem.Action <> aaNone) then Save;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.SetBaseDirectory(Value : string);begin if (Value <> '') then if Value[Length(Value)] = AbPathDelim then if (Length(Value) > 1) and (Value[Length(Value) - 1] <> ':') then System.Delete(Value, Length(Value), 1); if (Length(Value) = 0) or AbDirectoryExists(Value) then FBaseDirectory := Value else raise EAbNoSuchDirectory.CreateFmt('No such directory : "%s"',[Value]);end;{ -------------------------------------------------------------------------- }procedure TAbArchive.SetSpanningThreshold( Value : Longint );begin FSpanningThreshold := Value;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.SetLogFile(Value : string);begin FLogFile := Value;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.SetLogging(Value : Boolean);begin FLogging := Value; if Assigned(FLogStream) then begin FLogStream.Free; FLogStream := nil; end; if FLogging and (FLogFile <> '') then begin try FLogStream := TFileStream.Create(FLogFile, fmCreate or fmOpenWrite); MakeLogEntry(FArchiveName, ltStart); except raise EAbException.Create(AbLogCreateErrorS); {!!.02} end; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.TagItems(const FileMask : string); {tag all items that match the mask}var i : Integer;begin if Count > 0 then for i := 0 to pred(Count) do with TAbArchiveItem(FItemList[i]) do begin if MatchesStoredNameEx(FileMask) then Tagged := True; end;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.Unlock;begin if FStatus = asBusy then FStatus := asIdle; FPadLock.Locked := False;end;{ -------------------------------------------------------------------------- }procedure TAbArchive.UnTagItems(const FileMask : string); {clear tags for all items that match the mask}var i : Integer;begin if Count > 0 then for i := 0 to pred(Count) do with TAbArchiveItem(FItemList[i]) do begin if MatchesStoredNameEx(FileMask) then Tagged := False; end;end;{ ========================================================================== }procedure TAbArchive.DoSpanningMediaRequest(Sender: TObject; ImageNumber: Integer; var ImageName: string; var Abort: Boolean);begin raise EAbSpanningNotSupported.Create;end;{ TAbArchiveStreamHelper }constructor TAbArchiveStreamHelper.Create(AStream: TStream);begin if Assigned(AStream) then FStream := AStream else raise Exception.Create('nil stream');end;end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -