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 >
Pascal/Delphi Source File  |  2002-09-25  |  10KB  |  357 lines

  1. unit VKDBFPrx;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, SysUtils, Classes, VKDBFUtil;
  7.  
  8. type
  9.  
  10.   TProxyStreamType = (pstFile, pstInnerStream, pstOuterStream);
  11.  
  12.   TLockEvent = procedure(Sender: TObject; ProxyStreamType: TProxyStreamType; Stream: TStream; var LockSuccess: boolean) of object;
  13.   TUnlockEvent = procedure(Sender: TObject; ProxyStreamType: TProxyStreamType; Stream: TStream; var UnlockSuccess: boolean) of object;
  14.  
  15.   {TAccessMode}
  16.   TAccessMode = class(TPersistent)
  17.   private
  18.     fOpenRead      : boolean;
  19.     fOpenWrite     : boolean;
  20.     fOpenReadWrite : boolean;
  21.     fShareExclusive: boolean;
  22.     fShareDenyWrite: boolean;
  23.     fShareDenyNone : boolean;
  24.     function GetAccessMode: LongWord;
  25.     procedure SetAccessMode(const Value: LongWord);
  26.   public
  27.     FLast: LongWord;
  28.     constructor Create;
  29.     function IsExists(const Value: LongWord): boolean;
  30.   published
  31.     property AccessMode: LongWord read GetAccessMode write SetAccessMode;
  32.     property OpenRead       : boolean read fOpenRead       write fOpenRead      ;
  33.     property OpenWrite      : boolean read fOpenWrite      write fOpenWrite     ;
  34.     property OpenReadWrite  : boolean read fOpenReadWrite  write fOpenReadWrite ;
  35.     property ShareExclusive : boolean read fShareExclusive write fShareExclusive;
  36.     property ShareDenyWrite : boolean read fShareDenyWrite write fShareDenyWrite;
  37.     property ShareDenyNone  : boolean read fShareDenyNone  write fShareDenyNone ;
  38.   end;
  39.  
  40.   {TProxyStream}
  41.   TProxyStream = class(TPersistent)
  42.   private
  43.  
  44.     FHandler: Integer;
  45.     FAccessMode: TAccessMode;
  46.     FFileName: String;
  47.     FInnerStream: TMemoryStream;
  48.     FIsInnerStreamOpen: boolean;
  49.     FOuterStream: TStream;
  50.     FIsOuterStreamOpen: boolean;
  51.     FProxyStreamType: TProxyStreamType;
  52.     FOnLockEvent: TLockEvent;
  53.     FOnUnlockEvent: TUnlockEvent;
  54.  
  55.   public
  56.  
  57.     constructor Create;
  58.     destructor Destroy; override;
  59.  
  60.     property InnerStream: TMemoryStream read FInnerStream;
  61.     property OuterStream: TStream read FOuterStream write FOuterStream;
  62.     property Handler: Integer read FHandler;
  63.  
  64.     procedure Open;
  65.     procedure CreateProxyStream;
  66.     function IsOpen: boolean;
  67.     function Seek(Offset, Origin: Integer): Integer;
  68.     function Read(var Buffer; Count: LongWord): Integer;
  69.     function Write(const Buffer; Count: LongWord): Integer;
  70.     function Lock(Offset, NumberOfBytes: Integer): Boolean;
  71.     function UnLock(Offset, NumberOfBytes: Integer): Boolean;
  72.     procedure SetEndOfFile;
  73.     procedure LoadFromFile(FileName: String);
  74.     procedure Close;
  75.  
  76.   published
  77.  
  78.     property ProxyStreamType: TProxyStreamType read FProxyStreamType write FProxyStreamType;
  79.  
  80.     property AccessMode: TAccessMode read FAccessMode write FAccessMode;
  81.     property FileName: String read FFileName write FFileName;
  82.  
  83.     property OnLockEvent: TLockEvent read FOnLockEvent write FOnLockEvent;
  84.     property OnUnlockEvent: TUnlockEvent read FOnUnlockEvent write FOnUnlockEvent;
  85.  
  86.   end;
  87.  
  88. implementation
  89.  
  90. uses
  91.   VKDBFMemMgr;
  92.  
  93. { TAccessMode }
  94.  
  95. constructor TAccessMode.Create;
  96. begin
  97.   inherited Create;
  98.   fOpenRead         := true;
  99.   fOpenWrite        := false;
  100.   fOpenReadWrite    := false;
  101.   fShareExclusive   := true;
  102.   fShareDenyWrite   := false;
  103.   fShareDenyNone    := false;
  104. end;
  105.  
  106. function TAccessMode.GetAccessMode: LongWord;
  107. begin
  108.   Result := 0;
  109.   if fOpenRead       then Result := Result or fmOpenRead      ;
  110.   if fOpenWrite      then Result := Result or fmOpenWrite     ;
  111.   if fOpenReadWrite  then Result := Result or fmOpenReadWrite ;
  112.   if fShareExclusive then Result := Result or fmShareExclusive;
  113.   if fShareDenyWrite then Result := Result or fmShareDenyWrite;
  114.   if fShareDenyNone  then Result := Result or fmShareDenyNone ;
  115.   FLast := Result;
  116. end;
  117.  
  118. function TAccessMode.IsExists(const Value: LongWord): boolean;
  119. begin
  120.   Result := ( (AccessMode and Value) = Value );
  121. end;
  122.  
  123. procedure TAccessMode.SetAccessMode(const Value: LongWord);
  124. begin
  125.   fOpenRead       := false;
  126.   fOpenWrite      := false;
  127.   fOpenReadWrite  := false;
  128.   fShareExclusive := false;
  129.   fShareDenyWrite := false;
  130.   fShareDenyNone  := false;
  131.   if (Value and fmOpenRead       ) = fmOpenRead       then fOpenRead       := true;
  132.   if (Value and fmOpenWrite      ) = fmOpenWrite      then fOpenWrite      := true;
  133.   if (Value and fmOpenReadWrite  ) = fmOpenReadWrite  then fOpenReadWrite  := true;
  134.   if (Value and fmShareExclusive ) = fmShareExclusive then fShareExclusive := true;
  135.   if (Value and fmShareDenyWrite ) = fmShareDenyWrite then fShareDenyWrite := true;
  136.   if (Value and fmShareDenyNone  ) = fmShareDenyNone  then fShareDenyNone  := true;
  137. end;
  138.  
  139. { TProxyStream }
  140.  
  141. procedure TProxyStream.Close;
  142. begin
  143.   if IsOpen then
  144.     case ProxyStreamType of
  145.       pstFile:
  146.         begin
  147.           SysUtils.FileClose(FHandler);
  148.           FHandler := -1;
  149.         end;
  150.       pstInnerStream: FIsInnerStreamOpen := False;
  151.       pstOuterStream: FIsOuterStreamOpen := False;
  152.     end;
  153. end;
  154.  
  155. constructor TProxyStream.Create;
  156. begin
  157.   inherited Create;
  158.   FProxyStreamType := pstFile;
  159.   FHandler := -1;
  160.   FAccessMode := TAccessMode.Create;
  161.   FFileName := '';
  162.   FInnerStream := TMemoryStream.Create;
  163.   FOuterStream := nil;
  164.   FIsInnerStreamOpen := False;
  165.   FIsOuterStreamOpen := False;
  166.   FOnLockEvent := nil;
  167.   FOnUnlockEvent := nil;
  168. end;
  169.  
  170. procedure TProxyStream.CreateProxyStream;
  171. begin
  172.   case ProxyStreamType of
  173.     pstFile: FHandler := SysUtils.FileCreate(FileName);
  174.     pstInnerStream:
  175.       begin
  176.         FInnerStream.Size := 0;
  177.         FInnerStream.Position := 0;
  178.         FIsInnerStreamOpen := True;
  179.       end;
  180.     pstOuterStream:
  181.       begin
  182.         FOuterStream.Size := 0;
  183.         FOuterStream.Position := 0;
  184.         FIsOuterStreamOpen := True;
  185.       end;
  186.   end;
  187. end;
  188.  
  189. destructor TProxyStream.Destroy;
  190. begin
  191.   Close;
  192.   FInnerStream.Destroy;
  193.   FAccessMode.Destroy;
  194.   inherited Destroy;
  195. end;
  196.  
  197. function TProxyStream.IsOpen: boolean;
  198. begin
  199.   Result := False;
  200.   case ProxyStreamType of
  201.     pstFile: Result := (FHandler > 0);
  202.     pstInnerStream: Result := FIsInnerStreamOpen;
  203.     pstOuterStream: Result := FIsOuterStreamOpen;
  204.   end;
  205. end;
  206.  
  207. procedure TProxyStream.LoadFromFile(FileName: String);
  208. var
  209.   Stream: TFileStream;
  210.  
  211.   procedure CopyFile;
  212.   const
  213.     MaxBufSize = $F000;
  214.   var
  215.     Buffer: PChar;
  216.     r: Integer;
  217.   begin
  218.     SysUtils.FileSeek(FHandler, 0, 0);
  219.     Windows.SetEndOfFile(FHandler);
  220.     Buffer := VKDBFMemMgr.oMem.GetMem('TProxyStream.LoadFromFile', MaxBufSize);
  221.     try
  222.       repeat
  223.         r := Stream.Read(Buffer^, MaxBufSize);
  224.         SysUtils.FileWrite(FHandler, Buffer^, r);
  225.       until r <= 0;
  226.     finally
  227.       VKDBFMemMgr.oMem.FreeMem(Buffer);
  228.     end;
  229.     SysUtils.FileSeek(FHandler, 0, 0);
  230.   end;
  231.  
  232. begin
  233.   Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  234.   try
  235.     case ProxyStreamType of
  236.       pstFile: CopyFile;
  237.       pstInnerStream: FInnerStream.LoadFromFile(FileName);
  238.       pstOuterStream:
  239.         begin
  240.           FOuterStream.Size := 0;
  241.           FOuterStream.CopyFrom(Stream, Stream.Size);
  242.           FOuterStream.Position := 0;
  243.         end;
  244.     end;
  245.   finally
  246.     Stream.Free;
  247.   end;
  248. end;
  249.  
  250. function TProxyStream.Lock(Offset, NumberOfBytes: Integer): Boolean;
  251. begin
  252.   Result := False;
  253.   case ProxyStreamType of
  254.     pstFile: Result := VKDBFUtil.FileLock(FHandler, Offset, NumberOfBytes);
  255.     pstInnerStream: Result := True;
  256.     pstOuterStream:
  257.       begin
  258.         if Assigned(OnLockEvent) then
  259.           OnLockEvent(self, ProxyStreamType, FOuterStream, Result)
  260.         else
  261.           Result := True;
  262.       end;
  263.   end;
  264. end;
  265.  
  266. procedure TProxyStream.Open;
  267. begin
  268.   case ProxyStreamType of
  269.     pstFile: FHandler := SysUtils.FileOpen(FileName, AccessMode.AccessMode);
  270.     pstInnerStream:
  271.       begin
  272.         FInnerStream.Position := 0;
  273.         FIsInnerStreamOpen := True;
  274.       end;
  275.     pstOuterStream:
  276.       begin
  277.         FOuterStream.Position := 0;
  278.         FIsOuterStreamOpen := True;
  279.       end;
  280.   end;
  281. end;
  282.  
  283. function TProxyStream.Read(var Buffer; Count: LongWord): Integer;
  284. begin
  285.   Result := -1;
  286.   case ProxyStreamType of
  287.     pstFile: Result := SysUtils.FileRead(FHandler, Buffer, Count);
  288.     pstInnerStream: Result := FInnerStream.Read(Buffer, Count);
  289.     pstOuterStream: Result := FOuterStream.Read(Buffer, Count);
  290.   end;
  291. end;
  292.  
  293. function TProxyStream.Seek(Offset, Origin: Integer): Integer;
  294. //var
  295. //  OldPos: Integer;
  296. begin
  297.   Result := -1;
  298.   case ProxyStreamType of
  299.     pstFile: Result := SysUtils.FileSeek(FHandler, Offset, Origin);
  300.     pstInnerStream:
  301.       begin
  302.         //OldPos := FInnerStream.Position;
  303.         Result := FInnerStream.Seek(Offset, Origin);
  304.         //if (Result < 0) or (Result > FInnerStream.Size) then begin
  305.         //  FInnerStream.Position := OldPos;
  306.         //  Result := -1;
  307.         //end;
  308.       end;
  309.     pstOuterStream:
  310.       begin
  311.         //OldPos := FOuterStream.Position;
  312.         Result := FOuterStream.Seek(Offset, Origin);
  313.         //if (Result < 0) or (Result > FOuterStream.Size) then begin
  314.         //  FOuterStream.Position := OldPos;
  315.         //  Result := -1;
  316.         //end;
  317.       end;
  318.   end;
  319. end;
  320.  
  321. procedure TProxyStream.SetEndOfFile;
  322. begin
  323.   case ProxyStreamType of
  324.     pstFile: Windows.SetEndOfFile(FHandler);
  325.     pstInnerStream: FInnerStream.Size := FInnerStream.Position;
  326.     pstOuterStream: FOuterStream.Size := FOuterStream.Position;
  327.   end;
  328. end;
  329.  
  330. function TProxyStream.UnLock(Offset, NumberOfBytes: Integer): Boolean;
  331. begin
  332.   Result := False;
  333.   case ProxyStreamType of
  334.     pstFile: Result := VKDBFUtil.FileUnLock(FHandler, Offset, NumberOfBytes);
  335.     pstInnerStream: Result := True;
  336.     pstOuterStream:
  337.       begin
  338.         if Assigned(OnUnlockEvent) then
  339.           OnUnlockEvent(self, ProxyStreamType, FOuterStream, Result)
  340.         else
  341.           Result := True;
  342.       end;
  343.   end;
  344. end;
  345.  
  346. function TProxyStream.Write(const Buffer; Count: LongWord): Integer;
  347. begin
  348.   Result := -1;
  349.   case ProxyStreamType of
  350.     pstFile: Result := SysUtils.FileWrite(FHandler, Buffer, Count);
  351.     pstInnerStream: Result := FInnerStream.Write(Buffer, Count);
  352.     pstOuterStream: Result := FOuterStream.Write(Buffer, Count);
  353.   end;
  354. end;
  355.  
  356. end.
  357.