program bunzip2test;
{
    This file is part of the Free Pascal packages.
    Copyright (c) 1999-2012 by the Free Pascal development team

    Tests bzip2 decompression.

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}
 
{$mode objfpc}{$h+}

uses SysUtils, classes, bzip2stream, md5;
// Uses new bunzip2 code (using classes, not objects) to test decompression of a bzip2 compressed file.

{$R testbzip2.res} //contains readme.txt.bz2
//Change this whenever you change the test resource:
const ExpectedHash='4ab247ef61f1f9a6fec26493aab823cd';

function Decompress(SourceFile, TargetFile: string): boolean;
var
  InFile:TFileStream;
  Decompressed:TDecompressBzip2Stream;
  OutFile:TFileStream;
  Buffer: Pointer;
  i: integer;
const buffersize=$2000;
begin
  result:=false; //fail by default
  InFile:=TFileStream.Create(SourceFile, fmOpenRead);
  try
    Decompressed:=TDecompressBzip2Stream.Create(InFile);
    OutFile:=TFileStream.Create(TargetFile, fmCreate);
    try
      //We don't have seek on the TDecompressBzip2stream, so can't use
      //CopyFrom...
      //Decompressed.CopyFrom(InFile, InFile.Size);
      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;
  	  FreeMem(Buffer, BufferSize);
    end;
  finally
    InFile.Free;
  end;
end;

var
  code: cardinal;
  CompressedFile: string;
  ExampleFileResourceStream: TResourceStream;
  ExampleFileStream: TFileStream;
  UncompressedFile: string;
  UncompressedHash: string;
begin
  code := 0;
  UncompressedFile:=SysUtils.GetTempFileName(EmptyStr, 'UNC');
  CompressedFile:=SysUtils.GetTempFileName(EmptyStr, 'BZ2');

  // Set up test bz2 file
  // create a resource stream which points to our resource
  ExampleFileResourceStream := TResourceStream.Create(HInstance, 'ALL', 'RT_RCDATA');
  try
    ExampleFileStream := TFileStream.Create(CompressedFile, fmCreate);
    try
      ExampleFileStream.CopyFrom(ExampleFileResourceStream, ExampleFileResourceStream.Size);
    finally
      ExampleFileStream.Free;
    end;
  finally
    ExampleFileResourceStream.Free;
  end;

  // Actual decompression
  if decompress(CompressedFile, UncompressedFile) then
  begin
    // Now check if contents match.
  UncompressedHash:=MD5Print(MD5File(UncompressedFile, MDDefBufSize));
	if UncompressedHash=ExpectedHash then
	begin
    code:=0; //success
	end
	else
	begin
    writeln('MD5 hash comparison between original file and uncompressed file failed');
    writeln('Got hash:'+UncompressedHash);
    writeln('Expected:'+ExpectedHash);
	  code:=2;
	end;
  end
  else
  begin
    writeln('bunzip2 decompression failure');
    code:=1;
  end;
  
  try
    if CompressedFile<>EmptyStr then DeleteFile(CompressedFile);
    if UncompressedFile<>EmptyStr then DeleteFile(UncompressedFile);
  finally
    // Ignore errors; operating system should clean out temp files
  end; 
  
  if code = 0 then
    writeln('Basic bzip2 tests passed')
  else
    writeln('Basic bzip2 test failed: ', code);
  Halt(code);
end.
