[Lazarus] Can't copy TMemoryStream to TProcess.Input

Leonardo M. Ramé l.rame at griensu.com
Sat Apr 6 18:22:39 CEST 2013


On 2013-04-06 17:46:06 +0200, Mattias Gaertner wrote:
> On Sat, 6 Apr 2013 12:37:06 -0300
> Leonardo M. Ramé <l.rame at griensu.com> wrote:
> 
> >[...]
> > > Check return value of Proc.Input.Write.
> > > And call Proc.CloseInput when your input was written completely.
> > > 
> > > 
> > 
> > Mmm, I'm getting the same result. 
> > 
> > I attached the new code.
> 
> When you give Proc.Input.Write 200 bytes and it returns that the other
> process could only process 100 of them. What bytes do you have to write
> next?
> 

Sorry, I'm not getting it. Which other process?, apart from that,
Proc.Input.Write is always returning the sizeof(buffer) except when it
reaches the end, where it can be less than it.

It seems that the Proc.Input part is ok, aparently the Proc.Output is
wrong :(

I attached a slightly modified code.

-- 
Leonardo M. Ramé
http://leonardorame.blogspot.com
-------------- next part --------------
program test;

{$mode objfpc}{$H+}

uses
  SysUtils, Classes, 
  process,
  math;

function CompressLZMA(AStream: TMemoryStream): TMemoryStream;
var
  Proc: TProcess;
  lInBuffer: array [0..2047] of byte;
  lOutBuffer: array [0..2047] of byte;
  ReadCount: longint;
  WriteCount: longint;
  InputWriteCount: longint;
begin
  Result := TMemoryStream.Create;
  AStream.Position:= 0;
  Proc := TProcess.Create(nil); 
  try
    Proc.Executable := '/usr/bin/lzma';
    Proc.Parameters.Add('-z');
    Proc.Parameters.Add('-c');
    Proc.Options := [poUsePipes, poStderrToOutPut];
    Proc.Execute; 
  
    InputWriteCount := 0;
    repeat
      ReadCount := AStream.Read(lInBuffer, SizeOf(lInBuffer));
      InputWriteCount := Proc.Input.Write(lInBuffer, ReadCount);
      writeln(Format('%d - %d', [InputWriteCount, AStream.Size]));
      while (Proc.Output.NumBytesAvailable > 0) do
      begin
        WriteCount := Min(SizeOf(lOutBuffer), Proc.Output.NumBytesAvailable);
        WriteCount := Proc.Output.Read(lOutBuffer, WriteCount);
        Result.Write(lOutBuffer, WriteCount);
      end;
      if AStream.Position = AStream.Size then
        Proc.CloseInput; 
    until Proc.Input = nil;
    Result.Position:= 0;
  finally
    Proc.Free;
  end;
end; 

var
  lStr: TMemoryStream;
begin
  lStr := TMemoryStream.Create;
  try
    lStr.LoadFromFile('mg.dcm');
    CompressLZMA(lStr).SaveToFile('output.lzma');    
  finally
    lStr.Free;
  end;
end.


More information about the Lazarus mailing list