unit wscatcher;
{$mode objfpc}{$H+}
interface
uses
Classes, UTF8Process, Process;
type
{ TWSCatcher }
TWSCatcher = class(TThread)
private
FProcess: TProcessUTF8;
FInput, FOutput, FError: TStringList;
public
constructor Create;
destructor Destroy; override;
procedure Execute; override;
procedure Terminate;
procedure SendToSTDIN(const sData: string);
property ReceivedFromSTDOUT: TStringList read FOutput;
property ReceivedFromSTDERR: TStringList read FError;
property Process: TProcessUTF8 read FProcess;
end;
implementation
uses
SysUtils;
{ TWSCatcher }
constructor TWSCatcher.Create;
begin
inherited Create(True);
FInput:=TStringList.Create;
FError:=TStringList.Create;
FOutput:=TStringList.Create;
FProcess:=TProcessUTF8.Create(nil);
FProcess.Options:=[poNoConsole,poUsePipes];
end;
destructor TWSCatcher.Destroy;
begin
FProcess.Terminate(0);
FProcess.Free;
FOutput.Free;
FError.Free;
FInput.Free;
inherited Destroy;
end;
procedure TWSCatcher.Execute;
var
Send: string='';
Error: string='';
Received: string='';
ByteRead: byte=0;
begin
FProcess.Execute;
with FProcess do while Running do begin
if Output.NumBytesAvailable>0
then begin
ByteRead:=Output.ReadByte;
if (ByteRead<>13) and (ByteRead<>10) and (ByteRead<>0)
then Received:=Received+Char(ByteRead)
else begin
if Received.Trim<>''
then FOutput.Add(Received.Trim);
Received:='';
end;
end;
if Stderr.NumBytesAvailable>0
then begin
ByteRead:=Stderr.ReadByte;
if (ByteRead<>13) and (ByteRead<>10) and (ByteRead<>0)
then Error:=Error+Char(ByteRead)
else begin
if Error.Trim<>''
then FError.Add(Error.Trim);
Error:='';
end;
end;
while FInput.Count>0 do begin
Send:=FInput.Strings[0].Trim+LineEnding;
if Send<>LineEnding
then Input.Write(Send[1],Length(Send));
FInput.Delete(0);
end;
end;
ByteRead:=0;
Received:='';
Error:='';
Send:='';
end;
procedure TWSCatcher.Terminate;
begin
FProcess.Terminate(0);
inherited Terminate;
end;
procedure TWSCatcher.SendToSTDIN(const sData: string);
begin
if (sData.Trim<>'') and (Pos(#13,sData)=0) and (Pos(#10,sData)=0) and (Pos(#0,sData)=0)
then FInput.Add(sData.Trim);
end;
end.