├── Demo
├── Binary
│ └── HttpDownloadDemo.exe
├── HttpDownloadDemo.dpr
├── HttpDownloadDemo.dproj
├── HttpDownloadDemo.dproj.local
├── HttpDownloadDemo.identcache
├── HttpDownloadDemo.res
├── HttpDownloadDemo.skincfg
├── HttpDownloadDemo_Icon.ico
├── HttpDownloadDemo_Icon1.ico
├── MainForm.fmx
├── MainForm.pas
├── MultiCircularProgress.pas
└── __history
│ └── HttpDownloadDemo.dpr.~1~
├── DemoCapture.png
├── LICENSE
├── Package
├── HttpParallelDownloader.dpk
├── HttpParallelDownloader.dproj
├── HttpParallelDownloader.dproj.local
├── HttpParallelDownloader.identcache
├── HttpParallelDownloader.res
├── ThredingFileDownloader.pas
└── __history
│ ├── HttpParallelDownloader.dpk.~1~
│ ├── ThredingFileDownloader.pas.~1~
│ └── ThredingFileDownloader.pas.~2~
├── README.md
└── ThredingFileDownloader.pas
/Demo/Binary/HttpDownloadDemo.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/Binary/HttpDownloadDemo.exe
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo.dpr:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------
2 |
3 | // This software is Copyright (c) 2015 Embarcadero Technologies, Inc.
4 | // You may only use this software if you are an authorized licensee
5 | // of an Embarcadero developer tools product.
6 | // This software is considered a Redistributable as defined under
7 | // the software license agreement that comes with the Embarcadero Products
8 | // and is subject to that software license agreement.
9 |
10 | //---------------------------------------------------------------------------
11 |
12 | program HttpDownloadDemo;
13 |
14 | uses
15 | System.StartUpCopy,
16 | FMX.Forms,
17 | MultiCircularProgress in 'MultiCircularProgress.pas',
18 | MainForm in 'MainForm.pas' {Form1},
19 | ThredingFileDownloader in '..\ThredingFileDownloader.pas';
20 |
21 | {$R *.res}
22 |
23 | begin
24 | Application.Initialize;
25 | Application.CreateForm(TForm1, Form1);
26 | Application.Run;
27 | end.
28 |
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {C012BE5A-E320-4F64-B4B8-09CA88732176}
4 | 18.7
5 | FMX
6 | HttpDownloadDemo.dpr
7 | True
8 | Release
9 | Win32
10 | 5215
11 | Application
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Base
29 | true
30 |
31 |
32 | true
33 | Base
34 | true
35 |
36 |
37 | true
38 | Base
39 | true
40 |
41 |
42 | true
43 | Base
44 | true
45 |
46 |
47 | true
48 | Base
49 | true
50 |
51 |
52 | true
53 | Base
54 | true
55 |
56 |
57 | true
58 | Base
59 | true
60 |
61 |
62 | true
63 | Cfg_1
64 | true
65 | true
66 |
67 |
68 | true
69 | Cfg_1
70 | true
71 | true
72 |
73 |
74 | true
75 | Cfg_1
76 | true
77 | true
78 |
79 |
80 | true
81 | Cfg_1
82 | true
83 | true
84 |
85 |
86 | true
87 | Base
88 | true
89 |
90 |
91 | true
92 | Cfg_2
93 | true
94 | true
95 |
96 |
97 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
98 | true
99 | true
100 | HttpDownloadDemo
101 | true
102 | true
103 | $(BDS)\bin\delphi_PROJECTICON.ico
104 | true
105 | true
106 | true
107 | $(BDS)\bin\delphi_PROJECTICNS.icns
108 | true
109 | true
110 | true
111 | .\$(Platform)\$(Config)
112 | .\$(Platform)\$(Config)
113 | false
114 | false
115 | false
116 | false
117 | false
118 |
119 |
120 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
121 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
122 | FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage)
123 | true
124 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
125 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
126 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
127 | Debug
128 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
129 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
130 | android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar
131 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;apiKey=
132 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
133 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
134 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
135 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
136 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
137 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
138 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
139 |
140 |
141 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png
142 | iPhoneAndiPad
143 | true
144 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png
145 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png
146 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
147 | $(MSBuildProjectName)
148 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png
149 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png
150 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png
151 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png
152 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png
153 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png
154 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
155 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png
156 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png
157 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
158 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png
159 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png
160 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png
161 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png
162 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSFaceIDUsageDescription=The reason for accessing the face id;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false
163 | fmxhrh;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage)
164 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png
165 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
166 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png
167 | Debug
168 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png
169 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png
170 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png
171 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png
172 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png
173 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png
174 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png
175 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png
176 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png
177 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png
178 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png
179 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png
180 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png
181 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png
182 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png
183 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png
184 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_828x1792.png
185 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1136x640.png
186 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2688.png
187 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1334x750.png
188 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1792x828.png
189 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2688x1242.png
190 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png
191 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2224.png
192 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2388.png
193 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_2048x2732.png
194 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2224x1668.png
195 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2388x1668.png
196 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2732x2048.png
197 |
198 |
199 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png
200 | iPhoneAndiPad
201 | true
202 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png
203 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png
204 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
205 | $(MSBuildProjectName)
206 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png
207 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png
208 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png
209 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png
210 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png
211 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png
212 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
213 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png
214 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png
215 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
216 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png
217 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png
218 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png
219 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png
220 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSFaceIDUsageDescription=The reason for accessing the face id;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false
221 | fmxhrh;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage)
222 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png
223 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
224 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png
225 | Debug
226 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png
227 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png
228 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png
229 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png
230 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png
231 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png
232 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png
233 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png
234 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png
235 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png
236 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png
237 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png
238 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png
239 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png
240 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png
241 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png
242 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_828x1792.png
243 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1136x640.png
244 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2688.png
245 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1334x750.png
246 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1792x828.png
247 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2688x1242.png
248 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png
249 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2224.png
250 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2388.png
251 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_2048x2732.png
252 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2224x1668.png
253 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2388x1668.png
254 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2732x2048.png
255 |
256 |
257 | true
258 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x1136.png
259 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png
260 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_72x72.png
261 | iPhoneAndiPad
262 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_50x50.png
263 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
264 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_114x114.png
265 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png
266 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
267 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x748.png
268 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png
269 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
270 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png
271 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2208.png
272 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png
273 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_100x100.png
274 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png
275 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png
276 | fmxhrh;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;bindcompfmx;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;inet;soapmidas;RESTComponents;dbexpress;IndyIPClient;$(DCC_UsePackage)
277 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_29x29.png
278 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_144x144.png
279 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
280 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera;CFBundleShortVersionString=1.0.0;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSFaceIDUsageDescription=The reason for accessing the face id;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false
281 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2208x1242.png
282 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png
283 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1496.png
284 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png
285 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_58x58.png
286 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_87x87.png
287 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_320x480.png
288 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_57x57.png
289 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png
290 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_640x960.png
291 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_29x29.png
292 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2008.png
293 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_750x1334.png
294 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1004.png
295 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1125x2436.png
296 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2436x1125.png
297 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png
298 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_828x1792.png
299 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1136x640.png
300 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1242x2688.png
301 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1334x750.png
302 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_1792x828.png
303 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2688x1242.png
304 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png
305 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2224.png
306 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1668x2388.png
307 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_2048x2732.png
308 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2224x1668.png
309 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2388x1668.png
310 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2732x2048.png
311 |
312 |
313 | true
314 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;soapmidas;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage)
315 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSContactsUsageDescription=The reason for accessing the contacts;CFBundleShortVersionString=1.0.0;NSLocationUsageDescription=The reason for accessing the location information of the user
316 |
317 |
318 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSContactsUsageDescription=The reason for accessing the contacts;CFBundleShortVersionString=1.0.0;NSLocationUsageDescription=The reason for accessing the location information of the user
319 | Debug
320 | true
321 | true
322 | Base
323 | true
324 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;soaprtl;emsclient;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;soapmidas;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage);$(DCC_UsePackage)
325 |
326 |
327 | true
328 | true
329 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
330 | $(BDS)\bin\default_app.manifest
331 | 1033
332 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
333 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;tethering;vclib;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;DUnitXRuntime;dbxcds;DatasnapConnectorsFreePascal;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;CloudService;DBXMSSQLDriver;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACInfxDriver;FireDACDb2Driver;adortl;FireDACASADriver;bindcompfmx;vcldbx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;Tee;DBXOdbcDriver;ibmonitor;vclFireDAC;xmlrtl;DataSnapNativeClient;ibxpress;svnui;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;vclactnband;soaprtl;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;emsclient;VCLRESTComponents;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;Intraweb;VclSmp;DataSnapConnectors;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;fmxobj;FireDACMySQLDriver;soapmidas;vclx;svn;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;bdertl;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage)
334 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
335 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
336 |
337 |
338 | true
339 | true
340 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
341 | $(BDS)\bin\default_app.manifest
342 | 1033
343 | CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)
344 | fmxhrh;FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;tethering;vclib;DataSnapClient;DataSnapServer;DataSnapCommon;DBXInterBaseDriver;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;CloudService;DBXMSSQLDriver;IndyIPCommon;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;dsnapxml;FireDACInfxDriver;FireDACDb2Driver;adortl;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;Tee;DBXOdbcDriver;ibmonitor;vclFireDAC;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;vclactnband;soaprtl;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;emsclient;VCLRESTComponents;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;Intraweb;VclSmp;DataSnapConnectors;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;fmxobj;FireDACMySQLDriver;soapmidas;vclx;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage)
345 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
346 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
347 |
348 |
349 | DEBUG;$(DCC_Define)
350 | true
351 | false
352 | true
353 | true
354 | true
355 |
356 |
357 | Debug
358 |
359 |
360 | true
361 | Cfg_1
362 | true
363 |
364 |
365 | false
366 | Debug
367 | true
368 | 1033
369 | true
370 | download-ga42fd477b_640 (1).ico
371 |
372 |
373 | Debug
374 |
375 |
376 | false
377 | RELEASE;$(DCC_Define)
378 | 0
379 | 0
380 |
381 |
382 | true
383 | 1033
384 | download-ga42fd477b_640 (1).ico
385 | true
386 |
387 |
388 |
389 | MainSource
390 |
391 |
392 |
393 |
394 | fmx
395 |
396 |
397 |
398 | Cfg_2
399 | Base
400 |
401 |
402 | Base
403 |
404 |
405 | Cfg_1
406 | Base
407 |
408 |
409 |
410 | Delphi.Personality.12
411 | Application
412 |
413 |
414 |
415 | HttpDownloadDemo.dpr
416 |
417 |
418 | Composants Microsoft Office 2000 Sample Automation Server Wrapper
419 | Composants Microsoft Office XP Sample Automation Server Wrapper
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 | true
455 |
456 |
457 |
458 |
459 |
460 |
461 | true
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 | HttpDownloadDemo.exe
476 | true
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 | true
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 | 1
512 |
513 |
514 | Contents\MacOS
515 | 1
516 |
517 |
518 | 0
519 |
520 |
521 |
522 |
523 | classes
524 | 1
525 |
526 |
527 |
528 |
529 | res\xml
530 | 1
531 |
532 |
533 |
534 |
535 | library\lib\armeabi-v7a
536 | 1
537 |
538 |
539 |
540 |
541 | library\lib\armeabi
542 | 1
543 |
544 |
545 |
546 |
547 | library\lib\mips
548 | 1
549 |
550 |
551 |
552 |
553 | library\lib\armeabi-v7a
554 | 1
555 |
556 |
557 |
558 |
559 | res\drawable
560 | 1
561 |
562 |
563 |
564 |
565 | res\values
566 | 1
567 |
568 |
569 |
570 |
571 | res\values-v21
572 | 1
573 |
574 |
575 |
576 |
577 | res\values
578 | 1
579 |
580 |
581 |
582 |
583 | res\drawable
584 | 1
585 |
586 |
587 |
588 |
589 | res\drawable-xxhdpi
590 | 1
591 |
592 |
593 |
594 |
595 | res\drawable-ldpi
596 | 1
597 |
598 |
599 |
600 |
601 | res\drawable-mdpi
602 | 1
603 |
604 |
605 |
606 |
607 | res\drawable-hdpi
608 | 1
609 |
610 |
611 |
612 |
613 | res\drawable-xhdpi
614 | 1
615 |
616 |
617 |
618 |
619 | res\drawable-mdpi
620 | 1
621 |
622 |
623 |
624 |
625 | res\drawable-hdpi
626 | 1
627 |
628 |
629 |
630 |
631 | res\drawable-xhdpi
632 | 1
633 |
634 |
635 |
636 |
637 | res\drawable-xxhdpi
638 | 1
639 |
640 |
641 |
642 |
643 | res\drawable-xxxhdpi
644 | 1
645 |
646 |
647 |
648 |
649 | res\drawable-small
650 | 1
651 |
652 |
653 |
654 |
655 | res\drawable-normal
656 | 1
657 |
658 |
659 |
660 |
661 | res\drawable-large
662 | 1
663 |
664 |
665 |
666 |
667 | res\drawable-xlarge
668 | 1
669 |
670 |
671 |
672 |
673 | res\values
674 | 1
675 |
676 |
677 |
678 |
679 | 1
680 |
681 |
682 | Contents\MacOS
683 | 1
684 |
685 |
686 | 0
687 |
688 |
689 |
690 |
691 | Contents\MacOS
692 | 1
693 | .framework
694 |
695 |
696 | Contents\MacOS
697 | 1
698 | .framework
699 |
700 |
701 | 0
702 |
703 |
704 |
705 |
706 | 1
707 | .dylib
708 |
709 |
710 | 1
711 | .dylib
712 |
713 |
714 | 1
715 | .dylib
716 |
717 |
718 | Contents\MacOS
719 | 1
720 | .dylib
721 |
722 |
723 | Contents\MacOS
724 | 1
725 | .dylib
726 |
727 |
728 | 0
729 | .dll;.bpl
730 |
731 |
732 |
733 |
734 | 1
735 | .dylib
736 |
737 |
738 | 1
739 | .dylib
740 |
741 |
742 | 1
743 | .dylib
744 |
745 |
746 | Contents\MacOS
747 | 1
748 | .dylib
749 |
750 |
751 | Contents\MacOS
752 | 1
753 | .dylib
754 |
755 |
756 | 0
757 | .bpl
758 |
759 |
760 |
761 |
762 | 0
763 |
764 |
765 | 0
766 |
767 |
768 | 0
769 |
770 |
771 | 0
772 |
773 |
774 | Contents\Resources\StartUp\
775 | 0
776 |
777 |
778 | Contents\Resources\StartUp\
779 | 0
780 |
781 |
782 | 0
783 |
784 |
785 |
786 |
787 | 1
788 |
789 |
790 | 1
791 |
792 |
793 | 1
794 |
795 |
796 |
797 |
798 | 1
799 |
800 |
801 | 1
802 |
803 |
804 | 1
805 |
806 |
807 |
808 |
809 | 1
810 |
811 |
812 | 1
813 |
814 |
815 | 1
816 |
817 |
818 |
819 |
820 | 1
821 |
822 |
823 | 1
824 |
825 |
826 | 1
827 |
828 |
829 |
830 |
831 | 1
832 |
833 |
834 | 1
835 |
836 |
837 | 1
838 |
839 |
840 |
841 |
842 | 1
843 |
844 |
845 | 1
846 |
847 |
848 | 1
849 |
850 |
851 |
852 |
853 | 1
854 |
855 |
856 | 1
857 |
858 |
859 | 1
860 |
861 |
862 |
863 |
864 | 1
865 |
866 |
867 | 1
868 |
869 |
870 | 1
871 |
872 |
873 |
874 |
875 | 1
876 |
877 |
878 | 1
879 |
880 |
881 | 1
882 |
883 |
884 |
885 |
886 | 1
887 |
888 |
889 | 1
890 |
891 |
892 | 1
893 |
894 |
895 |
896 |
897 | 1
898 |
899 |
900 | 1
901 |
902 |
903 | 1
904 |
905 |
906 |
907 |
908 | 1
909 |
910 |
911 | 1
912 |
913 |
914 | 1
915 |
916 |
917 |
918 |
919 | 1
920 |
921 |
922 | 1
923 |
924 |
925 | 1
926 |
927 |
928 |
929 |
930 | 1
931 |
932 |
933 | 1
934 |
935 |
936 | 1
937 |
938 |
939 |
940 |
941 | 1
942 |
943 |
944 | 1
945 |
946 |
947 | 1
948 |
949 |
950 |
951 |
952 | 1
953 |
954 |
955 | 1
956 |
957 |
958 | 1
959 |
960 |
961 |
962 |
963 | 1
964 |
965 |
966 | 1
967 |
968 |
969 | 1
970 |
971 |
972 |
973 |
974 | 1
975 |
976 |
977 | 1
978 |
979 |
980 | 1
981 |
982 |
983 |
984 |
985 | 1
986 |
987 |
988 | 1
989 |
990 |
991 | 1
992 |
993 |
994 |
995 |
996 | 1
997 |
998 |
999 | 1
1000 |
1001 |
1002 | 1
1003 |
1004 |
1005 |
1006 |
1007 | 1
1008 |
1009 |
1010 | 1
1011 |
1012 |
1013 | 1
1014 |
1015 |
1016 |
1017 |
1018 | 1
1019 |
1020 |
1021 | 1
1022 |
1023 |
1024 | 1
1025 |
1026 |
1027 |
1028 |
1029 | 1
1030 |
1031 |
1032 | 1
1033 |
1034 |
1035 | 1
1036 |
1037 |
1038 |
1039 |
1040 | 1
1041 |
1042 |
1043 | 1
1044 |
1045 |
1046 | 1
1047 |
1048 |
1049 |
1050 |
1051 | 1
1052 |
1053 |
1054 |
1055 |
1056 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1057 | 1
1058 |
1059 |
1060 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1061 | 1
1062 |
1063 |
1064 |
1065 |
1066 | 1
1067 |
1068 |
1069 | 1
1070 |
1071 |
1072 |
1073 |
1074 | ..\
1075 | 1
1076 |
1077 |
1078 | ..\
1079 | 1
1080 |
1081 |
1082 |
1083 |
1084 | 1
1085 |
1086 |
1087 | 1
1088 |
1089 |
1090 | 1
1091 |
1092 |
1093 |
1094 |
1095 | 1
1096 |
1097 |
1098 | 1
1099 |
1100 |
1101 | 1
1102 |
1103 |
1104 |
1105 |
1106 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1107 | 1
1108 |
1109 |
1110 |
1111 |
1112 | ..\
1113 | 1
1114 |
1115 |
1116 | ..\
1117 | 1
1118 |
1119 |
1120 |
1121 |
1122 | Contents
1123 | 1
1124 |
1125 |
1126 | Contents
1127 | 1
1128 |
1129 |
1130 |
1131 |
1132 | Contents\Resources
1133 | 1
1134 |
1135 |
1136 | Contents\Resources
1137 | 1
1138 |
1139 |
1140 |
1141 |
1142 | library\lib\armeabi-v7a
1143 | 1
1144 |
1145 |
1146 | 1
1147 |
1148 |
1149 | 1
1150 |
1151 |
1152 | 1
1153 |
1154 |
1155 | 1
1156 |
1157 |
1158 | Contents\MacOS
1159 | 1
1160 |
1161 |
1162 | Contents\MacOS
1163 | 1
1164 |
1165 |
1166 | 0
1167 |
1168 |
1169 |
1170 |
1171 | 1
1172 |
1173 |
1174 | 1
1175 |
1176 |
1177 |
1178 |
1179 | Assets
1180 | 1
1181 |
1182 |
1183 | Assets
1184 | 1
1185 |
1186 |
1187 |
1188 |
1189 | Assets
1190 | 1
1191 |
1192 |
1193 | Assets
1194 | 1
1195 |
1196 |
1197 |
1198 |
1199 |
1200 |
1201 |
1202 |
1203 |
1204 |
1205 |
1206 |
1207 |
1208 | True
1209 | True
1210 | True
1211 | True
1212 | True
1213 | True
1214 | True
1215 | True
1216 |
1217 |
1218 | 12
1219 |
1220 |
1221 |
1222 |
1223 |
1224 |
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo.dproj.local:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 2022/05/26 12:11:43.000.871,=C:\Users\Kamel\Desktop\HttpDownload\MultiCircularProgress.pas
8 | 2022/05/26 15:47:02.000.574,=C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas
9 | 2022/05/26 15:47:30.000.395,C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas=C:\Users\Kamel\Desktop\HttpDownload\ThredingFileDownloader.pas
10 | 2022/05/26 17:41:11.000.190,=C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas
11 | 2022/05/26 17:41:50.000.115,C:\Users\Kamel\Desktop\HttpDownload\Unit1.fmx=C:\Users\Kamel\Desktop\HttpDownload\MainForm.fmx
12 | 2022/05/26 17:41:50.000.115,C:\Users\Kamel\Desktop\HttpDownload\Unit1.pas=C:\Users\Kamel\Desktop\HttpDownload\MainForm.pas
13 | 2022/05/29 14:09:32.000.815,C:\Users\Kamel\Desktop\HttpDownload\FDownloadDemo.pas=
14 | 2022/06/01 21:22:18.000.405,=C:\Users\neptune\Desktop\HttpDownload\ThredingFileDownloader.pas
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo.identcache:
--------------------------------------------------------------------------------
1 | DC:\Users\neptune\Desktop\HttpDownload\Demo\MultiCircularProgress.pas ?C:\Users\neptune\Desktop\HttpDownload\Demo\HttpDownloadDemo.dpr @C:\Users\neptune\Desktop\HttpDownload\ThredingFileDownloader.pas 7C:\Users\neptune\Desktop\HttpDownload\Demo\MainForm.pas
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/HttpDownloadDemo.res
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo.skincfg:
--------------------------------------------------------------------------------
1 | [ExpressSkins]
2 | Default=1
3 | ShowNotifications=1
4 | Enabled=1
5 | dxSkinsDefaultPainters=1
6 |
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo_Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/HttpDownloadDemo_Icon.ico
--------------------------------------------------------------------------------
/Demo/HttpDownloadDemo_Icon1.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/HttpDownloadDemo_Icon1.ico
--------------------------------------------------------------------------------
/Demo/MainForm.fmx:
--------------------------------------------------------------------------------
1 | object Form1: TForm1
2 | Left = 0
3 | Top = 0
4 | BorderIcons = [biSystemMenu, biMinimize]
5 | Caption = 'Multi-Threading Download Demo'
6 | ClientHeight = 621
7 | ClientWidth = 596
8 | Position = DesktopCenter
9 | FormFactor.Width = 320
10 | FormFactor.Height = 480
11 | FormFactor.Devices = [Desktop]
12 | OnCreate = FormCreate
13 | DesignerMasterStyle = 0
14 | object Rectangle1: TRectangle
15 | Align = Top
16 | Fill.Color = claWhite
17 | Size.Width = 596.000000000000000000
18 | Size.Height = 257.000000000000000000
19 | Size.PlatformDefault = False
20 | Stroke.Kind = None
21 | object Layout11: TLayout
22 | Align = Contents
23 | Size.Width = 596.000000000000000000
24 | Size.Height = 257.000000000000000000
25 | Size.PlatformDefault = False
26 | TabOrder = 3
27 | object Label5: TLabel
28 | Align = Top
29 | StyledSettings = [Family, Size]
30 | Margins.Left = 10.000000000000000000
31 | Margins.Top = 5.000000000000000000
32 | Position.X = 10.000000000000000000
33 | Position.Y = 5.000000000000000000
34 | Size.Width = 586.000000000000000000
35 | Size.Height = 17.000000000000000000
36 | Size.PlatformDefault = False
37 | TextSettings.Font.StyleExt = {00070000000000000004000000}
38 | TextSettings.FontColor = claRoyalblue
39 | Text =
40 | 'Multi-Threading for Http files download FMX Demo (kamel_mh@yahoo' +
41 | '.fr)'
42 | TabOrder = 0
43 | end
44 | end
45 | object Layout1: TLayout
46 | Align = Left
47 | Margins.Left = 10.000000000000000000
48 | Margins.Top = 40.000000000000000000
49 | Margins.Bottom = 20.000000000000000000
50 | Position.X = 10.000000000000000000
51 | Position.Y = 40.000000000000000000
52 | Size.Width = 205.000000000000000000
53 | Size.Height = 197.000000000000000000
54 | Size.PlatformDefault = False
55 | TabOrder = 0
56 | end
57 | object Layout2: TLayout
58 | Align = Client
59 | Margins.Left = 20.000000000000000000
60 | Margins.Top = 40.000000000000000000
61 | Size.Width = 301.000000000000000000
62 | Size.Height = 217.000000000000000000
63 | Size.PlatformDefault = False
64 | TabOrder = 1
65 | object Layout3: TLayout
66 | Align = Top
67 | Size.Width = 301.000000000000000000
68 | Size.Height = 30.000000000000000000
69 | Size.PlatformDefault = False
70 | TabOrder = 6
71 | object Label14: TLabel
72 | Align = FitLeft
73 | Size.Width = 100.000000000000000000
74 | Size.Height = 30.000000000000000000
75 | Size.PlatformDefault = False
76 | Text = 'File Name :'
77 | TabOrder = 2
78 | end
79 | object Label15: TLabel
80 | Align = Client
81 | Margins.Left = 5.000000000000000000
82 | Size.Width = 196.000000000000000000
83 | Size.Height = 30.000000000000000000
84 | Size.PlatformDefault = False
85 | Text = '-'
86 | TabOrder = 13
87 | end
88 | end
89 | object Layout4: TLayout
90 | Align = Top
91 | Position.Y = 120.000000000000000000
92 | Size.Width = 301.000000000000000000
93 | Size.Height = 30.000000000000000000
94 | Size.PlatformDefault = False
95 | TabOrder = 5
96 | object Label20: TLabel
97 | Align = Client
98 | Margins.Left = 5.000000000000000000
99 | Size.Width = 196.000000000000000000
100 | Size.Height = 30.000000000000000000
101 | Size.PlatformDefault = False
102 | Text = '-'
103 | TabOrder = 13
104 | end
105 | object Label21: TLabel
106 | Align = FitLeft
107 | Size.Width = 100.000000000000000000
108 | Size.Height = 30.000000000000000000
109 | Size.PlatformDefault = False
110 | Text = 'Progress :'
111 | TabOrder = 2
112 | end
113 | end
114 | object Layout5: TLayout
115 | Align = Top
116 | Position.Y = 60.000000000000000000
117 | Size.Width = 301.000000000000000000
118 | Size.Height = 30.000000000000000000
119 | Size.PlatformDefault = False
120 | TabOrder = 1
121 | object Label18: TLabel
122 | Align = Client
123 | Margins.Left = 5.000000000000000000
124 | Size.Width = 196.000000000000000000
125 | Size.Height = 30.000000000000000000
126 | Size.PlatformDefault = False
127 | Text = '-'
128 | TabOrder = 13
129 | end
130 | object Label19: TLabel
131 | Align = FitLeft
132 | Size.Width = 100.000000000000000000
133 | Size.Height = 30.000000000000000000
134 | Size.PlatformDefault = False
135 | Text = 'Download Speed :'
136 | TabOrder = 2
137 | end
138 | end
139 | object Layout6: TLayout
140 | Align = Top
141 | Position.Y = 30.000000000000000000
142 | Size.Width = 301.000000000000000000
143 | Size.Height = 30.000000000000000000
144 | Size.PlatformDefault = False
145 | TabOrder = 0
146 | object Label16: TLabel
147 | Align = Client
148 | Margins.Left = 5.000000000000000000
149 | Size.Width = 196.000000000000000000
150 | Size.Height = 30.000000000000000000
151 | Size.PlatformDefault = False
152 | Text = '-'
153 | TabOrder = 13
154 | end
155 | object Label17: TLabel
156 | Align = FitLeft
157 | Size.Width = 100.000000000000000000
158 | Size.Height = 30.000000000000000000
159 | Size.PlatformDefault = False
160 | Text = 'File Size :'
161 | TabOrder = 2
162 | end
163 | end
164 | object Layout7: TLayout
165 | Align = Top
166 | Position.Y = 150.000000000000000000
167 | Size.Width = 301.000000000000000000
168 | Size.Height = 30.000000000000000000
169 | Size.PlatformDefault = False
170 | TabOrder = 4
171 | object Label22: TLabel
172 | Align = Client
173 | Margins.Left = 5.000000000000000000
174 | Size.Width = 196.000000000000000000
175 | Size.Height = 30.000000000000000000
176 | Size.PlatformDefault = False
177 | Text = '-'
178 | TabOrder = 13
179 | end
180 | object Label23: TLabel
181 | Align = FitLeft
182 | Size.Width = 100.000000000000000000
183 | Size.Height = 30.000000000000000000
184 | Size.PlatformDefault = False
185 | Text = 'Remaining time :'
186 | TabOrder = 2
187 | end
188 | end
189 | object Layout8: TLayout
190 | Align = Top
191 | Position.Y = 90.000000000000000000
192 | Size.Width = 301.000000000000000000
193 | Size.Height = 30.000000000000000000
194 | Size.PlatformDefault = False
195 | TabOrder = 2
196 | object Label24: TLabel
197 | Align = Client
198 | Margins.Left = 5.000000000000000000
199 | Size.Width = 196.000000000000000000
200 | Size.Height = 30.000000000000000000
201 | Size.PlatformDefault = False
202 | Text = '-'
203 | TabOrder = 13
204 | end
205 | object Label25: TLabel
206 | Align = FitLeft
207 | Size.Width = 100.000000000000000000
208 | Size.Height = 30.000000000000000000
209 | Size.PlatformDefault = False
210 | Text = 'Downloaded :'
211 | TabOrder = 2
212 | end
213 | end
214 | object Layout9: TLayout
215 | Align = Top
216 | Position.Y = 180.000000000000000000
217 | Size.Width = 301.000000000000000000
218 | Size.Height = 30.000000000000000000
219 | Size.PlatformDefault = False
220 | TabOrder = 3
221 | object Label3: TLabel
222 | Align = Client
223 | StyledSettings = [Family, Size, Style]
224 | Margins.Left = 5.000000000000000000
225 | Size.Width = 196.000000000000000000
226 | Size.Height = 30.000000000000000000
227 | Size.PlatformDefault = False
228 | TextSettings.FontColor = claGreen
229 | Text = '-'
230 | TabOrder = 13
231 | end
232 | object Label4: TLabel
233 | Align = FitLeft
234 | Size.Width = 100.000000000000000000
235 | Size.Height = 30.000000000000000000
236 | Size.PlatformDefault = False
237 | Text = 'Resume :'
238 | TabOrder = 2
239 | end
240 | end
241 | end
242 | object Layout10: TLayout
243 | Align = Right
244 | Position.X = 536.000000000000000000
245 | Size.Width = 60.000000000000000000
246 | Size.Height = 257.000000000000000000
247 | Size.PlatformDefault = False
248 | TabOrder = 2
249 | object Image1: TImage
250 | MultiResBitmap.Height = 128
251 | MultiResBitmap.Width = 128
252 | MultiResBitmap = <
253 | item
254 | Width = 128
255 | Height = 128
256 | PNG = {
257 | 89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61
258 | CB000000017352474200AECE1CE90000000467414D410000B18F0BFC61050000
259 | 10BB49444154785EED9D799055D59DC7BFF7DCB7F5EB85160D448A0470012B38
260 | FCA1A4A69CB12A24450F0C49662A33461A824B32C649395366B4B0C2D4202392
261 | A492312513323191D4B810C4069724236023B4518362149360109BA5A15B4016
262 | E9A6D7B7DE7BEE9CDFEDD3F89ADEDE72D7D7F753D5727FBF07C2BBDFEF39BF73
263 | EE728E8232C230A0E019840D8669486116B2B84AE43ECD38A6EA1C938D2C2671
264 | 15B51A47B5F8ED5124A09A7F300E5DFC371D62E8613A3A9530CEAA0C6738C309
265 | 45C10708E3086238A870B4E1ABC88A9C61FEB932C0D70620C18D064C85861B8D
266 | 0C6E3074CC4D03B3D12B041692C62BADF97E893E213859A50A3D51E03D45C55E
267 | 25823D0861B7526F9AC4B786F09D01F81BA810ED709E91C022CE313FA363665C
268 | 0773FC9B08C9132A7844C521C6B04B8963BBE8775E617F85A4FC1DBEC01706E0
269 | DB4577DD813A2385C5A28BFEB268DD13E447DE42459728312F28316CC644EC64
270 | 8B203A246FE36903F0E731D3388F6F6A3A9669DD981C8FFBC3B089048C500DCE
271 | 84546C542EC12FD83FE090FCC87378EE848ABACE8C8D982F6AFADDA94E2C8C57
272 | C8819A4F4924A1C76AD128C60CEB9465A25428E0F2234FE01903185B84D029D1
273 | BDA7B132D185EBFCD2DAF3857A85F804FC4114B3EF8A19C50BCACDE6CCC3753C
274 | 7192F9062CE429AC4977E3FA7213FE62C808D11ABCC362B89FDD8A4699760D57
275 | 4F36DF84D96234FF2396C142991A57F088280D712C674BF19E4C398E2B06102D
276 | BED2E058954AE1DB712E3AC5714C82211D8BE1C70AC383A247E89369C770DC00
277 | 4603E66B5D7834A4E30A990A10682A8E8626E09F957AEC92294770CC007C8768
278 | F527F083540677C5C5485FA60372488819422C824794A958C11638D31B386200
279 | DE806B790F36A959FC854C058C821EC69F593596B27AEC9729DBB0BD25F25F62
280 | 59B2137B02F1F387CE159D333A7732651BB6F500C66F11E2ADF861AA03F7C42B
281 | DC196CFA9D4412466C22D6B2E9F88EF27968326D29B608239C5B63A4F19498DE
282 | 7D49A6024A8047B14D898892700BBA65CA322C378098DB4F56FAB00D595C2F53
283 | CEA03BD0C950C1545CBAF31BC63B4625BEC896E28CCC5882A5678D3F8B697A3B
284 | 768829DE2C997286F044E01FF7C8C03ECEED5C894BDB9F71AD9E89A9E241F552
285 | 2C6037A14DA64AC6B2EFC29FC6957A2F7686B2982153CE11FE0470C7697160EF
286 | 98F6E0C67F82D1F218664DB2A976E68116C631B50A756C095A64AA242C396366
287 | CB774B7C87E9E81546386B3E0FE20A748EE95CD33997A99228D90054F3CD6E7F
288 | 1C883F80274C20CE399D7B992A9A920CC0B7A386F762ABE335DF03B86E0271CE
289 | E9DC9306325514451B80E6F9C687784AD53057A6C61D6E9B80CE3D69405AC854
290 | C1146D007E143F0CE6F9EE9B8034202D6458304519803F8165A94EDC23C3718F
291 | DB26202D4813191644C106A01B3BC9147E165CDE1D8C9B26202D4813D246A6F2
292 | A62003D0831CBC0B4FC739AA642A2007574D2034216D482399CA8B820C6064F1
293 | 03552FDC65E309374D40DA904632CC8BBC0D603C89F9F430870C0346C14D1390
294 | 46A4950CC7242F03185B50A5A5F1F3E0499EFC71CB04A49196C1CF4933991A95
295 | 3105A51730790F5685345C29530179E2960942595C499A996F4B8FC1D8067812
296 | 9F4925F16D190614885B2620CD483B198EC8D806C8E0477186880C038AC00D13
297 | 9066A49D0C47645403F0C7B19069E3F3A50DAB71C304A41D6928C36119D100F4
298 | AE1ECF628D0C032CC00D139086E67B972330B20112F83B7A574F860116E1B409
299 | 4843D252864318D600C67F822929FC47B9BFA8E9164E9A8034242D4953991AC4
300 | F006B80275895E5C27C3001B70D204A425692AC3410C3180B9F0520A7707ADDF
301 | 7E9C320169499A0E775D60A80136E0EA140F46FE4EE194094853D2568617186A
302 | 802CEE0C2EF93A8B1326204D495B195E6090D0B41A97C6F13519063888132620
303 | 6DCD15D77218DCD23B5047AB71C928C061EC3681A9ADD0588626830C40EBF005
304 | 833F77B1D3047230B8588626170CC037A3C25C8431C075EC3401694C5ACB30A7
305 | 07C8629E6757E01C87D86602D23829B496980630E7FE692C3233019EC12E1318
306 | 3A160D5C13F8B804F0FC1F230A700E3B4C90AB757F0FD080A9B4EAB69909F01C
307 | 569B80B43697D917F4F7001A6E8CF39CF14080E7B0D204E6F2FA42733AEEEF01
308 | 52B8817E0DF03696994054FF01CD993900043E6B7E10E079AC3201694EDA33DA
309 | 6327CDC77E7830C03B5861025373A13DDD2098863E7313A5001F51B20984E6A4
310 | 3D838E6BBCB5854140BE946402D25C68AFF0C7F16F4A126BFBB31E60D23CA0A6
311 | C0D566D44AE00BEBC481BDB7314EEDFE5FF4B4BE2EA3FCD0B3099C7F6FB3ADFF
312 | B48955286AE12AA302F728FA637898A53CF4AE7FD54C60F15B40A4D0954FEC15
313 | FF630A686FE2B7363F792B3ADEDB2813F6518C09780C6B196DAA28636FD07B08
314 | D8F52D71405FA5901FA718EEEF1EFEE7D4EBEBD1BEDF7EF18962CA0169CF6847
315 | 4D197B87D60660DF2332F027BDC7F7A1F5FFEE81425E7088424D40DAD32C4074
316 | 1C1E834EDA9E7B8133EFF4C73E434B7689AEFF261886F37B48166202D29ED15E
317 | BA32F616461AD8B1584C583B65C23F1C7EFA4E64BA8EC8C879F2350169CFE446
318 | CADEA4AF05D8F90D71504865739793AFFC0FCE1FD82223F7C8C704A43DDD0BF0
319 | F6A64DC77F05FCF12732F0363DAD7BD1B67D797F09F300799820CA2E6CA1EE65
320 | DEBC4F4CC27F2F036FA2253AD0BCE1E6FED2E521463581D0DE27B78033623C50
321 | 0FA43A64EC350C1CDA7807B23DC764EC2D46330143DC1B5B988E49B21578E936
322 | 71E0BDEBD6279AD6A2F39028551E66581308EDA907F0FC16E71738B10DD8FBB0
323 | 0CBC41F7D13DF8A0718567EAFE680C6382340B31F4C8C0FBD0930B6FFFBB186A
324 | EF960977C9F6B6E3E02F97D0517FC207E49A80B4674C87CF26DA9A28054B4549
325 | 3827639730380E6EBC5598C0B2DD5B1C63C004A43D53C210873E23755C0C0A97
326 | 0911DC1BBE1CDFF910BA8F6C9791FF20131CFE08E798980758BA0B95639CDA21
327 | CA41D1ABA49744D7E1D770FCA595BEA8FBA3D197C459C6194EC8D87FEC5D259A
328 | E22B3270864CCF59D1F58B12A4D8B28FA3A388C6FF2153147C2063FFA18812B0
329 | 5388D1E7502746757FC33268899332E1730CB431A868492486BD46E00FD2A7C4
330 | 784098C081F1405BE3F7D1D3EAE8EEEEB6D167C0A8AC400B19A0D9F7AF849C79
331 | 1978D3DE250DCF3737E144D303E2C8BF6D2517F31AB082669A05B4A1D247D702
332 | 46E28FC2006D3B65602D99AED338BC6919142A3965424C4122A2E318C357918D
333 | 321C9079FFA27060D72D40EF8732610D06D7D0BC6109B424ED4C5A3E4418DE9F
334 | FE00D2340834C46CE66D99F7371931186C5C0208D1ACA26DDB1AF47EE0EC4CC3
335 | 0984EE7B497BB3FA2B31D8BFF3B2537CF41AF0C6FD32288D8E038D38F96A792E
336 | 971C57FB35EF1FFE85B03BC1CAE8F59077FF0B38F6A20C8A237DFEA4A8FBB789
337 | 96521E83BE5C52D4EBAB102D451A40A9C789888A43745C16D078A0498C07BA8B
338 | BBC461F02C9A9F5C023DEDBFABE4F95065A0E51AF45FFFB93001640CE531C11D
339 | 20DB2EC70385DFA96BFDCDFDE83BF93B19951F91B0D07A75FF7CB6BF07E8EF12
340 | FC7B676324DADF0076AF1007F977E3ED7FDE8A0F5F1725A48C0947F0A218F87F
341 | 6C00930ABC02155D322A1FF6AF055A5E90C1E8A4DADB70A4E1F6B2ACFB03A862
342 | A27C69159A649853021623C955E477A6FC0489F9F2ED40D75199181EAE6744DD
343 | AF879E11A5A38C5119B65D7E1FFA6498D30308C47470B3AFEF0B8C8476BE7F3C
344 | A08FFCF4DBB15FAF40E2D49B322A4F12A2DB8F46B1598626830C8089D819AAF1
345 | E9F30163D1F116F0DA72190CE6DC9F7E8DD37BBCF386BC5D541B3857DB8B4619
346 | 9A0C32005B847488E12919961FEFFF1438FC9C0CFA497ED482235BBE4E03E1B2
347 | 271CC2D39F7A1829199A0CEE01044A18EB134A99AE1942E381DF7E03387FD80C
348 | B99646F313F562A6E8BFF70F0B259304AFA9C47A9AF1C994C95003DC8AC33136
349 | B89B282BF46E311EA817E382148E3E772F9267F7CA0FCA9BEA6A345DB56AE84D
350 | BFA106A06B0231AC2BCBC1E0009D7F4062CBDFE0CC5BFE5E83205F68F0178F62
351 | DDC0DC3F97612B9FB9C5D8E5784B1402FBF60D548678CF714EF588D1FF47A6E9
352 | 3D81C1EDA9BC6115EF7EF67A5CA7DC3CF42DB011BF3A7F025F499EC373B66C20
353 | C1C5FFB2EE57E26F77FFBDD4AEA4A88F1E78CE434BB6E3E8B36230AA5ADBF18A
354 | AF674C8A62F19CEFE119991AC488E2D276A37A27DE5435CC9529EBD044EBFF17
355 | D131316FBF99EE24E9CE36BCFDC00CB0B0B5068800FB7A2B31F7F3ABE98D9AA1
356 | 8CD80F5377C1C2B0E6C67A806B54C4B06A24F189510B31FB3A1A79A88C670465
357 | 4E4445D3EC35A35FDE1F7324A644B03CC1E905FD003F915290AD8961F9C5F3FE
358 | 8B19DB00B7E140AC023F9661804FA855F1C8ACD5F8930C47646C030807B16A3C
359 | A885D12253011E27A4A2AD3A8A55321C95310D408801616F28826F95ED25E232
360 | 22291A6C551877CD5C8D6E991A95BC0C408852B02B16C1F8B874E6632E0B63FD
361 | ECEFE6FF7457DE0620943056E82AF6CBB0340C1A9B043F1FFF948EAAA0399AC5
362 | 7D32CC8B82AFF2F1065C9BECC49E3847954C158EF8BE676BEA70963A29EBAF33
363 | FA1243CFA0A7F5D5A2CF47862331A51A7F9DCFC02F97A2FE3AFE049625DBB121
364 | 5E519A7C47CE0923E455A90246C3BCDC1BC11D73BE8FC7642A6F0A2A0103B0DB
365 | B131565BFA2613575D064C2A745B80802108F11F29467CA2280310EC0A7C8747
366 | B05586451398A0346261BC943957FC861F2575E17C3B6A94937819D9D26F1B07
367 | E5A070E846CF659598376375F12BBD953C04E3BFC164FD345E0DE99825534513
368 | 98207FD4105AA654E1739F5E8992D6AB29BA040CC0FE1E67D44BB1400BA3E485
369 | 728372901FA2B19DB8BC120B4A159F28D90004BB096D6A15EA340426B01D86E3
370 | 136A5037ED7E6B2ECD975C0272E1CF629ADE8E1D4139B08790382D9F9C808556
371 | 894F58D2030C60F604D5F89C189D94BCD94FD0130C86067CB5B59867A5F884A5
372 | 0620D8529C31A2F8423045B40E9AEAD1687F960535FF622C3700C16E4137BB12
373 | 5FE1157838912CED42F77836015DE1AB8EE1A7C6747CA994A9DE68583A06180E
374 | F3B2710A3F2BE9DE8160BC8D09E8DAFE27AAF0AFD73E88C765CA166C37004137
375 | 9078279E5239E6C854518C17138443785F88BF74C6CAC26EEC14832D25E06258
376 | 3DF6AB5370038FE227A53C5452EEE580DEDFAB8CE0D11997E02F9D109F70A407
377 | C8C568C07CAD0B8F8AA9E215325530E5D813D0635C5531DC357BB5B34BF538D2
378 | 03E4A2D463975A81393C8E878A7DDAB89C7A82B4826C6518FF7D490C739C169F
379 | 70BC07C8856FC26CA30F0FB12CFE56A60AC2EF3D41348C5DD515583E6B15F6C9
380 | 94E3B86A8001F8062CE429AC4977E3FA42DF45F49B09E84DDD4B54ECAB8960D5
381 | D50F62EB58CFEDDB8D270C40D0BB88C8E2CB62F2BB32D189EB0A31821F4C40C2
382 | D786F06E3C82EF7DE65A3C3FDC9BBA6EE019030C601860C626D41949DC9DEAC2
383 | 827805AD6C36365E354126015E5383A6EA28D65D3D1B2F7A45F8013C67805CF8
384 | F3986974E24E4DC3D7B46E4C1EAB57F08A09A8B5D3824CE1303609E1D7CF5CED
385 | DDE5F83D6D8001F87644D1217A851416335D94091D13E4474370D30421A0371C
386 | C2D658185BAA6AD1F8A97B9172BBC68F852F0C900B7F031568C33C238145DCC0
387 | FC8C8699715D4C6773BE8913262055C514CEA08597454BDF5511C18BB55568CA
388 | 5D84D10FF8CE000388B182F96F371A30151A6E3432B8C1D031370DCC462FAA8F
389 | 74013D7DD6ACFE421B2CD11E3B31864444C1FBA2A5BF1D51B18785F03B73D5ED
390 | 076078BDA58F846F0D301CA6299E41D8C8629A183A5E73E0006666B298AE734C
391 | 111F7F52D3318933D42A6954F585118DCBEF4F35BB328BB411452FE3E80CA9E6
392 | 6EAAA7CD7DF518DA62211C8946D03C7D0A5A71BB68F83E157B28C0FF032953D1
393 | 09FE65A60D0000000049454E44AE426082}
394 | FileName = 'C:\Users\Kamel\Desktop\download-ga42fd477b_640 (1).ico'
395 | end>
396 | Align = Top
397 | Size.Width = 60.000000000000000000
398 | Size.Height = 50.000000000000000000
399 | Size.PlatformDefault = False
400 | end
401 | end
402 | end
403 | object OpenDialog1: TOpenDialog
404 | Left = 544
405 | Top = 96
406 | end
407 | object Panel1: TPanel
408 | Align = Top
409 | Position.Y = 257.000000000000000000
410 | Size.Width = 596.000000000000000000
411 | Size.Height = 144.000000000000000000
412 | Size.PlatformDefault = False
413 | TabOrder = 1
414 | object Label9: TLabel
415 | Position.X = 9.000000000000000000
416 | Position.Y = 11.000000000000000000
417 | Size.Width = 80.000000000000000000
418 | Size.Height = 17.000000000000000000
419 | Size.PlatformDefault = False
420 | Text = 'Url Samples :'
421 | TabOrder = 9
422 | end
423 | object Label1: TLabel
424 | Position.X = 8.000000000000000000
425 | Position.Y = 85.000000000000000000
426 | Size.Width = 112.000000000000000000
427 | Size.Height = 24.000000000000000000
428 | Size.PlatformDefault = False
429 | Text = 'Number of Threads :'
430 | TabOrder = 6
431 | end
432 | object ComboBox1: TComboBox
433 | Items.Strings = (
434 | '2'
435 | '4'
436 | '8'
437 | '16')
438 | ItemIndex = 2
439 | Position.X = 120.000000000000000000
440 | Position.Y = 88.000000000000000000
441 | Size.Width = 65.000000000000000000
442 | Size.Height = 22.000000000000000000
443 | Size.PlatformDefault = False
444 | TabOrder = 17
445 | OnChange = ComboBox1Change
446 | end
447 | object Button1: TButton
448 | Position.X = 258.000000000000000000
449 | Position.Y = 99.000000000000000000
450 | TabOrder = 2
451 | Text = 'Start'
452 | OnClick = Button1Click
453 | end
454 | object Button2: TButton
455 | Enabled = False
456 | Position.X = 347.000000000000000000
457 | Position.Y = 99.000000000000000000
458 | TabOrder = 4
459 | Text = 'Pause'
460 | OnClick = Button2Click
461 | end
462 | object Label2: TLabel
463 | Position.X = 9.000000000000000000
464 | Position.Y = 64.000000000000000000
465 | Size.Width = 96.000000000000000000
466 | Size.Height = 17.000000000000000000
467 | Size.PlatformDefault = False
468 | Text = 'Save location :'
469 | TabOrder = 7
470 | end
471 | object Edit2: TEdit
472 | Touch.InteractiveGestures = [LongTap, DoubleTap]
473 | TabOrder = 0
474 | ReadOnly = True
475 | Text =
476 | 'https://www.reaconverter.com/download/reaConverterStandard-Setup' +
477 | '.exe'
478 | Position.X = 104.000000000000000000
479 | Position.Y = 61.000000000000000000
480 | Enabled = False
481 | Size.Width = 457.000000000000000000
482 | Size.Height = 22.000000000000000000
483 | Size.PlatformDefault = False
484 | end
485 | object Button3: TButton
486 | Position.X = 561.000000000000000000
487 | Position.Y = 61.000000000000000000
488 | Size.Width = 24.000000000000000000
489 | Size.Height = 22.000000000000000000
490 | Size.PlatformDefault = False
491 | TabOrder = 1
492 | Text = '....'
493 | OnClick = Button3Click
494 | end
495 | object Label6: TLabel
496 | Position.X = 7.000000000000000000
497 | Position.Y = 110.000000000000000000
498 | Size.Width = 89.000000000000000000
499 | Size.Height = 24.000000000000000000
500 | Size.PlatformDefault = False
501 | Text = 'Progress Style :'
502 | TabOrder = 5
503 | end
504 | object ComboBox2: TComboBox
505 | Items.Strings = (
506 | 'Arcs and Pies'
507 | 'Arcs Only'
508 | 'Pies Only')
509 | ItemIndex = 0
510 | Position.X = 119.000000000000000000
511 | Position.Y = 114.000000000000000000
512 | Size.Width = 108.000000000000000000
513 | Size.Height = 22.000000000000000000
514 | Size.PlatformDefault = False
515 | TabOrder = 3
516 | OnChange = ComboBox2Change
517 | end
518 | object Button4: TButton
519 | Position.X = 464.000000000000000000
520 | Position.Y = 98.000000000000000000
521 | Size.Width = 121.000000000000000000
522 | Size.Height = 22.000000000000000000
523 | Size.PlatformDefault = False
524 | TabOrder = 18
525 | Text = 'Mask details <<'
526 | OnClick = Button4Click
527 | end
528 | object ComboBox3: TComboBox
529 | Items.Strings = (
530 |
531 | 'http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflo' +
532 | 'wer_1080p_30fps_normal.mp4'
533 |
534 | 'https://downloads.realvnc.com/download/file/vnc.files/VNC-Server' +
535 | '-6.9.1-Windows.exe?_gda=2.224252188.641449548.1654009827-21240'
536 | 'https://github.com/kamel78/DBPL/archive/refs/heads/master.zip')
537 | Position.X = 96.000000000000000000
538 | Position.Y = 9.000000000000000000
539 | Size.Width = 489.000000000000000000
540 | Size.Height = 22.000000000000000000
541 | Size.PlatformDefault = False
542 | TabOrder = 19
543 | OnChange = ComboBox3Change
544 | end
545 | object Label7: TLabel
546 | Position.X = 9.000000000000000000
547 | Position.Y = 36.000000000000000000
548 | Size.Width = 33.000000000000000000
549 | Size.Height = 17.000000000000000000
550 | Size.PlatformDefault = False
551 | Text = 'URL :'
552 | TabOrder = 8
553 | end
554 | object Edit1: TEdit
555 | Touch.InteractiveGestures = [LongTap, DoubleTap]
556 | TabOrder = 20
557 | Position.X = 40.000000000000000000
558 | Position.Y = 35.000000000000000000
559 | Size.Width = 545.000000000000000000
560 | Size.Height = 22.000000000000000000
561 | Size.PlatformDefault = False
562 | end
563 | end
564 | object Layout12: TLayout
565 | Align = Client
566 | Size.Width = 596.000000000000000000
567 | Size.Height = 220.000000000000000000
568 | Size.PlatformDefault = False
569 | TabOrder = 3
570 | object StringGrid1: TStringGrid
571 | Align = Client
572 | CanFocus = True
573 | ClipChildren = True
574 | Size.Width = 596.000000000000000000
575 | Size.Height = 220.000000000000000000
576 | Size.PlatformDefault = False
577 | TabOrder = 0
578 | RowCount = 0
579 | Viewport.Width = 592.000000000000000000
580 | Viewport.Height = 195.000000000000000000
581 | object StringColumn1: TStringColumn
582 | Size.Width = 41.000000000000000000
583 | end
584 | object StringColumn2: TStringColumn
585 | end
586 | object StringColumn3: TStringColumn
587 | Size.Width = 178.000000000000000000
588 | end
589 | object StringColumn4: TStringColumn
590 | Size.Width = 247.000000000000000000
591 | end
592 | end
593 | end
594 | end
595 |
--------------------------------------------------------------------------------
/Demo/MainForm.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/MainForm.pas
--------------------------------------------------------------------------------
/Demo/MultiCircularProgress.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Demo/MultiCircularProgress.pas
--------------------------------------------------------------------------------
/Demo/__history/HttpDownloadDemo.dpr.~1~:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------
2 |
3 | // This software is Copyright (c) 2015 Embarcadero Technologies, Inc.
4 | // You may only use this software if you are an authorized licensee
5 | // of an Embarcadero developer tools product.
6 | // This software is considered a Redistributable as defined under
7 | // the software license agreement that comes with the Embarcadero Products
8 | // and is subject to that software license agreement.
9 |
10 | //---------------------------------------------------------------------------
11 |
12 | program HttpDownloadDemo;
13 |
14 | uses
15 | System.StartUpCopy,
16 | FMX.Forms,
17 | MultiCircularProgress in 'MultiCircularProgress.pas',
18 | ThredingFileDownloader in 'ThredingFileDownloader.pas',
19 | MainForm in 'MainForm.pas' {Form1};
20 |
21 | {$R *.res}
22 |
23 | begin
24 | Application.Initialize;
25 | Application.CreateForm(TForm1, Form1);
26 | Application.Run;
27 | end.
28 |
--------------------------------------------------------------------------------
/DemoCapture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/DemoCapture.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Faraoun Kamel Mohamed
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Package/HttpParallelDownloader.dpk:
--------------------------------------------------------------------------------
1 | package HttpParallelDownloader;
2 |
3 | {$R *.res}
4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
5 | {$ALIGN 8}
6 | {$ASSERTIONS ON}
7 | {$BOOLEVAL OFF}
8 | {$DEBUGINFO OFF}
9 | {$EXTENDEDSYNTAX ON}
10 | {$IMPORTEDDATA ON}
11 | {$IOCHECKS ON}
12 | {$LOCALSYMBOLS ON}
13 | {$LONGSTRINGS ON}
14 | {$OPENSTRINGS ON}
15 | {$OPTIMIZATION OFF}
16 | {$OVERFLOWCHECKS OFF}
17 | {$RANGECHECKS OFF}
18 | {$REFERENCEINFO ON}
19 | {$SAFEDIVIDE OFF}
20 | {$STACKFRAMES ON}
21 | {$TYPEDADDRESS OFF}
22 | {$VARSTRINGCHECKS ON}
23 | {$WRITEABLECONST OFF}
24 | {$MINENUMSIZE 1}
25 | {$IMAGEBASE $400000}
26 | {$DEFINE DEBUG}
27 | {$ENDIF IMPLICITBUILDING}
28 | {$IMPLICITBUILD ON}
29 |
30 | requires
31 | rtl;
32 |
33 | contains
34 | ThredingFileDownloader in 'ThredingFileDownloader.pas';
35 |
36 | end.
37 |
--------------------------------------------------------------------------------
/Package/HttpParallelDownloader.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {7C82F406-AC23-4785-8CA7-A16BBEFFEB24}
4 | HttpParallelDownloader.dpk
5 | 18.7
6 | FMX
7 | True
8 | Debug
9 | Win32
10 | 1
11 | Package
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | true
28 | Base
29 | true
30 |
31 |
32 | true
33 | Base
34 | true
35 |
36 |
37 | true
38 | Base
39 | true
40 |
41 |
42 | true
43 | Base
44 | true
45 |
46 |
47 | true
48 | Cfg_1
49 | true
50 | true
51 |
52 |
53 | true
54 | Base
55 | true
56 |
57 |
58 | .\$(Platform)\$(Config)
59 | .\$(Platform)\$(Config)
60 | false
61 | false
62 | false
63 | false
64 | false
65 | true
66 | true
67 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
68 | All
69 | HttpParallelDownloader
70 |
71 |
72 | None
73 | android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar
74 |
75 |
76 | None
77 |
78 |
79 | None
80 |
81 |
82 | None
83 |
84 |
85 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
86 | Debug
87 | true
88 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
89 | 1033
90 |
91 |
92 | DEBUG;$(DCC_Define)
93 | true
94 | false
95 | true
96 | true
97 | true
98 |
99 |
100 | false
101 |
102 |
103 | false
104 | RELEASE;$(DCC_Define)
105 | 0
106 | 0
107 |
108 |
109 |
110 | MainSource
111 |
112 |
113 |
114 |
115 | Cfg_2
116 | Base
117 |
118 |
119 | Base
120 |
121 |
122 | Cfg_1
123 | Base
124 |
125 |
126 |
127 | Delphi.Personality.12
128 | Package
129 |
130 |
131 |
132 | HttpParallelDownloader.dpk
133 |
134 |
135 |
136 |
137 |
138 | true
139 |
140 |
141 |
142 |
143 | true
144 |
145 |
146 |
147 |
148 | true
149 |
150 |
151 |
152 |
153 | HttpParallelDownloader.bpl
154 | true
155 |
156 |
157 |
158 |
159 | 1
160 |
161 |
162 | 0
163 |
164 |
165 |
166 |
167 | classes
168 | 1
169 |
170 |
171 |
172 |
173 | res\xml
174 | 1
175 |
176 |
177 |
178 |
179 | library\lib\armeabi-v7a
180 | 1
181 |
182 |
183 |
184 |
185 | library\lib\armeabi
186 | 1
187 |
188 |
189 |
190 |
191 | library\lib\mips
192 | 1
193 |
194 |
195 |
196 |
197 | library\lib\armeabi-v7a
198 | 1
199 |
200 |
201 |
202 |
203 | res\drawable
204 | 1
205 |
206 |
207 |
208 |
209 | res\values
210 | 1
211 |
212 |
213 |
214 |
215 | res\values-v21
216 | 1
217 |
218 |
219 |
220 |
221 | res\values
222 | 1
223 |
224 |
225 |
226 |
227 | res\drawable
228 | 1
229 |
230 |
231 |
232 |
233 | res\drawable-xxhdpi
234 | 1
235 |
236 |
237 |
238 |
239 | res\drawable-ldpi
240 | 1
241 |
242 |
243 |
244 |
245 | res\drawable-mdpi
246 | 1
247 |
248 |
249 |
250 |
251 | res\drawable-hdpi
252 | 1
253 |
254 |
255 |
256 |
257 | res\drawable-xhdpi
258 | 1
259 |
260 |
261 |
262 |
263 | res\drawable-mdpi
264 | 1
265 |
266 |
267 |
268 |
269 | res\drawable-hdpi
270 | 1
271 |
272 |
273 |
274 |
275 | res\drawable-xhdpi
276 | 1
277 |
278 |
279 |
280 |
281 | res\drawable-xxhdpi
282 | 1
283 |
284 |
285 |
286 |
287 | res\drawable-xxxhdpi
288 | 1
289 |
290 |
291 |
292 |
293 | res\drawable-small
294 | 1
295 |
296 |
297 |
298 |
299 | res\drawable-normal
300 | 1
301 |
302 |
303 |
304 |
305 | res\drawable-large
306 | 1
307 |
308 |
309 |
310 |
311 | res\drawable-xlarge
312 | 1
313 |
314 |
315 |
316 |
317 | res\values
318 | 1
319 |
320 |
321 |
322 |
323 | 1
324 |
325 |
326 | 1
327 |
328 |
329 | 0
330 |
331 |
332 |
333 |
334 | 1
335 | .framework
336 |
337 |
338 | 1
339 | .framework
340 |
341 |
342 | 0
343 |
344 |
345 |
346 |
347 | 1
348 | .dylib
349 |
350 |
351 | 1
352 | .dylib
353 |
354 |
355 | 0
356 | .dll;.bpl
357 |
358 |
359 |
360 |
361 | 1
362 | .dylib
363 |
364 |
365 | 1
366 | .dylib
367 |
368 |
369 | 1
370 | .dylib
371 |
372 |
373 | 1
374 | .dylib
375 |
376 |
377 | 1
378 | .dylib
379 |
380 |
381 | 0
382 | .bpl
383 |
384 |
385 |
386 |
387 | 0
388 |
389 |
390 | 0
391 |
392 |
393 | 0
394 |
395 |
396 | 0
397 |
398 |
399 | 0
400 |
401 |
402 | 0
403 |
404 |
405 | 0
406 |
407 |
408 |
409 |
410 | 1
411 |
412 |
413 | 1
414 |
415 |
416 | 1
417 |
418 |
419 |
420 |
421 | 1
422 |
423 |
424 | 1
425 |
426 |
427 | 1
428 |
429 |
430 |
431 |
432 | 1
433 |
434 |
435 | 1
436 |
437 |
438 | 1
439 |
440 |
441 |
442 |
443 | 1
444 |
445 |
446 | 1
447 |
448 |
449 | 1
450 |
451 |
452 |
453 |
454 | 1
455 |
456 |
457 | 1
458 |
459 |
460 | 1
461 |
462 |
463 |
464 |
465 | 1
466 |
467 |
468 | 1
469 |
470 |
471 | 1
472 |
473 |
474 |
475 |
476 | 1
477 |
478 |
479 | 1
480 |
481 |
482 | 1
483 |
484 |
485 |
486 |
487 | 1
488 |
489 |
490 | 1
491 |
492 |
493 | 1
494 |
495 |
496 |
497 |
498 | 1
499 |
500 |
501 | 1
502 |
503 |
504 | 1
505 |
506 |
507 |
508 |
509 | 1
510 |
511 |
512 | 1
513 |
514 |
515 | 1
516 |
517 |
518 |
519 |
520 | 1
521 |
522 |
523 | 1
524 |
525 |
526 | 1
527 |
528 |
529 |
530 |
531 | 1
532 |
533 |
534 | 1
535 |
536 |
537 | 1
538 |
539 |
540 |
541 |
542 | 1
543 |
544 |
545 | 1
546 |
547 |
548 | 1
549 |
550 |
551 |
552 |
553 | 1
554 |
555 |
556 | 1
557 |
558 |
559 | 1
560 |
561 |
562 |
563 |
564 | 1
565 |
566 |
567 | 1
568 |
569 |
570 | 1
571 |
572 |
573 |
574 |
575 | 1
576 |
577 |
578 | 1
579 |
580 |
581 | 1
582 |
583 |
584 |
585 |
586 | 1
587 |
588 |
589 | 1
590 |
591 |
592 | 1
593 |
594 |
595 |
596 |
597 | 1
598 |
599 |
600 | 1
601 |
602 |
603 | 1
604 |
605 |
606 |
607 |
608 | 1
609 |
610 |
611 | 1
612 |
613 |
614 | 1
615 |
616 |
617 |
618 |
619 | 1
620 |
621 |
622 | 1
623 |
624 |
625 | 1
626 |
627 |
628 |
629 |
630 | 1
631 |
632 |
633 | 1
634 |
635 |
636 | 1
637 |
638 |
639 |
640 |
641 | 1
642 |
643 |
644 | 1
645 |
646 |
647 | 1
648 |
649 |
650 |
651 |
652 | 1
653 |
654 |
655 | 1
656 |
657 |
658 | 1
659 |
660 |
661 |
662 |
663 | 1
664 |
665 |
666 | 1
667 |
668 |
669 | 1
670 |
671 |
672 |
673 |
674 | 1
675 |
676 |
677 |
678 |
679 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
680 | 1
681 |
682 |
683 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
684 | 1
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 | 1
693 |
694 |
695 | 1
696 |
697 |
698 | 1
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 | Contents\Resources
707 | 1
708 |
709 |
710 | Contents\Resources
711 | 1
712 |
713 |
714 |
715 |
716 | library\lib\armeabi-v7a
717 | 1
718 |
719 |
720 | 1
721 |
722 |
723 | 1
724 |
725 |
726 | 1
727 |
728 |
729 | 1
730 |
731 |
732 | 1
733 |
734 |
735 | 1
736 |
737 |
738 | 0
739 |
740 |
741 |
742 |
743 | 1
744 |
745 |
746 | 1
747 |
748 |
749 |
750 |
751 | Assets
752 | 1
753 |
754 |
755 | Assets
756 | 1
757 |
758 |
759 |
760 |
761 | Assets
762 | 1
763 |
764 |
765 | Assets
766 | 1
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 | False
781 | False
782 | False
783 | False
784 | False
785 | False
786 | False
787 | True
788 | False
789 |
790 |
791 | 12
792 |
793 |
794 |
795 |
796 |
797 |
--------------------------------------------------------------------------------
/Package/HttpParallelDownloader.dproj.local:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2022/06/01 20:46:35.136,=rtl.dcp
5 | 2022/06/01 20:47:13.713,C:\Users\neptune\Desktop\HttpDownload\Package\HttpParallelDownloader.dproj=C:\Users\neptune\Documents\Embarcadero\Studio\Projets\Package1.dproj
6 | 2022/06/01 20:50:38.107,=C:\Users\neptune\Desktop\HttpDownload\Package\ThredingFileDownloader.pas
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Package/HttpParallelDownloader.identcache:
--------------------------------------------------------------------------------
1 | HC:\Users\neptune\Desktop\HttpDownload\Package\ThredingFileDownloader.pas @C:\Users\neptune\Desktop\HttpDownload\ThredingFileDownloader.pas
--------------------------------------------------------------------------------
/Package/HttpParallelDownloader.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/HttpParallelDownloader.res
--------------------------------------------------------------------------------
/Package/ThredingFileDownloader.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/ThredingFileDownloader.pas
--------------------------------------------------------------------------------
/Package/__history/HttpParallelDownloader.dpk.~1~:
--------------------------------------------------------------------------------
1 | package HttpParallelDownloader;
2 |
3 | {$R *.res}
4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
5 | {$ALIGN 8}
6 | {$ASSERTIONS ON}
7 | {$BOOLEVAL OFF}
8 | {$DEBUGINFO OFF}
9 | {$EXTENDEDSYNTAX ON}
10 | {$IMPORTEDDATA ON}
11 | {$IOCHECKS ON}
12 | {$LOCALSYMBOLS ON}
13 | {$LONGSTRINGS ON}
14 | {$OPENSTRINGS ON}
15 | {$OPTIMIZATION OFF}
16 | {$OVERFLOWCHECKS OFF}
17 | {$RANGECHECKS OFF}
18 | {$REFERENCEINFO ON}
19 | {$SAFEDIVIDE OFF}
20 | {$STACKFRAMES ON}
21 | {$TYPEDADDRESS OFF}
22 | {$VARSTRINGCHECKS ON}
23 | {$WRITEABLECONST OFF}
24 | {$MINENUMSIZE 1}
25 | {$IMAGEBASE $400000}
26 | {$DEFINE DEBUG}
27 | {$ENDIF IMPLICITBUILDING}
28 | {$IMPLICITBUILD ON}
29 |
30 | requires
31 | rtl;
32 |
33 | end.
34 |
--------------------------------------------------------------------------------
/Package/__history/ThredingFileDownloader.pas.~1~:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/__history/ThredingFileDownloader.pas.~1~
--------------------------------------------------------------------------------
/Package/__history/ThredingFileDownloader.pas.~2~:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamel78/Multi-Threading-Advanced-Http-Downloader/318cbd18f6515799eb7c33fa8f0f22d3bd5dd282/Package/__history/ThredingFileDownloader.pas.~2~
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Multi Threading Advanced Http Downloader
2 |
3 | TThredingFileDownloader
4 |
5 | An Embarcadero Rad Studio/Delphi component (FMX) for parallelized http/https files downloading. Download is parallelized using variable number of threads for acceleration. Several additional options are implemented including:
6 | - Pause/Resume of the download task at any progress phase. It is far away from a simple a threads suspension, while an internal progression state is automatically saved so the resume can be performed either is the application is close and restarted (a method ResumeFromTempFile permit to restart the download again at any time).
7 | - Automatic estimation of download speed (instant speed) and remaining time.
8 | - A sufficiently large set of event permitting a powerful control of the download progression : OnThredDownloadingData, OnDownloadTerminated, OnDownloadError, OnDownloadInfoUpdate, OnDownloadStarted, OnDownloadPaused, OnCannotResume, OnDownloadResumed, OnDownloadCanceled
9 | - Detailed download information per individual thread
10 |
11 | The included Demo program illustrate the use of the component conjointly with a special progress bar developed for such applications (installation of the package is not necessary to Run the Demo since the creation of the objects is done explicitly in the code).
12 | Tested on Rad 10.2/10.3 and should work for 10.4 and Alexandria.
13 | Designed for FMX Multi-resolution applications (Windows, Android and Mac …)
14 |
15 | Remarks and bugs report are welcome.
16 |
17 |
18 |
19 |
20 | 
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ThredingFileDownloader.pas:
--------------------------------------------------------------------------------
1 | unit ThredingFileDownloader;
2 |
3 | {********************************************************************************************
4 | Développer par Faraoun Kamel Mohamed
5 | Université Djilali Liabes -Sidi Bel Abbes - Algérie
6 | kamel_mh@yahoo.fr
7 |
8 | Multi-Thread Http Downloader component for FMX:Windows/Android/Mac...
9 | 01 June 2022
10 | ********************************************************************************************}
11 |
12 |
13 | interface
14 |
15 | uses System.Net.HttpClient,System.Classes,System.SysUtils,FMX.Types,System.SyncObjs,FMX.Forms,System.NetEncoding,System.ioutils;
16 |
17 | Type
18 |
19 | TSaveDownloadTrackState=Record
20 | tStart,tEnd,
21 | tProgress:Int64;
22 | End;
23 | TSaveDownloadState=array of TSaveDownloadTrackState;
24 | TDownloadThreadDataEvent = procedure(const Sender: TObject; ThreadNo, ASpeed: Integer;AReadCount: Int64; APercentage:Double; var Abort: Boolean) of object;
25 | TDownloadInfoUpdateEvent=procedure(const Sender: TObject;AverageSpeed:Double;DownloadedAmount:Int64;DownloadedPercentage:Double;EstimatedReminingTime:Int64)of object;
26 | TFilenameChangedEvent=procedure(const Sender:TObject;Oldname:string;NewName:string)of object;
27 | TCannotResumeInfo=procedure(Const Sender: TObject;var cancel:boolean)of object;
28 | TTrackDownloader = class(TThread)
29 | private
30 | FOnThreadData: TDownloadThreadDataEvent;
31 | protected
32 | FURL, FFileName: string;
33 | FStartPoint, FEndPoint: Int64;
34 | FThreadNo: Integer;
35 | FTimeStart: Cardinal;
36 | FThSaveState:TSaveDownloadState;
37 | FFileSize:Int64;
38 | procedure ReceiveDataEvent(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean);
39 | public
40 | constructor Create(const URL, FileName: string; ThreadNo: Integer; StartPoint, EndPoint: Int64);
41 | destructor Destroy; override;
42 | procedure Execute; override;
43 | property OnThreadData: TDownloadThreadDataEvent write FOnThreadData;
44 | end;
45 |
46 | TThredingFileDownloader= class
47 | private
48 | FDownloadThreads: array of TTrackDownloader;
49 | FCriticalSection:TCriticalSection;
50 | FThreadsDownloadedAmout:array of Int64;
51 | FDownloadedAmount:Int64;
52 | [volatile]FIncrementTester:Int64;
53 | FDownloadedPerCentage:Double;
54 | [volatile]FDownloadSpeed:Double;
55 | FEstimatedRemainingTime:Int64;
56 | FNumOfThreads,FDefaultNumOfThreads:integer;
57 | [volatile]FFinished:boolean;
58 | [volatile]FStopDownload: Boolean;
59 | FIsDownloading:boolean;
60 | FFileSize:int64;
61 | FCanResume:boolean;
62 | FFilename,FUrl:String;
63 | FSaveStateStream:TFileStream;
64 | FOnDownloadThreadData:TDownloadThreadDataEvent;
65 | FONDownloadStarted,FOnDownloadTerminated,
66 | FOnDownloadPaused,FOnDownloadResumed,
67 | FOnDownloadError,FOnDownloadCanceled:TNotifyEvent;
68 | FOnDownloadInfoUpdate:TDownloadInfoUpdateEvent;
69 | FOnCannotResume:TCannotResumeInfo;
70 | FonFilenameChanged:TFilenameChangedEvent;
71 | FSpeedCalculator:TTimer; // Used to compute
72 | FStartingDownload,FEndingDownload:Int64; // true instant download speed
73 | FStartingTime,FEndingTime:Cardinal;
74 | FSaveResumeProgress:TSaveDownloadState;
75 | FOutputPath:string;
76 | procedure ThreadReceiveDataHandler(const Sender: TObject; ThreadNo, ASpeed: Integer;AReadCount: Int64; APercentage:Double; var Abort: Boolean);
77 | procedure SpeedCalculatorEvent(Sender:Tobject);
78 | procedure _DoDownload(AskForResume:boolean=True);
79 | procedure _SaveDownloadState;
80 | procedure _SaveDownloadInfo;
81 | function _LoadDownloadState(wFilename:string):boolean;
82 | function _LoadDownloadInfo(wFilename: string):boolean;
83 | procedure _ResumeDownload;
84 | function _IndirectlyGetFileSize(wUrl:string):int64;
85 | procedure _IndirecrReceiveDataEvent(const Sender: TObject; AContentLength:Int64; AReadCount: Int64; var Abort: Boolean);
86 | function _CleanURL(wURL:string):string;
87 | public
88 | constructor Create;
89 | destructor destroy;override;
90 | procedure DoDownload;
91 | procedure PauseDownload;
92 | procedure ResumeDownload;
93 | procedure CancelDownload;
94 | function StandarizedSize(value:Int64):string;
95 | function ResumeFromTempFile(wFilename:String):integer;
96 | property NumOfThreads:integer read FDefaultNumOfThreads write FDefaultNumOfThreads default 4;
97 | property Filename:string read FFilename;
98 | property URL:string read FUrl write FUrl;
99 | property OnThredDownloadingData:TDownloadThreadDataEvent read FOnDownloadThreadData write FOnDownloadThreadData;
100 | property OnDownloadTerminated:TNotifyEvent read FOnDownloadTerminated write FOnDownloadTerminated;
101 | property OnDownloadError:TNotifyEvent read FOnDownloadError write FOnDownloadError;
102 | property OnDownloadInfoUpdate:TDownloadInfoUpdateEvent read FOnDownloadInfoUpdate write FOnDownloadInfoUpdate;
103 | property OnDownloadStarted :TNotifyEvent read FONDownloadStarted write FONDownloadStarted;
104 | property OnDownloadPaused:TNotifyEvent read FOnDownloadPaused write FOnDownloadPaused;
105 | property OnDownloadResumed:TNotifyEvent read FOnDownloadResumed write FOnDownloadResumed;
106 | property OnCannotResume:TCannotResumeInfo read FOnCannotResume write FOnCannotResume;
107 | property OnDownloadCanceled:TNotifyEvent read FOnDownloadCanceled write FOnDownloadCanceled;
108 | property ActiveFileSize:int64 read FFileSize;
109 | property OutputPath:string read FOutputPath write FOutputPath;
110 | property IsDownloading:boolean read FIsDownloading;
111 | property IsResumeSupported:boolean read FCanResume;
112 | end;
113 |
114 |
115 | implementation
116 | uses MainForm;
117 | { TThredingFileDownloader }
118 |
119 | ///*******************************************************************************************************************************************************//
120 | constructor TThredingFileDownloader.Create;
121 | begin
122 | FDefaultNumOfThreads:=4;
123 | FFinished:=False;
124 | FStopDownload:=False;
125 | FDownloadedAmount:=0;
126 | FDownloadedPerCentage:=0;
127 | FDownloadSpeed:=0;
128 | FSpeedCalculator:=TTimer.Create(nil);
129 | FSpeedCalculator.Parent:=nil;
130 | FSpeedCalculator.Interval:=2000;
131 | FSpeedCalculator.OnTimer:=SpeedCalculatorEvent;
132 | Setlength(FSaveResumeProgress,0);
133 | FOutputPath:=ExtractFilePath(ParamStr(0));
134 | end;
135 |
136 | ///*******************************************************************************************************************************************************//
137 | function TThredingFileDownloader._CleanURL(wURL: string): string;
138 | var tmp:string;
139 | begin
140 | tmp:=wURL;
141 | if not UpperCase(tmp).StartsWith('HTTP') then begin
142 | Result:='';
143 | exit;
144 | end;
145 | if pos('?',tmp)>0 then tmp:=Copy(tmp,1,Pos('?',tmp)-1);
146 | Result:=Tmp;
147 | end;
148 |
149 | ///*******************************************************************************************************************************************************//
150 | procedure TThredingFileDownloader._DoDownload;
151 | var wClient: THTTPClient;
152 | wResponse: IHTTPResponse;
153 | wStrmFile: TFileStream;
154 | wStart, wEnd, wSize, wFragSize: Int64;
155 | i: Integer;
156 | wFilename,zFilename:String;
157 | CancelDownload:boolean;
158 | begin
159 | wClient := THTTPClient.Create;
160 | wResponse := wClient.Head(FURL);
161 | if wResponse.StatusCode<>200 then begin
162 | if Assigned(FOnDownloadError) then TThread.Synchronize(nil,procedure
163 | begin
164 | FOnDownloadError(Self);
165 | end);
166 | exit;
167 | end;
168 | FStartingTime:=TThread.GetTickCount;
169 | FStartingDownload:=0;
170 | FCriticalSection:=TCriticalSection.Create;
171 | try
172 | try
173 | FURL:=_CleanURL(FURL);
174 | if FURL='' then begin
175 | raise Exception.Create('Invalid Url for download, only http/https protocols are supported .....');
176 | exit;
177 | end;
178 | FCanResume:=wClient.CheckDownloadResume(FURL);
179 | if FCanResume then FNumOfThreads:=FDefaultNumOfThreads
180 | else begin
181 | FNumOfThreads:=1;
182 | CancelDownload:=False;
183 | if Assigned(FOnCannotResume)and AskForResume then TThread.Synchronize(nil,procedure begin FOnCannotResume(Self,CancelDownload);end);
184 | if CancelDownload then exit;
185 | end;
186 | wSize := wResponse.ContentLength;
187 | if wSize=-1 then wSize:=_IndirectlyGetFileSize(Furl);
188 | FFilename:=ExtractFileName(URL.Replace('/','\'));
189 | if wResponse.ContainsHeader('Content-Disposition')
190 | then wFilename:=wResponse.GetHeaderValue('Content-Disposition')
191 | else if wResponse.ContainsHeader('content-disposition')
192 | then wFilename:=wResponse.GetHeaderValue('content-disposition')
193 | else wFilename:='';
194 | if wFilename<>'' then begin
195 | if pos('"',wFilename)>0 then wFilename:=wFilename.Split(['"'])[1]
196 | else wFilename:=wFilename.Split(['='])[1];
197 | end;
198 | if wFilename<>'' then FFilename:=wFilename
199 | else if FFilename='' then raise Exception.Create('Unknown file name, download cannot be performed ...');
200 | FFileSize:=wSize;
201 | SetLength(FDownloadThreads, FNumOfThreads);
202 | SetLength(FThreadsDownloadedAmout, FNumOfThreads);
203 | SetLength(FSaveResumeProgress, FNumOfThreads);
204 | wStrmFile := TFileStream.Create(FOutputPath+'_'+FFileName+'.temporary', fmCreate);
205 | try
206 | wStrmFile.Size := wSize+(FNumOfThreads*24+1)+(Length(TEncoding.UTF8.GetBytes(FURL))+2);
207 | finally
208 | wStrmFile.Free;
209 | end;
210 | FSaveStateStream:= TFileStream.Create(FOutputPath+'_'+FFileName+'.temporary', fmOpenWrite or fmShareDenyNone);
211 | _SaveDownloadInfo;
212 | wFragSize := wSize div FNumOfThreads;
213 | wStart := 0;
214 | wEnd := wStart + wFragSize;
215 | for i := 0 to FNumOfThreads-1 do begin
216 | if FFinished then Break;
217 | FThreadsDownloadedAmout[i]:=0;
218 | FDownloadThreads[I] := TTrackDownloader.Create(URL, FOutputPath+'_'+FFileName+'.temporary', i, wStart, wEnd);
219 | FDownloadThreads[I].OnThreadData := ThreadReceiveDataHandler;
220 | FDownloadThreads[I].FThSaveState:=FSaveResumeProgress;
221 | FDownloadThreads[I].FFileSize:=FFileSize;
222 | FSaveResumeProgress[I].tStart:=wStart;
223 | FSaveResumeProgress[I].tEnd:=wEnd;
224 | FSaveResumeProgress[i].tProgress:=0;
225 | wStart := wStart + wFragSize;
226 | wEnd := wStart + wFragSize;
227 | end;
228 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Start;
229 | FIsDownloading:=True;
230 | if Assigned(FONDownloadStarted) then TThread.Synchronize(nil,procedure begin FONDownloadStarted(Self);end);
231 | FSpeedCalculator.Enabled:=True;
232 | FFinished := False;
233 | while not FFinished do begin
234 | FFinished := True;
235 | for i := 0 to FNumOfThreads-1 do FFinished := FFinished and FDownloadThreads[I].Finished;
236 | end;
237 | FSpeedCalculator.Enabled:=False;
238 | FIsDownloading:=False;
239 | FFinished:=False;
240 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Free;
241 | SetLength(FDownloadThreads,0);
242 | SetLength(FThreadsDownloadedAmout,0);
243 | if not FStopDownload then begin
244 | SetLength(FSaveResumeProgress,0);
245 | if Assigned(FOnDownloadTerminated) then TThread.Synchronize(nil,procedure begin FOnDownloadTerminated(Self);end);
246 | end;
247 | Except
248 | if Assigned(FOnDownloadError) then TThread.Synchronize(nil,procedure begin FOnDownloadError(Self);end);
249 | end;
250 | finally
251 | wClient.Free;
252 | FCriticalSection.Free;
253 | if not CancelDownload then begin
254 | if not FStopDownload then FSaveStateStream.Size:=FSaveStateStream.Size-FNumOfThreads*24-1-Length(TEncoding.UTF8.GetBytes(FURL))-2;
255 | FSaveStateStream.Free;
256 | if not FStopDownload then begin
257 | i:=0;
258 | wFilename:=FFilename;
259 | zFilename:=FFilename;
260 | if FileExists(wFilename) then begin
261 | repeat
262 | i:=i+1;
263 | wFilename:=Tpath.GetFileNameWithoutExtension(FFilename)+i.ToString+ExtractFileExt(FFilename);
264 | until (not FileExists(wFilename));
265 | RenameFile(FOutputPath+'_'+FFileName+'.temporary',FOutputPath+wFilename);
266 | FFilename:=wFilename;
267 | if Assigned(FonFilenameChanged) then TThread.Synchronize(nil,procedure
268 | begin
269 | FonFilenameChanged(Self,zFilename,FFilename);
270 | end);
271 | end
272 | else RenameFile(FOutputPath+'_'+FFileName+'.temporary',FOutputPath+FFilename);
273 | end;
274 | end;
275 | FStopDownload:=False;
276 | end;
277 | end;
278 |
279 | ///*******************************************************************************************************************************************************//
280 | procedure TThredingFileDownloader.CancelDownload;
281 | begin
282 | if not FIsDownloading then exit;
283 | FStopDownload:=True;
284 | Sleep(50);
285 | Repeat
286 | Application.ProcessMessages;
287 | until not FStopDownload;
288 | if Assigned(FOnDownloadCanceled) then FOnDownloadCanceled(Self);
289 | end;
290 |
291 | ///*******************************************************************************************************************************************************//
292 | procedure TThredingFileDownloader._ResumeDownload;
293 | var wClient: THTTPClient;
294 | wResponse: IHTTPResponse;
295 | wStrmFile: TFileStream;
296 | wStart, wEnd, wSize, wFragSize: Int64;
297 | i: Integer;
298 | wFilename,zFilename:String;
299 | cancel:boolean;
300 | begin
301 | wClient := THTTPClient.Create;
302 | FStartingTime:=TThread.GetTickCount;
303 | FStartingDownload:=0;
304 | FCriticalSection:=TCriticalSection.Create;
305 | try
306 | try
307 | if FCanResume then begin
308 | FNumOfThreads:=length(FSaveResumeProgress);
309 | wFragSize := wSize div FNumOfThreads;
310 | SetLength(FDownloadThreads, FNumOfThreads);
311 | SetLength(FThreadsDownloadedAmout, FNumOfThreads);
312 | for i := 0 to FNumOfThreads-1 do
313 | begin
314 | if FFinished then Break;
315 | FDownloadThreads[I] := TTrackDownloader.Create(URL, FOutputPath+'_'+FFileName+'.temporary', i, FSaveResumeProgress[i].tStart+FSaveResumeProgress[i].tProgress, FSaveResumeProgress[i].tEnd);
316 | FDownloadThreads[I].OnThreadData := ThreadReceiveDataHandler;
317 | FDownloadThreads[I].FThSaveState:=FSaveResumeProgress;
318 | FDownloadThreads[I].FFileSize:=FFileSize;
319 | end;
320 | FSaveStateStream:= TFileStream.Create(FOutputPath+'_'+FFileName+'.temporary', fmOpenWrite or fmShareDenyNone);
321 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Start;
322 | if Assigned(FOnDownloadResumed) then TThread.Synchronize(nil,procedure begin FOnDownloadResumed(Self);end);
323 | FSpeedCalculator.Enabled:=True;
324 | FFinished := False;
325 | while not FFinished do
326 | begin
327 | FFinished := True;
328 | for i := 0 to FNumOfThreads-1 do FFinished := FFinished and FDownloadThreads[I].Finished;
329 | end;
330 | FSpeedCalculator.Enabled:=False;
331 | for i := 0 to FNumOfThreads-1 do FDownloadThreads[I].Free;
332 | FIsDownloading:=False;
333 | FFinished:=False;
334 | if not FStopDownload then
335 | if Assigned(FOnDownloadTerminated) then TThread.Synchronize(nil,procedure begin FOnDownloadTerminated(Self);end);
336 | end
337 | else begin
338 | Cancel:=true;
339 | if Assigned(FOnCannotResume) then TThread.Synchronize(nil,procedure begin FOnCannotResume(Self,Cancel);end);
340 | if not cancel then _DoDownload(False);
341 | end;
342 | Except
343 | if Assigned(FOnDownloadError) then FOnDownloadError(Self);
344 | end;
345 | finally
346 | wClient.Free;
347 | FCriticalSection.Free;
348 | if not FStopDownload then FSaveStateStream.Size:=FSaveStateStream.Size-FNumOfThreads*24-1-Length(TEncoding.UTF8.GetBytes(FURL))-2;
349 | FSaveStateStream.Free;
350 | if not FStopDownload then begin
351 | i:=0;
352 | wFilename:=FFilename;
353 | zFilename:=FFilename;
354 | if FileExists(wFilename) then begin
355 | repeat
356 | i:=i+1;
357 | wFilename:=Tpath.GetFileNameWithoutExtension(FFilename)+i.ToString+ExtractFileExt(FFilename);
358 | until (not FileExists(wFilename));
359 | RenameFile('_'+FFileName+'.temporary',wFilename);
360 | FFilename:=wFilename;
361 | if Assigned(FonFilenameChanged) then TThread.Synchronize(nil,procedure
362 | begin
363 | FonFilenameChanged(Self,zFilename,FFilename);
364 | end);
365 | end
366 | else RenameFile('_'+FFileName+'.temporary',FFilename);
367 |
368 | end;
369 | FStopDownload:=False;
370 | end;
371 | end;
372 |
373 | ///*******************************************************************************************************************************************************//
374 | procedure TThredingFileDownloader._SaveDownloadInfo;
375 | var Tmp:TBytes;
376 | wSaveResumeInfo:TSaveDownloadState;
377 | i:integer;
378 | wLength:Word;
379 | begin
380 | Tmp:=TEncoding.UTF8.GetBytes(FURL);
381 | wLength:=Length(Tmp);
382 | Setlength(Tmp,Length(Tmp)+2);
383 | Tmp[Length(Tmp)-2]:=Hi(wLength);
384 | Tmp[Length(Tmp)-1]:=Lo(wLength);
385 | try
386 | FSaveStateStream.Seek(FFileSize, TSeekOrigin.soBeginning);
387 | FSaveStateStream.Write(Tmp,length(Tmp));
388 | finally
389 | end;
390 | end;
391 |
392 | ///*******************************************************************************************************************************************************//
393 | procedure TThredingFileDownloader._SaveDownloadState;
394 | var Tmp:TBytes;
395 | wSaveResumeProgress:TSaveDownloadState;
396 | i:integer;
397 | begin
398 | Setlength(wSaveResumeProgress,length(FSaveResumeProgress));
399 | for i:=0 to Length(FSaveResumeProgress)-1 do begin
400 | wSaveResumeProgress[i].tStart:=FSaveResumeProgress[i].tStart;
401 | wSaveResumeProgress[i].tEnd:=FSaveResumeProgress[i].tEnd;
402 | wSaveResumeProgress[i].tProgress:=FThreadsDownloadedAmout[i];
403 | end;
404 |
405 | SetLength(Tmp,length(wSaveResumeProgress)*24+1);
406 | Tmp[length(Tmp)-1]:=length(FSaveResumeProgress);
407 | Move(wSaveResumeProgress[0],Tmp[0],Length(Tmp)-1);
408 | try
409 | FSaveStateStream.Seek(FFileSize+Length(TEncoding.UTF8.GetBytes(FURL))+2, TSeekOrigin.soBeginning);
410 | FSaveStateStream.Write(Tmp,length(Tmp));
411 | finally
412 | end;
413 | end;
414 |
415 | ///*******************************************************************************************************************************************************//
416 | function TThredingFileDownloader._LoadDownloadState(wFilename: string):boolean;
417 | var LStream: TFileStream;
418 | Tmp:TBytes;
419 | begin
420 | SetLength(Tmp,1);
421 | Result:=True;
422 | Setlength(FSaveResumeProgress,0);
423 | LStream := TFileStream.Create(FOutputPath+wFileName, fmOpenRead);
424 | Try
425 | try
426 | LStream.Seek(LStream.Size-1, TSeekOrigin.soBeginning);
427 | LStream.Read(Tmp[0],1);
428 | setlength(FSaveResumeProgress,Tmp[0]);
429 | SetLength(Tmp,Tmp[0]*24);
430 | LStream.Seek(LStream.Size-1-Length(Tmp), TSeekOrigin.soBeginning);
431 | LStream.Read(Tmp[0],Length(Tmp));
432 | Move(Tmp[0],FSaveResumeProgress[0],Length(Tmp));
433 | except
434 | Result:=False;
435 | end;
436 | finally
437 | LStream.Free;
438 | end;
439 | end;
440 |
441 | ///*******************************************************************************************************************************************************//
442 | function TThredingFileDownloader._LoadDownloadInfo(wFilename: string):boolean;
443 | var LStream: TFileStream;
444 | Tmp:TBytes;
445 | wLength:Word;
446 | begin
447 | Result:=true;
448 | SetLength(Tmp,2);
449 | LStream := TFileStream.Create(FOutputPath+wFileName, fmOpenRead);
450 | try
451 | try
452 | LStream.Seek(LStream.Size-(Length(FSaveResumeProgress)*24+1)-2, TSeekOrigin.soBeginning);
453 | LStream.Read(Tmp[0],2);
454 | wLength:=Tmp[0]*256+Tmp[1];
455 | SetLength(Tmp,wLength);
456 | FFileSize:=LStream.Size-(Length(FSaveResumeProgress)*24+1)-(Length(Tmp)+2);
457 | LStream.Seek(FFileSize , TSeekOrigin.soBeginning);
458 | LStream.Read(Tmp,Length(Tmp));
459 | FUrl:=TEncoding.UTF8.GetString(Tmp);
460 | except
461 | Result:=false;
462 | end;
463 | finally
464 | LStream.Free;
465 | end;
466 | end;
467 |
468 | ///*******************************************************************************************************************************************************//
469 | destructor TThredingFileDownloader.destroy;
470 | begin
471 | inherited;
472 | end;
473 |
474 | ///*******************************************************************************************************************************************************//
475 | procedure TThredingFileDownloader.DoDownload;
476 | begin
477 | TThread.CreateAnonymousThread(procedure begin
478 | _DoDownload;
479 | end).Start;
480 | end;
481 |
482 | ///*******************************************************************************************************************************************************//
483 | procedure TThredingFileDownloader.PauseDownload;
484 | begin
485 | FStopDownload:=True;
486 | if Assigned(FOnDownloadPaused) then TThread.Synchronize(nil,procedure begin FOnDownloadPaused(Self);end);
487 | end;
488 |
489 | ///*******************************************************************************************************************************************************//
490 | procedure TThredingFileDownloader.ResumeDownload;
491 | begin
492 | _LoadDownloadState('_'+FFileName+'.temporary');
493 | _LoadDownloadInfo('_'+FFileName+'.temporary');
494 | if Length(FSaveResumeProgress)>0 then TThread.CreateAnonymousThread(procedure begin
495 | _ResumeDownload;
496 | end).Start
497 | else raise Exception.Create('No saved state exist to resume download ');
498 | end;
499 |
500 | ///*******************************************************************************************************************************************************//
501 | function TThredingFileDownloader.ResumeFromTempFile(wFilename: String):integer;
502 | var LStream:TFileStream;
503 | begin
504 | Result:=0;
505 | if not _LoadDownloadState(wFilename) or(wFilename[1]<>'_')or(ExtractFileExt(wFilename)<>'.temporary') then raise Exception.Create('Invalid temporary file for download resume...')
506 | else begin
507 | FFilename:=wFilename.Replace('_','').Replace('.temporary','');
508 | Result:=Length(FSaveResumeProgress);
509 | FCanResume:=True;
510 | ResumeDownload;
511 | end;
512 | end;
513 |
514 | ///*******************************************************************************************************************************************************//
515 | procedure TThredingFileDownloader.SpeedCalculatorEvent(Sender: Tobject);
516 | var wTime:Cardinal;
517 | wSpeed:Double;
518 | wDownloaded:Int64;
519 | begin
520 | FEndingTime:=TThread.GetTickCount;
521 | FEndingDownload:=FDownloadedAmount;
522 | wTime:=FEndingTime-FStartingTime;
523 | wDownloaded:=FEndingDownload-FStartingDownload;
524 | FStartingTime:=FEndingTime;
525 | FStartingDownload:=FEndingDownload;
526 | wSpeed:=Round(((wDownloaded*1000)/wTime)*100)/100;
527 | FDownloadSpeed:=wSpeed;
528 | end;
529 |
530 | ///*******************************************************************************************************************************************************//
531 | function TThredingFileDownloader.StandarizedSize(value: Int64): string;
532 | begin
533 | if Value<1024 then Result:=value.ToString+' Byte'
534 | else if value<1024*1024 then Result:=(Round((Value/1024)*100)/100).ToString+' KB'
535 | else if value<1024*1024*1024 then Result:=(Round((Value/(1024*1024))*100)/100).ToString+' MB'
536 | else Result:=(Round((Value/(1024*1024*1024))*100)/100).ToString+' GB';
537 | end;
538 |
539 | ///*******************************************************************************************************************************************************//
540 | procedure TThredingFileDownloader.ThreadReceiveDataHandler(const Sender: TObject; ThreadNo, ASpeed: Integer;AReadCount: Int64;APercentage:Double; var Abort: Boolean);
541 | var i:integer;
542 | wAverageDownloaded:Double;
543 | wRemainingTime:Int64;
544 | wAbort:boolean;
545 | begin
546 | if not FStopDownload then begin
547 | FCriticalSection.Enter;
548 | FThreadsDownloadedAmout[ThreadNo]:=AReadCount+FSaveResumeProgress[ThreadNo].tProgress;
549 | _SaveDownloadState;
550 | FDownloadedAmount :=0;
551 | for i:=0 to FNumOfThreads-1 do FDownloadedAmount:=FDownloadedAmount+FThreadsDownloadedAmout[i];
552 | if FDownloadedAmount>FFileSize then
553 | i:=1;
554 |
555 | if FFileSize>-1 then begin
556 | FDownloadedPerCentage:=(FDownloadedAmount/FFileSize)*100;
557 | FDownloadedPerCentage:=Round(FDownloadedPerCentage*100)/100;
558 | end
559 | else FDownloadedPerCentage:=-1;
560 | if FFileSize>-1 then wRemainingTime:=Round((FFileSize-FDownloadedAmount)/FdownloadSpeed) // Estimated Remaining time in second
561 | else wRemainingTime:=-1;
562 | FEstimatedRemainingTime:=wRemainingTime;
563 | FCriticalSection.Release;
564 | if Assigned(FOnDownloadThreadData) then begin
565 | wAbort:=Abort;
566 | TThread.Synchronize(nil,procedure begin
567 | FOnDownloadThreadData(Sender,ThreadNo,ASpeed,AReadCount+FSaveResumeProgress[ThreadNo].tProgress, APercentage,wAbort);
568 | end);
569 | Abort:=wAbort;
570 | end;
571 | if Assigned(FOnDownloadInfoUpdate) then
572 | TThread.Synchronize(nil, procedure begin
573 | FOnDownloadInfoUpdate(Self,FDownloadSpeed,FDownloadedAmount,FDownloadedPerCentage,FEstimatedRemainingTime);
574 | end);
575 | end;
576 | Abort:=FStopDownload;
577 | end;
578 |
579 | { TDownloadThread }
580 |
581 | ///*******************************************************************************************************************************************************//
582 | constructor TTrackDownloader.Create(const URL, FileName: string; ThreadNo: Integer; StartPoint, EndPoint: Int64);
583 | begin
584 | inherited Create(True);
585 | FURL := URL;
586 | FFileName := FileName;
587 | FThreadNo := ThreadNo;
588 | FStartPoint := StartPoint;
589 | FEndPoint := EndPoint;
590 | end;
591 |
592 | ///*******************************************************************************************************************************************************//
593 | destructor TTrackDownloader.Destroy;
594 | begin
595 | inherited;
596 | end;
597 |
598 | ///*******************************************************************************************************************************************************//
599 | procedure TTrackDownloader.Execute;
600 | var LResponse: IHTTPResponse;
601 | LStream: TFileStream;
602 | LHttpClient: THTTPClient;
603 | begin
604 | inherited;
605 | LHttpClient := THTTPClient.Create;
606 | try
607 | LHttpClient.OnReceiveData := ReceiveDataEvent;
608 | LStream := TFileStream.Create(FFileName, fmOpenWrite or fmShareDenyNone);
609 | try
610 | FTimeStart := GetTickCount;
611 | LStream.Seek(FStartPoint, TSeekOrigin.soBeginning);
612 | LResponse := LHttpClient.GetRange(FURL, FStartPoint, FEndPoint, LStream);
613 | finally
614 | LStream.Free;
615 | end;
616 | finally
617 | LHttpClient.Free;
618 | end;
619 | end;
620 |
621 | ///*******************************************************************************************************************************************************//
622 | procedure TTrackDownloader.ReceiveDataEvent(const Sender: TObject; AContentLength:Int64; AReadCount: Int64; var Abort: Boolean);
623 | var LTime: Cardinal;
624 | LSpeed: Integer;
625 | LPrecentage:Double;
626 | begin
627 | if Assigned(FOnThreadData) then begin
628 | LTime := GetTickCount - FTimeStart;
629 | if AReadCount = 0 then LSpeed := 0
630 | else LSpeed := (AReadCount * 1000) div LTime; // Byte per Second
631 | if FFileSize>-1 then
632 | LPrecentage:=Round(((AReadCount+FThSaveState[FThreadNo].tProgress)/(AContentLength+FThSaveState[FThreadNo].tProgress))*10000)/100
633 | else LPrecentage:=-1;
634 | FOnThreadData(Sender, FThreadNo, LSpeed,AReadCount, LPrecentage, Abort);
635 | end;
636 | end;
637 |
638 | ///*******************************************************************************************************************************************************//
639 | procedure TThredingFileDownloader._IndirecrReceiveDataEvent(const Sender: TObject; AContentLength:Int64; AReadCount: Int64; var Abort: Boolean);
640 | begin
641 | FIncrementTester:=AContentLength;
642 | Abort:=True
643 | end;
644 |
645 | function TThredingFileDownloader._IndirectlyGetFileSize(wUrl: string): int64;
646 | var wClient:THTTPClient;
647 | wResponce:IHTTPResponse;
648 | begin
649 | wClient:=THTTPClient.Create;
650 | wClient.OnReceiveData:=_IndirecrReceiveDataEvent;
651 | FIncrementTester:=0;
652 | try
653 | wResponce:=wClient.Get(wUrl);
654 | Sleep(100);
655 | Result:=FIncrementTester;
656 | finally
657 | wClient.Free;
658 | end;
659 | end;
660 |
661 |
662 |
663 | end.
664 |
--------------------------------------------------------------------------------