Browse Source

+ Added IOStreams
* Implemented fake seek for input pipe in some cases.

michael 26 years ago
parent
commit
920bff693e
2 changed files with 137 additions and 11 deletions
  1. 96 0
      fcl/inc/iostream.pp
  2. 41 11
      fcl/inc/pipes.pp

+ 96 - 0
fcl/inc/iostream.pp

@@ -0,0 +1,96 @@
+unit iostream;
+
+Interface
+
+Uses Classes;
+
+Type
+
+  TiosType = (iosInput,iosOutPut,iosError); 
+  EIOStreamError = Class(EStreamError);
+  
+  TIOStream = Class(THandleStream)
+    Private
+      FType,
+      FPos : Longint;
+    Public
+      Constructor Create(IOSType : TiosType);
+      Function Read(var Buffer; Count: Longint): Longint;override;
+      Function Write(const Buffer; Count: Longint): Longint;override;
+      Procedure SetSize(NewSize: Longint); override;
+      Function Seek(Offset: Longint; Origin: Word): Longint; override;
+   end;
+
+Implementation
+
+Const
+  SReadOnlyStream = 'Cannot write to an input stream.';
+  SWriteOnlyStream = 'Cannot read from an output stream.';
+  SInvalidOperation = 'Cannot perform this operation on a IOStream.';
+  
+Constructor TIOStream.Create(IOSType : TiosType);
+
+begin
+  FType:=Ord(IOSType);
+  Inherited Create(Ftype);
+end;
+
+
+Function TIOStream.Read(var Buffer; Count: Longint): Longint;
+
+begin
+  If Ftype>0 then
+    Raise EIOStreamError.Create(SWriteOnlyStream)
+  else
+    begin
+    Result:=Inherited Read(Buffer,Count);
+    Inc(FPos,Result);
+    end;
+end;
+
+
+Function TIOStream.Write(const Buffer; Count: Longint): Longint;
+
+begin
+  If Ftype=0 then
+    Raise EIOStreamError.Create(SReadOnlyStream)
+  else
+    begin
+    Result:=Inherited Write(Buffer,Count);
+    Inc(FPos,Result);
+    end;
+end;
+
+
+Procedure TIOStream.SetSize(NewSize: Longint); 
+
+begin
+  Raise EIOStreamError.Create(SInvalidOperation);
+end;
+
+
+Function TIOStream.Seek(Offset: Longint; Origin: Word): Longint; 
+
+Const BufSize = 100;
+
+Var Buf : array[1..BufSize] of Byte;
+
+begin
+  If (Origin=soFromCurrent) and (Offset=0) then
+     result:=FPos;
+  { Try to fake seek by reading and discarding }
+  if (Ftype>0) or
+     Not((Origin=soFromCurrent) and (Offset>=0) or  
+         ((Origin=soFrombeginning) and (OffSet>=FPos))) then 
+     Raise EIOStreamError.Create(SInvalidOperation);
+  if Origin=soFromBeginning then
+    Dec(Offset,FPos);
+  While ((Offset Div BufSize)>0) 
+        and (Read(Buf,SizeOf(Buf))=BufSize) do
+     Dec(Offset,BufSize);
+  If (Offset>0) then
+    Read(Buf,BufSize);
+  Result:=FPos;   
+end;
+
+end.

+ 41 - 11
fcl/inc/pipes.pp

@@ -27,18 +27,18 @@ Type
   EPipeSeek = Class (EPipeError);
   EPipeCreation = Class (EPipeError);
 
-  TPipeStream = Class (THandleStream)
-    public
-      Function Seek (Offset : Longint;Origin : Word) : longint;override;
-    end;
-
-  TInputPipeStream = Class(TPipeStream)
+  TInputPipeStream = Class(THandleStream)
+    Private 
+      FPos : longint;
     public
       Function Write (Const Buffer; Count : Longint) :Longint; Override;
+      Function Seek (Offset : Longint;Origin : Word) : longint;override;
+      Function Read (Var Buffer; Count : Longint) : longint; Override;
     end;
 
-  TOutputPipeStream = Class(TPipeStream)
+  TOutputPipeStream = Class(THandleStream)
     Public
+      Function Seek (Offset : Longint;Origin : Word) : longint;override;
       Function Read (Var Buffer; Count : Longint) : longint; Override;
     end;
 
@@ -70,16 +70,40 @@ begin
     Raise EPipeCreation.Create (EPipeMsg)
 end;
 
-Function TPipeStream.Seek (Offset : Longint;Origin : Word) : longint;
+Function TInputPipeStream.Write (Const Buffer; Count : Longint) : longint;
 
 begin
-  Raise EPipeSeek.Create (ENoSeekMsg);
+  Raise ENoWritePipe.Create (ENoWriteMsg);
 end;
 
-Function TInputPipeStream.Write (Const Buffer; Count : Longint) : longint;
+Function TInputPipeStream.Read (Var Buffer; Count : Longint) : longint;
 
 begin
-  Raise ENoWritePipe.Create (ENoWriteMsg);
+  Result:=Inherited Read(Buffer,Count);
+  Inc(FPos,Result);
+end;
+
+Function TInputPipeStream.Seek (Offset : Longint;Origin : Word) : longint;
+
+Const BufSize = 100;
+
+Var Buf : array[1..BufSize] of Byte;
+
+begin
+  If (Origin=soFromCurrent) and (Offset=0) then
+     result:=FPos;
+  { Try to fake seek by reading and discarding }
+  if Not((Origin=soFromCurrent) and (Offset>=0) or  
+         ((Origin=soFrombeginning) and (OffSet>=FPos))) then 
+     Raise EPipeSeek.Create(ENoSeekMSg);
+  if Origin=soFromBeginning then
+    Dec(Offset,FPos);
+  While ((Offset Div BufSize)>0) 
+        and (Read(Buf,SizeOf(Buf))=BufSize) do
+     Dec(Offset,BufSize);
+  If (Offset>0) then
+    Read(Buf,BufSize);
+  Result:=FPos;   
 end;
 
 Function TOutputPipeStream.Read(Var Buffer; Count : Longint) : longint;
@@ -88,4 +112,10 @@ begin
   Raise ENoReadPipe.Create (ENoReadMsg);
 end;
 
+Function TOutputPipeStream.Seek (Offset : Longint;Origin : Word) : longint;
+
+begin
+  Raise EPipeSeek.Create (ENoSeekMsg);
+end;
+
 end.