diff --git a/Pascal/Test/MainUnit.pas b/Pascal/Test/MainUnit.pas
index 6c72829..ed6661e 100644
--- a/Pascal/Test/MainUnit.pas
+++ b/Pascal/Test/MainUnit.pas
@@ -53,6 +53,8 @@ function MsvcrtWcstod(Str: PWideChar; PtrEnd: PPWideChar): Double; cdecl; extern
var
pure_parse_float_library: HMODULE;
pure_parse_float: function(Str: PAnsiChar; Double: PDouble; PtrEnd: PPAnsiChar): Double; cdecl;
+ dll_pure_parse_float_library: HMODULE;
+ dll_pure_parse_float: function(Str: PAnsiChar; Double: PDouble; PtrEnd: PPAnsiChar): Double; cdecl;
// from ieee_convert32.dll/ieee_convert64.dll
function IeeeStringToDouble(Str: UnicodeString; out Value: Double): Integer;
@@ -103,6 +105,20 @@ function PureStringToDoubleC(Str: UnicodeString; out Value: Double): Integer;
Result := PEnd - PAnsiChar(AnsiStr);
end;
+// from user dll
+function PureStringToDoubleUserDll(Str: UnicodeString; out Value: Double): Integer;
+var
+ AnsiStr: AnsiString;
+ PEnd: PAnsiChar;
+begin
+ Value := 0.0;
+ AnsiStr := AnsiString(Str);// unicode -> ansi
+
+ dll_pure_parse_float(PAnsiChar(AnsiStr), @Value, @PEnd);
+
+ Result := PEnd - PAnsiChar(AnsiStr);
+end;
+
// form MSVCRT.dll
function MsvcrtStringToDouble(Str: UnicodeString; out Value: Double): Integer;
var
@@ -159,6 +175,14 @@ procedure AssertEqual(S: UnicodeString);
begin
CountA := IeeeStringToDouble(S, A);
+ if @dll_pure_parse_float <> nil then
+ begin
+ CountB := PureStringToDoubleUserDll(S, B);
+ Assert(CountA = CountB);
+ Assert(ABin = BBin);
+ exit;
+ end;
+
case Mode of
ModePure:
begin
@@ -202,6 +226,21 @@ function UlpDiff(S: UnicodeString): TUlpDiffType;
BBin: Int64 absolute B;
begin
IeeeStringToDouble(S, A);
+
+ if @dll_pure_parse_float <> nil then
+ begin
+ PureStringToDoubleUserDll(S, B);
+ if ABin = BBin then
+ begin
+ exit(udtSame);
+ end;
+ if (ABin - 1 = BBin) or (ABin + 1 = BBin) then
+ begin
+ exit(udtOne);
+ end;
+ exit(udtMoreThanOne);
+ end;
+
case Mode of
ModePure:
begin
@@ -713,7 +752,7 @@ procedure Benchmark();
AnsiTestStrings := AnsiTestStrings + [AnsiString(S)];
end;
- Times := [0, 0, 0, 0, 0];
+ Times := [0, 0, 0, 0, 0, 0];
for N := 0 to 400 - 1 do
begin
// netlib/David M. Gay
@@ -762,6 +801,17 @@ procedure Benchmark();
end;
Times[4] := Times[4] + Int64(TThread.GetTickCount64() - Time);
end;
+
+ // ParseFloat dll
+ if @dll_pure_parse_float <> nil then
+ begin
+ Time := TThread.GetTickCount64();
+ for I := 0 to High(AnsiTestStrings) do
+ begin
+ dll_pure_parse_float(PAnsiChar(AnsiTestStrings[I]), @D, @PAnsiEnd);
+ end;
+ Times[5] := Times[5] + Int64(TThread.GetTickCount64() - Time);
+ end;
end;
Writeln('Netlib strtod: ', Times[0], 'ms');
@@ -779,6 +829,10 @@ procedure Benchmark();
Writeln(' ', (Times[4] / Times[3]):0:2, 'x slower');
end;
end;
+ if @dll_pure_parse_float <> nil then
+ begin
+ Writeln('User DLL ParseFloat: ', Times[5], 'ms');
+ end;
end;
procedure DoRunTests();
@@ -787,9 +841,57 @@ procedure DoRunTests();
I: Integer;
SuccessCount: Integer;
CmdSize, CmdMode: UnicodeString;
+ DllName, DllFunctionName: UnicodeString;
begin
Writeln('=== PureFloatParser Test ===');
+ if FindCmdLineSwitch('dll') then
+ begin
+ if not FindCmdLineSwitch('function') then
+ begin
+ Writeln('Please use -function with -dll option!');
+ exit;
+ end;
+ // load dll
+ {$IFDEF FPC}
+ DllName := GetCmdLineArg('dll', ['-']);
+ {$ELSE}
+ DllName := '';
+ FindCmdLineSwitch('dll', DllName, True, [clstValueNextParam]);
+ {$ENDIF}
+ if DllName = '' then
+ begin
+ Writeln('Bad -dll param!');
+ exit;
+ end;
+ dll_pure_parse_float_library := LoadLibrary(PWideChar(DllName));
+ if pure_parse_float_library = 0 then
+ begin
+ Writeln('Can''t open "' + DllName + '" dll!');
+ exit;
+ end;
+ // load func
+ {$IFDEF FPC}
+ DllFunctionName := GetCmdLineArg('function', ['-']);
+ {$ELSE}
+ DllFunctionName := '';
+ FindCmdLineSwitch('function', DllFunctionName, True, [clstValueNextParam]);
+ {$ENDIF}
+ if DllFunctionName = '' then
+ begin
+ Writeln('Bad -function param!');
+ exit;
+ end;
+ @dll_pure_parse_float := GetProcAddress(dll_pure_parse_float_library, PWideChar(DllFunctionName));
+ if @dll_pure_parse_float = nil then
+ begin
+ Writeln('Can''t load function "' + DllFunctionName + '" from dll!');
+ exit;
+ end;
+ // print info
+ Writeln('*** Parser function "' + DllFunctionName + '", from user DLL "', DllName, '" ***');
+ end;
+
if FindCmdLineSwitch('c') then
begin
if @pure_parse_float = nil then
@@ -855,7 +957,8 @@ procedure DoRunTests();
Writeln('Bad param parser!');
exit;
end;
- end else
+ end
+ else if @dll_pure_parse_float = nil then
begin
Writeln('Use "-parser pure/delphi/microsoft" for change a parser under test.');
Writeln(' Parser=Pure by default.');
@@ -867,11 +970,19 @@ procedure DoRunTests();
else
Writeln(' 64 bit cpu');
- case Mode of
- ModePure: Writeln(' Parser=Pure');
- ModeDelphi: Writeln(' Parser=Delphi');
- ModeMicrosoft: Writeln(' Parser=Microsoft');
- end;
+ if @dll_pure_parse_float = nil then
+ begin
+ case Mode of
+ ModePure: Writeln(' Parser=Pure');
+ ModeDelphi: Writeln(' Parser=Delphi');
+ ModeMicrosoft: Writeln(' Parser=Microsoft');
+ end;
+ if TestCVersion then
+ begin
+ Writeln(' Test C Version');
+ end;
+ end else
+ Writeln(' Parser=User DLL');
case TestCount of
SizeSmall: Writeln(' Size=Small');
@@ -879,11 +990,6 @@ procedure DoRunTests();
SizeLarge: Writeln(' Size=Large');
end;
- if TestCVersion then
- begin
- Writeln(' Test C Version');
- end;
-
Writeln;
// make tests
@@ -971,6 +1077,7 @@ initialization
finalization
FreeLibrary(pure_parse_float_library);
+ FreeLibrary(dll_pure_parse_float_library);
end.
diff --git a/Pascal/Test/Test.dproj b/Pascal/Test/Test.dproj
index 539e174..ceb687c 100644
--- a/Pascal/Test/Test.dproj
+++ b/Pascal/Test/Test.dproj
@@ -34,6 +34,12 @@
true
true
+
+ true
+ Cfg_1
+ true
+ true
+
true
Base
@@ -68,7 +74,7 @@
vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;vcldb;ibxbindings;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
-size medium -parser pure
(None)
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 32.exe
1033
@@ -80,7 +86,7 @@
vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;vcldb;ibxbindings;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
-size medium -parser pure
(None)
- CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
+ 64.exe
1033
@@ -96,6 +102,9 @@
false
+
+ -size medium -parser pure
+
0
RELEASE;$(DCC_Define)