* * *

Author Topic: [SOLVED] Stream newb - simple question  (Read 692 times)

BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
[SOLVED] Stream newb - simple question
« on: February 10, 2012, 10:27:20 am »
Hi all,

Trying to decompress .bz2 files, but getting a stream read error.
(Note: I know there's an error in the Pascal bzip2 decompressor on i386; see bug 21242; I'm trying this with a x64 Linux compiler)

I've tried to chain the input file stream to the decompression stream, but I'm probably doing something wrong there. The code errors at the marked point.

Code:
Code: [Select]
var
  InFile:TFileStream;
  Decompressed:TDecompressBzip2Stream;
  OutFile:TFileStream;
begin
  result:=false;
  InFile:=TFileStream.Create(SourceFile, fmOpenRead);
  try
    Decompressed:=TDecompressBzip2Stream.Create(InFile);
    OutFile:=TFileStream.Create(TargetFile, fmCreate);
    try
      Decompressed.CopyFrom(InFile, InFile.Size); //error occurs here.
      OutFile.CopyFrom(Decompressed, Decompressed.Size);
      result:=true;
    finally
      Decompressed.Free;
      OutFile.Free;
    end;
  finally
    InFile.Free;
  end;

Entire Lazarus program attached.

Thanks!
« Last Edit: February 10, 2012, 04:29:06 pm by BigChimp »
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

User137

  • Hero Member
  • *****
  • Posts: 503
Re: Stream newb - simple question
« Reply #1 on: February 10, 2012, 03:15:29 pm »
I don't know about these streams, but doesn't the program logic feel odd? I mean, you give TDecompressBzip2Stream 2 references to InFile.

I'd try with like:
Code: [Select]
...
  try
    Decompressed:=TDecompressBzip2Stream.Create(InFile);
    OutFile:=TFileStream.Create(TargetFile, fmCreate);
    try
      //Decompressed.CopyFrom(InFile, InFile.Size); //error occurs here. (Just comment it out)
      // Possibly here is some method from TDecompressBzip2Stream, don't know, maybe not needed
      OutFile.CopyFrom(Decompressed, Decompressed.Size);
...

BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
Re: Stream newb - simple question
« Reply #2 on: February 10, 2012, 03:25:07 pm »
Thanks, user137.

Yes, I am giving 2 references, but I had thought that I had to instruct the TDecompressBzip2Stream to actually get its data from the other stream, therefore the copyfrom method.

If I try your code, I get
Quote
TDecompressBzip2Stream.Seek not implemented
(running on a patched x86 Windows compiler that has the bunzip2 i386 asm code disabled, so should not error there)

TDecompressBzip2Stream has just these public methods/functions:
Code: [Select]
Constructor Create(ASource : TStream);
Destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
« Last Edit: February 10, 2012, 03:27:29 pm by BigChimp »
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

ludob

  • Hero Member
  • *****
  • Posts: 623
Re: Stream newb - simple question
« Reply #3 on: February 10, 2012, 04:10:48 pm »
If I try your code, I get
Quote
TDecompressBzip2Stream.Seek not implemented
And since the decompressed size is not known before decompressing, stream copy isn't possible. You'll need to use buffer reads:
Code: [Select]
function Decompress(SourceFile, TargetFile: string; out ErrorLog: string): boolean;
var
  InFile:TFileStream;
  Decompressed:TDecompressBzip2Stream;
  OutFile:TFileStream;
  Buffer: Pointer;
  i:integer;
const buffersize=$2000;
begin
  result:=false;
  InFile:=TFileStream.Create(SourceFile, fmOpenRead);
  try
    Decompressed:=TDecompressBzip2Stream.Create(InFile);
    OutFile:=TFileStream.Create(TargetFile, fmCreate);
    try
      GetMem(Buffer,BufferSize);
      repeat
        i:=Decompressed.Read(buffer^,BufferSize);
        if i>0 then
          OutFile.WriteBuffer(buffer^,i);
      until i<BufferSize;
      result:=true;
    finally
      Decompressed.Free;
      OutFile.Free;
    end;
  finally
    InFile.Free;
  end;
end;


BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
Re: Stream newb - simple question
« Reply #4 on: February 10, 2012, 04:28:55 pm »
Thanks, that solved it!
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

User137

  • Hero Member
  • *****
  • Posts: 503
Re: [SOLVED] Stream newb - simple question
« Reply #5 on: February 10, 2012, 11:27:01 pm »
Lastly:
Code: [Select]
free(buffer);Or there will be a memory leak  ;D

BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
Re: [SOLVED] Stream newb - simple question
« Reply #6 on: February 11, 2012, 08:30:49 am »
 :)

Thanks; used FreeMem(Buffer, BufferSize) though...

That's why nobody should let me near pointers and raw memory until I have my adult teeth.. I mean need a walking frame  :)
« Last Edit: February 11, 2012, 08:36:36 am by BigChimp »
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

ludob

  • Hero Member
  • *****
  • Posts: 623
Re: [SOLVED] Stream newb - simple question
« Reply #7 on: February 11, 2012, 08:32:29 am »
Lastly:
Code: [Select]
free(buffer);Or there will be a memory leak  ;D
That was left as an exercise for the OP   >:D

BigChimp

  • Hero Member
  • *****
  • Posts: 1012
    • CheckRide remote control and other open source projects
Re: [SOLVED] Stream newb - simple question
« Reply #8 on: February 11, 2012, 08:41:43 am »
Hi Ludo,

Have you had your coffee already  :)
CheckRide remote control and other open source projects:
https://bitbucket.org/reiniero/

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads