Skip to content

Commit

Permalink
Merge branch 'feature/10-check+update-simple-types' into develop
Browse files Browse the repository at this point in the history
Fixes #10
  • Loading branch information
delphidabbler committed Jun 1, 2023
2 parents b77edec + d47d9a6 commit aa57c8d
Show file tree
Hide file tree
Showing 15 changed files with 190 additions and 140 deletions.
28 changes: 14 additions & 14 deletions Src/BDiff/BDiff.BlockSort.pas
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ interface

uses
// Project
BDiff.Types;
BDiff.Types,
Common.Types;


type
Expand All @@ -25,11 +26,11 @@ TBlockSort = class(TObject)
/// <summary>Compares elements of array of <c>TCChar</c> characters
/// starting from index <c>A</c>, with elements of same array starting at
/// index <c>B</c>.</summary>
class function Compare(A: Cardinal; B: Cardinal; Data: PCCharArray;
DataSize: Cardinal): Integer;
class function Compare(A, B: Int32; Data: PCCharArray; DataSize: Int32):
Int32;
/// <summary>Heap sort sink.</summary>
class procedure Sink(Left: Cardinal; Right: Cardinal; Block: PBlock;
Data: PCCharArray; DataSize: Cardinal);
class procedure Sink(Left, Right: Int32; Block: PBlock; Data: PCCharArray;
DataSize: Int32);
public
/// <summary>Returns array of offsets into data, sorted by position.
/// </summary>
Expand All @@ -40,7 +41,7 @@ TBlockSort = class(TObject)
/// Caller must free.</returns>
/// <exception>Raises <c>EOutOfMemory</c> if the reutned data block can't
/// be allocated.</exception>
class function Execute(Data: PCCharArray; DataSize: Cardinal): PBlock;
class function Execute(Data: PCCharArray; DataSize: Int32): PBlock;
end;


Expand All @@ -67,12 +68,12 @@ implementation

{ TBlockSort }

class function TBlockSort.Compare(A, B: Cardinal; Data: PCCharArray;
DataSize: Cardinal): Integer;
class function TBlockSort.Compare(A, B: Int32; Data: PCCharArray;
DataSize: Int32): Int32;
begin
var PA: PCChar := @Data[A];
var PB: PCChar := @Data[B];
var Len: Cardinal := DataSize - A;
var Len: Int32 := DataSize - A;
if DataSize - B < Len then
Len := DataSize - B;
while (Len <> 0) and (PA^ = PB^) do
Expand All @@ -86,13 +87,12 @@ class function TBlockSort.Compare(A, B: Cardinal; Data: PCCharArray;
Result := PA^ - PB^;
end;

class function TBlockSort.Execute(Data: PCCharArray; DataSize: Cardinal):
PBlock;
class function TBlockSort.Execute(Data: PCCharArray; DataSize: Int32): PBlock;
begin
if DataSize = 0 then
Exit(nil);

GetMem(Result, SizeOf(Cardinal) * DataSize);
GetMem(Result, SizeOf(Int32) * DataSize);

// initialize unsorted data
for var I := 0 to Pred(DataSize) do
Expand All @@ -116,8 +116,8 @@ class function TBlockSort.Execute(Data: PCCharArray; DataSize: Cardinal):
end;
end;

class procedure TBlockSort.Sink(Left, Right: Cardinal; Block: PBlock;
Data: PCCharArray; DataSize: Cardinal);
class procedure TBlockSort.Sink(Left, Right: Int32; Block: PBlock;
Data: PCCharArray; DataSize: Int32);
begin
var I := Left;
var X := Block[I];
Expand Down
43 changes: 21 additions & 22 deletions Src/BDiff/BDiff.Differ.pas
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ interface
// Project
BDiff.FileData,
BDiff.Logger,
BDiff.Types;
BDiff.Types,
Common.Types;


type
Expand All @@ -27,21 +28,21 @@ TDiffer = class(TObject)
type
/// <summary>Structure for a matching block.</summary>
TMatch = record
OldOffset: Cardinal;
NewOffset: Cardinal;
BlockLength: Cardinal;
OldOffset: Int32;
NewOffset: Int32;
BlockLength: Int32;
end;

var
// Property values
fMinMatchLength: Cardinal;
fMinMatchLength: Int32;
fFormat: TFormat;

/// <summary>Finds a maximum length match a given search string in the old
/// file and returns a <c>TMatch</c> record that describes the match.
/// </summary>
function FindMaxMatch(OldFile: TFileData; SortedOldData: PBlock;
SearchText: PCChar; SearchTextLength: Cardinal): TMatch;
SearchText: PCChar; SearchTextLength: Int32): TMatch;

/// <summary>Finds maximum length sub-string of <c>CompareData</c> that is
/// in <c>Data</c>.</summary>
Expand All @@ -55,10 +56,9 @@ TMatch = record
/// <c>CompareData</c>.</param>
/// <param name="FoundPos">[out] Position in <c>Data</c> where sub-string
/// was found.</param>
/// <returns><c>Cardinal</c>. Length of found sub-string.</returns>
function FindString(Data: PCCharArray; Block: PBlock; DataSize: Cardinal;
CompareData: PCChar; CompareDataSize: Cardinal; out FoundPos: Cardinal):
Cardinal;
/// <returns><c>Int32</c>. Length of found sub-string.</returns>
function FindString(Data: PCCharArray; Block: PBlock; DataSize: Int32;
CompareData: PCChar; CompareDataSize: Int32; out FoundPos: Int32): Int32;

public

Expand All @@ -77,7 +77,7 @@ TMatch = record

/// <summary>Minimum length of data chunks that can be recognized as equal.
/// </summary>
property MinMatchLength: Cardinal
property MinMatchLength: Int32
read fMinMatchLength write fMinMatchLength default 24;

/// <summary>Format of generated diff.</summary>
Expand Down Expand Up @@ -109,13 +109,13 @@ constructor TDiffer.Create;
end;

function TDiffer.FindMaxMatch(OldFile: TFileData; SortedOldData: PBlock;
SearchText: PCChar; SearchTextLength: Cardinal): TMatch;
SearchText: PCChar; SearchTextLength: Int32): TMatch;
begin
Result.BlockLength := 0; {no match}
Result.NewOffset := 0;
while (SearchTextLength <> 0) do
begin
var FoundPos: Cardinal;
var FoundPos: Int32;
var FoundLen := FindString(
OldFile.Data,
SortedOldData,
Expand All @@ -136,30 +136,29 @@ function TDiffer.FindMaxMatch(OldFile: TFileData; SortedOldData: PBlock;
end;
end;

function TDiffer.FindString(Data: PCCharArray; Block: PBlock;
DataSize: Cardinal; CompareData: PCChar; CompareDataSize: Cardinal;
out FoundPos: Cardinal): Cardinal;
function TDiffer.FindString(Data: PCCharArray; Block: PBlock; DataSize: Int32;
CompareData: PCChar; CompareDataSize: Int32; out FoundPos: Int32): Int32;
begin
var First: Cardinal := 0;
var Last: Cardinal := DataSize - 1;
var First: Int32 := 0;
var Last: Int32 := DataSize - 1;
Result := 0;
FoundPos := 0;

// Do binary search of Data
while First <= Last do
begin
// Get mid point of (sorted) Data to search
var Mid: Cardinal := (First + Last) div 2;
var Mid: Int32 := (First + Last) div 2;
// Set pointer to start of Data search string
var PData: PCChar := @Data[Block[Mid]];
// Set pointer to start of CompareData
var PCompareData: PCChar := CompareData;
// Calculate maximum possible size of matching substring
var FoundMax: Cardinal := DataSize - Block[Mid];
var FoundMax: Int32 := DataSize - Block[Mid];
if FoundMax > CompareDataSize then
FoundMax := CompareDataSize;
// Find and count match chars from Data and CompareData
var FoundSize: Cardinal := 0;
var FoundSize: Int32 := 0;
while (FoundSize < FoundMax) and (PData^ = PCompareData^) do
begin
Inc(FoundSize);
Expand Down Expand Up @@ -212,7 +211,7 @@ procedure TDiffer.MakeDiff(const OldFileName, NewFileName: string;
PatchWriter.Header(OldFile, NewFile);
// main loop
var ToDo := NewFile.Size;
var NewOffset: Cardinal := 0;
var NewOffset: Int32 := 0;
while (ToDo <> 0) do
begin
var Match := FindMaxMatch(
Expand Down
20 changes: 12 additions & 8 deletions Src/BDiff/BDiff.FileData.pas
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ TFileData = class(TObject)
var
// Property values
fData: PCCharArray;
fSize: Cardinal;
fSize: Int32;
fName: string;
/// <summary>Loads data from the file into a memory block pointed to by the
/// <c>Data</c> property.</summary>
Expand All @@ -39,7 +39,7 @@ TFileData = class(TObject)
/// <summary>Name of file.</summary>
property Name: string read fName;
/// <summary>Size of file's data.</summary>
property Size: Cardinal read fSize;
property Size: Int32 read fSize;
/// <summary>Pointer to memory containing file's content.</summary>
/// <remarks>Callers must not free the memory.</remarks>
property Data: PCCharArray read fData;
Expand All @@ -54,6 +54,7 @@ implementation
System.SysUtils,
Winapi.Windows,
// Project
BDiff.IO,
Common.Errors;


Expand All @@ -79,17 +80,20 @@ procedure TFileData.LoadFile;
try
if FileHandle = INVALID_HANDLE_VALUE then
Error('Cannot open file %s', [fName]);
fSize := GetFileSize(FileHandle, nil);
if fSize = Cardinal(-1) then
Error('Cannot find size of file %s - may be to large', [fName]);
if fSize = 0 then
var FileSize: Int64 := TIO.FileSize(FileHandle);
if FileSize = -1 then
Error('Cannot find size of file %s', [fName]);
if FileSize = 0 then
Error('File %s is empty', [fName]);
if FileSize > MaxInt then
Error('File %s is too large (>= 2GiB)', [fName]);
fSize := Int32(FileSize);
try
GetMem(fData, fSize);
var BytesRead: Integer := FileRead(FileHandle, fData^, fSize);
var BytesRead: Int32 := FileRead(FileHandle, fData^, fSize);
if BytesRead = -1 then
Error('Cannot read from file %s', [fName]);
if fSize <> Cardinal(BytesRead) then
if fSize <> BytesRead then
Error('Error reading from file %s', [fName]);
except
if Assigned(fData) then
Expand Down

0 comments on commit aa57c8d

Please sign in to comment.