diff --git a/Packages/DXE2/X2Utils.dpk b/Packages/DXE2/X2Utils.dpk
index e3806f5..a9731ab 100644
--- a/Packages/DXE2/X2Utils.dpk
+++ b/Packages/DXE2/X2Utils.dpk
@@ -25,7 +25,7 @@ package X2Utils;
{$IMAGEBASE $400000}
{$ENDIF IMPLICITBUILDING}
{$DESCRIPTION 'X2Utils'}
-{$LIBSUFFIX 'DXE2'}
+{$LIBSUFFIX 'XE2'}
{$RUNONLY}
{$IMPLICITBUILD ON}
diff --git a/Packages/DXE2/X2Utils.dproj b/Packages/DXE2/X2Utils.dproj
index 9d6898f..78af53b 100644
--- a/Packages/DXE2/X2Utils.dproj
+++ b/Packages/DXE2/X2Utils.dproj
@@ -9,7 +9,7 @@
13.4
True
Debug
- Win64
+ Win32
3
Package
@@ -160,7 +160,13 @@
-
+
+ X²CL GraphicList (Designtime)
+ X²CL MenuBar (Designtime)
+ UnameIT - Designtime
+ Microsoft Office 2000 Sample Automation Server Wrapper Components
+ Microsoft Office XP Sample Automation Server Wrapper Components
+
True
diff --git a/UnitTests/Units/StringsTest.pas b/UnitTests/Units/StringsTest.pas
index cef60dd..503530d 100644
--- a/UnitTests/Units/StringsTest.pas
+++ b/UnitTests/Units/StringsTest.pas
@@ -9,6 +9,7 @@ type
TStringsTest = class(TTestCase)
published
procedure TestSplit;
+ procedure TestSkipEmptyItems;
end;
@@ -31,6 +32,18 @@ begin
CheckEquals('value2', items[1], 'Items[1]');
end;
+
+procedure TStringsTest.TestSkipEmptyItems;
+var
+ items: TStringDynArray;
+
+begin
+ Split('/value1///value2//', '/', items, True);
+ CheckEquals(2, Length(items), 'Length');
+ CheckEquals('value1', items[0], 'Items[0]');
+ CheckEquals('value2', items[1], 'Items[1]');
+end;
+
initialization
RegisterTest('Strings', TStringsTest.Suite);
diff --git a/X2UtStrings.pas b/X2UtStrings.pas
index 6c7f5fb..bc2f8c9 100644
--- a/X2UtStrings.pas
+++ b/X2UtStrings.pas
@@ -78,7 +78,7 @@ type
* @todo though optimized, it now fails on #0 characters, need
* to determine the end by checking the AnsiString length.
*}
- procedure Split(const ASource, ADelimiter: String; out ADest: TStringDynArray);
+ procedure Split(const ASource, ADelimiter: String; out ADest: TStringDynArray; ASkipEmptyItems: Boolean = False);
{** Appends string parts with a specified glue value.
*
@@ -201,7 +201,7 @@ begin
end;
-procedure Split(const ASource, ADelimiter: String; out ADest: TStringDynArray);
+procedure Split(const ASource, ADelimiter: String; out ADest: TStringDynArray; ASkipEmptyItems: Boolean);
// StrPos is slow. Sloooooow slow. This function may not be advanced or
// the fastest one around, but it sure kicks StrPos' ass.
// 11.5 vs 1.7 seconds on a 2.4 Ghz for 10.000 iterations, baby!
@@ -253,69 +253,73 @@ const
GrowMax = 256;
var
- iCapacity: Integer;
- iCount: Integer;
- iDelimLen: Integer;
- iLength: Integer;
- iPos: Integer;
- iSize: Integer;
- pDelimiter: PChar;
- pLast: PChar;
- pPos: PChar;
+ capacity: Integer;
+ count: Integer;
+ delimiterLength: Integer;
+ sourceLength: Integer;
+ position: Integer;
+ size: Integer;
+ delimiter: PChar;
+ lastPos: PChar;
+ currentPos: PChar;
begin
// Reserve some space
- iCapacity := GrowStart;
- iCount := 0;
- SetLength(ADest, iCapacity);
+ capacity := GrowStart;
+ count := 0;
+ SetLength(ADest, capacity);
- iDelimLen := Length(ADelimiter);
- iLength := Length(ASource);
- iPos := -1;
- pDelimiter := PChar(ADelimiter);
- pPos := PChar(ASource);
+ delimiterLength := Length(ADelimiter);
+ sourceLength := Length(ASource);
+ position := 0;
+ delimiter := PChar(ADelimiter);
+ currentPos := PChar(ASource);
repeat
// Find delimiter
- pLast := pPos;
- pPos := StrPosEx(pPos, pDelimiter);
+ lastPos := currentPos;
+ currentPos := StrPosEx(currentPos, delimiter);
- if pPos <> nil then
+ if currentPos <> nil then
begin
- // Make space
- Inc(iCount);
- if iCount > iCapacity then
+ size := (Integer(currentPos) - Integer(lastPos)) div SizeOf(Char);
+
+ if (size > 0) or (not ASkipEmptyItems) then
begin
- if iCapacity < GrowMax then
- Inc(iCapacity, iCapacity)
- else
- Inc(iCapacity, GrowMax);
+ // Make space
+ Inc(count);
+ if count > capacity then
+ begin
+ if capacity < GrowMax then
+ Inc(capacity, capacity)
+ else
+ Inc(capacity, GrowMax);
- SetLength(ADest, iCapacity);
+ SetLength(ADest, capacity);
+ end;
+
+ // Copy substring
+ SetString(ADest[count - 1], lastPos, size);
end;
- // Copy substring
- iSize := (Integer(pPos) - Integer(pLast)) div SizeOf(Char);
- SetString(ADest[iCount - 1], pLast, iSize);
-
// Move pointer
- Inc(pPos, iDelimLen);
- Inc(iPos, iSize + iDelimLen);
+ Inc(currentPos, delimiterLength);
+ Inc(position, size + delimiterLength);
end else
begin
- if iPos < iLength then
+ if position < sourceLength then
begin
// Copy what's left
- Inc(iCount);
- if iCount > iCapacity then
- SetLength(ADest, iCount);
+ Inc(count);
+ if count > capacity then
+ SetLength(ADest, count);
- ADest[iCount - 1] := pLast;
+ ADest[count - 1] := lastPos;
end;
- if iCount <> iCapacity then
+ if count <> capacity then
// Shrink array
- SetLength(ADest, iCount);
+ SetLength(ADest, count);
break;
end;