home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2003 January
/
Chip_2003-01_cd1.bin
/
zkuste
/
delphi
/
kompon
/
d56
/
VKDBF.ZIP
/
VKDBFPrx.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-09-25
|
10KB
|
357 lines
unit VKDBFPrx;
interface
uses
Windows, SysUtils, Classes, VKDBFUtil;
type
TProxyStreamType = (pstFile, pstInnerStream, pstOuterStream);
TLockEvent = procedure(Sender: TObject; ProxyStreamType: TProxyStreamType; Stream: TStream; var LockSuccess: boolean) of object;
TUnlockEvent = procedure(Sender: TObject; ProxyStreamType: TProxyStreamType; Stream: TStream; var UnlockSuccess: boolean) of object;
{TAccessMode}
TAccessMode = class(TPersistent)
private
fOpenRead : boolean;
fOpenWrite : boolean;
fOpenReadWrite : boolean;
fShareExclusive: boolean;
fShareDenyWrite: boolean;
fShareDenyNone : boolean;
function GetAccessMode: LongWord;
procedure SetAccessMode(const Value: LongWord);
public
FLast: LongWord;
constructor Create;
function IsExists(const Value: LongWord): boolean;
published
property AccessMode: LongWord read GetAccessMode write SetAccessMode;
property OpenRead : boolean read fOpenRead write fOpenRead ;
property OpenWrite : boolean read fOpenWrite write fOpenWrite ;
property OpenReadWrite : boolean read fOpenReadWrite write fOpenReadWrite ;
property ShareExclusive : boolean read fShareExclusive write fShareExclusive;
property ShareDenyWrite : boolean read fShareDenyWrite write fShareDenyWrite;
property ShareDenyNone : boolean read fShareDenyNone write fShareDenyNone ;
end;
{TProxyStream}
TProxyStream = class(TPersistent)
private
FHandler: Integer;
FAccessMode: TAccessMode;
FFileName: String;
FInnerStream: TMemoryStream;
FIsInnerStreamOpen: boolean;
FOuterStream: TStream;
FIsOuterStreamOpen: boolean;
FProxyStreamType: TProxyStreamType;
FOnLockEvent: TLockEvent;
FOnUnlockEvent: TUnlockEvent;
public
constructor Create;
destructor Destroy; override;
property InnerStream: TMemoryStream read FInnerStream;
property OuterStream: TStream read FOuterStream write FOuterStream;
property Handler: Integer read FHandler;
procedure Open;
procedure CreateProxyStream;
function IsOpen: boolean;
function Seek(Offset, Origin: Integer): Integer;
function Read(var Buffer; Count: LongWord): Integer;
function Write(const Buffer; Count: LongWord): Integer;
function Lock(Offset, NumberOfBytes: Integer): Boolean;
function UnLock(Offset, NumberOfBytes: Integer): Boolean;
procedure SetEndOfFile;
procedure LoadFromFile(FileName: String);
procedure Close;
published
property ProxyStreamType: TProxyStreamType read FProxyStreamType write FProxyStreamType;
property AccessMode: TAccessMode read FAccessMode write FAccessMode;
property FileName: String read FFileName write FFileName;
property OnLockEvent: TLockEvent read FOnLockEvent write FOnLockEvent;
property OnUnlockEvent: TUnlockEvent read FOnUnlockEvent write FOnUnlockEvent;
end;
implementation
uses
VKDBFMemMgr;
{ TAccessMode }
constructor TAccessMode.Create;
begin
inherited Create;
fOpenRead := true;
fOpenWrite := false;
fOpenReadWrite := false;
fShareExclusive := true;
fShareDenyWrite := false;
fShareDenyNone := false;
end;
function TAccessMode.GetAccessMode: LongWord;
begin
Result := 0;
if fOpenRead then Result := Result or fmOpenRead ;
if fOpenWrite then Result := Result or fmOpenWrite ;
if fOpenReadWrite then Result := Result or fmOpenReadWrite ;
if fShareExclusive then Result := Result or fmShareExclusive;
if fShareDenyWrite then Result := Result or fmShareDenyWrite;
if fShareDenyNone then Result := Result or fmShareDenyNone ;
FLast := Result;
end;
function TAccessMode.IsExists(const Value: LongWord): boolean;
begin
Result := ( (AccessMode and Value) = Value );
end;
procedure TAccessMode.SetAccessMode(const Value: LongWord);
begin
fOpenRead := false;
fOpenWrite := false;
fOpenReadWrite := false;
fShareExclusive := false;
fShareDenyWrite := false;
fShareDenyNone := false;
if (Value and fmOpenRead ) = fmOpenRead then fOpenRead := true;
if (Value and fmOpenWrite ) = fmOpenWrite then fOpenWrite := true;
if (Value and fmOpenReadWrite ) = fmOpenReadWrite then fOpenReadWrite := true;
if (Value and fmShareExclusive ) = fmShareExclusive then fShareExclusive := true;
if (Value and fmShareDenyWrite ) = fmShareDenyWrite then fShareDenyWrite := true;
if (Value and fmShareDenyNone ) = fmShareDenyNone then fShareDenyNone := true;
end;
{ TProxyStream }
procedure TProxyStream.Close;
begin
if IsOpen then
case ProxyStreamType of
pstFile:
begin
SysUtils.FileClose(FHandler);
FHandler := -1;
end;
pstInnerStream: FIsInnerStreamOpen := False;
pstOuterStream: FIsOuterStreamOpen := False;
end;
end;
constructor TProxyStream.Create;
begin
inherited Create;
FProxyStreamType := pstFile;
FHandler := -1;
FAccessMode := TAccessMode.Create;
FFileName := '';
FInnerStream := TMemoryStream.Create;
FOuterStream := nil;
FIsInnerStreamOpen := False;
FIsOuterStreamOpen := False;
FOnLockEvent := nil;
FOnUnlockEvent := nil;
end;
procedure TProxyStream.CreateProxyStream;
begin
case ProxyStreamType of
pstFile: FHandler := SysUtils.FileCreate(FileName);
pstInnerStream:
begin
FInnerStream.Size := 0;
FInnerStream.Position := 0;
FIsInnerStreamOpen := True;
end;
pstOuterStream:
begin
FOuterStream.Size := 0;
FOuterStream.Position := 0;
FIsOuterStreamOpen := True;
end;
end;
end;
destructor TProxyStream.Destroy;
begin
Close;
FInnerStream.Destroy;
FAccessMode.Destroy;
inherited Destroy;
end;
function TProxyStream.IsOpen: boolean;
begin
Result := False;
case ProxyStreamType of
pstFile: Result := (FHandler > 0);
pstInnerStream: Result := FIsInnerStreamOpen;
pstOuterStream: Result := FIsOuterStreamOpen;
end;
end;
procedure TProxyStream.LoadFromFile(FileName: String);
var
Stream: TFileStream;
procedure CopyFile;
const
MaxBufSize = $F000;
var
Buffer: PChar;
r: Integer;
begin
SysUtils.FileSeek(FHandler, 0, 0);
Windows.SetEndOfFile(FHandler);
Buffer := VKDBFMemMgr.oMem.GetMem('TProxyStream.LoadFromFile', MaxBufSize);
try
repeat
r := Stream.Read(Buffer^, MaxBufSize);
SysUtils.FileWrite(FHandler, Buffer^, r);
until r <= 0;
finally
VKDBFMemMgr.oMem.FreeMem(Buffer);
end;
SysUtils.FileSeek(FHandler, 0, 0);
end;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
case ProxyStreamType of
pstFile: CopyFile;
pstInnerStream: FInnerStream.LoadFromFile(FileName);
pstOuterStream:
begin
FOuterStream.Size := 0;
FOuterStream.CopyFrom(Stream, Stream.Size);
FOuterStream.Position := 0;
end;
end;
finally
Stream.Free;
end;
end;
function TProxyStream.Lock(Offset, NumberOfBytes: Integer): Boolean;
begin
Result := False;
case ProxyStreamType of
pstFile: Result := VKDBFUtil.FileLock(FHandler, Offset, NumberOfBytes);
pstInnerStream: Result := True;
pstOuterStream:
begin
if Assigned(OnLockEvent) then
OnLockEvent(self, ProxyStreamType, FOuterStream, Result)
else
Result := True;
end;
end;
end;
procedure TProxyStream.Open;
begin
case ProxyStreamType of
pstFile: FHandler := SysUtils.FileOpen(FileName, AccessMode.AccessMode);
pstInnerStream:
begin
FInnerStream.Position := 0;
FIsInnerStreamOpen := True;
end;
pstOuterStream:
begin
FOuterStream.Position := 0;
FIsOuterStreamOpen := True;
end;
end;
end;
function TProxyStream.Read(var Buffer; Count: LongWord): Integer;
begin
Result := -1;
case ProxyStreamType of
pstFile: Result := SysUtils.FileRead(FHandler, Buffer, Count);
pstInnerStream: Result := FInnerStream.Read(Buffer, Count);
pstOuterStream: Result := FOuterStream.Read(Buffer, Count);
end;
end;
function TProxyStream.Seek(Offset, Origin: Integer): Integer;
//var
// OldPos: Integer;
begin
Result := -1;
case ProxyStreamType of
pstFile: Result := SysUtils.FileSeek(FHandler, Offset, Origin);
pstInnerStream:
begin
//OldPos := FInnerStream.Position;
Result := FInnerStream.Seek(Offset, Origin);
//if (Result < 0) or (Result > FInnerStream.Size) then begin
// FInnerStream.Position := OldPos;
// Result := -1;
//end;
end;
pstOuterStream:
begin
//OldPos := FOuterStream.Position;
Result := FOuterStream.Seek(Offset, Origin);
//if (Result < 0) or (Result > FOuterStream.Size) then begin
// FOuterStream.Position := OldPos;
// Result := -1;
//end;
end;
end;
end;
procedure TProxyStream.SetEndOfFile;
begin
case ProxyStreamType of
pstFile: Windows.SetEndOfFile(FHandler);
pstInnerStream: FInnerStream.Size := FInnerStream.Position;
pstOuterStream: FOuterStream.Size := FOuterStream.Position;
end;
end;
function TProxyStream.UnLock(Offset, NumberOfBytes: Integer): Boolean;
begin
Result := False;
case ProxyStreamType of
pstFile: Result := VKDBFUtil.FileUnLock(FHandler, Offset, NumberOfBytes);
pstInnerStream: Result := True;
pstOuterStream:
begin
if Assigned(OnUnlockEvent) then
OnUnlockEvent(self, ProxyStreamType, FOuterStream, Result)
else
Result := True;
end;
end;
end;
function TProxyStream.Write(const Buffer; Count: LongWord): Integer;
begin
Result := -1;
case ProxyStreamType of
pstFile: Result := SysUtils.FileWrite(FHandler, Buffer, Count);
pstInnerStream: Result := FInnerStream.Write(Buffer, Count);
pstOuterStream: Result := FOuterStream.Write(Buffer, Count);
end;
end;
end.