├── README.md
├── Samples
├── FMX
│ ├── Unit1.fmx
│ ├── Unit1.pas
│ ├── fmxPerformance.dpr
│ ├── fmxPerformance.dproj
│ └── fmxPerformance.res
├── FPC
│ ├── FPCPerformanceTest.ico
│ ├── FPCPerformanceTest.lpr
│ ├── FPCPerformanceTest.res
│ ├── FPCperformanceTest.lpi
│ ├── FPCperformanceTest.lps
│ ├── unit1.lfm
│ └── unit1.pas
└── VCL
│ ├── Unit1.dfm
│ ├── Unit1.pas
│ ├── VCLPerformanceTest.dpr
│ ├── VCLPerformanceTest.dproj
│ └── VCLPerformanceTest.res
├── Source
├── Cadencer.pas
├── CoreAtomic.inc
├── CoreCipher.pas
├── CoreClasses.pas
├── CoreCompress.pas
├── CoreComputeThread.inc
├── CoreEndian.inc
├── CoreThreadPost.inc
├── Core_AtomVar.inc
├── Core_DelphiParallelFor.inc
├── Core_FPCParallelFor.inc
├── Core_LineProcessor.inc
├── Core_MT19937.inc
├── Core_OrderData.inc
├── DataFrameEngine.pas
├── DoStatusIO.pas
├── FPCGenericStructlist.pas
├── Fast_MD5.pas
├── GHashList.pas
├── Geometry2DUnit.pas
├── Geometry3DUnit.pas
├── GeometryLib.pas
├── GeometryRotationUnit.pas
├── GeometrySplit.inc
├── GeometrySplitHeader.inc
├── LinearAction.pas
├── ListEngine.pas
├── MH.pas
├── MH_1.pas
├── MH_2.pas
├── MH_3.pas
├── MH_ZDB.pas
├── MH_delphi.inc
├── MH_fpc.inc
├── MemoryStream64.pas
├── NotifyObjectBase.pas
├── NumberBase.pas
├── OpCode.pas
├── PascalStrings.pas
├── TextDataEngine.pas
├── TextParsing.pas
├── TextTable.pas
├── UPascalStrings.pas
├── UnicodeMixedLib.pas
├── ZIOThread.pas
├── ZJson.pas
├── ZJson_delphi.inc
├── ZJson_fpc.inc
├── ZS_JsonDataObjects.pas
├── clear_with_dcu.bat
├── md5_32.asm
├── md5_32.obj
├── md5_64.asm
├── md5_64.obj
├── zDefine.inc
└── zExpression.pas
└── clear_with_dcu.bat
/README.md:
--------------------------------------------------------------------------------
1 | # CoreCipher
2 |
3 | CoreCipher is a Delphi and FPC library for cryptography. It provides support for RC6,TwoFish,AES, DES, 3DES, Blowfish, MD5,SHA1,MixFunctions,LSC,LQC, all work in parallel and mobile platform!
4 |
5 | **supports parallel encryption/decryption**
6 |
7 | ### multi platform supported:,test with Delphi 10.2 upate 2 and FPC 3.0.4
8 |
9 | - Windows x86+x64
10 | - Android pad with armv8 aarch64
11 | - Android mobile with armv6 or last
12 | - IOS Device armv7(ip4)+armv8(ipad pro,iphone5s or last aarch64)
13 | - IOS Simulaor:n/a
14 | - OSX
15 | - Ubuntu16.04 x64 server
16 | - Ubuntu18.04 x86+x64 Desktop
17 | - Ubuntu18.04 x86+x64 Server
18 | - Ubuntu18.04 arm32+arm neon Server
19 | - Ubuntu18.04 arm32+arm neon desktop
20 | - Ubuntu16.04 Mate arm32 desktop
21 | - Raspberry Pi 3 Debian linux armv7 desktop,only fpc 3.0.4,test passed.
22 | - wince(arm eabi hard flaot),windows 10 IOT,only fpc 3.3.1,test passed.
23 |
24 | ### multi cpu architectures supported,test with Delphi 10.2 upate 2 and FPC 3.0.4
25 |
26 | - MIPS(fpc-little endian), soft float, test pass on QEMU
27 | - intel X86(fpc-x86), soft float
28 | - intel X86(delphi+fpc), hard float,ATHLON64,COREI,COREAVX,COREAVX2
29 | - intel X64(fpc-x86_64), soft float
30 | - intel X64(delphi+fpc), hard float,ATHLON64,COREI,COREAVX,COREAVX2
31 | - ARM(fpc-arm32-eabi, hard float):ARMV3,ARMV4,ARMV4T,ARMV5,ARMV5T,ARMV5TE,ARMV5TEJ,ARMV6,ARMV6K,ARMV6T2,ARMV6Z,ARMV6M,ARMV7,ARMV7A,ARMV7R,ARMV7M,ARMV7EM
32 | - ARM(fpc-arm64-eabi, hard float):ARMV8,aarch64
33 |
34 |
35 |
36 | enjoy.~
37 |
38 | # update history
39 |
40 | ### 2018-9-29
41 |
42 | - fixed rc6 on freepascal for IOT
43 | - IOT power on FPC support
44 |
45 | ### 2018-7-6
46 |
47 | - update the name rules of the Library
48 | - Support for fpc/86/64 platform, all base libraries support for Linux.
49 | - power support for the FPC compiler 3.1.1
50 | - newed Big/Little Endian order support
51 | - fixing the problem of using 32 bit FPC compiler to for with Int64
52 | - fixed string the FPC compiler runs on Linux.
53 |
54 | ### 2018-5-21
55 |
56 | - fixed twofish on memory leak
57 | - update Parallel core(fpc required package:MultiThreadProcsLaz)
58 | - added UPascalStrings.pas(fpc on unicode)
59 |
60 |
61 | ### 2018-3-1
62 |
63 | newed Smith–Waterman algorithm
64 |
65 | The Smith–Waterman algorithm performs local sequence alignment; that is, for determining similar regions between two strings of nucleic acid sequences or protein sequences. Instead of looking at the entire sequence, the Smith–Waterman algorithm compares segments of all possible lengths and optimizes the similarity measure.
66 |
67 | The algorithm was first proposed by Temple F. Smith and Michael S. Waterman in 1981.[1] Like the Needleman–Wunsch algorithm, of which it is a variation, Smith–Waterman is a dynamic programming algorithm. As such, it has the desirable property that it is guaranteed to find the optimal local alignment with respect to the scoring system being used (which includes the substitution matrix and the gap-scoring scheme). The main difference to the Needleman–Wunsch algorithm is that negative scoring matrix cells are set to zero, which renders the (thus positively scoring) local alignments visible. Traceback procedure starts at the highest scoring matrix cell and proceeds until a cell with score zero is encountered, yielding the highest scoring local alignment. Because of its cubic computational complexity in time and quadratic complexity in space, it often cannot be practically applied to large-scale problems and is replaced in favor of less general but computationally more efficient alternatives such as (Gotoh, 1982),[2] (Altschul and Erickson, 1986),[3] and (Myers and Miller 1988).
68 |
69 | https://en.wikipedia.org/wiki/Smith%E2%80%93Waterman_algorithm
70 |
71 |
72 | create by QQ 600585@qq.com
73 |
74 | 2017-11-15
75 |
--------------------------------------------------------------------------------
/Samples/FMX/Unit1.fmx:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 0
3 | Top = 0
4 | Caption = 'Form1'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | OnCreate = FormCreate
11 | OnDestroy = FormDestroy
12 | DesignerMasterStyle = 0
13 | object Memo1: TMemo
14 | Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
15 | Align = Client
16 | Size.Width = 640.000000000000000000
17 | Size.Height = 480.000000000000000000
18 | Size.PlatformDefault = False
19 | TabOrder = 0
20 | ReadOnly = True
21 | end
22 | object Button1: TButton
23 | Anchors = [akTop, akRight]
24 | Position.X = 528.000000000000000000
25 | Position.Y = 8.000000000000000000
26 | TabOrder = 1
27 | Text = 'test'
28 | OnClick = Button1Click
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/Samples/FMX/Unit1.pas:
--------------------------------------------------------------------------------
1 | unit Unit1;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, CoreCipher,
8 | FMX.StdCtrls, FMX.Controls.Presentation, FMX.Memo,
9 | DoStatusIO, FMX.Layouts;
10 |
11 | type
12 | TForm1 = class(TForm)
13 | Memo1: TMemo;
14 | Button1: TButton;
15 | procedure Button1Click(Sender: TObject);
16 | procedure FormCreate(Sender: TObject);
17 | procedure FormDestroy(Sender: TObject);
18 | private
19 | { Private declarations }
20 | public
21 | { Public declarations }
22 | procedure DoStatusNear(AText: string; const ID: Integer = 0);
23 | end;
24 |
25 | var
26 | Form1: TForm1;
27 |
28 | implementation
29 |
30 | {$R *.fmx}
31 |
32 |
33 | procedure TForm1.Button1Click(Sender: TObject);
34 | begin
35 | Button1.Visible:=False;
36 | TestCoreCipher;
37 | Button1.Visible:=True;
38 | end;
39 |
40 | procedure TForm1.DoStatusNear(AText: string; const ID: Integer);
41 | begin
42 | Memo1.Lines.Add(AText);
43 | Memo1.GoToTextEnd;
44 | Application.ProcessMessages;
45 | end;
46 |
47 | procedure TForm1.FormCreate(Sender: TObject);
48 | begin
49 | AddDoStatusHook(Self, DoStatusNear);
50 | end;
51 |
52 | procedure TForm1.FormDestroy(Sender: TObject);
53 | begin
54 | DeleteDoStatusHook(Self);
55 | end;
56 |
57 | end.
58 |
--------------------------------------------------------------------------------
/Samples/FMX/fmxPerformance.dpr:
--------------------------------------------------------------------------------
1 | program fmxPerformance;
2 |
3 | uses
4 | System.StartUpCopy,
5 | FMX.Forms,
6 | Unit1 in 'Unit1.pas' {Form1},
7 | CoreCipher in '..\..\Source\CoreCipher.pas',
8 | CoreClasses in '..\..\Source\CoreClasses.pas',
9 | DoStatusIO in '..\..\Source\DoStatusIO.pas',
10 | Fast_MD5 in '..\..\Source\Fast_MD5.pas',
11 | ListEngine in '..\..\Source\ListEngine.pas',
12 | MemoryStream64 in '..\..\Source\MemoryStream64.pas',
13 | PascalStrings in '..\..\Source\PascalStrings.pas',
14 | UnicodeMixedLib in '..\..\Source\UnicodeMixedLib.pas',
15 | UPascalStrings in '..\..\Source\UPascalStrings.pas';
16 |
17 | {$R *.res}
18 |
19 | begin
20 | Application.Initialize;
21 | Application.CreateForm(TForm1, Form1);
22 | Application.Run;
23 | end.
24 |
--------------------------------------------------------------------------------
/Samples/FMX/fmxPerformance.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PassByYou888/CoreCipher/c3757295fe4e252b42187e1a28f21588b57b6728/Samples/FMX/fmxPerformance.res
--------------------------------------------------------------------------------
/Samples/FPC/FPCPerformanceTest.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PassByYou888/CoreCipher/c3757295fe4e252b42187e1a28f21588b57b6728/Samples/FPC/FPCPerformanceTest.ico
--------------------------------------------------------------------------------
/Samples/FPC/FPCPerformanceTest.lpr:
--------------------------------------------------------------------------------
1 | program FPCperformanceTest;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | uses
6 | {$IFDEF UNIX}{$IFDEF UseCThreads}
7 | cthreads,
8 | {$ENDIF}{$ENDIF}
9 | Interfaces, // this includes the LCL widgetset
10 | Forms, Unit1, CoreCipher, DoStatusIO
11 | { you can add units after this };
12 |
13 | {$R *.res}
14 |
15 | begin
16 | RequireDerivedFormResource:=True;
17 | Application.Initialize;
18 | Application.CreateForm(TForm1, Form1);
19 | Application.Run;
20 | end.
21 |
22 |
--------------------------------------------------------------------------------
/Samples/FPC/FPCPerformanceTest.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PassByYou888/CoreCipher/c3757295fe4e252b42187e1a28f21588b57b6728/Samples/FPC/FPCPerformanceTest.res
--------------------------------------------------------------------------------
/Samples/FPC/FPCperformanceTest.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Samples/FPC/FPCperformanceTest.lps:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/Samples/FPC/unit1.lfm:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 499
3 | Height = 502
4 | Top = 128
5 | Width = 715
6 | Caption = 'Form1'
7 | ClientHeight = 502
8 | ClientWidth = 715
9 | OnCreate = FormCreate
10 | OnDestroy = FormDestroy
11 | LCLVersion = '1.8.0.6'
12 | object Memo1: TMemo
13 | Left = 0
14 | Height = 502
15 | Top = 0
16 | Width = 715
17 | Align = alClient
18 | Lines.Strings = (
19 | 'Memo1'
20 | )
21 | ScrollBars = ssAutoBoth
22 | TabOrder = 0
23 | end
24 | object Button1: TButton
25 | Left = 608
26 | Height = 25
27 | Top = 16
28 | Width = 75
29 | Caption = 'test'
30 | OnClick = Button1Click
31 | TabOrder = 1
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/Samples/FPC/unit1.pas:
--------------------------------------------------------------------------------
1 | unit Unit1;
2 |
3 | {$mode objfpc}{$H+}
4 | {$MODESWITCH AdvancedRecords}
5 |
6 |
7 | interface
8 |
9 | uses
10 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
11 | CoreCipher, DoStatusIO, PascalStrings;
12 |
13 | type
14 |
15 | { TForm1 }
16 |
17 | TForm1 = class(TForm)
18 | Button1: TButton;
19 | Memo1: TMemo;
20 | procedure Button1Click(Sender: TObject);
21 | procedure FormCreate(Sender: TObject);
22 | procedure FormDestroy(Sender: TObject);
23 | private
24 | { private declarations }
25 | public
26 | { public declarations }
27 | procedure DoStatusNear(AText: Systemstring; const ID: Integer=0);
28 | end;
29 |
30 | var
31 | Form1: TForm1;
32 |
33 | implementation
34 |
35 | {$R *.lfm}
36 |
37 | { TForm1 }
38 | procedure TForm1.DoStatusNear(AText: Systemstring; const ID: Integer=0);
39 | begin
40 | Form1.Memo1.Lines.Add(AText);
41 | Application.ProcessMessages;
42 | end;
43 |
44 |
45 | procedure TForm1.FormCreate(Sender: TObject);
46 | begin
47 | AddDoStatusHook(Self, @DoStatusNear);
48 | end;
49 |
50 | procedure TForm1.Button1Click(Sender: TObject);
51 | begin
52 | Button1.Visible:=False;
53 | TestCoreCipher;
54 | Button1.Visible:=True;
55 | end;
56 |
57 | procedure TForm1.FormDestroy(Sender: TObject);
58 | begin
59 | DeleteDoStatusHook(Self);
60 | end;
61 |
62 | end.
63 |
64 |
--------------------------------------------------------------------------------
/Samples/VCL/Unit1.dfm:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 0
3 | Top = 0
4 | Caption = 'Form1'
5 | ClientHeight = 412
6 | ClientWidth = 852
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | OnCreate = FormCreate
15 | OnDestroy = FormDestroy
16 | DesignSize = (
17 | 852
18 | 412)
19 | PixelsPerInch = 96
20 | TextHeight = 13
21 | object Memo1: TMemo
22 | Left = 0
23 | Top = 0
24 | Width = 852
25 | Height = 412
26 | Align = alClient
27 | ScrollBars = ssBoth
28 | TabOrder = 0
29 | end
30 | object Button1: TButton
31 | Left = 744
32 | Top = 8
33 | Width = 75
34 | Height = 25
35 | Anchors = [akTop, akRight]
36 | Caption = 'test'
37 | TabOrder = 1
38 | OnClick = Button1Click
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/Samples/VCL/Unit1.pas:
--------------------------------------------------------------------------------
1 | unit Unit1;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, DoStatusIO,
8 | CoreCipher;
9 |
10 | type
11 | TForm1 = class(TForm)
12 | Memo1: TMemo;
13 | Button1: TButton;
14 | procedure Button1Click(Sender: TObject);
15 | procedure FormCreate(Sender: TObject);
16 | procedure FormDestroy(Sender: TObject);
17 | private
18 | { Private declarations }
19 | public
20 | { Public declarations }
21 | procedure DoStatusNear(AText: string; const ID: Integer = 0);
22 | end;
23 |
24 | var
25 | Form1: TForm1;
26 |
27 | implementation
28 |
29 | {$R *.dfm}
30 |
31 | procedure TForm1.Button1Click(Sender: TObject);
32 | begin
33 | Button1.Visible:=False;
34 | TestCoreCipher;
35 | Button1.Visible:=True;
36 | end;
37 |
38 | procedure TForm1.DoStatusNear(AText: string; const ID: Integer);
39 | begin
40 | Memo1.Lines.Add(AText);
41 | Application.ProcessMessages;
42 | end;
43 |
44 | procedure TForm1.FormCreate(Sender: TObject);
45 | begin
46 | AddDoStatusHook(Self, DoStatusNear);
47 | end;
48 |
49 | procedure TForm1.FormDestroy(Sender: TObject);
50 | begin
51 | DeleteDoStatusHook(Self);
52 | end;
53 |
54 | end.
55 |
--------------------------------------------------------------------------------
/Samples/VCL/VCLPerformanceTest.dpr:
--------------------------------------------------------------------------------
1 | program VCLPerformanceTest;
2 |
3 | uses
4 | Vcl.Forms,
5 | Unit1 in 'Unit1.pas' {Form1},
6 | CoreCipher in '..\..\Source\CoreCipher.pas',
7 | CoreClasses in '..\..\Source\CoreClasses.pas',
8 | DoStatusIO in '..\..\Source\DoStatusIO.pas',
9 | Fast_MD5 in '..\..\Source\Fast_MD5.pas',
10 | ListEngine in '..\..\Source\ListEngine.pas',
11 | MemoryStream64 in '..\..\Source\MemoryStream64.pas',
12 | PascalStrings in '..\..\Source\PascalStrings.pas',
13 | UnicodeMixedLib in '..\..\Source\UnicodeMixedLib.pas',
14 | UPascalStrings in '..\..\Source\UPascalStrings.pas';
15 |
16 | {$R *.res}
17 |
18 | begin
19 | Application.Initialize;
20 | Application.MainFormOnTaskbar := True;
21 | Application.CreateForm(TForm1, Form1);
22 | Application.Run;
23 | end.
24 |
--------------------------------------------------------------------------------
/Samples/VCL/VCLPerformanceTest.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PassByYou888/CoreCipher/c3757295fe4e252b42187e1a28f21588b57b6728/Samples/VCL/VCLPerformanceTest.res
--------------------------------------------------------------------------------
/Source/Cadencer.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * cadencer imp library written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | unit Cadencer;
21 |
22 | {$INCLUDE zDefine.inc}
23 |
24 | interface
25 |
26 | uses CoreClasses;
27 |
28 | type
29 | {
30 | Progression event for time-base animations/simulations.
31 | deltaTime is the time delta since last progress and newTime is the new
32 | time after the progress event is completed.
33 | }
34 | TCadencerProgressMethod = procedure(Sender: TObject; const deltaTime, newTime: Double) of object;
35 | TCadencerProgressCall = procedure(Sender: TObject; const deltaTime, newTime: Double);
36 | {$IFDEF FPC}
37 | TCadencerProgressProc = procedure(Sender: TObject; const deltaTime, newTime: Double) is nested;
38 | {$ELSE FPC}
39 | TCadencerProgressProc = reference to procedure(Sender: TObject; const deltaTime, newTime: Double);
40 | {$ENDIF FPC}
41 |
42 | ICadencerProgressInterface = interface
43 | procedure CadencerProgress(const deltaTime, newTime: Double);
44 | end;
45 |
46 | {
47 | This component allows auto-progression of animation.
48 | Basicly dropping this component and linking it to your app will send
49 | it real-time progression events (time will be measured in seconds) while
50 | keeping the CPU 100% busy if possible (ie. if things change in your app).
51 | The progression time (the one you'll see in you progression events)
52 | is calculated using (CurrentTime-OriginTime)*TimeMultiplier,
53 | CurrentTime being either manually or automatically updated using
54 | TimeReference (setting CurrentTime does NOT trigger progression).
55 | }
56 | TCadencer = class(TCoreClassObject)
57 | private
58 | { Private Declarations }
59 | FTimeMultiplier: Double;
60 | LastTime, DownTime, LastMultiplier: Double;
61 | FLastDeltaTime: Double;
62 | FEnabled: Boolean;
63 | FSleepLength: Integer;
64 | FCurrentTime: Double;
65 | FOriginTime: Double;
66 | FMaxDeltaTime, FMinDeltaTime, FFixedDeltaTime: Double;
67 | FOnProgress: TCadencerProgressMethod;
68 | FOnProgressCall: TCadencerProgressCall;
69 | FOnProgressProc: TCadencerProgressProc;
70 | FProgressing: Integer;
71 | FProgressIntf: ICadencerProgressInterface;
72 | protected
73 | function StoreTimeMultiplier: Boolean;
74 | procedure SetEnabled(const val_: Boolean);
75 | procedure SetTimeMultiplier(const val_: Double);
76 | procedure SetCurrentTime(const Value: Double);
77 | { Returns raw ref time (no multiplier, no offset) }
78 | function GetRawReferenceTime: Double;
79 | public
80 | constructor Create;
81 | destructor Destroy; override;
82 |
83 | { Allows to manually trigger a progression. Time stuff is handled automatically. If cadencer is disabled, this functions does nothing. }
84 | procedure Progress;
85 |
86 | { Adjusts CurrentTime if necessary, then returns its value. }
87 | function UpdateCurrentTime: Double;
88 |
89 | { Returns True if a "Progress" is underway. }
90 | function IsBusy: Boolean;
91 |
92 | { Reset the time parameters and returns to zero. }
93 | procedure Reset;
94 |
95 | { Value soustracted to current time to obtain progression time. }
96 | property OriginTime: Double read FOriginTime write FOriginTime;
97 | { Current time (manually or automatically set, see TimeReference). }
98 | property CurrentTime: Double read FCurrentTime write SetCurrentTime;
99 |
100 | { Enables/Disables cadencing.
101 | Disabling won't cause a jump when restarting, it is working like a play/pause (ie. may modify OriginTime to keep things smooth). }
102 | property Enabled: Boolean read FEnabled write SetEnabled default True;
103 |
104 | { Multiplier applied to the time reference. }
105 | property TimeMultiplier: Double read FTimeMultiplier write SetTimeMultiplier stored StoreTimeMultiplier;
106 |
107 | { Maximum value for deltaTime in progression events.
108 | If null or negative, no max deltaTime is defined, otherwise, whenever an event whose actual deltaTime would be superior to MaxDeltaTime occurs,
109 | deltaTime is clamped to this max, and the extra time is hidden by the cadencer (it isn't visible in CurrentTime either).
110 | This option allows to limit progression rate in simulations where high values would result in errors/random behaviour. }
111 | property MaxDeltaTime: Double read FMaxDeltaTime write FMaxDeltaTime;
112 |
113 | { Minimum value for deltaTime in progression events.
114 | If superior to zero, this value specifies the minimum time step between two progression events.
115 | This option allows to limit progression rate in simulations where low values would result in errors/random behaviour. }
116 | property MinDeltaTime: Double read FMinDeltaTime write FMinDeltaTime;
117 |
118 | { Fixed time-step value for progression events.
119 | If superior to zero, progression steps will happen with that fixed delta time.
120 | The progression remains time based,
121 | so zero to N events may be fired depending on the actual deltaTime (if deltaTime is inferior to FixedDeltaTime, no event will be fired,
122 | if it is superior to two times FixedDeltaTime, two events will be fired, etc.).
123 | This option allows to use fixed time steps in simulations (while the animation and rendering itself may happen at a lower or higher framerate). }
124 | property FixedDeltaTime: Double read FFixedDeltaTime write FFixedDeltaTime;
125 |
126 | { Allows relinquishing time to other threads/processes.
127 | A "sleep" is issued BEFORE each progress if SleepLength>=0 (see help for the "sleep" procedure in delphi for details). }
128 | property SleepLength: Integer read FSleepLength write FSleepLength default -1;
129 |
130 | { LastDeltaTime from progress. }
131 | property LastDeltaTime: Double read FLastDeltaTime;
132 |
133 | { backcall }
134 | property OnProgress: TCadencerProgressMethod read FOnProgress write FOnProgress;
135 | property OnProgressCall: TCadencerProgressCall read FOnProgressCall write FOnProgressCall;
136 | property OnProgressProc: TCadencerProgressProc read FOnProgressProc write FOnProgressProc;
137 | { interface }
138 | property ProgressInterface: ICadencerProgressInterface read FProgressIntf write FProgressIntf;
139 | property OnProgressInterface: ICadencerProgressInterface read FProgressIntf write FProgressIntf;
140 | end;
141 |
142 | implementation
143 |
144 | function TCadencer.StoreTimeMultiplier: Boolean;
145 | begin
146 | Result := (FTimeMultiplier <> 1);
147 | end;
148 |
149 | procedure TCadencer.SetEnabled(const val_: Boolean);
150 | begin
151 | if FEnabled <> val_ then
152 | begin
153 | FEnabled := val_;
154 | if Enabled then
155 | FOriginTime := FOriginTime + GetRawReferenceTime - DownTime
156 | else
157 | DownTime := GetRawReferenceTime;
158 | end;
159 | end;
160 |
161 | procedure TCadencer.SetTimeMultiplier(const val_: Double);
162 | var
163 | rawRef: Double;
164 | begin
165 | if val_ <> FTimeMultiplier then
166 | begin
167 | if val_ = 0 then
168 | begin
169 | LastMultiplier := FTimeMultiplier;
170 | Enabled := False;
171 | end
172 | else
173 | begin
174 | rawRef := GetRawReferenceTime;
175 | if FTimeMultiplier = 0 then
176 | begin
177 | Enabled := True;
178 | FOriginTime := rawRef - (rawRef - FOriginTime) * LastMultiplier / val_;
179 | end
180 | else
181 | FOriginTime := rawRef - (rawRef - FOriginTime) * FTimeMultiplier / val_;
182 | end;
183 | FTimeMultiplier := val_;
184 | end;
185 | end;
186 |
187 | procedure TCadencer.SetCurrentTime(const Value: Double);
188 | begin
189 | LastTime := Value - (FCurrentTime - LastTime);
190 | FOriginTime := FOriginTime + (FCurrentTime - Value);
191 | FCurrentTime := Value;
192 | end;
193 |
194 | function TCadencer.GetRawReferenceTime: Double;
195 | begin
196 | Result := GetTimeTick * 0.001;
197 | end;
198 |
199 | constructor TCadencer.Create;
200 | begin
201 | inherited Create;
202 | DownTime := GetRawReferenceTime;
203 | FOriginTime := DownTime;
204 | FTimeMultiplier := 1;
205 | LastTime := 0;
206 | LastMultiplier := 0;
207 | FLastDeltaTime := 0;
208 | FSleepLength := -1;
209 | Enabled := True;
210 | FOnProgress := nil;
211 | FOnProgressCall := nil;
212 | FOnProgressProc := nil;
213 | FProgressIntf := nil;
214 | end;
215 |
216 | destructor TCadencer.Destroy;
217 | begin
218 | while FProgressing > 0 do
219 | TCompute.Sleep(1);
220 | inherited Destroy;
221 | end;
222 |
223 | procedure TCadencer.Progress;
224 | var
225 | deltaTime, newTime, totalDelta: Double;
226 | begin
227 | { basic protection against infinite loops, }
228 | { shall never happen, unless there is a bug in user code }
229 | if FProgressing < 0 then
230 | Exit;
231 | if Enabled then
232 | begin
233 | { avoid stalling everything else... }
234 | if SleepLength >= 0 then
235 | TCoreClassThread.Sleep(SleepLength);
236 | end;
237 | AtomInc(FProgressing);
238 | try
239 | if Enabled then
240 | begin
241 | { One of the processed messages might have disabled us }
242 | if Enabled then
243 | begin
244 | { ...and progress ! }
245 | newTime := UpdateCurrentTime;
246 | deltaTime := newTime - LastTime;
247 | if (deltaTime >= MinDeltaTime) and (deltaTime >= FixedDeltaTime) then
248 | begin
249 | if FMaxDeltaTime > 0 then
250 | begin
251 | if deltaTime > FMaxDeltaTime then
252 | begin
253 | FOriginTime := FOriginTime + (deltaTime - FMaxDeltaTime) / FTimeMultiplier;
254 | deltaTime := FMaxDeltaTime;
255 | newTime := LastTime + deltaTime;
256 | end;
257 | end;
258 | totalDelta := deltaTime;
259 | if FixedDeltaTime > 0 then
260 | deltaTime := FixedDeltaTime;
261 | while totalDelta >= deltaTime do
262 | begin
263 | LastTime := LastTime + deltaTime;
264 | FLastDeltaTime := deltaTime;
265 | try
266 | if Assigned(FOnProgress) then
267 | FOnProgress(Self, deltaTime, newTime);
268 | if Assigned(FOnProgressCall) then
269 | FOnProgressCall(Self, deltaTime, newTime);
270 | if Assigned(FOnProgressProc) then
271 | FOnProgressProc(Self, deltaTime, newTime);
272 | if Assigned(FProgressIntf) then
273 | FProgressIntf.CadencerProgress(deltaTime, newTime);
274 | except
275 | end;
276 |
277 | if deltaTime <= 0 then
278 | Break;
279 | totalDelta := totalDelta - deltaTime;
280 | end;
281 | end;
282 | end;
283 | end;
284 | finally
285 | AtomDec(FProgressing);
286 | end;
287 | end;
288 |
289 | function TCadencer.UpdateCurrentTime: Double;
290 | begin
291 | Result := (GetRawReferenceTime - FOriginTime) * FTimeMultiplier;
292 | FCurrentTime := Result;
293 | end;
294 |
295 | function TCadencer.IsBusy: Boolean;
296 | begin
297 | Result := (FProgressing > 0);
298 | end;
299 |
300 | procedure TCadencer.Reset;
301 | begin
302 | LastTime := 0;
303 | DownTime := GetRawReferenceTime;
304 | FOriginTime := DownTime;
305 | end;
306 |
307 | initialization
308 |
309 | finalization
310 |
311 | end.
312 |
--------------------------------------------------------------------------------
/Source/CoreAtomic.inc:
--------------------------------------------------------------------------------
1 | // used Critical Simulate Atomic with TMonitor.Enter(obj) and TMonitor.Exit(obj)
2 | // CriticalSimulateAtomic defined so performance to be reduced
3 |
4 | // used soft Simulate Critical(ring)
5 | // SoftCritical defined so performance to be reduced
6 |
7 | { * object lock create by qq600585 * }
8 | { ****************************************************************************** }
9 | { * https://zpascal.net * }
10 | { * https://github.com/PassByYou888/zAI * }
11 | { * https://github.com/PassByYou888/ZServer4D * }
12 | { * https://github.com/PassByYou888/PascalString * }
13 | { * https://github.com/PassByYou888/zRasterization * }
14 | { * https://github.com/PassByYou888/CoreCipher * }
15 | { * https://github.com/PassByYou888/zSound * }
16 | { * https://github.com/PassByYou888/zChinese * }
17 | { * https://github.com/PassByYou888/zExpression * }
18 | { * https://github.com/PassByYou888/zGameWare * }
19 | { * https://github.com/PassByYou888/zAnalysis * }
20 | { * https://github.com/PassByYou888/FFMPEG-Header * }
21 | { * https://github.com/PassByYou888/zTranslate * }
22 | { * https://github.com/PassByYou888/InfiniteIoT * }
23 | { * https://github.com/PassByYou888/FastMD5 * }
24 | { ****************************************************************************** }
25 |
26 | constructor TSoftCritical.Create;
27 | begin
28 | inherited Create;
29 | L := False;
30 | end;
31 |
32 | procedure TSoftCritical.Acquire;
33 | {$IFDEF ANTI_DEAD_ATOMIC_LOCK}
34 | var
35 | d: TTimeTick;
36 | {$ENDIF ANTI_DEAD_ATOMIC_LOCK}
37 | begin
38 | {$IFDEF ANTI_DEAD_ATOMIC_LOCK}
39 | d := GetTimeTick;
40 | while L do
41 | if GetTimeTick - d >= 5000 then
42 | RaiseInfo('dead lock');
43 | {$ELSE ANTI_DEAD_ATOMIC_LOCK}
44 | while L do
45 | NOP;
46 | {$ENDIF ANTI_DEAD_ATOMIC_LOCK}
47 | L := True;
48 | end;
49 |
50 | procedure TSoftCritical.Release;
51 | begin
52 | L := False;
53 | end;
54 |
55 | procedure TSoftCritical.Enter;
56 | begin
57 | Acquire;
58 | end;
59 |
60 | procedure TSoftCritical.Leave;
61 | begin
62 | Release;
63 | end;
64 |
65 | constructor TCritical.Create;
66 | begin
67 | inherited Create;
68 | LNum := 0;
69 | end;
70 |
71 | destructor TCritical.Destroy;
72 | begin
73 | inherited Destroy;
74 | end;
75 |
76 | procedure TCritical.Acquire;
77 | begin
78 | inherited Acquire;
79 | Inc(LNum);
80 | end;
81 |
82 | procedure TCritical.Release;
83 | begin
84 | Dec(LNum);
85 | inherited Release;
86 | end;
87 |
88 | procedure TCritical.Enter;
89 | begin
90 | Acquire();
91 | end;
92 |
93 | procedure TCritical.Leave;
94 | begin
95 | Release();
96 | end;
97 |
98 | procedure TCritical.Lock;
99 | begin
100 | Acquire();
101 | end;
102 |
103 | procedure TCritical.UnLock;
104 | begin
105 | Release();
106 | end;
107 |
108 | function TCritical.IsBusy: Boolean;
109 | begin
110 | Result := LNum > 0;
111 | end;
112 |
113 | procedure TCritical.Inc_(var x: Int64);
114 | begin
115 | Lock;
116 | Inc(x);
117 | UnLock;
118 | end;
119 |
120 | procedure TCritical.Inc_(var x: Int64; const v: Int64);
121 | begin
122 | Lock;
123 | Inc(x, v);
124 | UnLock;
125 | end;
126 |
127 | procedure TCritical.Dec_(var x: Int64);
128 | begin
129 | Lock;
130 | Dec(x);
131 | UnLock;
132 | end;
133 |
134 | procedure TCritical.Dec_(var x: Int64; const v: Int64);
135 | begin
136 | Lock;
137 | Dec(x, v);
138 | UnLock;
139 | end;
140 |
141 | procedure TCritical.Inc_(var x: UInt64);
142 | begin
143 | Lock;
144 | Inc(x);
145 | UnLock;
146 | end;
147 |
148 | procedure TCritical.Inc_(var x: UInt64; const v: UInt64);
149 | begin
150 | Lock;
151 | Inc(x, v);
152 | UnLock;
153 | end;
154 |
155 | procedure TCritical.Dec_(var x: UInt64);
156 | begin
157 | Lock;
158 | Dec(x);
159 | UnLock;
160 | end;
161 |
162 | procedure TCritical.Dec_(var x: UInt64; const v: UInt64);
163 | begin
164 | Lock;
165 | Dec(x, v);
166 | UnLock;
167 | end;
168 |
169 | procedure TCritical.Inc_(var x: Integer);
170 | begin
171 | Lock;
172 | Inc(x);
173 | UnLock;
174 | end;
175 |
176 | procedure TCritical.Inc_(var x: Integer; const v: Integer);
177 | begin
178 | Lock;
179 | Inc(x, v);
180 | UnLock;
181 | end;
182 |
183 | procedure TCritical.Dec_(var x: Integer);
184 | begin
185 | Lock;
186 | Dec(x);
187 | UnLock;
188 | end;
189 |
190 | procedure TCritical.Dec_(var x: Integer; const v: Integer);
191 | begin
192 | Lock;
193 | Dec(x, v);
194 | UnLock;
195 | end;
196 |
197 | procedure TCritical.Inc_(var x: Cardinal);
198 | begin
199 | Lock;
200 | Inc(x);
201 | UnLock;
202 | end;
203 |
204 | procedure TCritical.Inc_(var x: Cardinal; const v: Cardinal);
205 | begin
206 | Lock;
207 | Inc(x, v);
208 | UnLock;
209 | end;
210 |
211 | procedure TCritical.Dec_(var x: Cardinal);
212 | begin
213 | Lock;
214 | Dec(x);
215 | UnLock;
216 | end;
217 |
218 | procedure TCritical.Dec_(var x: Cardinal; const v: Cardinal);
219 | begin
220 | Lock;
221 | Dec(x, v);
222 | UnLock;
223 | end;
224 |
225 | type
226 | PCritical_Struct = ^TCritical_Struct;
227 |
228 | TCritical_Struct = record
229 | Obj: TObject;
230 | LEnter: Integer;
231 | LockTick: TTimeTick;
232 | Critical: TCritical;
233 | end;
234 |
235 | TGetCriticalLockState = (lsSame, lsNew, lsIdle);
236 |
237 | var
238 | CoreLockCritical: TCriticalSection;
239 | CoreComputeCritical: TCriticalSection;
240 | CoreTimeTickCritical: TCriticalSection;
241 | CriticalList: TCoreClassList;
242 |
243 | procedure InitCriticalLock;
244 | begin
245 | CoreLockCritical := TCriticalSection.Create;
246 | CoreComputeCritical := TCriticalSection.Create;
247 | CoreTimeTickCritical := TCriticalSection.Create;
248 | CriticalList := TCoreClassList.Create;
249 | end;
250 |
251 | procedure FreeCriticalLock;
252 | var
253 | i: Integer;
254 | p: PCritical_Struct;
255 | begin
256 | for i := 0 to CriticalList.Count - 1 do
257 | begin
258 | p := PCritical_Struct(CriticalList[i]);
259 | p^.Critical.Free;
260 | Dispose(p);
261 | end;
262 | CriticalList.Free;
263 | CriticalList := nil;
264 |
265 | CoreLockCritical.Free;
266 | CoreLockCritical := nil;
267 |
268 | CoreComputeCritical.Free;
269 | CoreComputeCritical := nil;
270 |
271 | CoreTimeTickCritical.Free;
272 | CoreTimeTickCritical := nil;
273 | end;
274 |
275 | procedure GetCriticalLock(const Obj: TObject; var output: PCritical_Struct; var state: TGetCriticalLockState);
276 | var
277 | i, pIndex: Integer;
278 | p1, p2: PCritical_Struct;
279 | begin
280 | output := nil;
281 | pIndex := -1;
282 | p1 := nil;
283 | i := 0;
284 | while i < CriticalList.Count do
285 | begin
286 | p2 := PCritical_Struct(CriticalList[i]);
287 | if p2^.Obj = Obj then
288 | begin
289 | output := p2;
290 | state := TGetCriticalLockState.lsSame;
291 | exit;
292 | end
293 | else if (p2^.Obj = nil) and (p2^.LEnter = 0) then
294 | begin
295 | p1 := p2;
296 | pIndex := i;
297 | end;
298 | Inc(i);
299 | end;
300 |
301 | if p1 <> nil then
302 | begin
303 | p1^.Obj := Obj;
304 | output := p1;
305 | if pIndex > 0 then
306 | CriticalList.Move(pIndex, 0);
307 | state := TGetCriticalLockState.lsIdle;
308 | end
309 | else
310 | begin
311 | new(p1);
312 | p1^.Obj := Obj;
313 | p1^.LEnter := 0;
314 | p1^.LockTick := GetTimeTick();
315 | p1^.Critical := TCritical.Create;
316 | CriticalList.Insert(0, p1);
317 | output := p1;
318 | state := TGetCriticalLockState.lsNew;
319 | end;
320 | end;
321 |
322 | procedure _LockCriticalObj(Obj: TObject);
323 | var
324 | p: PCritical_Struct;
325 | ls: TGetCriticalLockState;
326 | begin
327 | CoreLockCritical.Acquire;
328 | GetCriticalLock(Obj, p, ls);
329 | CoreLockCritical.Release;
330 | p^.Critical.Acquire;
331 | p^.LockTick := GetTimeTick();
332 | AtomInc(p^.LEnter);
333 | end;
334 |
335 | procedure _UnLockCriticalObj(Obj: TObject);
336 | var
337 | p: PCritical_Struct;
338 | ls: TGetCriticalLockState;
339 | begin
340 | CoreLockCritical.Acquire;
341 | GetCriticalLock(Obj, p, ls);
342 | CoreLockCritical.Release;
343 |
344 | AtomDec(p^.LEnter);
345 | if p^.LEnter < 0 then
346 | RaiseInfo('error: unlock failed: illegal unlock');
347 | p^.LockTick := GetTimeTick();
348 | p^.Critical.Release;
349 | end;
350 |
351 | procedure _RecycleLocker(const Obj: TObject);
352 | var
353 | p: PCritical_Struct;
354 | i: Integer;
355 | begin
356 | if (CoreLockCritical = nil) or (CriticalList = nil) or (CriticalList.Count = 0) then
357 | exit;
358 |
359 | CoreLockCritical.Acquire;
360 | i := 0;
361 | while i < CriticalList.Count do
362 | begin
363 | p := PCritical_Struct(CriticalList[i]);
364 | if p^.Obj = Obj then
365 | begin
366 | CriticalList.Delete(i);
367 | p^.Critical.Free;
368 | Dispose(p);
369 | break;
370 | end
371 | else
372 | Inc(i);
373 | end;
374 | CoreLockCritical.Release;
375 | end;
376 |
377 | function DeltaStep(const value_, Delta_: NativeInt): NativeInt;
378 | begin
379 | if Delta_ > 0 then
380 | Result := (value_ + (Delta_ - 1)) and (not(Delta_ - 1))
381 | else
382 | Result := value_;
383 | end;
384 |
385 | procedure AtomInc(var x: Int64);
386 | begin
387 | {$IFDEF FPC}
388 | CoreComputeCritical.Acquire;
389 | Inc(x);
390 | CoreComputeCritical.Release;
391 | {$ELSE FPC}
392 | System.AtomicIncrement(x);
393 | {$ENDIF FPC}
394 | end;
395 |
396 | procedure AtomInc(var x: Int64; const v: Int64);
397 | begin
398 | {$IFDEF FPC}
399 | CoreComputeCritical.Acquire;
400 | Inc(x, v);
401 | CoreComputeCritical.Release;
402 | {$ELSE FPC}
403 | System.AtomicIncrement(x, v);
404 | {$ENDIF FPC}
405 | end;
406 |
407 | procedure AtomDec(var x: Int64);
408 | begin
409 | {$IFDEF FPC}
410 | CoreComputeCritical.Acquire;
411 | Dec(x);
412 | CoreComputeCritical.Release;
413 | {$ELSE FPC}
414 | System.AtomicDecrement(x);
415 | {$ENDIF FPC}
416 | end;
417 |
418 | procedure AtomDec(var x: Int64; const v: Int64);
419 | begin
420 | {$IFDEF FPC}
421 | CoreComputeCritical.Acquire;
422 | Dec(x, v);
423 | CoreComputeCritical.Release;
424 | {$ELSE FPC}
425 | System.AtomicDecrement(x, v);
426 | {$ENDIF FPC}
427 | end;
428 |
429 | procedure AtomInc(var x: UInt64);
430 | begin
431 | {$IFDEF FPC}
432 | CoreComputeCritical.Acquire;
433 | Inc(x);
434 | CoreComputeCritical.Release;
435 | {$ELSE FPC}
436 | System.AtomicIncrement(x);
437 | {$ENDIF FPC}
438 | end;
439 |
440 | procedure AtomInc(var x: UInt64; const v: UInt64);
441 | begin
442 | {$IFDEF FPC}
443 | CoreComputeCritical.Acquire;
444 | Inc(x, v);
445 | CoreComputeCritical.Release;
446 | {$ELSE FPC}
447 | System.AtomicIncrement(x, v);
448 | {$ENDIF FPC}
449 | end;
450 |
451 | procedure AtomDec(var x: UInt64);
452 | begin
453 | {$IFDEF FPC}
454 | CoreComputeCritical.Acquire;
455 | Dec(x);
456 | CoreComputeCritical.Release;
457 | {$ELSE FPC}
458 | System.AtomicDecrement(x);
459 | {$ENDIF FPC}
460 | end;
461 |
462 | procedure AtomDec(var x: UInt64; const v: UInt64);
463 | begin
464 | {$IFDEF FPC}
465 | CoreComputeCritical.Acquire;
466 | Dec(x, v);
467 | CoreComputeCritical.Release;
468 | {$ELSE FPC}
469 | System.AtomicDecrement(x, v);
470 | {$ENDIF FPC}
471 | end;
472 |
473 | procedure AtomInc(var x: Integer);
474 | begin
475 | {$IFDEF FPC}
476 | CoreComputeCritical.Acquire;
477 | Inc(x);
478 | CoreComputeCritical.Release;
479 | {$ELSE FPC}
480 | System.AtomicIncrement(x);
481 | {$ENDIF FPC}
482 | end;
483 |
484 | procedure AtomInc(var x: Integer; const v: Integer);
485 | begin
486 | {$IFDEF FPC}
487 | CoreComputeCritical.Acquire;
488 | Inc(x, v);
489 | CoreComputeCritical.Release;
490 | {$ELSE FPC}
491 | System.AtomicIncrement(x, v);
492 | {$ENDIF FPC}
493 | end;
494 |
495 | procedure AtomDec(var x: Integer);
496 | begin
497 | {$IFDEF FPC}
498 | CoreComputeCritical.Acquire;
499 | Dec(x);
500 | CoreComputeCritical.Release;
501 | {$ELSE FPC}
502 | System.AtomicDecrement(x);
503 | {$ENDIF FPC}
504 | end;
505 |
506 | procedure AtomDec(var x: Integer; const v: Integer);
507 | begin
508 | {$IFDEF FPC}
509 | CoreComputeCritical.Acquire;
510 | Dec(x, v);
511 | CoreComputeCritical.Release;
512 | {$ELSE FPC}
513 | System.AtomicDecrement(x, v);
514 | {$ENDIF FPC}
515 | end;
516 |
517 | procedure AtomInc(var x: Cardinal);
518 | begin
519 | {$IFDEF FPC}
520 | CoreComputeCritical.Acquire;
521 | Inc(x);
522 | CoreComputeCritical.Release;
523 | {$ELSE FPC}
524 | System.AtomicIncrement(x);
525 | {$ENDIF FPC}
526 | end;
527 |
528 | procedure AtomInc(var x: Cardinal; const v: Cardinal);
529 | begin
530 | {$IFDEF FPC}
531 | CoreComputeCritical.Acquire;
532 | Inc(x, v);
533 | CoreComputeCritical.Release;
534 | {$ELSE FPC}
535 | System.AtomicIncrement(x, v);
536 | {$ENDIF FPC}
537 | end;
538 |
539 | procedure AtomDec(var x: Cardinal);
540 | begin
541 | {$IFDEF FPC}
542 | CoreComputeCritical.Acquire;
543 | Dec(x);
544 | CoreComputeCritical.Release;
545 | {$ELSE FPC}
546 | System.AtomicDecrement(x);
547 | {$ENDIF FPC}
548 | end;
549 |
550 | procedure AtomDec(var x: Cardinal; const v: Cardinal);
551 | begin
552 | {$IFDEF FPC}
553 | CoreComputeCritical.Acquire;
554 | Dec(x, v);
555 | CoreComputeCritical.Release;
556 | {$ELSE FPC}
557 | System.AtomicDecrement(x, v);
558 | {$ENDIF FPC}
559 | end;
560 |
--------------------------------------------------------------------------------
/Source/CoreEndian.inc:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * https://zpascal.net * }
3 | { * https://github.com/PassByYou888/zAI * }
4 | { * https://github.com/PassByYou888/ZServer4D * }
5 | { * https://github.com/PassByYou888/PascalString * }
6 | { * https://github.com/PassByYou888/zRasterization * }
7 | { * https://github.com/PassByYou888/CoreCipher * }
8 | { * https://github.com/PassByYou888/zSound * }
9 | { * https://github.com/PassByYou888/zChinese * }
10 | { * https://github.com/PassByYou888/zExpression * }
11 | { * https://github.com/PassByYou888/zGameWare * }
12 | { * https://github.com/PassByYou888/zAnalysis * }
13 | { * https://github.com/PassByYou888/FFMPEG-Header * }
14 | { * https://github.com/PassByYou888/zTranslate * }
15 | { * https://github.com/PassByYou888/InfiniteIoT * }
16 | { * https://github.com/PassByYou888/FastMD5 * }
17 | { ****************************************************************************** }
18 | {$IFDEF OverflowCheck}{$Q-}{$ENDIF}
19 | {$IFDEF RangeCheck}{$R-}{$ENDIF}
20 |
21 |
22 | function ROL8(const Value: Byte; Shift: Byte): Byte;
23 | begin
24 | Shift := Shift and $07;
25 | Result := Byte((Value shl Shift) or (Value shr (8 - Shift)));
26 | end;
27 |
28 | function ROL16(const Value: Word; Shift: Byte): Word;
29 | begin
30 | Shift := Shift and $0F;
31 | Result := Word((Value shl Shift) or (Value shr (16 - Shift)));
32 | end;
33 |
34 | function ROL32(const Value: Cardinal; Shift: Byte): Cardinal;
35 | begin
36 | Shift := Shift and $1F;
37 | Result := Cardinal((Value shl Shift) or (Value shr (32 - Shift)));
38 | end;
39 |
40 | function ROL64(const Value: UInt64; Shift: Byte): UInt64;
41 | begin
42 | Shift := Shift and $3F;
43 | Result := UInt64((Value shl Shift) or (Value shr (64 - Shift)));
44 | end;
45 |
46 | function ROR8(const Value: Byte; Shift: Byte): Byte;
47 | begin
48 | Shift := Shift and $07;
49 | Result := UInt8((Value shr Shift) or (Value shl (8 - Shift)));
50 | end;
51 |
52 | function ROR16(const Value: Word; Shift: Byte): Word;
53 | begin
54 | Shift := Shift and $0F;
55 | Result := Word((Value shr Shift) or (Value shl (16 - Shift)));
56 | end;
57 |
58 | function ROR32(const Value: Cardinal; Shift: Byte): Cardinal;
59 | begin
60 | Shift := Shift and $1F;
61 | Result := Cardinal((Value shr Shift) or (Value shl (32 - Shift)));
62 | end;
63 |
64 | function ROR64(const Value: UInt64; Shift: Byte): UInt64;
65 | begin
66 | Shift := Shift and $3F;
67 | Result := UInt64((Value shr Shift) or (Value shl (64 - Shift)));
68 | end;
69 |
70 | function Endian(const AValue: SmallInt): SmallInt;
71 | begin
72 | { the extra Word type cast is necessary because the "AValue shr 8" }
73 | { is turned into "Integer(AValue) shr 8", so if AValue < 0 then }
74 | { the sign bits from the upper 16 bits are shifted in rather than }
75 | { zeroes. }
76 | Result := SmallInt((Word(AValue) shr 8) or (Word(AValue) shl 8));
77 | end;
78 |
79 | function Endian(const AValue: Word): Word;
80 | begin
81 | Result := Word((AValue shr 8) or (AValue shl 8));
82 | end;
83 |
84 | function Endian(const AValue: Integer): Integer;
85 | begin
86 | Result := ((Cardinal(AValue) shl 8) and $FF00FF00) or ((Cardinal(AValue) shr 8) and $00FF00FF);
87 | Result := (Cardinal(Result) shl 16) or (Cardinal(Result) shr 16);
88 | end;
89 |
90 | function Endian(const AValue: Cardinal): Cardinal;
91 | begin
92 | Result := ((AValue shl 8) and $FF00FF00) or ((AValue shr 8) and $00FF00FF);
93 | Result := (Result shl 16) or (Result shr 16);
94 | end;
95 |
96 | function Endian(const AValue: Int64): Int64;
97 | begin
98 | Result := ((UInt64(AValue) shl 8) and $FF00FF00FF00FF00) or ((UInt64(AValue) shr 8) and $00FF00FF00FF00FF);
99 | Result := ((UInt64(Result) shl 16) and $FFFF0000FFFF0000) or ((UInt64(Result) shr 16) and $0000FFFF0000FFFF);
100 | Result := (UInt64(Result) shl 32) or ((UInt64(Result) shr 32));
101 | end;
102 |
103 | function Endian(const AValue: UInt64): UInt64;
104 | begin
105 | Result := ((AValue shl 8) and $FF00FF00FF00FF00) or ((AValue shr 8) and $00FF00FF00FF00FF);
106 | Result := ((Result shl 16) and $FFFF0000FFFF0000) or ((Result shr 16) and $0000FFFF0000FFFF);
107 | Result := (Result shl 32) or ((Result shr 32));
108 | end;
109 |
110 | function BE2N(const AValue: SmallInt): SmallInt;
111 | begin
112 | {$IFDEF BIG_ENDIAN}
113 | Result := AValue;
114 | {$ELSE}
115 | Result := Endian(AValue);
116 | {$ENDIF}
117 | end;
118 |
119 | function BE2N(const AValue: Word): Word;
120 | begin
121 | {$IFDEF BIG_ENDIAN}
122 | Result := AValue;
123 | {$ELSE}
124 | Result := Endian(AValue);
125 | {$ENDIF}
126 | end;
127 |
128 | function BE2N(const AValue: Integer): Integer;
129 | begin
130 | {$IFDEF BIG_ENDIAN}
131 | Result := AValue;
132 | {$ELSE}
133 | Result := Endian(AValue);
134 | {$ENDIF}
135 | end;
136 |
137 | function BE2N(const AValue: Cardinal): Cardinal;
138 | begin
139 | {$IFDEF BIG_ENDIAN}
140 | Result := AValue;
141 | {$ELSE}
142 | Result := Endian(AValue);
143 | {$ENDIF}
144 | end;
145 |
146 | function BE2N(const AValue: Int64): Int64;
147 | begin
148 | {$IFDEF BIG_ENDIAN}
149 | Result := AValue;
150 | {$ELSE}
151 | Result := Endian(AValue);
152 | {$ENDIF}
153 | end;
154 |
155 | function BE2N(const AValue: UInt64): UInt64;
156 | begin
157 | {$IFDEF BIG_ENDIAN}
158 | Result := AValue;
159 | {$ELSE}
160 | Result := Endian(AValue);
161 | {$ENDIF}
162 | end;
163 |
164 | function LE2N(const AValue: SmallInt): SmallInt;
165 | begin
166 | {$IFDEF LITTLE_ENDIAN}
167 | Result := AValue;
168 | {$ELSE}
169 | Result := Endian(AValue);
170 | {$ENDIF}
171 | end;
172 |
173 | function LE2N(const AValue: Word): Word;
174 | begin
175 | {$IFDEF LITTLE_ENDIAN}
176 | Result := AValue;
177 | {$ELSE}
178 | Result := Endian(AValue);
179 | {$ENDIF}
180 | end;
181 |
182 | function LE2N(const AValue: Integer): Integer;
183 | begin
184 | {$IFDEF LITTLE_ENDIAN}
185 | Result := AValue;
186 | {$ELSE}
187 | Result := Endian(AValue);
188 | {$ENDIF}
189 | end;
190 |
191 | function LE2N(const AValue: Cardinal): Cardinal;
192 | begin
193 | {$IFDEF LITTLE_ENDIAN}
194 | Result := AValue;
195 | {$ELSE}
196 | Result := Endian(AValue);
197 | {$ENDIF}
198 | end;
199 |
200 | function LE2N(const AValue: Int64): Int64;
201 | begin
202 | {$IFDEF LITTLE_ENDIAN}
203 | Result := AValue;
204 | {$ELSE}
205 | Result := Endian(AValue);
206 | {$ENDIF}
207 | end;
208 |
209 | function LE2N(const AValue: UInt64): UInt64;
210 | begin
211 | {$IFDEF LITTLE_ENDIAN}
212 | Result := AValue;
213 | {$ELSE}
214 | Result := Endian(AValue);
215 | {$ENDIF}
216 | end;
217 |
218 | function N2BE(const AValue: SmallInt): SmallInt;
219 | begin
220 | {$IFDEF BIG_ENDIAN}
221 | Result := AValue;
222 | {$ELSE}
223 | Result := Endian(AValue);
224 | {$ENDIF}
225 | end;
226 |
227 | function N2BE(const AValue: Word): Word;
228 | begin
229 | {$IFDEF BIG_ENDIAN}
230 | Result := AValue;
231 | {$ELSE}
232 | Result := Endian(AValue);
233 | {$ENDIF}
234 | end;
235 |
236 | function N2BE(const AValue: Integer): Integer;
237 | begin
238 | {$IFDEF BIG_ENDIAN}
239 | Result := AValue;
240 | {$ELSE}
241 | Result := Endian(AValue);
242 | {$ENDIF}
243 | end;
244 |
245 | function N2BE(const AValue: Cardinal): Cardinal;
246 | begin
247 | {$IFDEF BIG_ENDIAN}
248 | Result := AValue;
249 | {$ELSE}
250 | Result := Endian(AValue);
251 | {$ENDIF}
252 | end;
253 |
254 | function N2BE(const AValue: Int64): Int64;
255 | begin
256 | {$IFDEF BIG_ENDIAN}
257 | Result := AValue;
258 | {$ELSE}
259 | Result := Endian(AValue);
260 | {$ENDIF}
261 | end;
262 |
263 | function N2BE(const AValue: UInt64): UInt64;
264 | begin
265 | {$IFDEF BIG_ENDIAN}
266 | Result := AValue;
267 | {$ELSE}
268 | Result := Endian(AValue);
269 | {$ENDIF}
270 | end;
271 |
272 | function N2LE(const AValue: SmallInt): SmallInt;
273 | begin
274 | {$IFDEF LITTLE_ENDIAN}
275 | Result := AValue;
276 | {$ELSE}
277 | Result := Endian(AValue);
278 | {$ENDIF}
279 | end;
280 |
281 | function N2LE(const AValue: Word): Word;
282 | begin
283 | {$IFDEF LITTLE_ENDIAN}
284 | Result := AValue;
285 | {$ELSE}
286 | Result := Endian(AValue);
287 | {$ENDIF}
288 | end;
289 |
290 | function N2LE(const AValue: Integer): Integer;
291 | begin
292 | {$IFDEF LITTLE_ENDIAN}
293 | Result := AValue;
294 | {$ELSE}
295 | Result := Endian(AValue);
296 | {$ENDIF}
297 | end;
298 |
299 | function N2LE(const AValue: Cardinal): Cardinal;
300 | begin
301 | {$IFDEF LITTLE_ENDIAN}
302 | Result := AValue;
303 | {$ELSE}
304 | Result := Endian(AValue);
305 | {$ENDIF}
306 | end;
307 |
308 | function N2LE(const AValue: Int64): Int64;
309 | begin
310 | {$IFDEF LITTLE_ENDIAN}
311 | Result := AValue;
312 | {$ELSE}
313 | Result := Endian(AValue);
314 | {$ENDIF}
315 | end;
316 |
317 | function N2LE(const AValue: UInt64): UInt64;
318 | begin
319 | {$IFDEF LITTLE_ENDIAN}
320 | Result := AValue;
321 | {$ELSE}
322 | Result := Endian(AValue);
323 | {$ENDIF}
324 | end;
325 |
326 | procedure Swap(var v1, v2: Byte);
327 | var
328 | v: Byte;
329 | begin
330 | v := v1;
331 | v1 := v2;
332 | v2 := v;
333 | end;
334 |
335 | procedure Swap(var v1, v2: Word);
336 | var
337 | v: Word;
338 | begin
339 | v := v1;
340 | v1 := v2;
341 | v2 := v;
342 | end;
343 |
344 | procedure Swap(var v1, v2: Integer);
345 | var
346 | v: Integer;
347 | begin
348 | v := v1;
349 | v1 := v2;
350 | v2 := v;
351 | end;
352 |
353 | procedure Swap(var v1, v2: Cardinal);
354 | var
355 | v: Cardinal;
356 | begin
357 | v := v1;
358 | v1 := v2;
359 | v2 := v;
360 | end;
361 |
362 | procedure Swap(var v1, v2: Int64);
363 | var
364 | v: Int64;
365 | begin
366 | v := v1;
367 | v1 := v2;
368 | v2 := v;
369 | end;
370 |
371 | procedure Swap(var v1, v2: UInt64);
372 | var
373 | v: UInt64;
374 | begin
375 | v := v1;
376 | v1 := v2;
377 | v2 := v;
378 | end;
379 |
380 | {$IFDEF OVERLOAD_NATIVEINT}
381 |
382 |
383 | procedure Swap(var v1, v2: NativeInt);
384 | var
385 | v: NativeInt;
386 | begin
387 | v := v1;
388 | v1 := v2;
389 | v2 := v;
390 | end;
391 |
392 | procedure Swap(var v1, v2: NativeUInt);
393 | var
394 | v: NativeUInt;
395 | begin
396 | v := v1;
397 | v1 := v2;
398 | v2 := v;
399 | end;
400 | {$ENDIF OVERLOAD_NATIVEINT}
401 |
402 |
403 | procedure Swap(var v1, v2: string);
404 | var
405 | v: string;
406 | begin
407 | v := v1;
408 | v1 := v2;
409 | v2 := v;
410 | end;
411 |
412 | procedure Swap(var v1, v2: Single);
413 | var
414 | v: Single;
415 | begin
416 | v := v1;
417 | v1 := v2;
418 | v2 := v;
419 | end;
420 |
421 | procedure Swap(var v1, v2: Double);
422 | var
423 | v: Double;
424 | begin
425 | v := v1;
426 | v1 := v2;
427 | v2 := v;
428 | end;
429 |
430 | procedure Swap(var v1, v2: Pointer);
431 | var
432 | v: Pointer;
433 | begin
434 | v := v1;
435 | v1 := v2;
436 | v2 := v;
437 | end;
438 |
439 | procedure SwapVariant(var v1, v2: Variant);
440 | var
441 | v: Variant;
442 | begin
443 | v := v1;
444 | v1 := v2;
445 | v2 := v;
446 | end;
447 |
448 | function Swap(const v: Word): Word;
449 | begin
450 | Result := Endian(v);
451 | end;
452 |
453 | function Swap(const v: Cardinal): Cardinal;
454 | begin
455 | Result := Endian(v);
456 | end;
457 |
458 | function Swap(const v: UInt64): UInt64;
459 | begin
460 | Result := Endian(v);
461 | end;
462 |
463 | function SAR16(const AValue: SmallInt; const Shift: Byte): SmallInt;
464 | begin
465 | Result := SmallInt(
466 | Word(Word(Word(AValue) shr (Shift and 15)) or
467 | (Word(SmallInt(Word(0 - Word(Word(AValue) shr 15)) and Word(SmallInt(0 - (Ord((Shift and 15) <> 0) { and 1 } ))))) shl (16 - (Shift and 15)))));
468 | end;
469 |
470 | function SAR32(const AValue: Integer; Shift: Byte): Integer;
471 | begin
472 | Result := Integer(
473 | Cardinal(Cardinal(Cardinal(AValue) shr (Shift and 31)) or
474 | (Cardinal(Integer(Cardinal(0 - Cardinal(Cardinal(AValue) shr 31)) and Cardinal(Integer(0 - (Ord((Shift and 31) <> 0) { and 1 } ))))) shl (32 - (Shift and 31)))));
475 | end;
476 |
477 | function SAR64(const AValue: Int64; Shift: Byte): Int64;
478 | begin
479 | Result := Int64(
480 | UInt64(UInt64(UInt64(AValue) shr (Shift and 63)) or
481 | (UInt64(Int64(UInt64(0 - UInt64(UInt64(AValue) shr 63)) and UInt64(Int64(0 - (Ord((Shift and 63) <> 0) { and 1 } ))))) shl (64 - (Shift and 63)))));
482 | end;
483 |
484 | function MemoryAlign(addr: Pointer; alignment_: NativeUInt): Pointer;
485 | var
486 | tmp: NativeUInt;
487 | begin
488 | tmp := NativeUInt(addr) + (alignment_ - 1);
489 | Result := Pointer(tmp - (tmp mod alignment_));
490 | end;
491 |
492 | {$IFDEF OverflowCheck}{$Q+}{$ENDIF}
493 | {$IFDEF RangeCheck}{$R+}{$ENDIF}
494 |
495 |
496 | function if_(const bool_: Boolean; const True_, False_: Boolean): Boolean;
497 | begin
498 | if bool_ then
499 | Result := True_
500 | else
501 | Result := False_;
502 | end;
503 |
504 | function if_(const bool_: Boolean; const True_, False_: ShortInt): ShortInt;
505 | begin
506 | if bool_ then
507 | Result := True_
508 | else
509 | Result := False_;
510 | end;
511 |
512 | function if_(const bool_: Boolean; const True_, False_: SmallInt): SmallInt;
513 | begin
514 | if bool_ then
515 | Result := True_
516 | else
517 | Result := False_;
518 | end;
519 |
520 | function if_(const bool_: Boolean; const True_, False_: Integer): Integer;
521 | begin
522 | if bool_ then
523 | Result := True_
524 | else
525 | Result := False_;
526 | end;
527 |
528 | function if_(const bool_: Boolean; const True_, False_: Int64): Int64;
529 | begin
530 | if bool_ then
531 | Result := True_
532 | else
533 | Result := False_;
534 | end;
535 |
536 | function if_(const bool_: Boolean; const True_, False_: Byte): Byte;
537 | begin
538 | if bool_ then
539 | Result := True_
540 | else
541 | Result := False_;
542 | end;
543 |
544 | function if_(const bool_: Boolean; const True_, False_: Word): Word;
545 | begin
546 | if bool_ then
547 | Result := True_
548 | else
549 | Result := False_;
550 | end;
551 |
552 | function if_(const bool_: Boolean; const True_, False_: Cardinal): Cardinal;
553 | begin
554 | if bool_ then
555 | Result := True_
556 | else
557 | Result := False_;
558 | end;
559 |
560 | function if_(const bool_: Boolean; const True_, False_: UInt64): UInt64;
561 | begin
562 | if bool_ then
563 | Result := True_
564 | else
565 | Result := False_;
566 | end;
567 |
568 | function if_(const bool_: Boolean; const True_, False_: Single): Single;
569 | begin
570 | if bool_ then
571 | Result := True_
572 | else
573 | Result := False_;
574 | end;
575 |
576 | function if_(const bool_: Boolean; const True_, False_: Double): Double;
577 | begin
578 | if bool_ then
579 | Result := True_
580 | else
581 | Result := False_;
582 | end;
583 |
584 | function if_(const bool_: Boolean; const True_, False_: string): string;
585 | begin
586 | if bool_ then
587 | Result := True_
588 | else
589 | Result := False_;
590 | end;
591 |
592 | function ifv_(const bool_: Boolean; const True_, False_: Variant): Variant;
593 | begin
594 | if bool_ then
595 | Result := True_
596 | else
597 | Result := False_;
598 | end;
599 |
600 | function GetOffset(p_: Pointer; offset_: NativeInt): Pointer;
601 | begin
602 | Result := Pointer(NativeUInt(p_) + offset_);
603 | end;
604 |
605 | function GetPtr(p_: Pointer; offset_: NativeInt): Pointer;
606 | begin
607 | Result := Pointer(NativeUInt(p_) + offset_);
608 | end;
609 |
--------------------------------------------------------------------------------
/Source/CoreThreadPost.inc:
--------------------------------------------------------------------------------
1 | procedure TThreadPostData.Init;
2 | begin
3 | OnCall1 := nil;
4 | OnCall2 := nil;
5 | OnCall3 := nil;
6 | OnCall4 := nil;
7 | OnMethod1 := nil;
8 | OnMethod2 := nil;
9 | OnMethod3 := nil;
10 | OnMethod4 := nil;
11 | OnProc1 := nil;
12 | OnProc2 := nil;
13 | OnProc3 := nil;
14 | OnProc4 := nil;
15 | Data1 := nil;
16 | Data2 := nil;
17 | Data3 := NULL;
18 | end;
19 |
20 | procedure TThreadPost.FreeThreadProgressPostData(p: TThreadPostDataOrder.PT_);
21 | begin
22 | Dispose(p);
23 | end;
24 |
25 | constructor TThreadPost.Create(ThreadID_: TThreadID);
26 | begin
27 | inherited Create;
28 | FCritical := TCritical.Create;
29 | FThreadID := ThreadID_;
30 | FSyncPool := TThreadPostDataOrder.Create;
31 | FSyncPool.OnFreeOrderStruct := {$IFDEF FPC}@{$ENDIF FPC}FreeThreadProgressPostData;
32 | FProgressing := TAtomBool.Create(False);
33 | FOneStep := True;
34 | FResetRandomSeed := False;
35 | end;
36 |
37 | destructor TThreadPost.Destroy;
38 | begin
39 | FCritical.Acquire;
40 | FSyncPool.Clear;
41 | FSyncPool.Clear;
42 | FCritical.Release;
43 | DisposeObject(FSyncPool);
44 | FCritical.Free;
45 | FProgressing.Free;
46 | inherited Destroy;
47 | end;
48 |
49 | function TThreadPost.Count: Integer;
50 | begin
51 | FCritical.Acquire;
52 | Result := FSyncPool.Num;
53 | FCritical.Release;
54 | end;
55 |
56 | function TThreadPost.Busy: Boolean;
57 | begin
58 | Result := (Count > 0) or (FProgressing.V);
59 | end;
60 |
61 | function TThreadPost.Progress(ThreadID_: TThreadID): Integer;
62 | var
63 | i: Integer;
64 | temp: TThreadPostDataOrder;
65 | t_: TThreadPostData;
66 | begin
67 | Result := 0;
68 | if ThreadID_ <> FThreadID then
69 | exit;
70 |
71 | if FOneStep then
72 | begin
73 | if FSyncPool.Current <> nil then
74 | begin
75 | FProgressing.V := True;
76 | FCritical.Acquire;
77 | t_ := FSyncPool.Current^.Data^;
78 | FSyncPool.Next;
79 | FCritical.Release;
80 |
81 | if FResetRandomSeed then
82 | SetMT19937Seed(0);
83 | try
84 | if Assigned(t_.OnCall1) then
85 | t_.OnCall1();
86 | if Assigned(t_.OnCall2) then
87 | t_.OnCall2(t_.Data1);
88 | if Assigned(t_.OnCall3) then
89 | t_.OnCall3(t_.Data1, t_.Data2, t_.Data3);
90 | if Assigned(t_.OnCall4) then
91 | t_.OnCall4(t_.Data1, t_.Data2);
92 |
93 | if Assigned(t_.OnMethod1) then
94 | t_.OnMethod1();
95 | if Assigned(t_.OnMethod2) then
96 | t_.OnMethod2(t_.Data1);
97 | if Assigned(t_.OnMethod3) then
98 | t_.OnMethod3(t_.Data1, t_.Data2, t_.Data3);
99 | if Assigned(t_.OnMethod4) then
100 | t_.OnMethod4(t_.Data1, t_.Data2);
101 |
102 | if Assigned(t_.OnProc1) then
103 | t_.OnProc1();
104 | if Assigned(t_.OnProc2) then
105 | t_.OnProc2(t_.Data1);
106 | if Assigned(t_.OnProc3) then
107 | t_.OnProc3(t_.Data1, t_.Data2, t_.Data3);
108 | if Assigned(t_.OnProc4) then
109 | t_.OnProc4(t_.Data1, t_.Data2);
110 | except
111 | end;
112 |
113 | FProgressing.V := False;
114 | Result := 1;
115 | end;
116 | end
117 | else
118 | while (not FProgressing.V) and (Count > 0) do
119 | begin
120 | FProgressing.V := True;
121 | FCritical.Acquire;
122 | temp := FSyncPool;
123 | FSyncPool := TThreadPostDataOrder.Create;
124 | FCritical.Release;
125 | Result := temp.Num;
126 | while temp.Current <> nil do
127 | begin
128 | if FResetRandomSeed then
129 | SetMT19937Seed(0);
130 | try
131 | if Assigned(temp.Current^.Data^.OnCall1) then
132 | temp.Current^.Data^.OnCall1();
133 | if Assigned(temp.Current^.Data^.OnCall2) then
134 | temp.Current^.Data^.OnCall2(temp.Current^.Data^.Data1);
135 | if Assigned(temp.Current^.Data^.OnCall3) then
136 | temp.Current^.Data^.OnCall3(temp.Current^.Data^.Data1, temp.Current^.Data^.Data2, temp.Current^.Data^.Data3);
137 | if Assigned(temp.Current^.Data^.OnCall4) then
138 | temp.Current^.Data^.OnCall4(temp.Current^.Data^.Data1, temp.Current^.Data^.Data2);
139 |
140 | if Assigned(temp.Current^.Data^.OnMethod1) then
141 | temp.Current^.Data^.OnMethod1();
142 | if Assigned(temp.Current^.Data^.OnMethod2) then
143 | temp.Current^.Data^.OnMethod2(temp.Current^.Data^.Data1);
144 | if Assigned(temp.Current^.Data^.OnMethod3) then
145 | temp.Current^.Data^.OnMethod3(temp.Current^.Data^.Data1, temp.Current^.Data^.Data2, temp.Current^.Data^.Data3);
146 | if Assigned(temp.Current^.Data^.OnMethod4) then
147 | temp.Current^.Data^.OnMethod4(temp.Current^.Data^.Data1, temp.Current^.Data^.Data2);
148 |
149 | if Assigned(temp.Current^.Data^.OnProc1) then
150 | temp.Current^.Data^.OnProc1();
151 | if Assigned(temp.Current^.Data^.OnProc2) then
152 | temp.Current^.Data^.OnProc2(temp.Current^.Data^.Data1);
153 | if Assigned(temp.Current^.Data^.OnProc3) then
154 | temp.Current^.Data^.OnProc3(temp.Current^.Data^.Data1, temp.Current^.Data^.Data2, temp.Current^.Data^.Data3);
155 | if Assigned(temp.Current^.Data^.OnProc4) then
156 | temp.Current^.Data^.OnProc4(temp.Current^.Data^.Data1, temp.Current^.Data^.Data2);
157 | except
158 | end;
159 | temp.Next;
160 | end;
161 | DisposeObject(temp);
162 | FProgressing.V := False;
163 | end;
164 | end;
165 |
166 | function TThreadPost.Progress(Thread_: TThread): Integer;
167 | begin
168 | Result := Progress(Thread_.ThreadID);
169 | end;
170 |
171 | function TThreadPost.Progress(): Integer;
172 | begin
173 | Result := Progress(TThread.CurrentThread);
174 | end;
175 |
176 | procedure TThreadPost.PostC1(OnSync: TThreadPostCall1);
177 | var
178 | t_: TThreadPostData;
179 | begin
180 | t_.Init();
181 | t_.OnCall1 := OnSync;
182 | FCritical.Acquire;
183 | FSyncPool.Push(t_);
184 | FCritical.Release;
185 | end;
186 |
187 | procedure TThreadPost.PostC2(Data1: Pointer; OnSync: TThreadPostCall2);
188 | var
189 | t_: TThreadPostData;
190 | begin
191 | t_.Init();
192 | t_.Data1 := Data1;
193 | t_.OnCall2 := OnSync;
194 | FCritical.Acquire;
195 | FSyncPool.Push(t_);
196 | FCritical.Release;
197 | end;
198 |
199 | procedure TThreadPost.PostC3(Data1: Pointer; Data2: TCoreClassObject; Data3: Variant; OnSync: TThreadPostCall3);
200 | var
201 | t_: TThreadPostData;
202 | begin
203 | t_.Init();
204 | t_.Data1 := Data1;
205 | t_.Data2 := Data2;
206 | t_.Data3 := Data3;
207 | t_.OnCall3 := OnSync;
208 | FCritical.Acquire;
209 | FSyncPool.Push(t_);
210 | FCritical.Release;
211 | end;
212 |
213 | procedure TThreadPost.PostC4(Data1: Pointer; Data2: TCoreClassObject; OnSync: TThreadPostCall4);
214 | var
215 | t_: TThreadPostData;
216 | begin
217 | t_.Init();
218 | t_.Data1 := Data1;
219 | t_.Data2 := Data2;
220 | t_.OnCall4 := OnSync;
221 | FCritical.Acquire;
222 | FSyncPool.Push(t_);
223 | FCritical.Release;
224 | end;
225 |
226 | procedure TThreadPost.PostM1(OnSync: TThreadPostMethod1);
227 | var
228 | t_: TThreadPostData;
229 | begin
230 | t_.Init();
231 | t_.OnMethod1 := OnSync;
232 | FCritical.Acquire;
233 | FSyncPool.Push(t_);
234 | FCritical.Release;
235 | end;
236 |
237 | procedure TThreadPost.PostM2(Data1: Pointer; OnSync: TThreadPostMethod2);
238 | var
239 | t_: TThreadPostData;
240 | begin
241 | t_.Init();
242 | t_.Data1 := Data1;
243 | t_.OnMethod2 := OnSync;
244 | FCritical.Acquire;
245 | FSyncPool.Push(t_);
246 | FCritical.Release;
247 | end;
248 |
249 | procedure TThreadPost.PostM3(Data1: Pointer; Data2: TCoreClassObject; Data3: Variant; OnSync: TThreadPostMethod3);
250 | var
251 | t_: TThreadPostData;
252 | begin
253 | t_.Init();
254 | t_.Data1 := Data1;
255 | t_.Data2 := Data2;
256 | t_.Data3 := Data3;
257 | t_.OnMethod3 := OnSync;
258 | FCritical.Acquire;
259 | FSyncPool.Push(t_);
260 | FCritical.Release;
261 | end;
262 |
263 | procedure TThreadPost.PostM4(Data1: Pointer; Data2: TCoreClassObject; OnSync: TThreadPostMethod4);
264 | var
265 | t_: TThreadPostData;
266 | begin
267 | t_.Init();
268 | t_.Data1 := Data1;
269 | t_.Data2 := Data2;
270 | t_.OnMethod4 := OnSync;
271 | FCritical.Acquire;
272 | FSyncPool.Push(t_);
273 | FCritical.Release;
274 | end;
275 |
276 | procedure TThreadPost.PostP1(OnSync: TThreadPostProc1);
277 | var
278 | t_: TThreadPostData;
279 | begin
280 | t_.Init();
281 | t_.OnProc1 := OnSync;
282 | FCritical.Acquire;
283 | FSyncPool.Push(t_);
284 | FCritical.Release;
285 | end;
286 |
287 | procedure TThreadPost.PostP2(Data1: Pointer; OnSync: TThreadPostProc2);
288 | var
289 | t_: TThreadPostData;
290 | begin
291 | t_.Init();
292 | t_.Data1 := Data1;
293 | t_.OnProc2 := OnSync;
294 | FCritical.Acquire;
295 | FSyncPool.Push(t_);
296 | FCritical.Release;
297 | end;
298 |
299 | procedure TThreadPost.PostP3(Data1: Pointer; Data2: TCoreClassObject; Data3: Variant; OnSync: TThreadPostProc3);
300 | var
301 | t_: TThreadPostData;
302 | begin
303 | t_.Init();
304 | t_.Data1 := Data1;
305 | t_.Data2 := Data2;
306 | t_.Data3 := Data3;
307 | t_.OnProc3 := OnSync;
308 | FCritical.Acquire;
309 | FSyncPool.Push(t_);
310 | FCritical.Release;
311 | end;
312 |
313 | procedure TThreadPost.PostP4(Data1: Pointer; Data2: TCoreClassObject; OnSync: TThreadPostProc4);
314 | var
315 | t_: TThreadPostData;
316 | begin
317 | t_.Init();
318 | t_.Data1 := Data1;
319 | t_.Data2 := Data2;
320 | t_.OnProc4 := OnSync;
321 | FCritical.Acquire;
322 | FSyncPool.Push(t_);
323 | FCritical.Release;
324 | end;
325 |
--------------------------------------------------------------------------------
/Source/Core_AtomVar.inc:
--------------------------------------------------------------------------------
1 | function TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.GetValue: T_;
2 | begin
3 | Critical.Acquire;
4 | Result := FValue__;
5 | Critical.Release;
6 | end;
7 |
8 | procedure TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.SetValue(const Value_: T_);
9 | begin
10 | Critical.Acquire;
11 | FValue__ := Value_;
12 | Critical.Release;
13 | end;
14 |
15 | function TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.GetValueP: PT_;
16 | begin
17 | Result := @FValue__;
18 | end;
19 |
20 | constructor TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.Create(Value_: T_);
21 | begin
22 | inherited Create;
23 | FValue__ := Value_;
24 | Critical := TCritical_.Create;
25 | end;
26 |
27 | destructor TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.Destroy;
28 | begin
29 | Critical.Free;
30 | inherited Destroy;
31 | end;
32 |
33 | function TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.Lock: T_;
34 | begin
35 | Critical.Acquire;
36 | Result := FValue__;
37 | end;
38 |
39 | function TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.LockP: PT_;
40 | begin
41 | Critical.Acquire;
42 | Result := @FValue__;
43 | end;
44 |
45 | procedure TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.UnLock(const Value_: T_);
46 | begin
47 | FValue__ := Value_;
48 | Critical.Release;
49 | end;
50 |
51 | procedure TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.UnLock(const Value_: PT_);
52 | begin
53 | FValue__ := Value_^;
54 | Critical.Release;
55 | end;
56 |
57 | procedure TAtomVar{$IFNDEF FPC}{$ENDIF FPC}.UnLock();
58 | begin
59 | Critical.Release;
60 | end;
61 |
--------------------------------------------------------------------------------
/Source/Core_DelphiParallelFor.inc:
--------------------------------------------------------------------------------
1 | {$IFDEF SystemParallel}
2 |
3 |
4 | procedure DelphiParallelFor(parallel: Boolean; b, e: Integer; OnFor: TDelphiParallelForProcedure32);
5 | var
6 | i: Integer;
7 | begin
8 | if b > e then
9 | exit;
10 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
11 | begin
12 | i := b;
13 | while i <= e do
14 | begin
15 | try
16 | OnFor(i);
17 | except
18 | end;
19 | inc(i);
20 | end;
21 | exit;
22 | end;
23 | ParallelOverflow.Acquire;
24 | try
25 | TParallel.&For(b, e, OnFor);
26 | finally
27 | ParallelOverflow.Release;
28 | end;
29 | end;
30 |
31 | procedure DelphiParallelFor(parallel: Boolean; b, e: Int64; OnFor: TDelphiParallelForProcedure64);
32 | var
33 | i: Int64;
34 | begin
35 | if b > e then
36 | exit;
37 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
38 | begin
39 | i := b;
40 | while i <= e do
41 | begin
42 | try
43 | OnFor(i);
44 | except
45 | end;
46 | inc(i);
47 | end;
48 | exit;
49 | end;
50 | ParallelOverflow.Acquire;
51 | try
52 | TParallel.&For(b, e, OnFor);
53 | finally
54 | ParallelOverflow.Release;
55 | end;
56 | end;
57 | {$ELSE SystemParallel}
58 |
59 |
60 | type
61 | TDelphiParallelThData32_Block = record
62 | b, e: Integer;
63 | Completed: ^Integer;
64 | OnFor: TDelphiParallelForProcedure32;
65 | Critical: TCritical;
66 | end;
67 |
68 | PDelphiParallelThData32_Block = ^TDelphiParallelThData32_Block;
69 |
70 | procedure DelphiParallelTh32_Block(ThSender: TCompute);
71 | var
72 | p: PDelphiParallelThData32_Block;
73 | Pass: Integer;
74 | begin
75 | p := ThSender.UserData;
76 | Pass := p^.b;
77 | while Pass <= p^.e do
78 | begin
79 | try
80 | p^.OnFor(Pass);
81 | except
82 | end;
83 | inc(Pass);
84 | end;
85 |
86 | p^.Critical.Acquire;
87 | AtomInc(p^.Completed^, p^.e - p^.b + 1);
88 | p^.Critical.Release;
89 | dispose(p);
90 | end;
91 |
92 | procedure DelphiParallelFor_Block(parallel: Boolean; b, e: Integer; OnFor: TDelphiParallelForProcedure32);
93 | var
94 | Total, Depth, Completed, StepTotal, stepW, Pass, w: Integer;
95 | p: PDelphiParallelThData32_Block;
96 | i: Integer;
97 | Critical: TCritical;
98 | begin
99 | if b > e then
100 | exit;
101 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
102 | begin
103 | i := b;
104 | while i <= e do
105 | begin
106 | try
107 | OnFor(i);
108 | except
109 | end;
110 | inc(i);
111 | end;
112 | exit;
113 | end;
114 | ParallelOverflow.Acquire;
115 | try
116 | Depth := ParallelGranularity;
117 | Total := e - b + 1;
118 | Critical := TCritical.Create;
119 |
120 | Completed := 0;
121 |
122 | if (Total < Depth) then
123 | begin
124 | Pass := b;
125 | while Pass <= e do
126 | begin
127 | new(p);
128 | p^.b := Pass;
129 | p^.e := Pass;
130 | p^.Completed := @Completed;
131 | p^.OnFor := OnFor;
132 | p^.Critical := Critical;
133 | TCompute.RunC(p, nil, DelphiParallelTh32_Block);
134 | inc(Pass);
135 | end;
136 | end
137 | else
138 | begin
139 | stepW := Total div Depth;
140 | StepTotal := Total div stepW;
141 | if Total mod stepW > 0 then
142 | inc(StepTotal);
143 |
144 | Pass := 0;
145 | while Pass < StepTotal do
146 | begin
147 | w := stepW * Pass;
148 | new(p);
149 | if w + stepW <= Total then
150 | begin
151 | p^.b := w + b;
152 | p^.e := w + stepW + b - 1;
153 | end
154 | else
155 | begin
156 | p^.b := w + b;
157 | p^.e := Total + b - 1;
158 | end;
159 | p^.Completed := @Completed;
160 | p^.OnFor := OnFor;
161 | p^.Critical := Critical;
162 | TCompute.RunC(p, nil, DelphiParallelTh32_Block);
163 | inc(Pass);
164 | end;
165 | end;
166 |
167 | repeat
168 | TThread.Sleep(1);
169 | Critical.Acquire;
170 | w := Completed;
171 | Critical.Release;
172 | until w >= Total;
173 |
174 | Critical.Free;
175 | finally
176 | ParallelOverflow.Release;
177 | end;
178 | end;
179 |
180 | type
181 | TDelphiParallelThData64_Block = record
182 | b, e: Int64;
183 | Completed: ^Int64;
184 | OnFor: TDelphiParallelForProcedure64;
185 | Critical: TCritical;
186 | end;
187 |
188 | PDelphiParallelThData64_Block = ^TDelphiParallelThData64_Block;
189 |
190 | procedure DelphiParallelTh64_Block(ThSender: TCompute);
191 | var
192 | p: PDelphiParallelThData64_Block;
193 | Pass: Int64;
194 | begin
195 | p := ThSender.UserData;
196 | Pass := p^.b;
197 | while Pass <= p^.e do
198 | begin
199 | try
200 | p^.OnFor(Pass);
201 | except
202 | end;
203 | inc(Pass);
204 | end;
205 |
206 | p^.Critical.Acquire;
207 | AtomInc(p^.Completed^, p^.e - p^.b + 1);
208 | p^.Critical.Release;
209 | dispose(p);
210 | end;
211 |
212 | procedure DelphiParallelFor_Block(parallel: Boolean; b, e: Int64; OnFor: TDelphiParallelForProcedure64);
213 | var
214 | Total, Depth, Completed, StepTotal, stepW, Pass, w: Int64;
215 | p: PDelphiParallelThData64_Block;
216 | i: Int64;
217 | Critical: TCritical;
218 | begin
219 | if b > e then
220 | exit;
221 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
222 | begin
223 | i := b;
224 | while i <= e do
225 | begin
226 | try
227 | OnFor(i);
228 | except
229 | end;
230 | inc(i);
231 | end;
232 | exit;
233 | end;
234 | ParallelOverflow.Acquire;
235 | try
236 | Depth := ParallelGranularity;
237 | Total := e - b + 1;
238 | Critical := TCritical.Create;
239 |
240 | Completed := 0;
241 |
242 | if (Total < Depth) then
243 | begin
244 | Pass := b;
245 | while Pass <= e do
246 | begin
247 | new(p);
248 | p^.b := Pass;
249 | p^.e := Pass;
250 | p^.Completed := @Completed;
251 | p^.OnFor := OnFor;
252 | p^.Critical := Critical;
253 | TCompute.RunC(p, nil, DelphiParallelTh64_Block);
254 | inc(Pass);
255 | end;
256 | end
257 | else
258 | begin
259 | stepW := Total div Depth;
260 | StepTotal := Total div stepW;
261 | if Total mod stepW > 0 then
262 | inc(StepTotal);
263 |
264 | Pass := 0;
265 | while Pass < StepTotal do
266 | begin
267 | w := stepW * Pass;
268 | new(p);
269 | if w + stepW <= Total then
270 | begin
271 | p^.b := w + b;
272 | p^.e := w + stepW + b - 1;
273 | end
274 | else
275 | begin
276 | p^.b := w + b;
277 | p^.e := Total + b - 1;
278 | end;
279 | p^.Completed := @Completed;
280 | p^.OnFor := OnFor;
281 | p^.Critical := Critical;
282 | TCompute.RunC(p, nil, DelphiParallelTh64_Block);
283 | inc(Pass);
284 | end;
285 | end;
286 |
287 | repeat
288 | TThread.Sleep(1);
289 | Critical.Acquire;
290 | w := Completed;
291 | Critical.Release;
292 | until w >= Total;
293 |
294 | Critical.Free;
295 | finally
296 | ParallelOverflow.Release;
297 | end;
298 | end;
299 |
300 | type
301 | TDelphiParallelThData32_Fold = record
302 | Pass: Int64;
303 | Total, Granularity: Integer;
304 | Completed: Boolean;
305 | OnFor: TDelphiParallelForProcedure32;
306 | Critical: TCritical;
307 | end;
308 |
309 | PDelphiParallelThData32_Fold = ^TDelphiParallelThData32_Fold;
310 |
311 | procedure DelphiParallelTh32_Fold(ThSender: TCompute);
312 | var
313 | p: PDelphiParallelThData32_Fold;
314 | begin
315 | p := ThSender.UserData;
316 | with p^ do
317 | while Pass <= Total do
318 | begin
319 | try
320 | OnFor(Pass);
321 | except
322 | end;
323 | inc(Pass, Granularity);
324 | end;
325 |
326 | p^.Critical.Acquire;
327 | p^.Completed := True;
328 | p^.Critical.Release;
329 | end;
330 |
331 | procedure DelphiParallelFor_Fold(parallel: Boolean; b, e: Integer; OnFor: TDelphiParallelForProcedure32);
332 | var
333 | p: PDelphiParallelThData32_Fold;
334 | i, Depth: Integer;
335 | Critical: TCritical;
336 | states: array of TDelphiParallelThData32_Fold;
337 | Completed: Boolean;
338 | begin
339 | if b > e then
340 | exit;
341 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
342 | begin
343 | i := b;
344 | while i <= e do
345 | begin
346 | try
347 | OnFor(i);
348 | except
349 | end;
350 | inc(i);
351 | end;
352 | exit;
353 | end;
354 | ParallelOverflow.Acquire;
355 | try
356 | Critical := TCritical.Create;
357 | Depth := Min(ParallelGranularity, e - b + 1);
358 | SetLength(states, Depth);
359 |
360 | i := 0;
361 | while i < Depth do
362 | begin
363 | p := @states[i];
364 | p^.Pass := b + i;
365 | p^.Total := e;
366 | p^.Granularity := ParallelGranularity;
367 | p^.Completed := False;
368 | p^.OnFor := OnFor;
369 | p^.Critical := Critical;
370 | TCompute.RunC(p, nil, DelphiParallelTh32_Fold);
371 | inc(i);
372 | end;
373 |
374 | repeat
375 | TThread.Sleep(1);
376 | Critical.Acquire;
377 | Completed := True;
378 | i := 0;
379 | while i < Length(states) do
380 | begin
381 | Completed := Completed and states[i].Completed;
382 | inc(i);
383 | end;
384 | Critical.Release;
385 | until Completed;
386 |
387 | Critical.Free;
388 | finally
389 | ParallelOverflow.Release;
390 | end;
391 | end;
392 |
393 | type
394 | TDelphiParallelThData64_Fold = record
395 | Pass: Int64;
396 | Total, Granularity: Int64;
397 | Completed: Boolean;
398 | OnFor: TDelphiParallelForProcedure64;
399 | Critical: TCritical;
400 | end;
401 |
402 | PDelphiParallelThData64_Fold = ^TDelphiParallelThData64_Fold;
403 |
404 | procedure DelphiParallelTh64_Fold(ThSender: TCompute);
405 | var
406 | p: PDelphiParallelThData64_Fold;
407 | begin
408 | p := ThSender.UserData;
409 | with p^ do
410 | while Pass <= Total do
411 | begin
412 | try
413 | OnFor(Pass);
414 | except
415 | end;
416 | inc(Pass, Granularity);
417 | end;
418 |
419 | p^.Critical.Acquire;
420 | p^.Completed := True;
421 | p^.Critical.Release;
422 | end;
423 |
424 | procedure DelphiParallelFor_Fold(parallel: Boolean; b, e: Int64; OnFor: TDelphiParallelForProcedure64);
425 | var
426 | p: PDelphiParallelThData64_Fold;
427 | i, Depth: Int64;
428 | Critical: TCritical;
429 | states: array of TDelphiParallelThData64_Fold;
430 | Completed: Boolean;
431 | begin
432 | if b > e then
433 | exit;
434 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
435 | begin
436 | i := b;
437 | while i <= e do
438 | begin
439 | try
440 | OnFor(i);
441 | except
442 | end;
443 | inc(i);
444 | end;
445 | exit;
446 | end;
447 | ParallelOverflow.Acquire;
448 | try
449 | Critical := TCritical.Create;
450 | Depth := Min(ParallelGranularity, e - b + 1);
451 | SetLength(states, Depth);
452 |
453 | i := 0;
454 | while i < Depth do
455 | begin
456 | p := @states[i];
457 | p^.Pass := b + i;
458 | p^.Total := e;
459 | p^.Granularity := ParallelGranularity;
460 | p^.Completed := False;
461 | p^.OnFor := OnFor;
462 | p^.Critical := Critical;
463 | TCompute.RunC(p, nil, DelphiParallelTh64_Fold);
464 | inc(i);
465 | end;
466 |
467 | repeat
468 | TThread.Sleep(1);
469 | Critical.Acquire;
470 | Completed := True;
471 | i := 0;
472 | while i < Length(states) do
473 | begin
474 | Completed := Completed and states[i].Completed;
475 | inc(i);
476 | end;
477 | Critical.Release;
478 | until Completed;
479 |
480 | Critical.Free;
481 | finally
482 | ParallelOverflow.Release;
483 | end;
484 | end;
485 |
486 | procedure DelphiParallelFor(parallel: Boolean; b, e: Integer; OnFor: TDelphiParallelForProcedure32);
487 | begin
488 | {$IFDEF FoldParallel}
489 | DelphiParallelFor_Fold(parallel, b, e, OnFor);
490 | {$ELSE FoldParallel}
491 | DelphiParallelFor_Block(parallel, b, e, OnFor);
492 | {$ENDIF FoldParallel}
493 | end;
494 |
495 | procedure DelphiParallelFor(parallel: Boolean; b, e: Int64; OnFor: TDelphiParallelForProcedure64);
496 | begin
497 | {$IFDEF FoldParallel}
498 | DelphiParallelFor_Fold(parallel, b, e, OnFor);
499 | {$ELSE FoldParallel}
500 | DelphiParallelFor_Block(parallel, b, e, OnFor);
501 | {$ENDIF FoldParallel}
502 | end;
503 |
504 | {$ENDIF SystemParallel}
505 |
506 |
507 | procedure DelphiParallelFor(b, e: Integer; OnFor: TDelphiParallelForProcedure32);
508 | begin
509 | DelphiParallelFor(True, b, e, OnFor);
510 | end;
511 |
512 | procedure DelphiParallelFor(b, e: Int64; OnFor: TDelphiParallelForProcedure64);
513 | begin
514 | DelphiParallelFor(True, b, e, OnFor);
515 | end;
516 |
517 | procedure DelphiParallelFor(OnFor: TDelphiParallelForProcedure32; b, e: Integer);
518 | begin
519 | DelphiParallelFor(b, e, OnFor);
520 | end;
521 |
522 | procedure DelphiParallelFor(OnFor: TDelphiParallelForProcedure64; b, e: Int64);
523 | begin
524 | DelphiParallelFor(b, e, OnFor);
525 | end;
526 |
527 | procedure DelphiParallelFor(parallel: Boolean; OnFor: TDelphiParallelForProcedure32; b, e: Integer);
528 | begin
529 | DelphiParallelFor(parallel, b, e, OnFor);
530 | end;
531 |
532 | procedure DelphiParallelFor(parallel: Boolean; OnFor: TDelphiParallelForProcedure64; b, e: Int64);
533 | begin
534 | DelphiParallelFor(parallel, b, e, OnFor);
535 | end;
536 |
537 | procedure ParallelFor(parallel: Boolean; b, e: Integer; OnFor: TDelphiParallelForProcedure32);
538 | begin
539 | DelphiParallelFor(parallel, b, e, OnFor);
540 | end;
541 |
542 | procedure ParallelFor(parallel: Boolean; b, e: Int64; OnFor: TDelphiParallelForProcedure64);
543 | begin
544 | DelphiParallelFor(parallel, b, e, OnFor);
545 | end;
546 |
547 | procedure ParallelFor(b, e: Integer; OnFor: TDelphiParallelForProcedure32);
548 | begin
549 | DelphiParallelFor(True, b, e, OnFor);
550 | end;
551 |
552 | procedure ParallelFor(b, e: Int64; OnFor: TDelphiParallelForProcedure64);
553 | begin
554 | DelphiParallelFor(True, b, e, OnFor);
555 | end;
556 |
557 | procedure ParallelFor(OnFor: TDelphiParallelForProcedure32; b, e: Integer);
558 | begin
559 | DelphiParallelFor(b, e, OnFor);
560 | end;
561 |
562 | procedure ParallelFor(OnFor: TDelphiParallelForProcedure64; b, e: Int64);
563 | begin
564 | DelphiParallelFor(b, e, OnFor);
565 | end;
566 |
567 | procedure ParallelFor(parallel: Boolean; OnFor: TDelphiParallelForProcedure32; b, e: Integer);
568 | begin
569 | DelphiParallelFor(parallel, b, e, OnFor);
570 | end;
571 |
572 | procedure ParallelFor(parallel: Boolean; OnFor: TDelphiParallelForProcedure64; b, e: Int64);
573 | begin
574 | DelphiParallelFor(parallel, b, e, OnFor);
575 | end;
576 |
--------------------------------------------------------------------------------
/Source/Core_FPCParallelFor.inc:
--------------------------------------------------------------------------------
1 | type
2 | TFPCParallelThData32_Block = record
3 | b, e: Integer;
4 | Completed: ^Integer;
5 | OnFor: TFPCParallelForProcedure32;
6 | Critical: TCritical;
7 | end;
8 |
9 | PFPCParallelThData32_Block = ^TFPCParallelThData32_Block;
10 |
11 | procedure FPCParallelTh32_Block(ThSender: TCompute);
12 | var
13 | p: PFPCParallelThData32_Block;
14 | Pass: Integer;
15 | begin
16 | p := ThSender.UserData;
17 | Pass := p^.b;
18 | while Pass <= p^.e do
19 | begin
20 | try
21 | p^.OnFor(Pass);
22 | except
23 | end;
24 | inc(Pass);
25 | end;
26 |
27 | p^.Critical.Acquire;
28 | AtomInc(p^.Completed^, p^.e - p^.b + 1);
29 | p^.Critical.Release;
30 | dispose(p);
31 | end;
32 |
33 | procedure FPCParallelFor_Block(parallel: Boolean; b, e: Integer; OnFor: TFPCParallelForProcedure32);
34 | var
35 | Total, Depth, Completed, StepTotal, stepW, Pass, w: Integer;
36 | p: PFPCParallelThData32_Block;
37 | i: Integer;
38 | Critical: TCritical;
39 | begin
40 | if b > e then
41 | exit;
42 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
43 | begin
44 | i := b;
45 | while i <= e do
46 | begin
47 | try
48 | OnFor(i);
49 | except
50 | end;
51 | inc(i);
52 | end;
53 | exit;
54 | end;
55 | ParallelOverflow.Acquire;
56 | try
57 | Depth := ParallelGranularity;
58 | Total := e - b + 1;
59 | Critical := TCritical.Create;
60 |
61 | Completed := 0;
62 |
63 | if (Total < Depth) then
64 | begin
65 | Pass := b;
66 | while Pass <= e do
67 | begin
68 | new(p);
69 | p^.b := Pass;
70 | p^.e := Pass;
71 | p^.Completed := @Completed;
72 | p^.OnFor := OnFor;
73 | p^.Critical := Critical;
74 | TCompute.RunC(p, nil, @FPCParallelTh32_Block);
75 | inc(Pass);
76 | end;
77 | end
78 | else
79 | begin
80 | stepW := Total div Depth;
81 | StepTotal := Total div stepW;
82 | if Total mod stepW > 0 then
83 | inc(StepTotal);
84 |
85 | Pass := 0;
86 | while Pass < StepTotal do
87 | begin
88 | w := stepW * Pass;
89 | new(p);
90 | if w + stepW <= Total then
91 | begin
92 | p^.b := w + b;
93 | p^.e := w + stepW + b - 1;
94 | end
95 | else
96 | begin
97 | p^.b := w + b;
98 | p^.e := Total + b - 1;
99 | end;
100 | p^.Completed := @Completed;
101 | p^.OnFor := OnFor;
102 | p^.Critical := Critical;
103 | TCompute.RunC(p, nil, @FPCParallelTh32_Block);
104 | inc(Pass);
105 | end;
106 | end;
107 |
108 | repeat
109 | TThread.Sleep(1);
110 | Critical.Acquire;
111 | w := Completed;
112 | Critical.Release;
113 | until w >= Total;
114 |
115 | Critical.Free;
116 | finally
117 | ParallelOverflow.Release;
118 | end;
119 | end;
120 |
121 | type
122 | TFPCParallelThData64_Block = record
123 | b, e: Int64;
124 | Completed: ^Int64;
125 | OnFor: TFPCParallelForProcedure64;
126 | Critical: TCritical;
127 | end;
128 |
129 | PFPCParallelThData64_Block = ^TFPCParallelThData64_Block;
130 |
131 | procedure FPCParallelTh64_Block(ThSender: TCompute);
132 | var
133 | p: PFPCParallelThData64_Block;
134 | Pass: Int64;
135 | begin
136 | p := ThSender.UserData;
137 | Pass := p^.b;
138 | while Pass <= p^.e do
139 | begin
140 | try
141 | p^.OnFor(Pass);
142 | except
143 | end;
144 | inc(Pass);
145 | end;
146 |
147 | p^.Critical.Acquire;
148 | AtomInc(p^.Completed^, p^.e - p^.b + 1);
149 | p^.Critical.Release;
150 | dispose(p);
151 | end;
152 |
153 | procedure FPCParallelFor_Block(parallel: Boolean; b, e: Int64; OnFor: TFPCParallelForProcedure64);
154 | var
155 | Total, Depth, Completed, StepTotal, stepW, Pass, w: Int64;
156 | p: PFPCParallelThData64_Block;
157 | i: Int64;
158 | Critical: TCritical;
159 | begin
160 | if b > e then
161 | exit;
162 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
163 | begin
164 | i := b;
165 | while i <= e do
166 | begin
167 | try
168 | OnFor(i);
169 | except
170 | end;
171 | inc(i);
172 | end;
173 | exit;
174 | end;
175 | ParallelOverflow.Acquire;
176 | try
177 | Depth := ParallelGranularity;
178 | Total := e - b + 1;
179 | Critical := TCritical.Create;
180 |
181 | Completed := 0;
182 |
183 | if (Total < Depth) then
184 | begin
185 | Pass := b;
186 | while Pass <= e do
187 | begin
188 | new(p);
189 | p^.b := Pass;
190 | p^.e := Pass;
191 | p^.Completed := @Completed;
192 | p^.OnFor := OnFor;
193 | p^.Critical := Critical;
194 | TCompute.RunC(p, nil, @FPCParallelTh64_Block);
195 | inc(Pass);
196 | end;
197 | end
198 | else
199 | begin
200 | stepW := Total div Depth;
201 | StepTotal := Total div stepW;
202 | if Total mod stepW > 0 then
203 | inc(StepTotal);
204 |
205 | Pass := 0;
206 | while Pass < StepTotal do
207 | begin
208 | w := stepW * Pass;
209 | new(p);
210 | if w + stepW <= Total then
211 | begin
212 | p^.b := w + b;
213 | p^.e := w + stepW + b - 1;
214 | end
215 | else
216 | begin
217 | p^.b := w + b;
218 | p^.e := Total + b - 1;
219 | end;
220 | p^.Completed := @Completed;
221 | p^.OnFor := OnFor;
222 | p^.Critical := Critical;
223 | TCompute.RunC(p, nil, @FPCParallelTh64_Block);
224 | inc(Pass);
225 | end;
226 | end;
227 |
228 | repeat
229 | TThread.Sleep(1);
230 | Critical.Acquire;
231 | w := Completed;
232 | Critical.Release;
233 | until w >= Total;
234 |
235 | Critical.Free;
236 | finally
237 | ParallelOverflow.Release;
238 | end;
239 | end;
240 |
241 | type
242 | TFPCParallelThData32_Fold = record
243 | Pass: Int64;
244 | Total, Granularity: Integer;
245 | Completed: Boolean;
246 | OnFor: TFPCParallelForProcedure32;
247 | Critical: TCritical;
248 | end;
249 |
250 | PFPCParallelThData32_Fold = ^TFPCParallelThData32_Fold;
251 |
252 | procedure FPCParallelTh32_Fold(ThSender: TCompute);
253 | var
254 | p: PFPCParallelThData32_Fold;
255 | begin
256 | p := ThSender.UserData;
257 | with p^ do
258 | while Pass <= Total do
259 | begin
260 | try
261 | OnFor(Pass);
262 | except
263 | end;
264 | inc(Pass, Granularity);
265 | end;
266 |
267 | p^.Critical.Acquire;
268 | p^.Completed := True;
269 | p^.Critical.Release;
270 | end;
271 |
272 | procedure FPCParallelFor_Fold(parallel: Boolean; b, e: Integer; OnFor: TFPCParallelForProcedure32);
273 | var
274 | p: PFPCParallelThData32_Fold;
275 | i, Depth: Integer;
276 | Critical: TCritical;
277 | states: array of TFPCParallelThData32_Fold;
278 | Completed: Boolean;
279 | begin
280 | if b > e then
281 | exit;
282 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
283 | begin
284 | i := b;
285 | while i <= e do
286 | begin
287 | try
288 | OnFor(i);
289 | except
290 | end;
291 | inc(i);
292 | end;
293 | exit;
294 | end;
295 | ParallelOverflow.Acquire;
296 | try
297 | Critical := TCritical.Create;
298 | Depth := Min(ParallelGranularity, e - b + 1);
299 | SetLength(states, Depth);
300 |
301 | i := 0;
302 | while i < Depth do
303 | begin
304 | p := @states[i];
305 | p^.Pass := b + i;
306 | p^.Total := e;
307 | p^.Granularity := ParallelGranularity;
308 | p^.Completed := False;
309 | p^.OnFor := OnFor;
310 | p^.Critical := Critical;
311 | TCompute.RunC(p, nil, @FPCParallelTh32_Fold);
312 | inc(i);
313 | end;
314 |
315 | repeat
316 | TThread.Sleep(1);
317 | Critical.Acquire;
318 | Completed := True;
319 | i := 0;
320 | while i < Length(states) do
321 | begin
322 | Completed := Completed and states[i].Completed;
323 | inc(i);
324 | end;
325 | Critical.Release;
326 | until Completed;
327 |
328 | Critical.Free;
329 | finally
330 | ParallelOverflow.Release;
331 | end;
332 | end;
333 |
334 | type
335 | TFPCParallelThData64_Fold = record
336 | Pass: Int64;
337 | Total, Granularity: Int64;
338 | Completed: Boolean;
339 | OnFor: TFPCParallelForProcedure64;
340 | Critical: TCritical;
341 | end;
342 |
343 | PFPCParallelThData64_Fold = ^TFPCParallelThData64_Fold;
344 |
345 | procedure FPCParallelTh64_Fold(ThSender: TCompute);
346 | var
347 | p: PFPCParallelThData64_Fold;
348 | begin
349 | p := ThSender.UserData;
350 | with p^ do
351 | while Pass <= Total do
352 | begin
353 | try
354 | OnFor(Pass);
355 | except
356 | end;
357 | inc(Pass, Granularity);
358 | end;
359 |
360 | p^.Critical.Acquire;
361 | p^.Completed := True;
362 | p^.Critical.Release;
363 | end;
364 |
365 | procedure FPCParallelFor_Fold(parallel: Boolean; b, e: Int64; OnFor: TFPCParallelForProcedure64);
366 | var
367 | p: PFPCParallelThData64_Fold;
368 | i, Depth: Int64;
369 | Critical: TCritical;
370 | states: array of TFPCParallelThData64_Fold;
371 | Completed: Boolean;
372 | begin
373 | if b > e then
374 | exit;
375 | if (not parallel) or (not WorkInParallelCore.V) or ParallelOverflow.Busy() then
376 | begin
377 | i := b;
378 | while i <= e do
379 | begin
380 | try
381 | OnFor(i);
382 | except
383 | end;
384 | inc(i);
385 | end;
386 | exit;
387 | end;
388 | ParallelOverflow.Acquire;
389 | try
390 | Critical := TCritical.Create;
391 | Depth := Min(ParallelGranularity, e - b + 1);
392 | SetLength(states, Depth);
393 | i := 0;
394 | while i < Depth do
395 | begin
396 | p := @states[i];
397 | p^.Pass := b + i;
398 | p^.Total := e;
399 | p^.Granularity := ParallelGranularity;
400 | p^.Completed := False;
401 | p^.OnFor := OnFor;
402 | p^.Critical := Critical;
403 | TCompute.RunC(p, nil, @FPCParallelTh64_Fold);
404 | inc(i);
405 | end;
406 |
407 | repeat
408 | TThread.Sleep(1);
409 | Critical.Acquire;
410 | Completed := True;
411 | i := 0;
412 | while i < Length(states) do
413 | begin
414 | Completed := Completed and states[i].Completed;
415 | inc(i);
416 | end;
417 | Critical.Release;
418 | until Completed;
419 |
420 | Critical.Free;
421 | finally
422 | ParallelOverflow.Release;
423 | end;
424 | end;
425 |
426 | procedure FPCParallelFor(parallel: Boolean; b, e: Integer; OnFor: TFPCParallelForProcedure32);
427 | begin
428 | {$IFDEF FoldParallel}
429 | FPCParallelFor_Fold(parallel, b, e, OnFor);
430 | {$ELSE FoldParallel}
431 | FPCParallelFor_Block(parallel, b, e, OnFor);
432 | {$ENDIF FoldParallel}
433 | end;
434 |
435 | procedure FPCParallelFor(parallel: Boolean; b, e: Int64; OnFor: TFPCParallelForProcedure64);
436 | begin
437 | {$IFDEF FoldParallel}
438 | FPCParallelFor_Fold(parallel, b, e, OnFor);
439 | {$ELSE FoldParallel}
440 | FPCParallelFor_Block(parallel, b, e, OnFor);
441 | {$ENDIF FoldParallel}
442 | end;
443 |
444 | procedure FPCParallelFor(b, e: Integer; OnFor: TFPCParallelForProcedure32);
445 | begin
446 | FPCParallelFor(True, b, e, OnFor);
447 | end;
448 |
449 | procedure FPCParallelFor(b, e: Int64; OnFor: TFPCParallelForProcedure64);
450 | begin
451 | FPCParallelFor(True, b, e, OnFor);
452 | end;
453 |
454 | procedure FPCParallelFor(OnFor: TFPCParallelForProcedure32; b, e: Integer);
455 | begin
456 | FPCParallelFor(b, e, OnFor);
457 | end;
458 |
459 | procedure FPCParallelFor(OnFor: TFPCParallelForProcedure64; b, e: Int64);
460 | begin
461 | FPCParallelFor(b, e, OnFor);
462 | end;
463 |
464 | procedure FPCParallelFor(parallel: Boolean; OnFor: TFPCParallelForProcedure32; b, e: Integer);
465 | begin
466 | FPCParallelFor(parallel, b, e, OnFor);
467 | end;
468 |
469 | procedure FPCParallelFor(parallel: Boolean; OnFor: TFPCParallelForProcedure64; b, e: Int64);
470 | begin
471 | FPCParallelFor(parallel, b, e, OnFor);
472 | end;
473 |
474 | procedure ParallelFor(parallel: Boolean; b, e: Integer; OnFor: TFPCParallelForProcedure32);
475 | begin
476 | FPCParallelFor(parallel, b, e, OnFor);
477 | end;
478 |
479 | procedure ParallelFor(parallel: Boolean; b, e: Int64; OnFor: TFPCParallelForProcedure64);
480 | begin
481 | FPCParallelFor(parallel, b, e, OnFor);
482 | end;
483 |
484 | procedure ParallelFor(b, e: Integer; OnFor: TFPCParallelForProcedure32);
485 | begin
486 | FPCParallelFor(True, b, e, OnFor);
487 | end;
488 |
489 | procedure ParallelFor(b, e: Int64; OnFor: TFPCParallelForProcedure64);
490 | begin
491 | FPCParallelFor(True, b, e, OnFor);
492 | end;
493 |
494 | procedure ParallelFor(OnFor: TFPCParallelForProcedure32; b, e: Integer);
495 | begin
496 | FPCParallelFor(b, e, OnFor);
497 | end;
498 |
499 | procedure ParallelFor(OnFor: TFPCParallelForProcedure64; b, e: Int64);
500 | begin
501 | FPCParallelFor(b, e, OnFor);
502 | end;
503 |
504 | procedure ParallelFor(parallel: Boolean; OnFor: TFPCParallelForProcedure32; b, e: Integer);
505 | begin
506 | FPCParallelFor(parallel, b, e, OnFor);
507 | end;
508 |
509 | procedure ParallelFor(parallel: Boolean; OnFor: TFPCParallelForProcedure64; b, e: Int64);
510 | begin
511 | FPCParallelFor(parallel, b, e, OnFor);
512 | end;
513 |
--------------------------------------------------------------------------------
/Source/Core_LineProcessor.inc:
--------------------------------------------------------------------------------
1 | {$IFDEF RangeCheck}{$R-}{$ENDIF}
2 | {$IFDEF OverflowCheck}{$Q-}{$ENDIF}
3 |
4 |
5 | procedure TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.CreateDone;
6 | begin
7 | end;
8 |
9 | constructor TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.Create(const data_: Pointer; const width_, height_: NativeInt; const Value_: T_; const LineTail_: Boolean);
10 | begin
11 | inherited Create;
12 | FData := PTArry_(data_);
13 | FWidth := width_;
14 | FHeight := height_;
15 | FValue := Value_;
16 | FLineTail := LineTail_;
17 | CreateDone();
18 | end;
19 |
20 | destructor TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.Destroy;
21 | begin
22 | inherited Destroy;
23 | end;
24 |
25 | procedure TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.VertLine(X, y1, y2: NativeInt);
26 | var
27 | i: NativeInt;
28 | p: PT_;
29 | begin
30 | if (X < 0) or (X >= FWidth) then
31 | Exit;
32 |
33 | if y1 < 0 then
34 | y1 := 0;
35 | if y1 >= FHeight then
36 | y1 := FHeight - 1;
37 |
38 | if y2 < 0 then
39 | y2 := 0;
40 | if y2 >= FHeight then
41 | y2 := FHeight - 1;
42 |
43 | if y2 < y1 then
44 | Swap(y1, y2);
45 |
46 | p := @FData^[X + y1 * FWidth];
47 | for i := y1 to y2 do
48 | begin
49 | Process(p, FValue);
50 | inc(p, FWidth);
51 | end;
52 | end;
53 |
54 | procedure TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.HorzLine(x1, Y, x2: NativeInt);
55 | var
56 | i: NativeInt;
57 | p: PT_;
58 | begin
59 | if (Y < 0) or (Y >= FHeight) then
60 | Exit;
61 |
62 | if x1 < 0 then
63 | x1 := 0;
64 | if x1 >= FWidth then
65 | x1 := FWidth - 1;
66 |
67 | if x2 < 0 then
68 | x2 := 0;
69 | if x2 >= FWidth then
70 | x2 := FWidth - 1;
71 |
72 | if x1 > x2 then
73 | Swap(x1, x2);
74 |
75 | p := @FData^[x1 + Y * FWidth];
76 |
77 | for i := x1 to x2 do
78 | begin
79 | Process(p, FValue);
80 | inc(p);
81 | end;
82 | end;
83 |
84 | procedure TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.Line(x1, y1, x2, y2: NativeInt);
85 | var
86 | dy, dx, SY, SX, i, Delta: NativeInt;
87 | pi, pl: NativeInt;
88 | begin
89 | if (x1 = x2) and (y1 = y2) then
90 | begin
91 | Process(@FData^[x1 + y1 * FWidth], FValue);
92 | Exit;
93 | end;
94 |
95 | dx := x2 - x1;
96 | dy := y2 - y1;
97 |
98 | if dx > 0 then
99 | SX := 1
100 | else if dx < 0 then
101 | begin
102 | dx := -dx;
103 | SX := -1;
104 | end
105 | else // Dx = 0
106 | begin
107 | if dy > 0 then
108 | VertLine(x1, y1, y2 - 1)
109 | else if dy < 0 then
110 | VertLine(x1, y2 + 1, y1);
111 | if FLineTail then
112 | Process(@FData^[x2 + y2 * FWidth], FValue);
113 | Exit;
114 | end;
115 |
116 | if dy > 0 then
117 | SY := 1
118 | else if dy < 0 then
119 | begin
120 | dy := -dy;
121 | SY := -1;
122 | end
123 | else // Dy = 0
124 | begin
125 | if x2 > x1 then
126 | HorzLine(x1, y1, x2 - 1)
127 | else
128 | HorzLine(x2 + 1, y1, x1);
129 | if FLineTail then
130 | Process(@FData^[x2 + y2 * FWidth], FValue);
131 | Exit;
132 | end;
133 |
134 | pi := x1 + y1 * FWidth;
135 | SY := SY * FWidth;
136 | pl := FWidth * FHeight;
137 |
138 | if dx > dy then
139 | begin
140 | Delta := dx shr 1;
141 | for i := 0 to dx - 1 do
142 | begin
143 | if (pi >= 0) and (pi < pl) then
144 | Process(@FData^[pi], FValue);
145 |
146 | inc(pi, SX);
147 | inc(Delta, dy);
148 | if Delta >= dx then
149 | begin
150 | inc(pi, SY);
151 | dec(Delta, dx);
152 | end;
153 | end;
154 | end
155 | else // Dx < Dy
156 | begin
157 | Delta := dy shr 1;
158 | for i := 0 to dy - 1 do
159 | begin
160 | if (pi >= 0) and (pi < pl) then
161 | Process(@FData^[pi], FValue);
162 |
163 | inc(pi, SY);
164 | inc(Delta, dx);
165 | if Delta >= dy then
166 | begin
167 | inc(pi, SX);
168 | dec(Delta, dy);
169 | end;
170 | end;
171 | end;
172 | if (FLineTail) and (pi >= 0) and (pi < pl) then
173 | Process(@FData^[pi], FValue);
174 | end;
175 |
176 | procedure TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.FillBox(x1, y1, x2, y2: NativeInt);
177 | var
178 | i: Integer;
179 | begin
180 | if y1 > y2 then
181 | Swap(y1, y2);
182 | for i := y1 to y2 do
183 | HorzLine(x1, i, x2);
184 | end;
185 |
186 | procedure TLineProcessor{$IFNDEF FPC}{$ENDIF FPC}.Process(const vp: PT_; const v: T_);
187 | begin
188 | vp^ := v;
189 | end;
190 | {$IFDEF RangeCheck}{$R+}{$ENDIF}
191 | {$IFDEF OverflowCheck}{$Q+}{$ENDIF}
192 |
--------------------------------------------------------------------------------
/Source/Core_OrderData.inc:
--------------------------------------------------------------------------------
1 | procedure TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.DoInternalFree(p: POrderStruct_);
2 | begin
3 | try
4 | DoFree(p^.Data);
5 | Dispose(p);
6 | except
7 | end;
8 | end;
9 |
10 | constructor TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Create;
11 | begin
12 | inherited Create;
13 | FFirst := nil;
14 | FLast := nil;
15 | FNum := 0;
16 | FOnFreeOrderStruct := nil;
17 | end;
18 |
19 | destructor TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Destroy;
20 | begin
21 | Clear;
22 | inherited Destroy;
23 | end;
24 |
25 | procedure TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.DoFree(var Data: T_);
26 | begin
27 | if Assigned(FOnFreeOrderStruct) then
28 | FOnFreeOrderStruct(Data);
29 | end;
30 |
31 | procedure TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Clear;
32 | var
33 | p, tmp: POrderStruct_;
34 | begin
35 | p := FFirst;
36 | while p <> nil do
37 | begin
38 | tmp := p^.Next;
39 | DoInternalFree(p);
40 | p := tmp;
41 | end;
42 | FFirst := nil;
43 | FLast := nil;
44 | FNum := 0;
45 | end;
46 |
47 | procedure TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Next;
48 | var
49 | tmp: POrderStruct_;
50 | begin
51 | if FFirst <> nil then
52 | begin
53 | tmp := FFirst^.Next;
54 | DoInternalFree(FFirst);
55 | FFirst := tmp;
56 | if FFirst = nil then
57 | FLast := nil;
58 | Dec(FNum);
59 | end;
60 | end;
61 |
62 | procedure TOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Push(Data: T_);
63 | var
64 | p: POrderStruct_;
65 | begin
66 | new(p);
67 | p^.Data := Data;
68 | p^.Next := nil;
69 |
70 | Inc(FNum);
71 | if (FFirst = nil) and (FLast = nil) then
72 | begin
73 | FFirst := p;
74 | FLast := p;
75 | end
76 | else if FLast <> nil then
77 | begin
78 | FLast^.Next := p;
79 | FLast := p;
80 | end;
81 | end;
82 |
83 | procedure TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.DoInternalFree(p: POrderPtrStruct_);
84 | begin
85 | try
86 | DoFree(p^.Data);
87 | Dispose(p);
88 | except
89 | end;
90 | end;
91 |
92 | constructor TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Create;
93 | begin
94 | inherited Create;
95 | FFirst := nil;
96 | FLast := nil;
97 | FNum := 0;
98 | FOnFreeOrderStruct := nil;
99 | end;
100 |
101 | destructor TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Destroy;
102 | begin
103 | Clear;
104 | inherited Destroy;
105 | end;
106 |
107 | procedure TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.DoFree(Data: PT_);
108 | begin
109 | if Assigned(FOnFreeOrderStruct) then
110 | FOnFreeOrderStruct(Data)
111 | else
112 | Dispose(Data);
113 | end;
114 |
115 | procedure TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Clear;
116 | var
117 | p, tmp: POrderPtrStruct_;
118 | begin
119 | p := FFirst;
120 | while p <> nil do
121 | begin
122 | tmp := p^.Next;
123 | DoInternalFree(p);
124 | p := tmp;
125 | end;
126 | FFirst := nil;
127 | FLast := nil;
128 | FNum := 0;
129 | end;
130 |
131 | procedure TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Next;
132 | var
133 | tmp: POrderPtrStruct_;
134 | begin
135 | if FFirst <> nil then
136 | begin
137 | tmp := FFirst^.Next;
138 | DoInternalFree(FFirst);
139 | FFirst := tmp;
140 | if FFirst = nil then
141 | FLast := nil;
142 | Dec(FNum);
143 | end;
144 | end;
145 |
146 | procedure TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Push(Data: T_);
147 | var
148 | p: POrderPtrStruct_;
149 | begin
150 | new(p);
151 | new(p^.Data);
152 | p^.Data^ := Data;
153 | p^.Next := nil;
154 |
155 | Inc(FNum);
156 | if (FFirst = nil) and (FLast = nil) then
157 | begin
158 | FFirst := p;
159 | FLast := p;
160 | end
161 | else if FLast <> nil then
162 | begin
163 | FLast^.Next := p;
164 | FLast := p;
165 | end;
166 | end;
167 |
168 | procedure TOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.PushPtr(Data: PT_);
169 | var
170 | p: POrderPtrStruct_;
171 | begin
172 | new(p);
173 | p^.Data := Data;
174 | p^.Next := nil;
175 |
176 | Inc(FNum);
177 | if (FFirst = nil) and (FLast = nil) then
178 | begin
179 | FFirst := p;
180 | FLast := p;
181 | end
182 | else if FLast <> nil then
183 | begin
184 | FLast^.Next := p;
185 | FLast := p;
186 | end;
187 | end;
188 |
189 | procedure TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.DoInternalFree(p: POrderStruct_);
190 | begin
191 | try
192 | DoFree(p^.Data);
193 | Dispose(p);
194 | except
195 | end;
196 | end;
197 |
198 | constructor TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Create;
199 | begin
200 | inherited Create;
201 | FCritical := TCritical.Create;
202 | FFirst := nil;
203 | FLast := nil;
204 | FNum := 0;
205 | FOnFreeCriticalOrderStruct := nil;
206 | end;
207 |
208 | destructor TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Destroy;
209 | begin
210 | Clear;
211 | FCritical.Free;
212 | inherited Destroy;
213 | end;
214 |
215 | procedure TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.DoFree(var Data: T_);
216 | begin
217 | if Assigned(FOnFreeCriticalOrderStruct) then
218 | FOnFreeCriticalOrderStruct(Data);
219 | end;
220 |
221 | procedure TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Clear;
222 | var
223 | p, tmp: POrderStruct_;
224 | begin
225 | FCritical.Lock;
226 | p := FFirst;
227 | while p <> nil do
228 | begin
229 | tmp := p^.Next;
230 | DoInternalFree(p);
231 | p := tmp;
232 | end;
233 | FFirst := nil;
234 | FLast := nil;
235 | FNum := 0;
236 | FCritical.UnLock;
237 | end;
238 |
239 | function TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.GetCurrent: POrderStruct_;
240 | begin
241 | FCritical.Lock;
242 | Result := FFirst;
243 | FCritical.UnLock;
244 | end;
245 |
246 | procedure TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Next;
247 | var
248 | tmp: POrderStruct_;
249 | begin
250 | FCritical.Lock;
251 | if FFirst <> nil then
252 | begin
253 | tmp := FFirst^.Next;
254 | DoInternalFree(FFirst);
255 | FFirst := tmp;
256 | if FFirst = nil then
257 | FLast := nil;
258 | Dec(FNum);
259 | end;
260 | FCritical.UnLock;
261 | end;
262 |
263 | procedure TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.Push(Data: T_);
264 | var
265 | p: POrderStruct_;
266 | begin
267 | new(p);
268 | p^.Data := Data;
269 | p^.Next := nil;
270 |
271 | FCritical.Lock;
272 | Inc(FNum);
273 | if (FFirst = nil) and (FLast = nil) then
274 | begin
275 | FFirst := p;
276 | FLast := p;
277 | end
278 | else if FLast <> nil then
279 | begin
280 | FLast^.Next := p;
281 | FLast := p;
282 | end;
283 | FCritical.UnLock;
284 | end;
285 |
286 | function TCriticalOrderStruct{$IFNDEF FPC}{$ENDIF FPC}.GetNum: NativeInt;
287 | begin
288 | FCritical.Lock;
289 | Result := FNum;
290 | FCritical.UnLock;
291 | end;
292 |
293 | procedure TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.DoInternalFree(p: POrderPtrStruct_);
294 | begin
295 | try
296 | DoFree(p^.Data);
297 | Dispose(p);
298 | except
299 | end;
300 | end;
301 |
302 | constructor TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Create;
303 | begin
304 | inherited Create;
305 | FCritical := TCritical.Create;
306 | FFirst := nil;
307 | FLast := nil;
308 | FNum := 0;
309 | FOnFreeCriticalOrderStruct := nil;
310 | end;
311 |
312 | destructor TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Destroy;
313 | begin
314 | Clear;
315 | FCritical.Free;
316 | inherited Destroy;
317 | end;
318 |
319 | procedure TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.DoFree(Data: PT_);
320 | begin
321 | if Assigned(FOnFreeCriticalOrderStruct) then
322 | FOnFreeCriticalOrderStruct(Data)
323 | else
324 | Dispose(Data);
325 | end;
326 |
327 | procedure TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Clear;
328 | var
329 | p, tmp: POrderPtrStruct_;
330 | begin
331 | FCritical.Lock;
332 | p := FFirst;
333 | while p <> nil do
334 | begin
335 | tmp := p^.Next;
336 | DoInternalFree(p);
337 | p := tmp;
338 | end;
339 | FFirst := nil;
340 | FLast := nil;
341 | FNum := 0;
342 | FCritical.UnLock;
343 | end;
344 |
345 | function TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.GetCurrent: POrderPtrStruct_;
346 | begin
347 | FCritical.Lock;
348 | Result := FFirst;
349 | FCritical.UnLock;
350 | end;
351 |
352 | procedure TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Next;
353 | var
354 | tmp: POrderPtrStruct_;
355 | begin
356 | FCritical.Lock;
357 | if FFirst <> nil then
358 | begin
359 | tmp := FFirst^.Next;
360 | DoInternalFree(FFirst);
361 | FFirst := tmp;
362 | if FFirst = nil then
363 | FLast := nil;
364 | Dec(FNum);
365 | end;
366 | FCritical.UnLock;
367 | end;
368 |
369 | procedure TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.Push(Data: T_);
370 | var
371 | p: POrderPtrStruct_;
372 | begin
373 | new(p);
374 | new(p^.Data);
375 | p^.Data^ := Data;
376 | p^.Next := nil;
377 |
378 | FCritical.Lock;
379 | Inc(FNum);
380 | if (FFirst = nil) and (FLast = nil) then
381 | begin
382 | FFirst := p;
383 | FLast := p;
384 | end
385 | else if FLast <> nil then
386 | begin
387 | FLast^.Next := p;
388 | FLast := p;
389 | end;
390 | FCritical.UnLock;
391 | end;
392 |
393 | procedure TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.PushPtr(Data: PT_);
394 | var
395 | p: POrderPtrStruct_;
396 | begin
397 | new(p);
398 | p^.Data := Data;
399 | p^.Next := nil;
400 |
401 | FCritical.Lock;
402 | Inc(FNum);
403 | if (FFirst = nil) and (FLast = nil) then
404 | begin
405 | FFirst := p;
406 | FLast := p;
407 | end
408 | else if FLast <> nil then
409 | begin
410 | FLast^.Next := p;
411 | FLast := p;
412 | end;
413 | FCritical.UnLock;
414 | end;
415 |
416 | function TCriticalOrderPtrStruct{$IFNDEF FPC}{$ENDIF FPC}.GetNum: NativeInt;
417 | begin
418 | FCritical.Lock;
419 | Result := FNum;
420 | FCritical.UnLock;
421 | end;
422 |
--------------------------------------------------------------------------------
/Source/FPCGenericStructlist.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Generic list of any type (TGenericStructList). * }
3 | { ****************************************************************************** }
4 | { * https://zpascal.net * }
5 | { * https://github.com/PassByYou888/zAI * }
6 | { * https://github.com/PassByYou888/ZServer4D * }
7 | { * https://github.com/PassByYou888/PascalString * }
8 | { * https://github.com/PassByYou888/zRasterization * }
9 | { * https://github.com/PassByYou888/CoreCipher * }
10 | { * https://github.com/PassByYou888/zSound * }
11 | { * https://github.com/PassByYou888/zChinese * }
12 | { * https://github.com/PassByYou888/zExpression * }
13 | { * https://github.com/PassByYou888/zGameWare * }
14 | { * https://github.com/PassByYou888/zAnalysis * }
15 | { * https://github.com/PassByYou888/FFMPEG-Header * }
16 | { * https://github.com/PassByYou888/zTranslate * }
17 | { * https://github.com/PassByYou888/InfiniteIoT * }
18 | { * https://github.com/PassByYou888/FastMD5 * }
19 | { ****************************************************************************** }
20 | {
21 | Based on FPC FGL unit, copyright by FPC team.
22 | License of FPC RTL is the same as our engine (modified LGPL,
23 | see COPYING.txt for details).
24 | Fixed to compile also under FPC 2.4.0 and 2.2.4.
25 | Some small comfortable methods added.
26 | }
27 |
28 | unit FPCGenericStructlist;
29 |
30 | {$IFDEF FPC}
31 | {$mode objfpc}{$H+}
32 |
33 | {$IF defined(VER2_2)} {$DEFINE OldSyntax} {$IFEND}
34 | {$IF defined(VER2_4)} {$DEFINE OldSyntax} {$IFEND}
35 |
36 | {$define HAS_ENUMERATOR}
37 | {$ifdef VER2_2} {$undef HAS_ENUMERATOR} {$endif}
38 | {$ifdef VER2_4_0} {$undef HAS_ENUMERATOR} {$endif}
39 | { Just undef enumerator always, in FPC 2.7.1 it's either broken
40 | or I shouldn't overuse TFPGListEnumeratorSpec. }
41 | {$undef HAS_ENUMERATOR}
42 |
43 | { FPC < 2.6.0 had buggy version of the Extract function,
44 | also with different interface, see http://bugs.freepascal.org/view.php?id=19960. }
45 | {$define HAS_EXTRACT}
46 | {$ifdef VER2_2} {$undef HAS_EXTRACT} {$endif}
47 | {$ifdef VER2_4} {$undef HAS_EXTRACT} {$endif}
48 | {$ENDIF FPC}
49 |
50 | interface
51 |
52 | {$IFDEF FPC}
53 |
54 | uses fgl;
55 |
56 | type
57 | { Generic list of types that are compared by CompareByte.
58 |
59 | This is equivalent to TFPGList, except it doesn't override IndexOf,
60 | so your type doesn't need to have a "=" operator built-in inside FPC.
61 | When calling IndexOf or Remove, it will simply compare values using
62 | CompareByte, this is what TFPSList.IndexOf uses.
63 | This way it works to create lists of records, vectors (constant size arrays),
64 | old-style TP objects, and also is suitable to create a list of methods
65 | (since for methods, the "=" is broken, for Delphi compatibility,
66 | see http://bugs.freepascal.org/view.php?id=9228).
67 |
68 | We also add some trivial helper methods like @link(Add) and @link(L). }
69 | generic TGenericsList = class(TFPSList)
70 | private
71 | type
72 | TCompareFunc = function(const Item1, Item2: t): Integer;
73 | TTypeList = array[0..MaxGListSize] of t;
74 | PTypeList = ^TTypeList;
75 | {$ifdef HAS_ENUMERATOR} TFPGListEnumeratorSpec = specialize TFPGListEnumerator; {$endif}
76 |
77 | {$ifndef OldSyntax}protected var{$else}
78 | {$ifdef PASDOC}protected var{$else} { PasDoc can't handle "var protected", and I don't know how/if they should be handled? }
79 | var protected{$endif}{$endif} FOnCompare: TCompareFunc;
80 |
81 | procedure CopyItem(Src, dest: Pointer); override;
82 | procedure Deref(Item: Pointer); override;
83 | function Get(index: Integer): t; {$ifdef CLASSESINLINE} inline; {$endif}
84 | function GetList: PTypeList; {$ifdef CLASSESINLINE} inline; {$endif}
85 | function ItemPtrCompare(Item1, Item2: Pointer): Integer;
86 | procedure Put(index: Integer; const Item: t); {$ifdef CLASSESINLINE} inline; {$endif}
87 | public
88 | constructor Create;
89 | function Add(const Item: t): Integer; {$ifdef CLASSESINLINE} inline; {$endif}
90 | {$ifdef HAS_EXTRACT} function Extract(const Item: t): t; {$ifdef CLASSESINLINE} inline; {$endif} {$endif}
91 | function First: t; {$ifdef CLASSESINLINE} inline; {$endif}
92 | {$ifdef HAS_ENUMERATOR} function GetEnumerator: TFPGListEnumeratorSpec; {$ifdef CLASSESINLINE} inline; {$endif} {$endif}
93 | function IndexOf(const Item: t): Integer;
94 | procedure Insert(index: Integer; const Item: t); {$ifdef CLASSESINLINE} inline; {$endif}
95 | function Last: t; {$ifdef CLASSESINLINE} inline; {$endif}
96 | {$ifndef OldSyntax}
97 | procedure Assign(Source: TGenericsList);
98 | {$endif OldSyntax}
99 | function Remove(const Item: t): Integer; {$ifdef CLASSESINLINE} inline; {$endif}
100 | procedure Sort(Compare: TCompareFunc);
101 | property Items[index: Integer]: t read Get write Put; default;
102 | property List: PTypeList read GetList;
103 | property ListData: PTypeList read GetList;
104 | end;
105 |
106 | {$ENDIF FPC}
107 |
108 | implementation
109 |
110 | {$IFDEF FPC}
111 | constructor TGenericsList.Create;
112 | begin
113 | inherited Create(SizeOf(t));
114 | end;
115 |
116 | procedure TGenericsList.CopyItem(Src, dest: Pointer);
117 | begin
118 | t(dest^) := t(Src^);
119 | end;
120 |
121 | procedure TGenericsList.Deref(Item: Pointer);
122 | begin
123 | Finalize(t(Item^));
124 | end;
125 |
126 | function TGenericsList.Get(index: Integer): t;
127 | begin
128 | Result := t(inherited Get(index)^);
129 | end;
130 |
131 | function TGenericsList.GetList: PTypeList;
132 | begin
133 | Result := PTypeList(FList);
134 | end;
135 |
136 | function TGenericsList.ItemPtrCompare(Item1, Item2: Pointer): Integer;
137 | begin
138 | Result := FOnCompare(t(Item1^), t(Item2^));
139 | end;
140 |
141 | procedure TGenericsList.Put(index: Integer; const Item: t);
142 | begin
143 | inherited Put(index, @Item);
144 | end;
145 |
146 | function TGenericsList.Add(const Item: t): Integer;
147 | begin
148 | Result := inherited Add(@Item);
149 | end;
150 |
151 | {$ifdef HAS_EXTRACT}
152 | function TGenericsList.Extract(const Item: t): t;
153 | begin
154 | inherited Extract(@Item, @Result);
155 | end;
156 | {$endif}
157 |
158 | function TGenericsList.First: t;
159 | begin
160 | Result := t(inherited First^);
161 | end;
162 |
163 | {$ifdef HAS_ENUMERATOR}
164 | function TGenericsList.GetEnumerator: TFPGListEnumeratorSpec;
165 | begin
166 | Result := TFPGListEnumeratorSpec.Create(Self);
167 | end;
168 | {$endif}
169 |
170 | function TGenericsList.IndexOf(const Item: t): Integer;
171 | begin
172 | Result := inherited IndexOf(@Item);
173 | end;
174 |
175 | procedure TGenericsList.Insert(index: Integer; const Item: t);
176 | begin
177 | t(inherited Insert(index)^) := Item;
178 | end;
179 |
180 | function TGenericsList.Last: t;
181 | begin
182 | Result := t(inherited Last^);
183 | end;
184 |
185 | {$ifndef OldSyntax}
186 | procedure TGenericsList.Assign(Source: TGenericsList);
187 | var
188 | i: Integer;
189 | begin
190 | Clear;
191 | for i := 0 to Source.Count - 1 do
192 | Add(Source[i]);
193 | end;
194 | {$endif OldSyntax}
195 |
196 | function TGenericsList.Remove(const Item: t): Integer;
197 | begin
198 | Result := IndexOf(Item);
199 | if Result >= 0 then
200 | Delete(Result);
201 | end;
202 |
203 | procedure TGenericsList.Sort(Compare: TCompareFunc);
204 | begin
205 | FOnCompare := Compare;
206 | inherited Sort(@ItemPtrCompare);
207 | end;
208 |
209 | {$ENDIF FPC}
210 |
211 | end.
212 |
213 |
214 |
215 |
--------------------------------------------------------------------------------
/Source/Fast_MD5.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Fast md5 * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 | unit Fast_MD5;
20 |
21 | {$INCLUDE zDefine.inc}
22 |
23 | interface
24 |
25 |
26 | uses CoreClasses, UnicodeMixedLib;
27 |
28 | {$IF Defined(MSWINDOWS) and Defined(Delphi)}
29 | procedure MD5_Transform(var Accu; const Buf);
30 | {$ENDIF Defined(MSWINDOWS) and Defined(Delphi)}
31 |
32 | function FastMD5(const buffPtr: PByte; bufSiz: nativeUInt): TMD5; overload;
33 | function FastMD5(stream: TCoreClassStream; StartPos, EndPos: Int64): TMD5; overload;
34 |
35 | implementation
36 |
37 | {$IF Defined(MSWINDOWS) and Defined(Delphi)}
38 |
39 |
40 | uses MemoryStream64;
41 |
42 | (*
43 | fastMD5 algorithm by Maxim Masiutin
44 | https://github.com/maximmasiutin/MD5_Transform-x64
45 |
46 | delphi imp by 600585@qq.com
47 | https://github.com/PassByYou888/FastMD5
48 | *)
49 |
50 | {$IF Defined(WIN32)}
51 | (*
52 | ; ==============================================================
53 | ;
54 | ; MD5_386.Asm - 386 optimized helper routine for calculating
55 | ; MD Message-Digest values
56 | ; written 2/2/94 by
57 | ;
58 | ; Peter Sawatzki
59 | ; Buchenhof 3
60 | ; D58091 Hagen, Germany Fed Rep
61 | ;
62 | ; EMail: Peter@Sawatzki.de
63 | ; EMail: 100031.3002@compuserve.com
64 | ; WWW: http://www.sawatzki.de
65 | ;
66 | ;
67 | ; original C Source was found in Dr. Dobbs Journal Sep 91
68 | ; MD5 algorithm from RSA Data Security, Inc.
69 | *)
70 | {$L MD5_32.obj}
71 | {$ELSEIF Defined(WIN64)}
72 | (*
73 | ; MD5_Transform-x64
74 | ; MD5 transform routine oprimized for x64 processors
75 | ; Copyright 2018 Ritlabs, SRL
76 | ; The 64-bit version is written by Maxim Masiutin
77 |
78 | ; The main advantage of this 64-bit version is that
79 | ; it loads 64 bytes of hashed message into 8 64-bit registers
80 | ; (RBP, R8, R9, R10, R11, R12, R13, R14) at the beginning,
81 | ; to avoid excessive memory load operations
82 | ; througout the routine.
83 |
84 | ; To operate with 32-bit values store in higher bits
85 | ; of a 64-bit register (bits 32-63) uses "Ror" by 32;
86 | ; 8 macro variables (M1-M8) are used to keep record
87 | ; or corrent state of whether the register has been
88 | ; Ror'ed or not.
89 |
90 | ; It also has an ability to use Lea instruction instead
91 | ; of two sequental Adds (uncomment UseLea=1), but it is
92 | ; slower on Skylake processors. Also, Intel in the
93 | ; Optimization Reference Maual discourages us of
94 | ; Lea as a replacement of two adds, since it is slower
95 | ; on the Atom processors.
96 |
97 | ; MD5_Transform-x64 is released under a dual license,
98 | ; and you may choose to use it under either the
99 | ; Mozilla Public License 2.0 (MPL 2.1, available from
100 | ; https://www.mozilla.org/en-US/MPL/2.0/) or the
101 | ; GNU Lesser General Public License Version 3,
102 | ; dated 29 June 2007 (LGPL 3, available from
103 | ; https://www.gnu.org/licenses/lgpl.html).
104 |
105 | ; MD5_Transform-x64 is based
106 | ; on the following code by Peter Sawatzki.
107 |
108 | ; The original notice by Peter Sawatzki follows.
109 | *)
110 | {$L MD5_64.obj}
111 | {$ENDIF}
112 |
113 | procedure MD5_Transform(var Accu; const Buf); register; external;
114 |
115 | function FastMD5(const buffPtr: PByte; bufSiz: nativeUInt): TMD5;
116 | var
117 | Digest: TMD5;
118 | Lo, Hi: Cardinal;
119 | p: PByte;
120 | ChunkIndex: Byte;
121 | ChunkBuff: array [0 .. 63] of Byte;
122 | begin
123 | Lo := 0;
124 | Hi := 0;
125 | PCardinal(@Digest[0])^ := $67452301;
126 | PCardinal(@Digest[4])^ := $EFCDAB89;
127 | PCardinal(@Digest[8])^ := $98BADCFE;
128 | PCardinal(@Digest[12])^ := $10325476;
129 |
130 | inc(Lo, bufSiz shl 3);
131 | inc(Hi, bufSiz shr 29);
132 |
133 | p := buffPtr;
134 |
135 | while bufSiz >= $40 do
136 | begin
137 | MD5_Transform(Digest, p^);
138 | inc(p, $40);
139 | dec(bufSiz, $40);
140 | end;
141 | if bufSiz > 0 then
142 | CopyPtr(p, @ChunkBuff[0], bufSiz);
143 |
144 | Result := PMD5(@Digest[0])^;
145 | ChunkBuff[bufSiz] := $80;
146 | ChunkIndex := bufSiz + 1;
147 | if ChunkIndex > $38 then
148 | begin
149 | if ChunkIndex < $40 then
150 | FillPtrByte(@ChunkBuff[ChunkIndex], $40 - ChunkIndex, 0);
151 | MD5_Transform(Result, ChunkBuff);
152 | ChunkIndex := 0
153 | end;
154 | FillPtrByte(@ChunkBuff[ChunkIndex], $38 - ChunkIndex, 0);
155 | PCardinal(@ChunkBuff[$38])^ := Lo;
156 | PCardinal(@ChunkBuff[$3C])^ := Hi;
157 | MD5_Transform(Result, ChunkBuff);
158 | end;
159 |
160 | function FastMD5(stream: TCoreClassStream; StartPos, EndPos: Int64): TMD5;
161 | const
162 | deltaSize: Cardinal = $40 * $FFFF;
163 |
164 | var
165 | Digest: TMD5;
166 | Lo, Hi: Cardinal;
167 | DeltaBuf: Pointer;
168 | bufSiz: Int64;
169 | Rest: Cardinal;
170 | p: PByte;
171 | ChunkIndex: Byte;
172 | ChunkBuff: array [0 .. 63] of Byte;
173 | begin
174 | if StartPos > EndPos then
175 | Swap(StartPos, EndPos);
176 | StartPos := umlClamp(StartPos, 0, stream.Size);
177 | EndPos := umlClamp(EndPos, 0, stream.Size);
178 | if EndPos - StartPos <= 0 then
179 | begin
180 | Result := FastMD5(nil, 0);
181 | exit;
182 | end;
183 | {$IFDEF OptimizationMemoryStreamMD5}
184 | if stream is TCoreClassMemoryStream then
185 | begin
186 | Result := FastMD5(Pointer(nativeUInt(TCoreClassMemoryStream(stream).Memory) + StartPos), EndPos - StartPos);
187 | exit;
188 | end;
189 | if stream is TMemoryStream64 then
190 | begin
191 | Result := FastMD5(TMemoryStream64(stream).PositionAsPtr(StartPos), EndPos - StartPos);
192 | exit;
193 | end;
194 | {$ENDIF}
195 | //
196 | Lo := 0;
197 | Hi := 0;
198 | PCardinal(@Digest[0])^ := $67452301;
199 | PCardinal(@Digest[4])^ := $EFCDAB89;
200 | PCardinal(@Digest[8])^ := $98BADCFE;
201 | PCardinal(@Digest[12])^ := $10325476;
202 |
203 | bufSiz := EndPos - StartPos;
204 | Rest := 0;
205 |
206 | inc(Lo, bufSiz shl 3);
207 | inc(Hi, bufSiz shr 29);
208 |
209 | DeltaBuf := GetMemory(deltaSize);
210 | stream.Position := StartPos;
211 |
212 | if bufSiz < $40 then
213 | begin
214 | stream.read(DeltaBuf^, bufSiz);
215 | p := DeltaBuf;
216 | end
217 | else
218 | while bufSiz >= $40 do
219 | begin
220 | if Rest = 0 then
221 | begin
222 | if bufSiz >= deltaSize then
223 | Rest := deltaSize
224 | else
225 | Rest := bufSiz;
226 | stream.ReadBuffer(DeltaBuf^, Rest);
227 |
228 | p := DeltaBuf;
229 | end;
230 | MD5_Transform(Digest, p^);
231 | inc(p, $40);
232 | dec(bufSiz, $40);
233 | dec(Rest, $40);
234 | end;
235 |
236 | if bufSiz > 0 then
237 | CopyPtr(p, @ChunkBuff[0], bufSiz);
238 |
239 | FreeMemory(DeltaBuf);
240 |
241 | Result := PMD5(@Digest[0])^;
242 | ChunkBuff[bufSiz] := $80;
243 | ChunkIndex := bufSiz + 1;
244 | if ChunkIndex > $38 then
245 | begin
246 | if ChunkIndex < $40 then
247 | FillPtrByte(@ChunkBuff[ChunkIndex], $40 - ChunkIndex, 0);
248 | MD5_Transform(Result, ChunkBuff);
249 | ChunkIndex := 0
250 | end;
251 | FillPtrByte(@ChunkBuff[ChunkIndex], $38 - ChunkIndex, 0);
252 | PCardinal(@ChunkBuff[$38])^ := Lo;
253 | PCardinal(@ChunkBuff[$3C])^ := Hi;
254 | MD5_Transform(Result, ChunkBuff);
255 | end;
256 |
257 | {$ELSE}
258 |
259 |
260 | function FastMD5(const buffPtr: PByte; bufSiz: nativeUInt): TMD5;
261 | begin
262 | Result := umlMD5(buffPtr, bufSiz);
263 | end;
264 |
265 | function FastMD5(stream: TCoreClassStream; StartPos, EndPos: Int64): TMD5;
266 | begin
267 | Result := umlStreamMD5(stream, StartPos, EndPos);
268 | end;
269 |
270 | {$ENDIF Defined(MSWINDOWS) and Defined(Delphi)}
271 |
272 | end.
273 |
--------------------------------------------------------------------------------
/Source/LinearAction.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * linear action written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 | unit LinearAction;
20 |
21 | {$INCLUDE zDefine.inc}
22 |
23 | interface
24 |
25 | uses CoreClasses, DoStatusIO, PascalStrings, UnicodeMixedLib;
26 |
27 | type
28 | TCoreActionID = Integer;
29 | TCoreActionString = SystemString;
30 | TCoreActionState = (asPlaying, asPause, asStop, asOver);
31 | TCoreActionStates = set of TCoreActionState;
32 | TCoreAction = class;
33 | TCoreActionList = class;
34 | TCoreActionLinear = class;
35 |
36 | TCoreAction = class(TCoreClassObject)
37 | public
38 | Owner: TCoreActionList;
39 | State: TCoreActionStates;
40 | ID: TCoreActionID;
41 | Desc: TCoreActionString;
42 |
43 | constructor Create(Owner_: TCoreActionList); virtual;
44 | destructor Destroy; override;
45 |
46 | procedure Run(); virtual;
47 | procedure Over(); virtual;
48 | procedure Stop(); virtual;
49 | procedure Pause(); virtual;
50 | procedure Progress(deltaTime: Double); virtual;
51 | end;
52 |
53 | TCoreActionClass = class of TCoreAction;
54 |
55 | TCoreActionList = class(TCoreClassObject)
56 | protected
57 | FSequenceList: TCoreClassListForObj;
58 | FFocusIndex: Integer;
59 | FLast: TCoreAction;
60 | public
61 | Owner: TCoreActionLinear;
62 | constructor Create(Owner_: TCoreActionLinear);
63 | destructor Destroy; override;
64 | procedure Clear;
65 | function Add(ActionClass_: TCoreActionClass): TCoreAction; overload;
66 | procedure Run();
67 | procedure Over();
68 | procedure Stop();
69 | function IsOver(): Boolean;
70 | function IsStop(): Boolean;
71 | property Last: TCoreAction read FLast;
72 | procedure Progress(deltaTime: Double);
73 | end;
74 |
75 | TCoreActionLinear = class(TCoreClassObject)
76 | protected
77 | FSequenceList: TCoreClassListForObj;
78 | FFocusIndex: Integer;
79 | FLast: TCoreActionList;
80 | public
81 | constructor Create();
82 | destructor Destroy; override;
83 | procedure Clear;
84 | function Add: TCoreActionList;
85 | procedure Run();
86 | procedure Stop();
87 | procedure Over();
88 | property Last: TCoreActionList read FLast;
89 | procedure Progress(deltaTime: Double);
90 |
91 | class procedure Test();
92 | end;
93 |
94 | implementation
95 |
96 | constructor TCoreAction.Create(Owner_: TCoreActionList);
97 | begin
98 | inherited Create;
99 | Owner := Owner_;
100 | State := [];
101 | ID := 0;
102 | Desc := '';
103 | end;
104 |
105 | destructor TCoreAction.Destroy;
106 | begin
107 | inherited Destroy;
108 | end;
109 |
110 | procedure TCoreAction.Run;
111 | begin
112 | State := [asPlaying];
113 | end;
114 |
115 | procedure TCoreAction.Over;
116 | begin
117 | if asPlaying in State then
118 | State := [asOver];
119 | end;
120 |
121 | procedure TCoreAction.Stop;
122 | begin
123 | if asPlaying in State then
124 | State := [asStop];
125 | end;
126 |
127 | procedure TCoreAction.Pause;
128 | begin
129 | if asPlaying in State then
130 | State := [asPlaying, asPause];
131 | end;
132 |
133 | procedure TCoreAction.Progress(deltaTime: Double);
134 | begin
135 |
136 | end;
137 |
138 | constructor TCoreActionList.Create(Owner_: TCoreActionLinear);
139 | begin
140 | inherited Create;
141 | FSequenceList := TCoreClassListForObj.Create;
142 | FFocusIndex := -1;
143 | FLast := nil;
144 | Owner := Owner_;
145 | end;
146 |
147 | destructor TCoreActionList.Destroy;
148 | begin
149 | Clear;
150 | DisposeObject(FSequenceList);
151 | inherited Destroy;
152 | end;
153 |
154 | procedure TCoreActionList.Clear;
155 | var
156 | i: Integer;
157 | begin
158 | for i := FSequenceList.Count - 1 downto 0 do
159 | DisposeObject(FSequenceList[i]);
160 | FSequenceList.Clear;
161 | end;
162 |
163 | function TCoreActionList.Add(ActionClass_: TCoreActionClass): TCoreAction;
164 | begin
165 | Result := ActionClass_.Create(Self);
166 | FSequenceList.Add(Result);
167 | end;
168 |
169 | procedure TCoreActionList.Run();
170 | begin
171 | if FSequenceList.Count > 0 then
172 | begin
173 | FFocusIndex := 0;
174 | FLast := FSequenceList[FFocusIndex] as TCoreAction;
175 | end
176 | else
177 | begin
178 | FFocusIndex := -1;
179 | FLast := nil;
180 | end;
181 | end;
182 |
183 | procedure TCoreActionList.Over;
184 | begin
185 | if FLast <> nil then
186 | FFocusIndex := FSequenceList.Count;
187 | end;
188 |
189 | procedure TCoreActionList.Stop;
190 | begin
191 | if FLast <> nil then
192 | FFocusIndex := -1;
193 | end;
194 |
195 | function TCoreActionList.IsOver: Boolean;
196 | begin
197 | Result := FFocusIndex >= FSequenceList.Count;
198 | end;
199 |
200 | function TCoreActionList.IsStop: Boolean;
201 | begin
202 | Result := FFocusIndex < 0;
203 | end;
204 |
205 | procedure TCoreActionList.Progress(deltaTime: Double);
206 | begin
207 | if (FFocusIndex < 0) or (FFocusIndex >= FSequenceList.Count) then
208 | Exit;
209 |
210 | FLast := FSequenceList[FFocusIndex] as TCoreAction;
211 |
212 | if FLast.State = [] then
213 | begin
214 | FLast.Run;
215 | Exit;
216 | end;
217 |
218 | if asPlaying in FLast.State then
219 | begin
220 | FLast.Progress(deltaTime);
221 | Exit;
222 | end;
223 |
224 | if asStop in FLast.State then
225 | begin
226 | FFocusIndex := -1;
227 | if Owner <> nil then
228 | Owner.Stop;
229 | Exit;
230 | end;
231 |
232 | if asOver in FLast.State then
233 | begin
234 | inc(FFocusIndex);
235 | if (FFocusIndex >= FSequenceList.Count) and (Owner <> nil) then
236 | Owner.Over;
237 | Exit;
238 | end;
239 | end;
240 |
241 | constructor TCoreActionLinear.Create();
242 | begin
243 | inherited Create;
244 | FSequenceList := TCoreClassListForObj.Create;
245 | FFocusIndex := -1;
246 | FLast := nil;
247 | end;
248 |
249 | destructor TCoreActionLinear.Destroy;
250 | begin
251 | Clear;
252 | DisposeObject(FSequenceList);
253 | inherited Destroy;
254 | end;
255 |
256 | procedure TCoreActionLinear.Clear;
257 | var
258 | i: Integer;
259 | begin
260 | for i := FSequenceList.Count - 1 downto 0 do
261 | DisposeObject(FSequenceList[i]);
262 | FSequenceList.Clear;
263 | FFocusIndex := -1;
264 | FLast := nil;
265 | end;
266 |
267 | function TCoreActionLinear.Add: TCoreActionList;
268 | begin
269 | Result := TCoreActionList.Create(Self);
270 | FSequenceList.Add(Result);
271 | end;
272 |
273 | procedure TCoreActionLinear.Run;
274 | begin
275 | if FSequenceList.Count > 0 then
276 | begin
277 | FFocusIndex := 0;
278 | FLast := FSequenceList[FFocusIndex] as TCoreActionList;
279 | end
280 | else
281 | begin
282 | FFocusIndex := -1;
283 | FLast := nil;
284 | end;
285 | end;
286 |
287 | procedure TCoreActionLinear.Stop;
288 | begin
289 | Clear;
290 | end;
291 |
292 | procedure TCoreActionLinear.Over;
293 | begin
294 | inc(FFocusIndex);
295 | if FFocusIndex < FSequenceList.Count then
296 | begin
297 | FLast := FSequenceList[FFocusIndex] as TCoreActionList;
298 | end
299 | else
300 | begin
301 | Clear;
302 | end;
303 | end;
304 |
305 | procedure TCoreActionLinear.Progress(deltaTime: Double);
306 | begin
307 | if FLast <> nil then
308 | FLast.Progress(deltaTime);
309 | end;
310 |
311 | class procedure TCoreActionLinear.Test();
312 | var
313 | al: TCoreActionList;
314 | i: Integer;
315 | begin
316 | al := TCoreActionList.Create(nil);
317 | for i := 1 to 2 do
318 | with al.Add(TCoreAction) do
319 | begin
320 | ID := i;
321 | Desc := PFormat('description %d', [i]);
322 | end;
323 | al.Run;
324 | while True do
325 | begin
326 | al.Progress(0.1);
327 | al.Last.Over;
328 | if al.IsOver or al.IsStop then
329 | Break;
330 | end;
331 |
332 | DisposeObject(al);
333 | end;
334 |
335 | end.
336 |
--------------------------------------------------------------------------------
/Source/MH.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Low MemoryHook written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | (*
21 | update history
22 | 2017-12-31
23 | *)
24 |
25 | unit MH;
26 |
27 | {$INCLUDE zDefine.inc}
28 |
29 | interface
30 |
31 | uses CoreClasses, SyncObjs, ListEngine;
32 |
33 | procedure BeginMemoryHook_1;
34 | procedure EndMemoryHook_1;
35 | function GetHookMemorySize_1: nativeUInt;
36 | function GetHookPtrList_1: TPointerHashNativeUIntList;
37 |
38 | procedure BeginMemoryHook_2;
39 | procedure EndMemoryHook_2;
40 | function GetHookMemorySize_2: nativeUInt;
41 | function GetHookPtrList_2: TPointerHashNativeUIntList;
42 |
43 | procedure BeginMemoryHook_3;
44 | procedure EndMemoryHook_3;
45 | function GetHookMemorySize_3: nativeUInt;
46 | function GetHookPtrList_3: TPointerHashNativeUIntList;
47 |
48 | implementation
49 |
50 | uses MH_ZDB, MH_1, MH_2, MH_3, DoStatusIO, PascalStrings;
51 |
52 | procedure BeginMemoryHook_1;
53 | begin
54 | MH_1.BeginMemoryHook($FFFF);
55 | end;
56 |
57 | procedure EndMemoryHook_1;
58 | begin
59 | MH_1.EndMemoryHook;
60 | end;
61 |
62 | function GetHookMemorySize_1: nativeUInt;
63 | begin
64 | Result := MH_1.GetHookMemorySize;
65 | end;
66 |
67 | function GetHookPtrList_1: TPointerHashNativeUIntList;
68 | begin
69 | Result := MH_1.GetHookPtrList;
70 | end;
71 |
72 | procedure BeginMemoryHook_2;
73 | begin
74 | MH_2.BeginMemoryHook($FFFF);
75 | end;
76 |
77 | procedure EndMemoryHook_2;
78 | begin
79 | MH_2.EndMemoryHook;
80 | end;
81 |
82 | function GetHookMemorySize_2: nativeUInt;
83 | begin
84 | Result := MH_2.GetHookMemorySize;
85 | end;
86 |
87 | function GetHookPtrList_2: TPointerHashNativeUIntList;
88 | begin
89 | Result := MH_2.GetHookPtrList;
90 | end;
91 |
92 | procedure BeginMemoryHook_3;
93 | begin
94 | MH_3.BeginMemoryHook($FFFF);
95 | end;
96 |
97 | procedure EndMemoryHook_3;
98 | begin
99 | MH_3.EndMemoryHook;
100 | end;
101 |
102 | function GetHookMemorySize_3: nativeUInt;
103 | begin
104 | Result := MH_3.GetHookMemorySize;
105 | end;
106 |
107 | function GetHookPtrList_3: TPointerHashNativeUIntList;
108 | begin
109 | Result := MH_3.GetHookPtrList;
110 | end;
111 |
112 | var
113 | MHStatusCritical: TCriticalSection;
114 | OriginDoStatusHook: TDoStatusCall;
115 |
116 | procedure InternalDoStatus(Text: SystemString; const ID: Integer);
117 | var
118 | hook_state_bak: Boolean;
119 | begin
120 | hook_state_bak := GlobalMemoryHook.V;
121 | GlobalMemoryHook.V := False;
122 | MHStatusCritical.Acquire;
123 | try
124 | OriginDoStatusHook(Text, ID);
125 | finally
126 | MHStatusCritical.Release;
127 | GlobalMemoryHook.V := hook_state_bak;
128 | end;
129 | end;
130 |
131 | initialization
132 |
133 | MHStatusCritical := TCriticalSection.Create;
134 | OriginDoStatusHook := OnDoStatusHook;
135 | OnDoStatusHook := {$IFDEF FPC}@{$ENDIF FPC}InternalDoStatus;
136 |
137 | finalization
138 |
139 | DisposeObject(MHStatusCritical);
140 | OnDoStatusHook := OriginDoStatusHook;
141 |
142 | end.
143 |
--------------------------------------------------------------------------------
/Source/MH_1.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Low MemoryHook written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | (*
21 | update history
22 | 2017-12-31
23 | *)
24 |
25 | unit MH_1;
26 |
27 | {$INCLUDE zDefine.inc}
28 |
29 | interface
30 |
31 | uses ListEngine, CoreClasses;
32 |
33 | procedure BeginMemoryHook; overload;
34 | procedure BeginMemoryHook(cacheLen: Integer); overload;
35 | procedure EndMemoryHook;
36 | function GetHookMemorySize: nativeUInt; overload;
37 | function GetHookMemorySize(p: Pointer): nativeUInt; overload;
38 | function GetHookMemoryMinimizePtr: Pointer;
39 | function GetHookMemoryMaximumPtr: Pointer;
40 | function GetHookPtrList: TPointerHashNativeUIntList;
41 | function GetMemoryHooked: TAtomBool;
42 |
43 | implementation
44 |
45 | var
46 | HookPtrList: TPointerHashNativeUIntList;
47 | MemoryHooked: TAtomBool;
48 |
49 | {$IFDEF FPC}
50 | {$INCLUDE MH_fpc.inc}
51 | {$ELSE}
52 | {$INCLUDE MH_delphi.inc}
53 | {$ENDIF}
54 |
55 |
56 | initialization
57 |
58 | InstallMemoryHook;
59 |
60 | finalization
61 |
62 | UnInstallMemoryHook;
63 |
64 | end.
65 |
--------------------------------------------------------------------------------
/Source/MH_2.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Low MemoryHook written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | (*
21 | update history
22 | 2017-12-31
23 | *)
24 |
25 | unit MH_2;
26 |
27 | {$INCLUDE zDefine.inc}
28 |
29 | interface
30 |
31 | uses ListEngine, CoreClasses;
32 |
33 | procedure BeginMemoryHook; overload;
34 | procedure BeginMemoryHook(cacheLen: Integer); overload;
35 | procedure EndMemoryHook;
36 | function GetHookMemorySize: nativeUInt; overload;
37 | function GetHookMemorySize(p: Pointer): nativeUInt; overload;
38 | function GetHookMemoryMinimizePtr: Pointer;
39 | function GetHookMemoryMaximumPtr: Pointer;
40 | function GetHookPtrList: TPointerHashNativeUIntList;
41 | function GetMemoryHooked: TAtomBool;
42 |
43 | implementation
44 |
45 | var
46 | HookPtrList: TPointerHashNativeUIntList;
47 | MemoryHooked: TAtomBool;
48 |
49 | {$IFDEF FPC}
50 | {$INCLUDE MH_fpc.inc}
51 | {$ELSE}
52 | {$INCLUDE MH_delphi.inc}
53 | {$ENDIF}
54 |
55 | initialization
56 |
57 | InstallMemoryHook;
58 |
59 | finalization
60 |
61 | UnInstallMemoryHook;
62 |
63 | end.
64 |
--------------------------------------------------------------------------------
/Source/MH_3.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Low MemoryHook written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | (*
21 | update history
22 | 2017-12-31
23 | *)
24 |
25 | unit MH_3;
26 |
27 | {$INCLUDE zDefine.inc}
28 |
29 | interface
30 |
31 | uses ListEngine, CoreClasses;
32 |
33 | procedure BeginMemoryHook; overload;
34 | procedure BeginMemoryHook(cacheLen: Integer); overload;
35 | procedure EndMemoryHook;
36 | function GetHookMemorySize: nativeUInt; overload;
37 | function GetHookMemorySize(p: Pointer): nativeUInt; overload;
38 | function GetHookMemoryMinimizePtr: Pointer;
39 | function GetHookMemoryMaximumPtr: Pointer;
40 | function GetHookPtrList: TPointerHashNativeUIntList;
41 | function GetMemoryHooked: TAtomBool;
42 |
43 | implementation
44 |
45 | var
46 | HookPtrList: TPointerHashNativeUIntList;
47 | MemoryHooked: TAtomBool;
48 |
49 | {$IFDEF FPC}
50 | {$INCLUDE MH_fpc.inc}
51 | {$ELSE}
52 | {$INCLUDE MH_delphi.inc}
53 | {$ENDIF}
54 |
55 | initialization
56 |
57 | InstallMemoryHook;
58 |
59 | finalization
60 |
61 | UnInstallMemoryHook;
62 |
63 | end.
64 |
--------------------------------------------------------------------------------
/Source/MH_ZDB.pas:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * Low MemoryHook written by QQ 600585@qq.com * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | (*
21 | update history
22 | 2017-12-31
23 | *)
24 |
25 | unit MH_ZDB;
26 |
27 | {$INCLUDE zDefine.inc}
28 |
29 | interface
30 |
31 | uses ListEngine, CoreClasses;
32 |
33 | procedure BeginMemoryHook; overload;
34 | procedure BeginMemoryHook(cacheLen: Integer); overload;
35 | procedure EndMemoryHook;
36 | function GetHookMemorySize: nativeUInt; overload;
37 | function GetHookMemorySize(p: Pointer): nativeUInt; overload;
38 | function GetHookMemoryMinimizePtr: Pointer;
39 | function GetHookMemoryMaximumPtr: Pointer;
40 | function GetHookPtrList: TPointerHashNativeUIntList;
41 | function GetMemoryHooked: TAtomBool;
42 |
43 | implementation
44 |
45 | var
46 | HookPtrList: TPointerHashNativeUIntList;
47 | MemoryHooked: TAtomBool;
48 |
49 | {$IFDEF FPC}
50 | {$INCLUDE MH_fpc.inc}
51 | {$ELSE}
52 | {$INCLUDE MH_delphi.inc}
53 | {$ENDIF}
54 |
55 | initialization
56 |
57 | InstallMemoryHook;
58 |
59 | finalization
60 |
61 | UnInstallMemoryHook;
62 |
63 | end.
64 |
--------------------------------------------------------------------------------
/Source/MH_delphi.inc:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * https://zpascal.net * }
3 | { * https://github.com/PassByYou888/zAI * }
4 | { * https://github.com/PassByYou888/ZServer4D * }
5 | { * https://github.com/PassByYou888/PascalString * }
6 | { * https://github.com/PassByYou888/zRasterization * }
7 | { * https://github.com/PassByYou888/CoreCipher * }
8 | { * https://github.com/PassByYou888/zSound * }
9 | { * https://github.com/PassByYou888/zChinese * }
10 | { * https://github.com/PassByYou888/zExpression * }
11 | { * https://github.com/PassByYou888/zGameWare * }
12 | { * https://github.com/PassByYou888/zAnalysis * }
13 | { * https://github.com/PassByYou888/FFMPEG-Header * }
14 | { * https://github.com/PassByYou888/zTranslate * }
15 | { * https://github.com/PassByYou888/InfiniteIoT * }
16 | { * https://github.com/PassByYou888/FastMD5 * }
17 | { ****************************************************************************** }
18 | type
19 | MPtrUInt = nativeUInt;
20 | MPtr = Pointer;
21 | PMPtrUInt = ^MPtrUInt;
22 |
23 | var
24 | OriginMM: TMemoryManagerEx;
25 | HookMM: TMemoryManagerEx;
26 | CurrentHookThread: TCoreClassThread;
27 |
28 | procedure BeginMemoryHook;
29 | begin
30 | if (MemoryHooked.V) or (CurrentHookThread <> nil) then
31 | RaiseInfo('illegal BeginMemoryHook');
32 |
33 | CurrentHookThread := TCoreClassThread.CurrentThread;
34 | HookPtrList.FastClear;
35 | MemoryHooked.V := True;
36 | end;
37 |
38 | procedure BeginMemoryHook(cacheLen: Integer);
39 | begin
40 | if (MemoryHooked.V) or (CurrentHookThread <> nil) then
41 | RaiseInfo('illegal BeginMemoryHook');
42 |
43 | CurrentHookThread := TCoreClassThread.CurrentThread;
44 | if length(HookPtrList.ListBuffer^) <> cacheLen then
45 | HookPtrList.SetHashBlockCount(cacheLen)
46 | else
47 | HookPtrList.FastClear;
48 |
49 | MemoryHooked.V := True;
50 | end;
51 |
52 | procedure EndMemoryHook;
53 | begin
54 | if not MemoryHooked.V then
55 | RaiseInfo('illegal EndMemoryHook');
56 |
57 | MemoryHooked.V := False;
58 | CurrentHookThread := nil;
59 | end;
60 |
61 | function GetHookMemorySize: nativeUInt;
62 | begin
63 | Result := HookPtrList.Total;
64 | end;
65 |
66 | function GetHookMemorySize(p: Pointer): nativeUInt;
67 | begin
68 | Result := HookPtrList[p];
69 | end;
70 |
71 | function GetHookMemoryMinimizePtr: Pointer;
72 | begin
73 | Result := HookPtrList.MinimizePtr;
74 | end;
75 |
76 | function GetHookMemoryMaximumPtr: Pointer;
77 | begin
78 | Result := HookPtrList.MaximumPtr;
79 | end;
80 |
81 | function GetHookPtrList: TPointerHashNativeUIntList;
82 | begin
83 | Result := HookPtrList;
84 | end;
85 |
86 | function GetMemoryHooked: TAtomBool;
87 | begin
88 | Result := MemoryHooked;
89 | end;
90 |
91 | function Hash_GetMem(Size: NativeInt): MPtr;
92 | begin
93 | Result := OriginMM.GetMem(DeltaStep(Size, C_MH_MemoryDelta));
94 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (Result = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
95 | Exit;
96 | MemoryHooked.V := False;
97 | GlobalMemoryHook.V := False;
98 | HookPtrList.Add(Result, Size, False);
99 | MemoryHooked.V := True;
100 | GlobalMemoryHook.V := True;
101 | end;
102 |
103 | function Hash_FreeMem(p: MPtr): Integer;
104 | begin
105 | Result := OriginMM.FreeMem(p);
106 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (p = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
107 | Exit;
108 | MemoryHooked.V := False;
109 | GlobalMemoryHook.V := False;
110 | HookPtrList.Delete(p);
111 | MemoryHooked.V := True;
112 | GlobalMemoryHook.V := True;
113 | end;
114 |
115 | function Hash_ReallocMem(p: MPtr; Size: NativeInt): MPtr;
116 | begin
117 | Result := OriginMM.ReallocMem(p, DeltaStep(Size, C_MH_MemoryDelta));
118 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
119 | Exit;
120 | MemoryHooked.V := False;
121 | GlobalMemoryHook.V := False;
122 | if p <> nil then
123 | begin
124 | if HookPtrList.Delete(p) then
125 | if Result <> nil then
126 | HookPtrList.Add(Result, Size, False);
127 | end
128 | else if Result <> nil then
129 | HookPtrList.Add(Result, Size, False);
130 | MemoryHooked.V := True;
131 | GlobalMemoryHook.V := True;
132 | end;
133 |
134 | function Hash_AllocMem(Size: NativeInt): MPtr;
135 | begin
136 | Result := OriginMM.AllocMem(DeltaStep(Size, C_MH_MemoryDelta));
137 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (Result = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
138 | Exit;
139 | MemoryHooked.V := False;
140 | GlobalMemoryHook.V := False;
141 | HookPtrList.Add(Result, Size, False);
142 | MemoryHooked.V := True;
143 | GlobalMemoryHook.V := True;
144 | end;
145 |
146 | procedure InstallMemoryHook;
147 | begin
148 | HookPtrList := TPointerHashNativeUIntList.CustomCreate(32);
149 | CurrentHookThread := nil;
150 |
151 | GetMemoryManager(OriginMM);
152 | HookMM := OriginMM;
153 |
154 | MemoryHooked := TAtomBool.Create(False);
155 |
156 | HookMM.GetMem := Hash_GetMem;
157 | HookMM.FreeMem := Hash_FreeMem;
158 | HookMM.ReallocMem := Hash_ReallocMem;
159 | HookMM.AllocMem := Hash_AllocMem;
160 |
161 | SetMemoryManager(HookMM);
162 | end;
163 |
164 | procedure UnInstallMemoryHook;
165 | begin
166 | SetMemoryManager(OriginMM);
167 | DisposeObject(HookPtrList);
168 | MemoryHooked.Free;
169 | MemoryHooked := nil;
170 | end;
171 |
--------------------------------------------------------------------------------
/Source/MH_fpc.inc:
--------------------------------------------------------------------------------
1 | { * https://zpascal.net * }
2 | { * https://github.com/PassByYou888/zAI * }
3 | { * https://github.com/PassByYou888/ZServer4D * }
4 | { * https://github.com/PassByYou888/PascalString * }
5 | { * https://github.com/PassByYou888/zRasterization * }
6 | { * https://github.com/PassByYou888/CoreCipher * }
7 | { * https://github.com/PassByYou888/zSound * }
8 | { * https://github.com/PassByYou888/zChinese * }
9 | { * https://github.com/PassByYou888/zExpression * }
10 | { * https://github.com/PassByYou888/zGameWare * }
11 | { * https://github.com/PassByYou888/zAnalysis * }
12 | { * https://github.com/PassByYou888/FFMPEG-Header * }
13 | { * https://github.com/PassByYou888/zTranslate * }
14 | { * https://github.com/PassByYou888/InfiniteIoT * }
15 | { * https://github.com/PassByYou888/FastMD5 * }
16 | { ****************************************************************************** }
17 |
18 | type
19 | MPtrUInt = ptruint;
20 | MPtr = Pointer;
21 | PMPtrUInt = ^MPtrUInt;
22 |
23 | var
24 | OriginMM: TMemoryManager;
25 | HookMM: TMemoryManager;
26 | CurrentHookThread: TCoreClassThread;
27 |
28 | procedure BeginMemoryHook;
29 | begin
30 | if (MemoryHooked.V) or (CurrentHookThread <> nil) then
31 | RaiseInfo('illegal BeginMemoryHook');
32 |
33 | CurrentHookThread := TCoreClassThread.CurrentThread;
34 | HookPtrList.FastClear;
35 | MemoryHooked.V := True;
36 | end;
37 |
38 | procedure BeginMemoryHook(cacheLen: Integer);
39 | begin
40 | if (MemoryHooked.V) or (CurrentHookThread <> nil) then
41 | RaiseInfo('illegal BeginMemoryHook');
42 |
43 | CurrentHookThread := TCoreClassThread.CurrentThread;
44 | if length(HookPtrList.ListBuffer^) <> cacheLen then
45 | HookPtrList.SetHashBlockCount(cacheLen)
46 | else
47 | HookPtrList.FastClear;
48 |
49 | MemoryHooked.V := True;
50 | end;
51 |
52 | procedure EndMemoryHook;
53 | begin
54 | if not MemoryHooked.V then
55 | RaiseInfo('illegal EndMemoryHook');
56 |
57 | MemoryHooked.V := False;
58 | CurrentHookThread := nil;
59 | end;
60 |
61 | function GetHookMemorySize: nativeUInt;
62 | begin
63 | Result := HookPtrList.Total;
64 | end;
65 |
66 | function GetHookMemorySize(p: Pointer): nativeUInt;
67 | begin
68 | Result := HookPtrList[p];
69 | end;
70 |
71 | function GetHookMemoryMinimizePtr: Pointer;
72 | begin
73 | Result := HookPtrList.MinimizePtr;
74 | end;
75 |
76 | function GetHookMemoryMaximumPtr: Pointer;
77 | begin
78 | Result := HookPtrList.MaximumPtr;
79 | end;
80 |
81 | function GetHookPtrList: TPointerHashNativeUIntList;
82 | begin
83 | Result := HookPtrList;
84 | end;
85 |
86 | function GetMemoryHooked: TAtomBool;
87 | begin
88 | Result := MemoryHooked;
89 | end;
90 |
91 | function Hash_GetMem(Size: ptruint): Pointer;
92 | begin
93 | Result := OriginMM.GetMem(DeltaStep(Size, C_MH_MemoryDelta));
94 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (Result = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
95 | Exit;
96 | MemoryHooked.V := False;
97 | GlobalMemoryHook.V := False;
98 | HookPtrList.Add(Result, Size, False);
99 | MemoryHooked.V := True;
100 | GlobalMemoryHook.V := True;
101 | end;
102 |
103 | function Hash_FreeMem(p: Pointer): ptruint;
104 | begin
105 | Result := OriginMM.FreeMem(p);
106 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (p = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
107 | Exit;
108 | MemoryHooked.V := False;
109 | GlobalMemoryHook.V := False;
110 | HookPtrList.Delete(p);
111 | MemoryHooked.V := True;
112 | GlobalMemoryHook.V := True;
113 | end;
114 |
115 | function Hash_FreememSize(p: Pointer; Size: ptruint): ptruint;
116 | begin
117 | Result := OriginMM.FreememSize(p, DeltaStep(Size, C_MH_MemoryDelta));
118 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (p = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
119 | Exit;
120 | MemoryHooked.V := False;
121 | GlobalMemoryHook.V := False;
122 | HookPtrList.Delete(p);
123 | MemoryHooked.V := True;
124 | GlobalMemoryHook.V := True;
125 | end;
126 |
127 | function Hash_AllocMem(Size: ptruint): Pointer;
128 | begin
129 | Result := OriginMM.AllocMem(DeltaStep(Size, C_MH_MemoryDelta));
130 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (Result = nil) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
131 | Exit;
132 | MemoryHooked.V := False;
133 | GlobalMemoryHook.V := False;
134 | HookPtrList.Add(Result, Size, True);
135 | MemoryHooked.V := True;
136 | GlobalMemoryHook.V := True;
137 | end;
138 |
139 | function Hash_ReallocMem(var p: Pointer; Size: ptruint): Pointer;
140 | begin
141 | Result := OriginMM.ReallocMem(p, DeltaStep(Size, C_MH_MemoryDelta));
142 | if (not MemoryHooked.V) or (not GlobalMemoryHook.V) or (CurrentHookThread <> TCoreClassThread.CurrentThread) then
143 | Exit;
144 | MemoryHooked.V := False;
145 | GlobalMemoryHook.V := False;
146 | if p <> nil then
147 | begin
148 | if HookPtrList.Delete(p) then
149 | if Result <> nil then
150 | HookPtrList.Add(Result, Size, False);
151 | end
152 | else if Result <> nil then
153 | HookPtrList.Add(Result, Size, False);
154 | MemoryHooked.V := True;
155 | GlobalMemoryHook.V := True;
156 | end;
157 |
158 | procedure InstallMemoryHook;
159 | begin
160 | HookPtrList := TPointerHashNativeUIntList.CustomCreate(32);
161 | CurrentHookThread := nil;
162 |
163 | GetMemoryManager(OriginMM);
164 | HookMM := OriginMM;
165 |
166 | MemoryHooked := TAtomBool.Create(False);
167 |
168 | HookMM.GetMem := @Hash_GetMem;
169 | HookMM.FreeMem := @Hash_FreeMem;
170 | HookMM.FreememSize := @Hash_FreememSize;
171 | HookMM.AllocMem := @Hash_AllocMem;
172 | HookMM.ReallocMem := @Hash_ReallocMem;
173 |
174 | SetMemoryManager(HookMM);
175 | end;
176 |
177 | procedure UnInstallMemoryHook;
178 | begin
179 | SetMemoryManager(OriginMM);
180 | DisposeObject(HookPtrList);
181 | MemoryHooked.Free;
182 | MemoryHooked := nil;
183 | end;
184 |
--------------------------------------------------------------------------------
/Source/ZJson_delphi.inc:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * json object library for delphi/objfpc * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 |
20 | procedure TZ_JsonArray.Clear;
21 | begin
22 | FInstance.Clear;
23 | end;
24 |
25 | procedure TZ_JsonArray.Delete(Index: Integer);
26 | begin
27 | FInstance.Delete(index);
28 | end;
29 |
30 | procedure TZ_JsonArray.Add(const v_: string);
31 | begin
32 | FInstance.Add(v_);
33 | end;
34 |
35 | procedure TZ_JsonArray.Add(const v_: TPascalString);
36 | begin
37 | FInstance.Add(v_.Text);
38 | end;
39 |
40 | procedure TZ_JsonArray.Add(const v_: Integer);
41 | begin
42 | FInstance.Add(v_);
43 | end;
44 |
45 | procedure TZ_JsonArray.Add(const v_: Int64);
46 | begin
47 | FInstance.Add(v_);
48 | end;
49 |
50 | procedure TZ_JsonArray.Add(const v_: UInt64);
51 | begin
52 | FInstance.Add(v_);
53 | end;
54 |
55 | procedure TZ_JsonArray.AddF(const v_: Double);
56 | begin
57 | FInstance.Add(v_);
58 | end;
59 |
60 | procedure TZ_JsonArray.Add(const v_: TDateTime);
61 | begin
62 | FInstance.Add(umlDateTimeToStr(v_).Text);
63 | end;
64 |
65 | procedure TZ_JsonArray.Add(const v_: Boolean);
66 | begin
67 | FInstance.Add(v_);
68 | end;
69 |
70 | function TZ_JsonArray.AddArray: TZ_JsonArray;
71 | begin
72 | Result := TZ_JsonArray.Create(self);
73 | Result.FInstance := FInstance.AddArray;
74 | end;
75 |
76 | function TZ_JsonArray.AddObject: TZ_JsonObject;
77 | begin
78 | Result := TZ_JsonObject.Create(self);
79 | Result.FInstance := FInstance.AddObject;
80 | end;
81 |
82 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: string);
83 | begin
84 | FInstance.Insert(index, v_);
85 | end;
86 |
87 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Integer);
88 | begin
89 | FInstance.Insert(index, v_);
90 | end;
91 |
92 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Int64);
93 | begin
94 | FInstance.Insert(index, v_);
95 | end;
96 |
97 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: UInt64);
98 | begin
99 | FInstance.Insert(index, v_);
100 | end;
101 |
102 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Double);
103 | begin
104 | FInstance.Insert(index, v_);
105 | end;
106 |
107 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: TDateTime);
108 | begin
109 | FInstance.Insert(index, umlDateTimeToStr(v_).Text);
110 | end;
111 |
112 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Boolean);
113 | begin
114 | FInstance.Insert(index, v_);
115 | end;
116 |
117 | function TZ_JsonArray.InsertArray(Index: Integer): TZ_JsonArray;
118 | begin
119 | Result := TZ_JsonArray.Create(self);
120 | Result.FInstance := FInstance.InsertArray(index);
121 | end;
122 |
123 | function TZ_JsonArray.InsertObject(Index: Integer): TZ_JsonObject;
124 | begin
125 | Result := TZ_JsonObject.Create(self);
126 | Result.FInstance := FInstance.InsertObject(index);
127 | end;
128 |
129 | function TZ_JsonArray.GetString(Index: Integer): string;
130 | begin
131 | Result := FInstance.S[index];
132 | end;
133 |
134 | procedure TZ_JsonArray.SetString(Index: Integer; const Value: string);
135 | begin
136 | FInstance.S[index] := Value;
137 | end;
138 |
139 | function TZ_JsonArray.GetInt(Index: Integer): Integer;
140 | begin
141 | Result := FInstance.I[index];
142 | end;
143 |
144 | procedure TZ_JsonArray.SetInt(Index: Integer; const Value: Integer);
145 | begin
146 | FInstance.I[index] := Value;
147 | end;
148 |
149 | function TZ_JsonArray.GetLong(Index: Integer): Int64;
150 | begin
151 | Result := FInstance.I64[index];
152 | end;
153 |
154 | procedure TZ_JsonArray.SetLong(Index: Integer; const Value: Int64);
155 | begin
156 | FInstance.I64[index] := Value;
157 | end;
158 |
159 | function TZ_JsonArray.GetULong(Index: Integer): UInt64;
160 | begin
161 | Result := FInstance.U64[index];
162 | end;
163 |
164 | procedure TZ_JsonArray.SetULong(Index: Integer; const Value: UInt64);
165 | begin
166 | FInstance.U64[index] := Value;
167 | end;
168 |
169 | function TZ_JsonArray.GetFloat(Index: Integer): Double;
170 | begin
171 | Result := FInstance.F[index];
172 | end;
173 |
174 | procedure TZ_JsonArray.SetFloat(Index: Integer; const Value: Double);
175 | begin
176 | FInstance.F[index] := Value;
177 | end;
178 |
179 | function TZ_JsonArray.GetDateTime(Index: Integer): TDateTime;
180 | begin
181 | Result := umlStrToDateTime(FInstance.S[index]);
182 | end;
183 |
184 | procedure TZ_JsonArray.SetDateTime(Index: Integer; const Value: TDateTime);
185 | begin
186 | FInstance.S[index] := umlDateTimeToStr(Value).Text;
187 | end;
188 |
189 | function TZ_JsonArray.GetBool(Index: Integer): Boolean;
190 | begin
191 | Result := FInstance.B[index];
192 | end;
193 |
194 | procedure TZ_JsonArray.SetBool(Index: Integer; const Value: Boolean);
195 | begin
196 | FInstance.B[index] := Value;
197 | end;
198 |
199 | function TZ_JsonArray.GetArray(Index: Integer): TZ_JsonArray;
200 | var
201 | arry: TZ_Instance_JsonArray;
202 | j: Integer;
203 | begin
204 | arry := FInstance.A[index];
205 | for j := FList.Count - 1 downto 0 do
206 | if (FList[j] is TZ_JsonArray) and (TZ_JsonArray(FList[j]).FInstance = arry) then
207 | begin
208 | Result := TZ_JsonArray(FList[j]);
209 | exit;
210 | end;
211 | Result := TZ_JsonArray.Create(self);
212 | Result.FInstance := arry;
213 | end;
214 |
215 | function TZ_JsonArray.GetObject(Index: Integer): TZ_JsonObject;
216 | var
217 | Obj_: TZ_Instance_JsonObject;
218 | j: Integer;
219 | begin
220 | Obj_ := FInstance.O[Index];
221 | for j := FList.Count - 1 downto 0 do
222 | if (FList[j] is TZ_JsonObject) and (TZ_JsonObject(FList[j]).FInstance = Obj_) then
223 | begin
224 | Result := TZ_JsonObject(FList[j]);
225 | exit;
226 | end;
227 | Result := TZ_JsonObject.Create(self);
228 | Result.FInstance := Obj_;
229 | end;
230 |
231 | function TZ_JsonArray.GetCount: Integer;
232 | begin
233 | Result := FInstance.Count;
234 | end;
235 |
236 | procedure TZ_JsonObject.Clear;
237 | begin
238 | FInstance.Clear;
239 | end;
240 |
241 | function TZ_JsonObject.IndexOf(const Name: string): Integer;
242 | begin
243 | Result := FInstance.IndexOf(Name);
244 | end;
245 |
246 | function TZ_JsonObject.GetString(const Name: string): string;
247 | begin
248 | Result := FInstance.S[Name];
249 | end;
250 |
251 | procedure TZ_JsonObject.SetString(const Name, Value: string);
252 | begin
253 | FInstance.S[Name] := Value;
254 | end;
255 |
256 | function TZ_JsonObject.GetInt(const Name: string): Integer;
257 | begin
258 | Result := FInstance.I[Name];
259 | end;
260 |
261 | procedure TZ_JsonObject.SetInt(const Name: string; const Value: Integer);
262 | begin
263 | FInstance.I[Name] := Value;
264 | end;
265 |
266 | function TZ_JsonObject.GetLong(const Name: string): Int64;
267 | begin
268 | Result := FInstance.I64[Name];
269 | end;
270 |
271 | procedure TZ_JsonObject.SetLong(const Name: string; const Value: Int64);
272 | begin
273 | FInstance.I64[Name] := Value;
274 | end;
275 |
276 | function TZ_JsonObject.GetULong(const Name: string): UInt64;
277 | begin
278 | Result := FInstance.U[Name];
279 | end;
280 |
281 | procedure TZ_JsonObject.SetULong(const Name: string; const Value: UInt64);
282 | begin
283 | FInstance.U[Name] := Value;
284 | end;
285 |
286 | function TZ_JsonObject.GetFloat(const Name: string): Double;
287 | begin
288 | Result := FInstance.F[Name];
289 | end;
290 |
291 | procedure TZ_JsonObject.SetFloat(const Name: string; const Value: Double);
292 | begin
293 | FInstance.F[Name] := Value;
294 | end;
295 |
296 | function TZ_JsonObject.GetDateTime(const Name: string): TDateTime;
297 | begin
298 | Result := umlStrToDateTime(FInstance.S[Name]);
299 | end;
300 |
301 | procedure TZ_JsonObject.SetDateTime(const Name: string; const Value: TDateTime);
302 | begin
303 | FInstance.S[Name] := umlDateTimeToStr(Value).Text;
304 | end;
305 |
306 | function TZ_JsonObject.GetBool(const Name: string): Boolean;
307 | begin
308 | Result := FInstance.B[Name];
309 | end;
310 |
311 | procedure TZ_JsonObject.SetBool(const Name: string; const Value: Boolean);
312 | begin
313 | FInstance.B[Name] := Value;
314 | end;
315 |
316 | function TZ_JsonObject.GetArray(const Name: string): TZ_JsonArray;
317 | var
318 | arry: TZ_Instance_JsonArray;
319 | j: Integer;
320 | begin
321 | arry := FInstance.A[Name];
322 | for j := FList.Count - 1 downto 0 do
323 | if (FList[j] is TZ_JsonArray) and (TZ_JsonArray(FList[j]).FInstance = arry) then
324 | begin
325 | Result := TZ_JsonArray(FList[j]);
326 | exit;
327 | end;
328 | Result := TZ_JsonArray.Create(self);
329 | Result.FInstance := arry;
330 | end;
331 |
332 | function TZ_JsonObject.GetObject(const Name: string): TZ_JsonObject;
333 | var
334 | Obj_: TZ_Instance_JsonObject;
335 | j: Integer;
336 | begin
337 | Obj_ := FInstance.O[Name];
338 | for j := FList.Count - 1 downto 0 do
339 | if (FList[j] is TZ_JsonObject) and (TZ_JsonObject(FList[j]).FInstance = Obj_) then
340 | begin
341 | Result := TZ_JsonObject(FList[j]);
342 | exit;
343 | end;
344 | Result := TZ_JsonObject.Create(self);
345 | Result.FInstance := Obj_;
346 | end;
347 |
348 | function TZ_JsonObject.GetName(Index: Integer): string;
349 | begin
350 | Result := FInstance.Names[Index];
351 | end;
352 |
353 | function TZ_JsonObject.GetCount: Integer;
354 | begin
355 | Result := FInstance.Count;
356 | end;
357 |
358 | procedure TZ_JsonObject.SaveToStream(stream: TCoreClassStream; Formated_: Boolean);
359 | begin
360 | FInstance.SaveToStream(stream, not Formated_, TEncoding.UTF8, True);
361 | end;
362 |
363 | procedure TZ_JsonObject.LoadFromStream(stream: TCoreClassStream);
364 | begin
365 | FInstance.LoadFromStream(stream, TEncoding.UTF8, True);
366 | end;
367 |
--------------------------------------------------------------------------------
/Source/ZJson_fpc.inc:
--------------------------------------------------------------------------------
1 | { ****************************************************************************** }
2 | { * json object library for delphi/objfpc * }
3 | { * https://zpascal.net * }
4 | { * https://github.com/PassByYou888/zAI * }
5 | { * https://github.com/PassByYou888/ZServer4D * }
6 | { * https://github.com/PassByYou888/PascalString * }
7 | { * https://github.com/PassByYou888/zRasterization * }
8 | { * https://github.com/PassByYou888/CoreCipher * }
9 | { * https://github.com/PassByYou888/zSound * }
10 | { * https://github.com/PassByYou888/zChinese * }
11 | { * https://github.com/PassByYou888/zExpression * }
12 | { * https://github.com/PassByYou888/zGameWare * }
13 | { * https://github.com/PassByYou888/zAnalysis * }
14 | { * https://github.com/PassByYou888/FFMPEG-Header * }
15 | { * https://github.com/PassByYou888/zTranslate * }
16 | { * https://github.com/PassByYou888/InfiniteIoT * }
17 | { * https://github.com/PassByYou888/FastMD5 * }
18 | { ****************************************************************************** }
19 | procedure TZ_JsonArray.Clear;
20 | begin
21 | FInstance.Clear;
22 | end;
23 |
24 | procedure TZ_JsonArray.Delete(Index: Integer);
25 | begin
26 | FInstance.Delete(index);
27 | end;
28 |
29 | procedure TZ_JsonArray.Add(const v_: string);
30 | begin
31 | FInstance.Add(v_);
32 | end;
33 |
34 | procedure TZ_JsonArray.Add(const v_: TPascalString);
35 | begin
36 | FInstance.Add(v_.Text);
37 | end;
38 |
39 | procedure TZ_JsonArray.Add(const v_: Integer);
40 | begin
41 | FInstance.Add(v_);
42 | end;
43 |
44 | procedure TZ_JsonArray.Add(const v_: Int64);
45 | begin
46 | FInstance.Add(v_);
47 | end;
48 |
49 | procedure TZ_JsonArray.Add(const v_: UInt64);
50 | begin
51 | FInstance.Add(v_);
52 | end;
53 |
54 | procedure TZ_JsonArray.AddF(const v_: Double);
55 | begin
56 | FInstance.Add(v_);
57 | end;
58 |
59 | procedure TZ_JsonArray.Add(const v_: TDateTime);
60 | begin
61 | FInstance.Add(umlDateTimeToStr(v_).Text);
62 | end;
63 |
64 | procedure TZ_JsonArray.Add(const v_: Boolean);
65 | begin
66 | FInstance.Add(v_);
67 | end;
68 |
69 | function TZ_JsonArray.AddArray: TZ_JsonArray;
70 | begin
71 | Result := TZ_JsonArray.Create(self);
72 | Result.FInstance := TZ_Instance_JsonArray.Create;
73 | FInstance.Add(Result.FInstance);
74 | end;
75 |
76 | function TZ_JsonArray.AddObject: TZ_JsonObject;
77 | begin
78 | Result := TZ_JsonObject.Create(self);
79 | Result.FInstance := TZ_Instance_JsonObject.Create;
80 | FInstance.Add(Result.FInstance);
81 | end;
82 |
83 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: string);
84 | begin
85 | FInstance.Insert(index, v_);
86 | end;
87 |
88 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Integer);
89 | begin
90 | FInstance.Insert(index, v_);
91 | end;
92 |
93 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Int64);
94 | begin
95 | FInstance.Insert(index, v_);
96 | end;
97 |
98 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: UInt64);
99 | begin
100 | FInstance.Insert(index, v_);
101 | end;
102 |
103 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Double);
104 | begin
105 | FInstance.Insert(index, v_);
106 | end;
107 |
108 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: TDateTime);
109 | begin
110 | FInstance.Insert(index, umlDateTimeToStr(v_).Text);
111 | end;
112 |
113 | procedure TZ_JsonArray.Insert(Index: Integer; const v_: Boolean);
114 | begin
115 | FInstance.Insert(index, v_);
116 | end;
117 |
118 | function TZ_JsonArray.InsertArray(Index: Integer): TZ_JsonArray;
119 | begin
120 | Result := TZ_JsonArray.Create(self);
121 | Result.FInstance := TZ_Instance_JsonArray.Create;
122 | FInstance.Insert(index, Result.FInstance);
123 | end;
124 |
125 | function TZ_JsonArray.InsertObject(Index: Integer): TZ_JsonObject;
126 | begin
127 | Result := TZ_JsonObject.Create(self);
128 | Result.FInstance := TZ_Instance_JsonObject.Create;
129 | FInstance.Insert(index, Result.FInstance);
130 | end;
131 |
132 | function TZ_JsonArray.GetString(Index: Integer): string;
133 | begin
134 | Result := FInstance.Strings[index];
135 | end;
136 |
137 | procedure TZ_JsonArray.SetString(Index: Integer; const Value: string);
138 | begin
139 | FInstance.Strings[index] := Value;
140 | end;
141 |
142 | function TZ_JsonArray.GetInt(Index: Integer): Integer;
143 | begin
144 | Result := FInstance.Integers[index];
145 | end;
146 |
147 | procedure TZ_JsonArray.SetInt(Index: Integer; const Value: Integer);
148 | begin
149 | FInstance.Integers[index] := Value;
150 | end;
151 |
152 | function TZ_JsonArray.GetLong(Index: Integer): Int64;
153 | begin
154 | Result := FInstance.Int64s[index];
155 | end;
156 |
157 | procedure TZ_JsonArray.SetLong(Index: Integer; const Value: Int64);
158 | begin
159 | FInstance.Int64s[index] := Value;
160 | end;
161 |
162 | function TZ_JsonArray.GetULong(Index: Integer): UInt64;
163 | begin
164 | Result := FInstance.QWords[index];
165 | end;
166 |
167 | procedure TZ_JsonArray.SetULong(Index: Integer; const Value: UInt64);
168 | begin
169 | FInstance.QWords[index] := Value;
170 | end;
171 |
172 | function TZ_JsonArray.GetFloat(Index: Integer): Double;
173 | begin
174 | Result := FInstance.Floats[index];
175 | end;
176 |
177 | procedure TZ_JsonArray.SetFloat(Index: Integer; const Value: Double);
178 | begin
179 | FInstance.Floats[index] := Value;
180 | end;
181 |
182 | function TZ_JsonArray.GetDateTime(Index: Integer): TDateTime;
183 | begin
184 | Result := umlStrToDateTime(FInstance.Strings[index]);
185 | end;
186 |
187 | procedure TZ_JsonArray.SetDateTime(Index: Integer; const Value: TDateTime);
188 | begin
189 | FInstance.Strings[index] := umlDateTimeToStr(Value).Text;
190 | end;
191 |
192 | function TZ_JsonArray.GetBool(Index: Integer): Boolean;
193 | begin
194 | Result := FInstance.Booleans[index];
195 | end;
196 |
197 | procedure TZ_JsonArray.SetBool(Index: Integer; const Value: Boolean);
198 | begin
199 | FInstance.Booleans[index] := Value;
200 | end;
201 |
202 | function TZ_JsonArray.GetArray(Index: Integer): TZ_JsonArray;
203 | var
204 | arry: TZ_Instance_JsonArray;
205 | j: Integer;
206 | begin
207 | arry := FInstance.Arrays[index];
208 | for j := FList.Count - 1 downto 0 do
209 | if (FList[j] is TZ_JsonArray) and (TZ_JsonArray(FList[j]).FInstance = arry) then
210 | begin
211 | Result := TZ_JsonArray(FList[j]);
212 | exit;
213 | end;
214 | Result := TZ_JsonArray.Create(self);
215 | Result.FInstance := arry;
216 | end;
217 |
218 | function TZ_JsonArray.GetObject(Index: Integer): TZ_JsonObject;
219 | var
220 | Obj_: TZ_Instance_JsonObject;
221 | j: Integer;
222 | begin
223 | Obj_ := FInstance.Objects[Index];
224 | for j := FList.Count - 1 downto 0 do
225 | if (FList[j] is TZ_JsonObject) and (TZ_JsonObject(FList[j]).FInstance = Obj_) then
226 | begin
227 | Result := TZ_JsonObject(FList[j]);
228 | exit;
229 | end;
230 | Result := TZ_JsonObject.Create(self);
231 | Result.FInstance := Obj_;
232 | end;
233 |
234 | function TZ_JsonArray.GetCount: Integer;
235 | begin
236 | Result := FInstance.Count;
237 | end;
238 |
239 | procedure TZ_JsonObject.Clear;
240 | begin
241 | FInstance.Clear;
242 | end;
243 |
244 | function TZ_JsonObject.IndexOf(const Name: string): Integer;
245 | begin
246 | Result := FInstance.IndexOfName(Name);
247 | end;
248 |
249 | function TZ_JsonObject.GetString(const Name: string): string;
250 | begin
251 | Result := FInstance.Strings[Name];
252 | end;
253 |
254 | procedure TZ_JsonObject.SetString(const Name, Value: string);
255 | begin
256 | FInstance.Strings[Name] := Value;
257 | end;
258 |
259 | function TZ_JsonObject.GetInt(const Name: string): Integer;
260 | begin
261 | Result := FInstance.Integers[Name];
262 | end;
263 |
264 | procedure TZ_JsonObject.SetInt(const Name: string; const Value: Integer);
265 | begin
266 | FInstance.Integers[Name] := Value;
267 | end;
268 |
269 | function TZ_JsonObject.GetLong(const Name: string): Int64;
270 | begin
271 | Result := FInstance.Int64s[Name];
272 | end;
273 |
274 | procedure TZ_JsonObject.SetLong(const Name: string; const Value: Int64);
275 | begin
276 | FInstance.Int64s[Name] := Value;
277 | end;
278 |
279 | function TZ_JsonObject.GetULong(const Name: string): UInt64;
280 | begin
281 | Result := FInstance.QWords[Name];
282 | end;
283 |
284 | procedure TZ_JsonObject.SetULong(const Name: string; const Value: UInt64);
285 | begin
286 | FInstance.QWords[Name] := Value;
287 | end;
288 |
289 | function TZ_JsonObject.GetFloat(const Name: string): Double;
290 | begin
291 | Result := FInstance.Floats[Name];
292 | end;
293 |
294 | procedure TZ_JsonObject.SetFloat(const Name: string; const Value: Double);
295 | begin
296 | FInstance.Floats[Name] := Value;
297 | end;
298 |
299 | function TZ_JsonObject.GetDateTime(const Name: string): TDateTime;
300 | begin
301 | Result := umlStrToDateTime(FInstance.Strings[Name]);
302 | end;
303 |
304 | procedure TZ_JsonObject.SetDateTime(const Name: string; const Value: TDateTime);
305 | begin
306 | FInstance.Strings[Name] := umlDateTimeToStr(Value).Text;
307 | end;
308 |
309 | function TZ_JsonObject.GetBool(const Name: string): Boolean;
310 | begin
311 | Result := FInstance.Booleans[Name];
312 | end;
313 |
314 | procedure TZ_JsonObject.SetBool(const Name: string; const Value: Boolean);
315 | begin
316 | FInstance.Booleans[Name] := Value;
317 | end;
318 |
319 | function TZ_JsonObject.GetArray(const Name: string): TZ_JsonArray;
320 | var
321 | arry: TZ_Instance_JsonArray;
322 | j: Integer;
323 | begin
324 | if FInstance.Find(Name, arry) then
325 | begin
326 | for j := FList.Count - 1 downto 0 do
327 | if (FList[j] is TZ_JsonArray) and (TZ_JsonArray(FList[j]).FInstance = arry) then
328 | begin
329 | Result := TZ_JsonArray(FList[j]);
330 | exit;
331 | end;
332 | end;
333 |
334 | arry := TZ_Instance_JsonArray.Create();
335 | FInstance.Arrays[Name] := arry;
336 | Result := TZ_JsonArray.Create(self);
337 | Result.FInstance := arry;
338 | end;
339 |
340 | function TZ_JsonObject.GetObject(const Name: string): TZ_JsonObject;
341 | var
342 | Obj_: TZ_Instance_JsonObject;
343 | j: Integer;
344 | begin
345 | if FInstance.Find(Name, Obj_) then
346 | begin
347 | for j := FList.Count - 1 downto 0 do
348 | if (FList[j] is TZ_JsonObject) and (TZ_JsonObject(FList[j]).FInstance = Obj_) then
349 | begin
350 | Result := TZ_JsonObject(FList[j]);
351 | exit;
352 | end;
353 | end;
354 |
355 | Obj_ := TZ_Instance_JsonObject.Create();
356 | FInstance.Objects[Name] := Obj_;
357 | Result := TZ_JsonObject.Create(self);
358 | Result.FInstance := Obj_;
359 | end;
360 |
361 | function TZ_JsonObject.GetName(Index: Integer): string;
362 | begin
363 | Result := FInstance.Names[index];
364 | end;
365 |
366 | function TZ_JsonObject.GetCount: Integer;
367 | begin
368 | Result := FInstance.Count;
369 | end;
370 |
371 | procedure TZ_JsonObject.SaveToStream(stream: TCoreClassStream; Formated_: Boolean);
372 | var
373 | s_: TPascalString;
374 | buff: TBytes;
375 | begin
376 | if Formated_ then
377 | s_.Text := FInstance.FormatJSON()
378 | else
379 | s_.Text := FInstance.AsJSON;
380 | buff := s_.Bytes;
381 | s_ := '';
382 | stream.Write(buff[0], length(buff));
383 | SetLength(buff, 0);
384 | end;
385 |
386 | procedure TZ_JsonObject.LoadFromStream(stream: TCoreClassStream);
387 | Var
388 | P: TJSONParser;
389 | j: TJSONData;
390 | begin
391 | DisposeObjectAndNil(FInstance);
392 | P := TJSONParser.Create(stream, [joUTF8]);
393 | try
394 | j := P.Parse;
395 | if j is TZ_Instance_JsonObject then
396 | FInstance := TZ_Instance_JsonObject(j)
397 | except
398 | end;
399 | FreeAndNil(P);
400 | end;
401 |
--------------------------------------------------------------------------------
/Source/clear_with_dcu.bat:
--------------------------------------------------------------------------------
1 | del/s *.dcu
2 | del/s *.o
3 | del/s *.ppu
4 | del/s *.rsm
5 | del/s *.replay
6 | del/s *.loginpackage
7 | del/s *.dres
8 | del/s *.local
9 | del/s *.identcache
10 | del/s *.stat
11 | del/s *.tvsconfig
12 | del/s *.deployproj
13 | del/s *.stat
14 | del/s *.delphilsp.json
15 | rem del/s *.pdb
16 | rem del/s *.exp
17 | rem del/s zAI\*.pdb
18 | rem del/s zAI\*.obj
19 | rem del/s zAI\*.lib
20 | rem del/s zAI\*.tlog
21 | rem del/s zAI\*.db
22 | rem rd/q/s zAI\AI_Build\cuda\dlib_build\dlib\Debug
23 | rem rd/q/s zAI\AI_Build\cuda\dlib_build\dlib\Release
24 | rem rd/q/s zAI\AI_Build\cuda\dlib_build\dlib\x64
25 | rem rd/q/s zAI\AI_Build\cuda\Debug
26 | rem rd/q/s zAI\AI_Build\cuda\Release
27 | rem rd/q/s zAI\AI_Build\cuda\x64
28 |
--------------------------------------------------------------------------------
/Source/md5_32.asm:
--------------------------------------------------------------------------------
1 | ;{ ****************************************************************************** }
2 | ;{ * https://zpascal.net * }
3 | ;{ * https://github.com/PassByYou888/zAI * }
4 | ;{ * https://github.com/PassByYou888/ZServer4D * }
5 | ;{ * https://github.com/PassByYou888/PascalString * }
6 | ;{ * https://github.com/PassByYou888/zRasterization * }
7 | ;{ * https://github.com/PassByYou888/CoreCipher * }
8 | ;{ * https://github.com/PassByYou888/zSound * }
9 | ;{ * https://github.com/PassByYou888/zChinese * }
10 | ;{ * https://github.com/PassByYou888/zExpression * }
11 | ;{ * https://github.com/PassByYou888/zGameWare * }
12 | ;{ * https://github.com/PassByYou888/zAnalysis * }
13 | ;{ * https://github.com/PassByYou888/FFMPEG-Header * }
14 | ;{ * https://github.com/PassByYou888/zTranslate * }
15 | ;{ * https://github.com/PassByYou888/InfiniteIoT * }
16 | ;{ * https://github.com/PassByYou888/FastMD5 * }
17 | ;{ ****************************************************************************** }
18 |
19 |
20 | ; MD5_386.Asm - 386 optimized helper routine for calculating
21 | ; MD Message-Digest values
22 | ; written 2/2/94 by
23 | ;
24 | ; Peter Sawatzki
25 | ; Buchenhof 3
26 | ; D58091 Hagen, Germany Fed Rep
27 | ;
28 | ; EMail: Peter@Sawatzki.de
29 | ; EMail: 100031.3002@compuserve.com
30 | ; WWW: http://www.sawatzki.de
31 | ;
32 | ;
33 | ; original C Source was found in Dr. Dobbs Journal Sep 91
34 | ; MD5 algorithm from RSA Data Security, Inc.
35 |
36 |
37 | ; This is a 32-bit version of MD5_Transform
38 | ; modifief by Maxim Masiutin for Borland 32-bit "register"
39 | ; calling convention. For more information on this calling convension, see
40 | ; https://en.wikipedia.org/wiki/X86_calling_conventions#Borland_register
41 |
42 | ; You can compile this code using Microsoft Macro Assembler
43 | ; ml.exe /c md5_32.asm
44 | ; or using Borland Turbo Assembler
45 | ; tasm32.exe /m md5_32.asm
46 |
47 | .386
48 | .MODEL FLAT
49 | .CODE
50 |
51 | FF Macro a,b,c,d,x,s,ac
52 | ; a:= ROL (a+x+ac + (b And c Or Not b And d), s) + b
53 | Add a, [EBp+(4*x)]
54 | Add a, ac
55 | Mov ESi, b
56 | Not ESi
57 | And ESi, d
58 | Mov EDi, c
59 | And EDi, b
60 | Or ESi, EDi
61 | Add a, ESi
62 | Rol a, s
63 | Add a, b
64 | EndM
65 |
66 | GG Macro a,b,c,d,x,s,ac
67 | ; a:= ROL (a+x+ac + (b And d Or c And Not d), s) + b
68 | Add a, [EBp+(4*x)]
69 | Add a, ac
70 | Mov ESi, d
71 | Not ESi
72 | And ESi, c
73 | Mov EDi, d
74 | And EDi, b
75 | Or ESi, EDi
76 | Add a, ESi
77 | Rol a, s
78 | Add a, b
79 | EndM
80 |
81 | HH Macro a,b,c,d,x,s,ac
82 | ; a:= ROL (a+x+ac + (b Xor c Xor d), s) + b
83 | Add a, [EBp+(4*x)]
84 | Add a, ac
85 | Mov ESi, d
86 | Xor ESi, c
87 | Xor ESi, b
88 | Add a, ESi
89 | Rol a, s
90 | Add a, b
91 | EndM
92 |
93 | II Macro a,b,c,d,x,s,ac
94 | ; a:= ROL (a+x+ac + (c Xor (b Or Not d)), s) + b
95 | Add a, [EBp+(4*x)]
96 | Add a, ac
97 | Mov ESi, d
98 | Not ESi
99 | Or ESi, b
100 | Xor ESi, c
101 | Add a, ESi
102 | Rol a, s
103 | Add a, b
104 | EndM
105 |
106 | MD5_Transform Proc
107 | Public MD5_Transform
108 |
109 | ; Use 32-bit Borland Register calling convention
110 | ; First Parameter in EAX
111 | ; Second Paramerter in EDX
112 |
113 | ; State buffer offset - in EAx
114 | ; Message offset - in EDx
115 |
116 | Push EBx
117 | Push ESi
118 | Push EDi
119 | Push EBp
120 |
121 | Mov EBp, EDx ; Now EBp holds Message offset
122 | Push EAx
123 | Mov EDx, [EAx+12]
124 | Mov ECx, [EAx+8]
125 | Mov EBx, [EAx+4]
126 | Mov EAx, [EAx]
127 |
128 | FF EAx,EBx,ECx,EDx, 0, 7, 0d76aa478h ; 1
129 | FF EDx,EAx,EBx,ECx, 1, 12, 0e8c7b756h ; 2
130 | FF ECx,EDx,EAx,EBx, 2, 17, 0242070dbh ; 3
131 | FF EBx,ECx,EDx,EAx, 3, 22, 0c1bdceeeh ; 4
132 | FF EAx,EBx,ECx,EDx, 4, 7, 0f57c0fafh ; 5
133 | FF EDx,EAx,EBx,ECx, 5, 12, 04787c62ah ; 6
134 | FF ECx,EDx,EAx,EBx, 6, 17, 0a8304613h ; 7
135 | FF EBx,ECx,EDx,EAx, 7, 22, 0fd469501h ; 8
136 | FF EAx,EBx,ECx,EDx, 8, 7, 0698098d8h ; 9
137 | FF EDx,EAx,EBx,ECx, 9, 12, 08b44f7afh ; 10
138 | FF ECx,EDx,EAx,EBx, 10, 17, 0ffff5bb1h ; 11
139 | FF EBx,ECx,EDx,EAx, 11, 22, 0895cd7beh ; 12
140 | FF EAx,EBx,ECx,EDx, 12, 7, 06b901122h ; 13
141 | FF EDx,EAx,EBx,ECx, 13, 12, 0fd987193h ; 14
142 | FF ECx,EDx,EAx,EBx, 14, 17, 0a679438eh ; 15
143 | FF EBx,ECx,EDx,EAx, 15, 22, 049b40821h ; 16
144 |
145 | GG EAx,EBx,ECx,EDx, 1, 5, 0f61e2562h ; 17
146 | GG EDx,EAx,EBx,ECx, 6, 9, 0c040b340h ; 18
147 | GG ECx,EDx,EAx,EBx, 11, 14, 0265e5a51h ; 19
148 | GG EBx,ECx,EDx,EAx, 0, 20, 0e9b6c7aah ; 20
149 | GG EAx,EBx,ECx,EDx, 5, 5, 0d62f105dh ; 21
150 | GG EDx,EAx,EBx,ECx, 10, 9, 002441453h ; 22
151 | GG ECx,EDx,EAx,EBx, 15, 14, 0d8a1e681h ; 23
152 | GG EBx,ECx,EDx,EAx, 4, 20, 0e7d3fbc8h ; 24
153 | GG EAx,EBx,ECx,EDx, 9, 5, 021e1cde6h ; 25
154 | GG EDx,EAx,EBx,ECx, 14, 9, 0c33707d6h ; 26
155 | GG ECx,EDx,EAx,EBx, 3, 14, 0f4d50d87h ; 27
156 | GG EBx,ECx,EDx,EAx, 8, 20, 0455a14edh ; 28
157 | GG EAx,EBx,ECx,EDx, 13, 5, 0a9e3e905h ; 29
158 | GG EDx,EAx,EBx,ECx, 2, 9, 0fcefa3f8h ; 30
159 | GG ECx,EDx,EAx,EBx, 7, 14, 0676f02d9h ; 31
160 | GG EBx,ECx,EDx,EAx, 12, 20, 08d2a4c8ah ; 32
161 |
162 | HH EAx,EBx,ECx,EDx, 5, 4, 0fffa3942h ; 33
163 | HH EDx,EAx,EBx,ECx, 8, 11, 08771f681h ; 34
164 | HH ECx,EDx,EAx,EBx, 11, 16, 06d9d6122h ; 35
165 | HH EBx,ECx,EDx,EAx, 14, 23, 0fde5380ch ; 36
166 | HH EAx,EBx,ECx,EDx, 1, 4, 0a4beea44h ; 37
167 | HH EDx,EAx,EBx,ECx, 4, 11, 04bdecfa9h ; 38
168 | HH ECx,EDx,EAx,EBx, 7, 16, 0f6bb4b60h ; 39
169 | HH EBx,ECx,EDx,EAx, 10, 23, 0bebfbc70h ; 40
170 | HH EAx,EBx,ECx,EDx, 13, 4, 0289b7ec6h ; 41
171 | HH EDx,EAx,EBx,ECx, 0, 11, 0eaa127fah ; 42
172 | HH ECx,EDx,EAx,EBx, 3, 16, 0d4ef3085h ; 43
173 | HH EBx,ECx,EDx,EAx, 6, 23, 004881d05h ; 44
174 | HH EAx,EBx,ECx,EDx, 9, 4, 0d9d4d039h ; 45
175 | HH EDx,EAx,EBx,ECx, 12, 11, 0e6db99e5h ; 46
176 | HH ECx,EDx,EAx,EBx, 15, 16, 01fa27cf8h ; 47
177 | HH EBx,ECx,EDx,EAx, 2, 23, 0c4ac5665h ; 48
178 |
179 | II EAx,EBx,ECx,EDx, 0, 6, 0f4292244h ; 49
180 | II EDx,EAx,EBx,ECx, 7, 10, 0432aff97h ; 50
181 | II ECx,EDx,EAx,EBx, 14, 15, 0ab9423a7h ; 51
182 | II EBx,ECx,EDx,EAx, 5, 21, 0fc93a039h ; 52
183 | II EAx,EBx,ECx,EDx, 12, 6, 0655b59c3h ; 53
184 | II EDx,EAx,EBx,ECx, 3, 10, 08f0ccc92h ; 54
185 | II ECx,EDx,EAx,EBx, 10, 15, 0ffeff47dh ; 55
186 | II EBx,ECx,EDx,EAx, 1, 21, 085845dd1h ; 56
187 | II EAx,EBx,ECx,EDx, 8, 6, 06fa87e4fh ; 57
188 | II EDx,EAx,EBx,ECx, 15, 10, 0fe2ce6e0h ; 58
189 | II ECx,EDx,EAx,EBx, 6, 15, 0a3014314h ; 59
190 | II EBx,ECx,EDx,EAx, 13, 21, 04e0811a1h ; 60
191 | II EAx,EBx,ECx,EDx, 4, 6, 0f7537e82h ; 61
192 | II EDx,EAx,EBx,ECx, 11, 10, 0bd3af235h ; 62
193 | II ECx,EDx,EAx,EBx, 2, 15, 02ad7d2bbh ; 63
194 | II EBx,ECx,EDx,EAx, 9, 21, 0eb86d391h ; 64
195 |
196 | Pop ESi
197 | Add [ESi], EAx
198 | Add [ESi+4], EBx
199 | Add [ESi+8], ECx
200 | Add [ESi+12], EDx
201 |
202 | ; restore the registers to comply to the calling convention
203 | Pop EBp
204 | Pop EDi
205 | Pop ESi
206 | Pop EBx
207 |
208 | Ret
209 | MD5_Transform EndP
210 |
211 | End
212 |
--------------------------------------------------------------------------------
/Source/md5_32.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PassByYou888/CoreCipher/c3757295fe4e252b42187e1a28f21588b57b6728/Source/md5_32.obj
--------------------------------------------------------------------------------
/Source/md5_64.asm:
--------------------------------------------------------------------------------
1 | ;{ ****************************************************************************** }
2 | ;{ * https://zpascal.net * }
3 | ;{ * https://github.com/PassByYou888/zAI * }
4 | ;{ * https://github.com/PassByYou888/ZServer4D * }
5 | ;{ * https://github.com/PassByYou888/PascalString * }
6 | ;{ * https://github.com/PassByYou888/zRasterization * }
7 | ;{ * https://github.com/PassByYou888/CoreCipher * }
8 | ;{ * https://github.com/PassByYou888/zSound * }
9 | ;{ * https://github.com/PassByYou888/zChinese * }
10 | ;{ * https://github.com/PassByYou888/zExpression * }
11 | ;{ * https://github.com/PassByYou888/zGameWare * }
12 | ;{ * https://github.com/PassByYou888/zAnalysis * }
13 | ;{ * https://github.com/PassByYou888/FFMPEG-Header * }
14 | ;{ * https://github.com/PassByYou888/zTranslate * }
15 | ;{ * https://github.com/PassByYou888/InfiniteIoT * }
16 | ;{ * https://github.com/PassByYou888/FastMD5 * }
17 | ;{ ****************************************************************************** }
18 |
19 |
20 | ; MD5_Transform-x64
21 | ; MD5 transform routine oprimized for x64 processors
22 | ; Copyright 2018 Ritlabs, SRL
23 | ; The 64-bit version is written by Maxim Masiutin
24 |
25 | ; The main advantage of this 64-bit version is that
26 | ; it loads 64 bytes of hashed message into 8 64-bit registers
27 | ; (RBP, R8, R9, R10, R11, R12, R13, R14) at the beginning,
28 | ; to avoid excessive memory load operations
29 | ; througout the routine.
30 |
31 | ; To operate with 32-bit values store in higher bits
32 | ; of a 64-bit register (bits 32-63) uses "Ror" by 32;
33 | ; 8 macro variables (M1-M8) are used to keep record
34 | ; or corrent state of whether the register has been
35 | ; Ror'ed or not.
36 |
37 | ; It also has an ability to use Lea instruction instead
38 | ; of two sequental Adds (uncomment UseLea=1), but it is
39 | ; slower on Skylake processors. Also, Intel in the
40 | ; Optimization Reference Maual discourages us of
41 | ; Lea as a replacement of two adds, since it is slower
42 | ; on the Atom processors.
43 |
44 | ; MD5_Transform-x64 is released under a dual license,
45 | ; and you may choose to use it under either the
46 | ; Mozilla Public License 2.0 (MPL 2.1, available from
47 | ; https://www.mozilla.org/en-US/MPL/2.0/) or the
48 | ; GNU Lesser General Public License Version 3,
49 | ; dated 29 June 2007 (LGPL 3, available from
50 | ; https://www.gnu.org/licenses/lgpl.html).
51 |
52 | ; MD5_Transform-x64 is based
53 | ; on the following code by Peter Sawatzki.
54 |
55 | ; The original notice by Peter Sawatzki follows.
56 |
57 | ; ==============================================================
58 | ;
59 | ; MD5_386.Asm - 386 optimized helper routine for calculating
60 | ; MD Message-Digest values
61 | ; written 2/2/94 by
62 | ;
63 | ; Peter Sawatzki
64 | ; Buchenhof 3
65 | ; D58091 Hagen, Germany Fed Rep
66 | ;
67 | ; EMail: Peter@Sawatzki.de
68 | ; EMail: 100031.3002@compuserve.com
69 | ; WWW: http://www.sawatzki.de
70 | ;
71 | ;
72 | ; original C Source was found in Dr. Dobbs Journal Sep 91
73 | ; MD5 algorithm from RSA Data Security, Inc.
74 |
75 |
76 |
77 | .CODE
78 |
79 |
80 | ; You can compile this code using Microsoft Macro Assembler
81 | ; ml64.exe /c md5_64.asm
82 |
83 |
84 |
85 | ; Uncomment the line below if you wish to have
86 | ; a "Lea" instruction instead of two subsequent "Add".
87 |
88 | ; UseLea=1
89 |
90 |
91 |
92 | ; The AA macro adds r to ac to a and stores result to r
93 | ; r and a can be either 32-bit (for the "Add" version)
94 | ; or 64-bit (for the "Lea" version)
95 |
96 | AA Macro r32,r64,ac,a32,a64
97 | IFDEF UseLea
98 | Lea r64, [r64+ac+a64]
99 | ELSE
100 | Add r32, ac
101 | Add r32, a32
102 | ENDIF
103 | EndM
104 |
105 | ; The JJ macro adds value from state buffer to the "a" register
106 | ; The "a" register can be either 32-bit (for the "Add" version)
107 | ; or 64-bit (for "Lea") - in this case it is passed as "r"
108 |
109 | JJ Macro a,x,ac,r
110 | IFE x
111 | IF M1
112 | Ror RBp, 32
113 | M1=0
114 | ENDIF
115 | AA a, r, ac, EBp, RBp
116 | ENDIF
117 | IFE x-1
118 | IFE M1
119 | Ror RBp, 32
120 | M1=1
121 | ENDIF
122 | AA a, r, ac, EBp, RBp
123 | ENDIF
124 | IFE x-2
125 | IF M2
126 | Ror R8, 32
127 | M2=0
128 | ENDIF
129 | AA a, r, ac, R8d, R8
130 | ENDIF
131 | IFE x-3
132 | IFE M2
133 | Ror R8, 32
134 | M2=1
135 | ENDIF
136 | AA a, r, ac, R8d, R8
137 | ENDIF
138 | IFE x-4
139 | IF M3
140 | Ror R9, 32
141 | M3=0
142 | ENDIF
143 | AA a, r, ac, R9d, R9
144 | ENDIF
145 | IFE x-5
146 | IFE M3
147 | Ror R9, 32
148 | M3=1
149 | ENDIF
150 | AA a, r, ac, R9d, R9
151 | ENDIF
152 | IFE x-6
153 | IF M4
154 | Ror R10, 32
155 | M4=0
156 | ENDIF
157 | AA a, r, ac, R10d, R10
158 | ENDIF
159 | IFE x-7
160 | IFE M4
161 | Ror R10, 32
162 | M4=1
163 | ENDIF
164 | AA a, r, ac, R10d, R10
165 | ENDIF
166 | IFE x-8
167 | IF M5
168 | Ror R11, 32
169 | M5=0
170 | ENDIF
171 | AA a, r, ac, R11d, R11
172 | ENDIF
173 | IFE x-9
174 | IFE M5
175 | Ror R11, 32
176 | M5=1
177 | ENDIF
178 | AA a, r, ac, R11d, R11
179 | ENDIF
180 | IFE x-10
181 | IF M6
182 | Ror R12, 32
183 | M6=0
184 | ENDIF
185 | AA a, r, ac, R12d, R12
186 | ENDIF
187 | IFE x-11
188 | IFE M6
189 | Ror R12, 32
190 | M6=1
191 | ENDIF
192 | AA a, r, ac, R12d, R12
193 | ENDIF
194 | IFE x-12
195 | IF M7
196 | Ror R13, 32
197 | M7=0
198 | ENDIF
199 | AA a, r, ac, R13d, R13
200 | ENDIF
201 | IFE x-13
202 | IFE M7
203 | Ror R13, 32
204 | M7=1
205 | ENDIF
206 | AA a, r, ac, R13d, R13
207 | ENDIF
208 | IFE x-14
209 | IF M8
210 | Ror R14, 32
211 | M8=0
212 | ENDIF
213 | AA a, r, ac, R14d, R14
214 | ENDIF
215 | IFE x-15
216 | IFE M8
217 | Ror R14, 32
218 | M8=1
219 | ENDIF
220 | AA a, r, ac, R14d, R14
221 | ENDIF
222 | EndM
223 |
224 |
225 | FF Macro a,b,c,d,x,s,ac,r
226 | ; a:= ROL (a+x+ac + (b And c Or Not b And d), s) + b
227 | JJ a, x, ac, r
228 | Mov ESI, b
229 | Not ESI
230 | And ESI, d
231 | Mov EDI, c
232 | And EDI, b
233 | Or ESI, EDI
234 | Add a, ESI
235 | Rol a, s
236 | Add a, b
237 | EndM
238 |
239 | GG Macro a,b,c,d,x,s,ac,r
240 | ; a:= ROL (a+x+ac + (b And d Or c And Not d), s) + b
241 | JJ a, x, ac, r
242 | Mov ESI, d
243 | Not ESI
244 | And ESI, c
245 | Mov EDI, d
246 | And EDI, b
247 | Or ESI, EDI
248 | Add a, ESI
249 | Rol a, s
250 | Add a, b
251 | EndM
252 |
253 | HH Macro a,b,c,d,x,s,ac,r
254 | ; a:= ROL (a+x+ac + (b Xor c Xor d), s) + b
255 | JJ a, x, ac, r
256 | Mov ESI, d
257 | Xor ESI, c
258 | Xor ESI, b
259 | Add a, ESI
260 | Rol a, s
261 | Add a, b
262 | EndM
263 |
264 | II Macro a,b,c,d,x,s,ac,r
265 | ; a:= ROL (a+x+ac + (c Xor (b Or Not d)), s) + b
266 | JJ a, x, ac, r
267 | Mov ESI, d
268 | Not ESI
269 | Or ESI, b
270 | Xor ESI, c
271 | Add a, ESI
272 | Rol a, s
273 | Add a, b
274 | EndM
275 |
276 | MD5_Transform Proc
277 | Public MD5_Transform
278 |
279 | ; save registers that the caller requires to be restored
280 | Push RBx
281 | Push RSi
282 | Push RDi
283 |
284 | Push RBp
285 | Push R12
286 | Push R13
287 | Push R14
288 |
289 | ; First parameter is passed in RCX, Second - in RDX
290 |
291 | ; State - in RCX
292 | ; Message - in RDX
293 |
294 | M1 = 0
295 | M2 = 0
296 | M3 = 0
297 | M4 = 0
298 | M5 = 0
299 | M6 = 0
300 | M7 = 0
301 | M8 = 0
302 |
303 | Mov R14, RDX ; Now the message buffer offset is in R14
304 |
305 | Mov RSi, Rcx ; Now state structure offset is in RSi
306 | Push Rsi ; State -> Stack
307 | Mov EAx, [RSi]
308 | Mov EBx, [RSi+4]
309 | Mov ECx, [RSi+8]
310 | Mov EDx, [RSi+12]
311 |
312 | Mov RBP, [R14+4*0]
313 | FF EAx,EBx,ECx,EDx, 0, 7, 0d76aa478h, RAx ; 1
314 | FF EDx,EAx,EBx,ECx, 1, 12, 0e8c7b756h, RDx ; 2
315 | Mov R8, [R14+4*2]
316 | FF ECx,EDx,EAx,EBx, 2, 17, 0242070dbh, RCx ; 3
317 | FF EBx,ECx,EDx,EAx, 3, 22, 0c1bdceeeh, RBx ; 4
318 | Mov R9, [R14+4*4]
319 | FF EAx,EBx,ECx,EDx, 4, 7, 0f57c0fafh, RAx ; 5
320 | FF EDx,EAx,EBx,ECx, 5, 12, 04787c62ah, RDx ; 6
321 | Mov R10, [R14+4*6]
322 | FF ECx,EDx,EAx,EBx, 6, 17, 0a8304613h, RCx ; 7
323 | FF EBx,ECx,EDx,EAx, 7, 22, 0fd469501h, RBx ; 8
324 | Mov R11, [R14+4*8]
325 | FF EAx,EBx,ECx,EDx, 8, 7, 0698098d8h, RAx ; 9
326 | FF EDx,EAx,EBx,ECx, 9, 12, 08b44f7afh, RDx ; 10
327 | Mov R12, [R14+4*10]
328 | FF ECx,EDx,EAx,EBx, 10, 17, 0ffff5bb1h, RCx ; 11
329 | FF EBx,ECx,EDx,EAx, 11, 22, 0895cd7beh, RBx ; 12
330 | Mov R13, [R14+4*12]
331 | FF EAx,EBx,ECx,EDx, 12, 7, 06b901122h, RAx ; 13
332 | FF EDx,EAx,EBx,ECx, 13, 12, 0fd987193h, RDx ; 14
333 | Mov R14, [R14+4*14]
334 | FF ECx,EDx,EAx,EBx, 14, 17, 0a679438eh, RCx ; 15
335 | FF EBx,ECx,EDx,EAx, 15, 22, 049b40821h, RBx ; 16
336 |
337 | GG EAx,EBx,ECx,EDx, 1, 5, 0f61e2562h, RAx ; 17
338 | GG EDx,EAx,EBx,ECx, 6, 9, 0c040b340h, RDx ; 18
339 | GG ECx,EDx,EAx,EBx, 11, 14, 0265e5a51h, RCx ; 19
340 | GG EBx,ECx,EDx,EAx, 0, 20, 0e9b6c7aah, RBx ; 20
341 | GG EAx,EBx,ECx,EDx, 5, 5, 0d62f105dh, RAx ; 21
342 | GG EDx,EAx,EBx,ECx, 10, 9, 002441453h, RDx ; 22
343 | GG ECx,EDx,EAx,EBx, 15, 14, 0d8a1e681h, RCx ; 23
344 | GG EBx,ECx,EDx,EAx, 4, 20, 0e7d3fbc8h, RBx ; 24
345 | GG EAx,EBx,ECx,EDx, 9, 5, 021e1cde6h, RAx ; 25
346 | GG EDx,EAx,EBx,ECx, 14, 9, 0c33707d6h, RDx ; 26
347 | GG ECx,EDx,EAx,EBx, 3, 14, 0f4d50d87h, RCx ; 27
348 | GG EBx,ECx,EDx,EAx, 8, 20, 0455a14edh, RBx ; 28
349 | GG EAx,EBx,ECx,EDx, 13, 5, 0a9e3e905h, RAx ; 29
350 | GG EDx,EAx,EBx,ECx, 2, 9, 0fcefa3f8h, RDx ; 30
351 | GG ECx,EDx,EAx,EBx, 7, 14, 0676f02d9h, RCx ; 31
352 | GG EBx,ECx,EDx,EAx, 12, 20, 08d2a4c8ah, RBx ; 32
353 |
354 | HH EAx,EBx,ECx,EDx, 5, 4, 0fffa3942h, RAx ; 33
355 | HH EDx,EAx,EBx,ECx, 8, 11, 08771f681h, RDx ; 34
356 | HH ECx,EDx,EAx,EBx, 11, 16, 06d9d6122h, RCx ; 35
357 | HH EBx,ECx,EDx,EAx, 14, 23, 0fde5380ch, RBx ; 36
358 | HH EAx,EBx,ECx,EDx, 1, 4, 0a4beea44h, RAx ; 37
359 | HH EDx,EAx,EBx,ECx, 4, 11, 04bdecfa9h, RDx ; 38
360 | HH ECx,EDx,EAx,EBx, 7, 16, 0f6bb4b60h, RCx ; 39
361 | HH EBx,ECx,EDx,EAx, 10, 23, 0bebfbc70h, RBx ; 40
362 | HH EAx,EBx,ECx,EDx, 13, 4, 0289b7ec6h, RAx ; 41
363 | HH EDx,EAx,EBx,ECx, 0, 11, 0eaa127fah, RDx ; 42
364 | HH ECx,EDx,EAx,EBx, 3, 16, 0d4ef3085h, RCx ; 43
365 | HH EBx,ECx,EDx,EAx, 6, 23, 004881d05h, RBx ; 44
366 | HH EAx,EBx,ECx,EDx, 9, 4, 0d9d4d039h, RAx ; 45
367 | HH EDx,EAx,EBx,ECx, 12, 11, 0e6db99e5h, RDx ; 46
368 | HH ECx,EDx,EAx,EBx, 15, 16, 01fa27cf8h, RCx ; 47
369 | HH EBx,ECx,EDx,EAx, 2, 23, 0c4ac5665h, RBx ; 48
370 |
371 | II EAx,EBx,ECx,EDx, 0, 6, 0f4292244h, RAx ; 49
372 | II EDx,EAx,EBx,ECx, 7, 10, 0432aff97h, RDx ; 50
373 | II ECx,EDx,EAx,EBx, 14, 15, 0ab9423a7h, RCx ; 51
374 | II EBx,ECx,EDx,EAx, 5, 21, 0fc93a039h, RBx ; 52
375 | II EAx,EBx,ECx,EDx, 12, 6, 0655b59c3h, RAx ; 53
376 | II EDx,EAx,EBx,ECx, 3, 10, 08f0ccc92h, RDx ; 54
377 | II ECx,EDx,EAx,EBx, 10, 15, 0ffeff47dh, RCx ; 55
378 | II EBx,ECx,EDx,EAx, 1, 21, 085845dd1h, RBx ; 56
379 | II EAx,EBx,ECx,EDx, 8, 6, 06fa87e4fh, RAx ; 57
380 | II EDx,EAx,EBx,ECx, 15, 10, 0fe2ce6e0h, RDx ; 58
381 | II ECx,EDx,EAx,EBx, 6, 15, 0a3014314h, RCx ; 59
382 | II EBx,ECx,EDx,EAx, 13, 21, 04e0811a1h, RBx ; 60
383 | II EAx,EBx,ECx,EDx, 4, 6, 0f7537e82h, RAx ; 61
384 | II EDx,EAx,EBx,ECx, 11, 10, 0bd3af235h, RDx ; 62
385 | II ECx,EDx,EAx,EBx, 2, 15, 02ad7d2bbh, RCx ; 63
386 | II EBx,ECx,EDx,EAx, 9, 21, 0eb86d391h, RBx ; 64
387 |
388 | Pop RSi ; get State pointer from stack
389 | Add [RSi], EAx
390 | Add [RSi+4], EBx
391 | Add [RSi+8], ECx
392 | Add [RSi+12], EDx
393 |
394 | ; restore volatile registers
395 | Pop R14
396 | Pop R13
397 | Pop R12
398 | Pop RBp
399 |
400 | Pop RDi
401 | Pop RSi
402 | Pop RBx
403 |
404 | Ret
405 | MD5_Transform EndP
406 |
407 | End
408 |
409 | ; That's All Folks!
410 |
--------------------------------------------------------------------------------
/Source/md5_64.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PassByYou888/CoreCipher/c3757295fe4e252b42187e1a28f21588b57b6728/Source/md5_64.obj
--------------------------------------------------------------------------------
/Source/zDefine.inc:
--------------------------------------------------------------------------------
1 | { * https://zpascal.net * }
2 | { * https://github.com/PassByYou888/zAI * }
3 | { * https://github.com/PassByYou888/ZServer4D * }
4 | { * https://github.com/PassByYou888/PascalString * }
5 | { * https://github.com/PassByYou888/zRasterization * }
6 | { * https://github.com/PassByYou888/CoreCipher * }
7 | { * https://github.com/PassByYou888/zSound * }
8 | { * https://github.com/PassByYou888/zChinese * }
9 | { * https://github.com/PassByYou888/zExpression * }
10 | { * https://github.com/PassByYou888/zGameWare * }
11 | { * https://github.com/PassByYou888/zAnalysis * }
12 | { * https://github.com/PassByYou888/FFMPEG-Header * }
13 | { * https://github.com/PassByYou888/zTranslate * }
14 | { * https://github.com/PassByYou888/InfiniteIoT * }
15 | { * https://github.com/PassByYou888/FastMD5 * }
16 | { ****************************************************************************** }
17 |
18 | {$IFDEF FPC}
19 | {$IFDEF FPC_DELPHI_MODE}
20 | {$MODE delphi}
21 | {$ELSE FPC_DELPHI_MODE}
22 | {$MODE objfpc}
23 | {$ENDIF FPC_DELPHI_MODE}
24 |
25 | {$MODESWITCH AdvancedRecords}
26 | {$MODESWITCH NestedProcVars}
27 | {$MODESWITCH NESTEDCOMMENTS}
28 | {$NOTES OFF}
29 | {$STACKFRAMES OFF}
30 | {$COPERATORS OFF}
31 | {$GOTO ON}
32 | {$INLINE ON}
33 | {$MACRO ON}
34 | {$HINTS ON}
35 | {$IEEEERRORS ON}
36 |
37 | {$DEFINE LITTLE_ENDIAN}
38 | {$UNDEF BIG_ENDIAN}
39 | {$IFDEF FPC_BIG_ENDIAN}
40 | {$UNDEF LITTLE_ENDIAN}
41 | {$DEFINE BIG_ENDIAN}
42 | {$ENDIF}
43 |
44 | {$UNDEF FirstCharInZero}
45 |
46 | {$UNDEF Delphi}
47 |
48 | // nativeint as int or int64 type variable when Modifier is overload
49 | {$UNDEF OVERLOAD_NATIVEINT}
50 |
51 | // fast MD5 only delphi supported, https://github.com/PassByYou888/FastMD5
52 | {$UNDEF FastMD5}
53 |
54 | // stream is MemoryStream64 or MemoryStream, usage fastMD5 or PurePascal MD5
55 | // be associate api: UnicodeMixedLib.umlStreamMD5, Fast_MD5.FastMD5
56 | {$DEFINE OptimizationMemoryStreamMD5}
57 |
58 | // multi thread Parallel switch.
59 | {$DEFINE Parallel}
60 |
61 | // Parallel for fold make better use CPU of multi core
62 | // if rem this "FoldParallel" parallel for block program, thread can use linear address
63 | {$DEFINE FoldParallel}
64 |
65 | // MT19937 of seed in the startup TCompute is 0
66 | {$DEFINE MT19937SeedOnTComputeThreadIs0}
67 |
68 | // automated loading common AI datasets on boot-time
69 | {$DEFINE Z_AI_Dataset_Build_In}
70 |
71 | // With SMALL_RASTER_FONT_Build_In and LARGE_RASTER_FONT_Build_In, boot-time memory usage increase by 100M-200M and start-up time to be delay 100ms
72 | {$DEFINE SMALL_RASTER_FONT_Build_In}
73 | // {$DEFINE LARGE_RASTER_FONT_Build_In}
74 |
75 | // ZDB_BACKUP is automatically made and replica caching is enabled.
76 | // usage ZDB_BACKUP so slows the open of large size ZDB file, after time, but does is high performance.
77 | // {$DEFINE ZDB_BACKUP}
78 |
79 | // ZDB Flush() uses physical IO as the temp storage device
80 | // {$DEFINE ZDB_PHYSICAL_FLUSH}
81 |
82 | // used Critical Simulate Atomic with TMonitor.Enter(obj) and TMonitor.Exit(obj)
83 | // CriticalSimulateAtomic defined so performance to be reduced
84 | {$DEFINE CriticalSimulateAtomic}
85 |
86 | // used soft Simulate Critical(ring)
87 | // SoftCritical defined so performance to be reduced
88 | // {$DEFINE SoftCritical}
89 | // {$DEFINE ANTI_DEAD_ATOMIC_LOCK}
90 |
91 | {$UNDEF debug}
92 | {$DEFINE release}
93 | {$DEFINE INLINE_ASM}
94 | {$R-}
95 | {$I-}
96 | {$S-}
97 | {$OPTIMIZATION ON}
98 | {$ELSE FPC} { IF DELPHI }
99 | {$DEFINE Delphi}
100 |
101 | {$DEFINE LITTLE_ENDIAN}
102 | {$UNDEF BIG_ENDIAN}
103 |
104 | {$IFDEF ANDROID}
105 | {$DEFINE FirstCharInZero}
106 | {$ENDIF ANDROID}
107 |
108 | {$IFDEF IOS}
109 | {$DEFINE FirstCharInZero}
110 | {$ENDIF IOS}
111 |
112 | // nativeint as int or int64 type variable when Modifier is overload
113 | {$DEFINE OVERLOAD_NATIVEINT}
114 |
115 | // fast MD5 only delphi supported, https://github.com/PassByYou888/FastMD5
116 | {$DEFINE FastMD5}
117 |
118 | // stream is MemoryStream64 or MemoryStream, usage fastMD5 or PurePascal MD5
119 | // be associate api: UnicodeMixedLib.umlStreamMD5, Fast_MD5.FastMD5
120 | {$DEFINE OptimizationMemoryStreamMD5}
121 |
122 | // multi thread Parallel switch.
123 | {$DEFINE Parallel}
124 |
125 | // Parallel for fold make better use CPU of multi core
126 | // if rem this "FoldParallel" is parallel for block program, thread can use linear address
127 | {$DEFINE FoldParallel}
128 |
129 | // Parallel programs use the delphi default TParallel
130 | // {$DEFINE SystemParallel}
131 |
132 | // paper: Mersenne Twister: A 623-dimensionallyequidistributed uniformpseudorandom number generator
133 | // Using this paper replace of Delphi Random() and Randomize() function, work on xe 10.3 or laster
134 | {$UNDEF InstallMT19937CoreToDelphi}
135 |
136 | // delphi 10.3
137 | {$IFDEF VER330}
138 | {$DEFINE InstallMT19937CoreToDelphi}
139 | {$ENDIF VER330}
140 |
141 | // delphi 10.4
142 | {$IFDEF VER340}
143 | {$DEFINE InstallMT19937CoreToDelphi}
144 | {$UNDEF FirstCharInZero}
145 | {$ENDIF VER340}
146 |
147 | // delphi 11.0
148 | {$IFDEF VER350}
149 | {$DEFINE InstallMT19937CoreToDelphi}
150 | {$UNDEF FirstCharInZero}
151 | {$ENDIF VER350}
152 |
153 | // delphi 11.x
154 | {$IFDEF VER360}
155 | {$DEFINE InstallMT19937CoreToDelphi}
156 | {$UNDEF FirstCharInZero}
157 | {$ENDIF VER360}
158 |
159 | // MT19937 of seed in the startup TCompute is 0
160 | {$DEFINE MT19937SeedOnTComputeThreadIs0}
161 |
162 | // automated loading common AI datasets on boot-time
163 | // {$DEFINE Z_AI_Dataset_Build_In}
164 |
165 | // With SMALL_RASTER_FONT_Build_In and LARGE_RASTER_FONT_Build_In, boot-time memory usage increase by 100M-200M and start-up time to be delay 100ms
166 | // {$DEFINE SMALL_RASTER_FONT_Build_In}
167 | // {$DEFINE LARGE_RASTER_FONT_Build_In}
168 |
169 | {$IF Defined(Android) or Defined(IOS)}
170 | {$DEFINE SMALL_RASTER_FONT_Build_In}
171 | {$ENDIF}
172 |
173 | // ZDB_BACKUP is automatically made and replica caching is enabled.
174 | // usage ZDB_BACKUP so slows the open of large size ZDB file, after time, but does is high performance.
175 | // {$DEFINE ZDB_BACKUP}
176 |
177 | // ZDB Flush() uses physical IO as the temp storage device
178 | // {$DEFINE ZDB_PHYSICAL_FLUSH}
179 |
180 | // used Critical Simulate Atomic with TMonitor.Enter(obj) and TMonitor.Exit(obj)
181 | // CriticalSimulateAtomic defined so performance to be reduced
182 | // {$DEFINE CriticalSimulateAtomic}
183 |
184 | // used soft Simulate Critical(ring)
185 | // SoftCritical defined so performance to be reduced
186 | // {$DEFINE SoftCritical}
187 | // {$DEFINE ANTI_DEAD_ATOMIC_LOCK}
188 |
189 | {$IFDEF release}
190 | {$DEFINE INLINE_ASM}
191 | {$R-} { range check }
192 | {$I-} { Input output checking }
193 | {$IF Defined(Android) or Defined(IOS)}
194 | {$O-} { close optimization }
195 | {$ELSE}
196 | {$O+} { open optimization }
197 | {$INLINE AUTO} { inline }
198 | {$IFEND}
199 | {$ELSE}
200 | {$UNDEF INLINE_ASM}
201 | {$O-} { close optimization }
202 | {$R-} { range check }
203 | {$I-} { Input output checking }
204 | {$D+} { debug information }
205 | {$ENDIF}
206 |
207 | {$IF Defined(Android) or Defined(IOS)}
208 | {$DEFINE SMALL_RASTER_FONT_Build_In}
209 | {$DEFINE PhysicsIO_On_Indy}
210 | {$ELSE}
211 | // PhysicsIO interface
212 | // {$DEFINE PhysicsIO_On_ICS}
213 | {$DEFINE PhysicsIO_On_CrossSocket}
214 | // {$DEFINE PhysicsIO_On_DIOCP}
215 | // {$DEFINE PhysicsIO_On_Indy}
216 | // {$DEFINE PhysicsIO_On_Synapse}
217 | {$IFEND}
218 |
219 | {$X+} { Extended syntax }
220 | {$Z1} { Minimum enum size }
221 | {$ENDIF FPC}
222 |
223 | // ZDB2.0 optimized TMemoryStream/TMemoryStream64 for Replace
224 | {$DEFINE ZDB2_Core_Used_Mem64}
225 |
226 | // Using fillchar replace of FillPtr
227 | // Maybe fillchar works on MMX / SSE2,
228 | // {$Define FillPtr_Used_FillChar}
229 |
230 | // Using Move replace of CopyPtr
231 | // {$Define CopyPtr_Used_Move}
232 |
233 | // Sequence packets default are opened in Physics-IO
234 | // Sequence package can support multi platform keep-alive mode
235 | // building a network CS system, the symmetry of compiler(FPC/Delphi) "UsedSequencePacket"
236 | {$DEFINE UsedSequencePacket}
237 |
238 | // Sequence package can support multi platform keep-alive mode
239 | // building a network CS system, the symmetry of compiler(FPC/Delphi) "UsedSequencePacketOnP2PVM"
240 | // Sequence packets default are closed in P2PVM-IO
241 | {$UNDEF UsedSequencePacketOnP2PVM}
242 |
243 | // CommunicationFramework used QuietMode
244 | {$UNDEF Communication_QuietMode}
245 |
246 | {$IFDEF DEBUG}
247 | // initialization status prompt
248 | {$DEFINE initializationStatus}
249 | // warning prompt
250 | {$WARNINGS ON}
251 | // JPEG support can output debug info
252 | {$UNDEF JPEG_Debug}
253 | {$ELSE DEBUG}
254 | // initialization status prompt
255 | {$UNDEF initializationStatus}
256 | // warning prompt
257 | {$WARNINGS OFF}
258 | // JPEG support can output debug info
259 | {$UNDEF JPEG_Debug}
260 | {$ENDIF DEBUG}
261 |
262 | {$IFDEF Parallel}
263 | // TMemoryRaster Parallel switch.
264 | {$UNDEF MemoryRaster_Parallel}
265 | // TRasterVertex Parallel switch.
266 | {$UNDEF Vertex_Parallel}
267 | // TMorphomatics Parallel switch.
268 | {$DEFINE Morphomatics_Parallel}
269 | // TMorphologyBinaryzation Parallel switch.
270 | {$DEFINE MorphologyBinaryzation_Parallel}
271 | {$ENDIF Parallel}
272 |
273 | {$HINTS OFF}
274 | {$C+} { Assertions }
275 | {$M-} { Run-Time Type Information }
276 | {$H+} { long string }
277 | {$A+} { Word Align Data }
278 | {$Q-} { Overflow checking }
279 | {$B-} { Complete boolean evaluation }
280 | {$J+} { Writeable typed constants }
281 |
282 | (*
283 | Pointer math is simply treating any given typed pointer in some narrow,
284 | instances as a scaled ordinal where you can perform simple arithmetic operations directly on the pointer variable.
285 | *)
286 | {$POINTERMATH OFF}
287 |
288 | {$UNDEF CPU64}
289 |
290 | {$IFDEF CPU64BITS}
291 | {$DEFINE CPU64}
292 | {$ELSE CPU64BITS}
293 | {$IFDEF CPUX64}
294 | {$DEFINE CPU64}
295 | {$ENDIF CPUX64}
296 | {$ENDIF CPU64BITS}
297 |
298 | {$IFNDEF CPU64}
299 | {$DEFINE CPU32}
300 | {$ENDIF CPU64}
301 |
302 | {$IFDEF BIG_ENDIAN}
303 | {$MESSAGE FATAL 'Big-endian system not supported'}
304 | {$ENDIF BIG_ENDIAN}
305 |
306 | {$IFOPT R+}
307 | {$DEFINE RangeCheck}
308 | {$ENDIF}
309 |
310 | {$IFOPT Q+}
311 | {$DEFINE OverflowCheck}
312 | {$ENDIF}
313 |
--------------------------------------------------------------------------------
/clear_with_dcu.bat:
--------------------------------------------------------------------------------
1 | del/s *.dcu
2 | del/s *.o
3 | del/s *.ppu
4 | del/s *.rsm
5 | del/s *.replay
6 | del/s *.loginpackage
7 | del/s *.dres
8 | del/s *.local
9 | del/s *.identcache
10 | del/s *.stat
11 |
--------------------------------------------------------------------------------