CopyParam.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Common.h"
  5. #include "CopyParam.h"
  6. #include "HierarchicalStorage.h"
  7. #include "TextsCore.h"
  8. //---------------------------------------------------------------------------
  9. __fastcall TCopyParamType::TCopyParamType()
  10. {
  11. Default();
  12. }
  13. //---------------------------------------------------------------------------
  14. __fastcall TCopyParamType::TCopyParamType(const TCopyParamType & Source)
  15. {
  16. Assign(&Source);
  17. }
  18. //---------------------------------------------------------------------------
  19. __fastcall TCopyParamType::~TCopyParamType()
  20. {
  21. }
  22. //---------------------------------------------------------------------------
  23. void __fastcall TCopyParamType::Default()
  24. {
  25. // when changing defaults, make sure GetInfoStr() can handle it
  26. FileNameCase = ncNoChange;
  27. PreserveReadOnly = false;
  28. PreserveTime = true;
  29. Rights.Number = TRights::rfDefault;
  30. PreserveRights = false; // Was True until #106
  31. IgnorePermErrors = false;
  32. AsciiFileMask.Masks = "*.*html; *.htm; *.txt; *.php; *.php3; *.cgi; *.c; *.cpp; *.h; *.pas; "
  33. "*.bas; *.tex; *.pl; .htaccess; *.xtml; *.css; *.cfg; *.ini; *.sh; *.xml";
  34. TransferMode = tmAutomatic;
  35. AddXToDirectories = true;
  36. ResumeSupport = rsSmart;
  37. ResumeThreshold = 100 * 1024; // (100 KiB)
  38. InvalidCharsReplacement = TokenReplacement;
  39. LocalInvalidChars = "/\\:*?\"<>|";
  40. CalculateSize = true;
  41. FileMask = "*.*";
  42. ExcludeFileMask.Masks = "";
  43. NegativeExclude = false;
  44. ClearArchive = false;
  45. CPSLimit = 0;
  46. }
  47. //---------------------------------------------------------------------------
  48. AnsiString __fastcall TCopyParamType::GetInfoStr(AnsiString Separator, int Options) const
  49. {
  50. TCopyParamType Defaults;
  51. AnsiString Result;
  52. bool SomeAttrExcluded = false;
  53. #define ADD(STR, EXCEPT) \
  54. if (FLAGCLEAR(Options, EXCEPT)) \
  55. { \
  56. Result += (Result.IsEmpty() ? AnsiString() : Separator) + (STR); \
  57. } \
  58. else \
  59. { \
  60. SomeAttrExcluded = true; \
  61. }
  62. if ((TransferMode != Defaults.TransferMode) ||
  63. ((TransferMode == tmAutomatic) && !(AsciiFileMask == Defaults.AsciiFileMask)))
  64. {
  65. AnsiString S = FORMAT(LoadStrPart(COPY_INFO_TRANSFER_TYPE, 1),
  66. (LoadStrPart(COPY_INFO_TRANSFER_TYPE, TransferMode + 2)));
  67. if (TransferMode == tmAutomatic)
  68. {
  69. S = FORMAT(S, (AsciiFileMask.Masks));
  70. }
  71. ADD(S, cpaExcludeMaskOnly | cpaNoTransferMode);
  72. }
  73. if (FileNameCase != Defaults.FileNameCase)
  74. {
  75. ADD(FORMAT(LoadStrPart(COPY_INFO_FILENAME, 1),
  76. (LoadStrPart(COPY_INFO_FILENAME, FileNameCase + 2))),
  77. cpaExcludeMaskOnly);
  78. }
  79. if ((InvalidCharsReplacement == NoReplacement) !=
  80. (Defaults.InvalidCharsReplacement == NoReplacement))
  81. {
  82. assert(InvalidCharsReplacement == NoReplacement);
  83. if (InvalidCharsReplacement == NoReplacement)
  84. {
  85. ADD(LoadStr(COPY_INFO_DONT_REPLACE_INV_CHARS), cpaExcludeMaskOnly);
  86. }
  87. }
  88. if ((PreserveRights != Defaults.PreserveRights) ||
  89. (PreserveRights &&
  90. ((Rights != Defaults.Rights) || (AddXToDirectories != Defaults.AddXToDirectories))))
  91. {
  92. assert(PreserveRights);
  93. if (PreserveRights)
  94. {
  95. AnsiString RightsStr = Rights.Text;
  96. if (AddXToDirectories)
  97. {
  98. RightsStr += ", " + LoadStr(COPY_INFO_ADD_X_TO_DIRS);
  99. }
  100. ADD(FORMAT(LoadStr(COPY_INFO_PERMISSIONS), (RightsStr)),
  101. cpaExcludeMaskOnly | cpaNoRights);
  102. }
  103. }
  104. if (PreserveTime != Defaults.PreserveTime)
  105. {
  106. ADD(LoadStr(PreserveTime ? COPY_INFO_TIMESTAMP : COPY_INFO_DONT_PRESERVE_TIME),
  107. cpaExcludeMaskOnly | cpaNoPreserveTime);
  108. }
  109. if ((PreserveRights || PreserveTime) &&
  110. (IgnorePermErrors != Defaults.IgnorePermErrors))
  111. {
  112. assert(IgnorePermErrors);
  113. if (IgnorePermErrors)
  114. {
  115. ADD(LoadStr(COPY_INFO_IGNORE_PERM_ERRORS),
  116. cpaExcludeMaskOnly | cpaNoIgnorePermErrors);
  117. }
  118. }
  119. if (PreserveReadOnly != Defaults.PreserveReadOnly)
  120. {
  121. assert(PreserveReadOnly);
  122. if (PreserveReadOnly)
  123. {
  124. ADD(LoadStr(COPY_INFO_PRESERVE_READONLY),
  125. cpaExcludeMaskOnly | cpaNoPreserveReadOnly);
  126. }
  127. }
  128. if (CalculateSize != Defaults.CalculateSize)
  129. {
  130. assert(!CalculateSize);
  131. if (!CalculateSize)
  132. {
  133. ADD(LoadStr(COPY_INFO_DONT_CALCULATE_SIZE), cpaExcludeMaskOnly);
  134. }
  135. }
  136. if (ClearArchive != Defaults.ClearArchive)
  137. {
  138. assert(ClearArchive);
  139. if (ClearArchive)
  140. {
  141. ADD(LoadStr(COPY_INFO_CLEAR_ARCHIVE),
  142. cpaExcludeMaskOnly | cpaNoClearArchive);
  143. }
  144. }
  145. if (((NegativeExclude != Defaults.NegativeExclude) && !(ExcludeFileMask == "")) ||
  146. !(ExcludeFileMask == Defaults.ExcludeFileMask))
  147. {
  148. ADD(FORMAT(LoadStr(NegativeExclude ? COPY_INFO_INCLUDE_MASK : COPY_INFO_EXCLUDE_MASK),
  149. (ExcludeFileMask.Masks)),
  150. cpaNoExcludeMask);
  151. }
  152. if (CPSLimit > 0)
  153. {
  154. ADD(FMTLOAD(COPY_INFO_CPS_LIMIT, (int(CPSLimit / 1024))), cpaExcludeMaskOnly);
  155. }
  156. if (SomeAttrExcluded)
  157. {
  158. Result += (Result.IsEmpty() ? AnsiString() : Separator) +
  159. FORMAT(LoadStrPart(COPY_INFO_NOT_USABLE, 1),
  160. (LoadStrPart(COPY_INFO_NOT_USABLE, (Result.IsEmpty() ? 3 : 2))));
  161. }
  162. else if (Result.IsEmpty())
  163. {
  164. Result = LoadStr(COPY_INFO_DEFAULT);
  165. }
  166. #undef ADD
  167. return Result;
  168. }
  169. //---------------------------------------------------------------------------
  170. void __fastcall TCopyParamType::Assign(const TCopyParamType * Source)
  171. {
  172. assert(Source != NULL);
  173. #define COPY(Prop) Prop = Source->Prop
  174. COPY(FileNameCase);
  175. COPY(PreserveReadOnly);
  176. COPY(PreserveTime);
  177. COPY(Rights);
  178. COPY(AsciiFileMask);
  179. COPY(TransferMode);
  180. COPY(AddXToDirectories);
  181. COPY(PreserveRights);
  182. COPY(IgnorePermErrors);
  183. COPY(ResumeSupport);
  184. COPY(ResumeThreshold);
  185. COPY(InvalidCharsReplacement);
  186. COPY(LocalInvalidChars);
  187. COPY(CalculateSize);
  188. COPY(FileMask);
  189. COPY(ExcludeFileMask);
  190. COPY(NegativeExclude);
  191. COPY(ClearArchive);
  192. COPY(CPSLimit);
  193. #undef COPY
  194. }
  195. //---------------------------------------------------------------------------
  196. TCopyParamType & __fastcall TCopyParamType::operator =(const TCopyParamType & rhp)
  197. {
  198. Assign(&rhp);
  199. return *this;
  200. }
  201. //---------------------------------------------------------------------------
  202. void __fastcall TCopyParamType::SetLocalInvalidChars(AnsiString value)
  203. {
  204. if (value != LocalInvalidChars)
  205. {
  206. FLocalInvalidChars = value;
  207. FTokenizibleChars = FLocalInvalidChars + TokenPrefix;
  208. }
  209. }
  210. //---------------------------------------------------------------------------
  211. bool __fastcall TCopyParamType::GetReplaceInvalidChars() const
  212. {
  213. return (InvalidCharsReplacement != NoReplacement);
  214. }
  215. //---------------------------------------------------------------------------
  216. void __fastcall TCopyParamType::SetReplaceInvalidChars(bool value)
  217. {
  218. if (ReplaceInvalidChars != value)
  219. {
  220. InvalidCharsReplacement = (value ? TokenReplacement : NoReplacement);
  221. }
  222. }
  223. //---------------------------------------------------------------------------
  224. char * __fastcall TCopyParamType::ReplaceChar(AnsiString & FileName, char * InvalidChar) const
  225. {
  226. int Index = InvalidChar - FileName.c_str() + 1;
  227. if (FileName.ByteType(Index) == mbSingleByte)
  228. {
  229. if (InvalidCharsReplacement == TokenReplacement)
  230. {
  231. FileName.Insert(CharToHex(FileName[Index]), Index + 1);
  232. FileName[Index] = TokenPrefix;
  233. InvalidChar = FileName.c_str() + Index + 2;
  234. }
  235. else
  236. {
  237. FileName[Index] = InvalidCharsReplacement;
  238. InvalidChar++;
  239. }
  240. }
  241. else
  242. {
  243. InvalidChar++;
  244. }
  245. return InvalidChar;
  246. }
  247. //---------------------------------------------------------------------------
  248. AnsiString __fastcall TCopyParamType::ValidLocalFileName(AnsiString FileName) const
  249. {
  250. if (InvalidCharsReplacement != NoReplacement)
  251. {
  252. bool ATokenReplacement = (InvalidCharsReplacement == TokenReplacement);
  253. const char * Chars =
  254. (ATokenReplacement ? FTokenizibleChars : LocalInvalidChars).c_str();
  255. char * InvalidChar = FileName.c_str();
  256. while ((InvalidChar = strpbrk(InvalidChar, Chars)) != NULL)
  257. {
  258. int Pos = (InvalidChar - FileName.c_str() + 1);
  259. char Char;
  260. if ((InvalidCharsReplacement == TokenReplacement) &&
  261. (*InvalidChar == TokenPrefix) &&
  262. (((FileName.Length() - Pos) <= 1) ||
  263. (((Char = HexToChar(FileName.SubString(Pos + 1, 2))) == '\0') ||
  264. (FTokenizibleChars.Pos(Char) == 0))))
  265. {
  266. InvalidChar++;
  267. }
  268. else
  269. {
  270. InvalidChar = ReplaceChar(FileName, InvalidChar);
  271. }
  272. }
  273. // Windows trim trailing space, hence we must encode it to preserve it
  274. if (!FileName.IsEmpty() && (FileName[FileName.Length()] == ' '))
  275. {
  276. ReplaceChar(FileName, FileName.c_str() + FileName.Length() - 1);
  277. }
  278. if (IsReservedName(FileName))
  279. {
  280. int P = FileName.Pos(".");
  281. if (P == 0)
  282. {
  283. P = FileName.Length() + 1;
  284. }
  285. FileName.Insert("%00", P);
  286. }
  287. }
  288. return FileName;
  289. }
  290. //---------------------------------------------------------------------------
  291. AnsiString __fastcall TCopyParamType::RestoreChars(AnsiString FileName) const
  292. {
  293. if (InvalidCharsReplacement == TokenReplacement)
  294. {
  295. char * InvalidChar = FileName.c_str();
  296. while ((InvalidChar = strchr(InvalidChar, TokenPrefix)) != NULL)
  297. {
  298. int Index = InvalidChar - FileName.c_str() + 1;
  299. if ((FileName.Length() >= Index + 2) &&
  300. (FileName.ByteType(Index) == mbSingleByte) &&
  301. (FileName.ByteType(Index + 1) == mbSingleByte) &&
  302. (FileName.ByteType(Index + 2) == mbSingleByte))
  303. {
  304. AnsiString Hex = FileName.SubString(Index + 1, 2);
  305. char Char = HexToChar(Hex);
  306. if ((Char != '\0') &&
  307. ((FTokenizibleChars.Pos(Char) > 0) ||
  308. ((Char == ' ') && (Index == FileName.Length() - 2))))
  309. {
  310. FileName[Index] = Char;
  311. FileName.Delete(Index + 1, 2);
  312. InvalidChar = FileName.c_str() + Index;
  313. }
  314. else if ((Hex == "00") &&
  315. ((Index == FileName.Length() - 2) || (FileName[Index + 3] == '.')) &&
  316. IsReservedName(FileName.SubString(1, Index - 1) + FileName.SubString(Index + 3, FileName.Length() - Index - 3 + 1)))
  317. {
  318. FileName.Delete(Index, 3);
  319. InvalidChar = FileName.c_str() + Index - 1;
  320. }
  321. else
  322. {
  323. InvalidChar++;
  324. }
  325. }
  326. else
  327. {
  328. InvalidChar++;
  329. }
  330. }
  331. }
  332. return FileName;
  333. }
  334. //---------------------------------------------------------------------------
  335. AnsiString __fastcall TCopyParamType::ValidLocalPath(AnsiString Path) const
  336. {
  337. AnsiString Result;
  338. while (!Path.IsEmpty())
  339. {
  340. if (!Result.IsEmpty())
  341. {
  342. Result += "\\";
  343. }
  344. Result += ValidLocalFileName(CutToChar(Path, '\\', false));
  345. }
  346. return Result;
  347. }
  348. //---------------------------------------------------------------------------
  349. // not used yet
  350. AnsiString __fastcall TCopyParamType::Untokenize(AnsiString FileName)
  351. {
  352. char * Token;
  353. AnsiString Result = FileName;
  354. while ((Token = AnsiStrScan(Result.c_str(), TokenPrefix)) != NULL)
  355. {
  356. int Index = Token - Result.c_str() + 1;
  357. if (Index > Result.Length() - 2)
  358. {
  359. Result = FileName;
  360. break;
  361. }
  362. else
  363. {
  364. char Ch = (char)HexToInt(Result.SubString(Index + 1, 2), -1);
  365. if (Ch == '\0')
  366. {
  367. Result = FileName;
  368. break;
  369. }
  370. else
  371. {
  372. Result[Index] = Ch;
  373. Result.Delete(Index + 1, 2);
  374. }
  375. }
  376. }
  377. return Result;
  378. }
  379. //---------------------------------------------------------------------------
  380. AnsiString __fastcall TCopyParamType::ChangeFileName(AnsiString FileName,
  381. TOperationSide Side, bool FirstLevel) const
  382. {
  383. if (FirstLevel)
  384. {
  385. FileName = MaskFileName(FileName, FileMask);
  386. }
  387. switch (FileNameCase) {
  388. case ncUpperCase: FileName = FileName.UpperCase(); break;
  389. case ncLowerCase: FileName = FileName.LowerCase(); break;
  390. case ncFirstUpperCase: FileName = FileName.SubString(1, 1).UpperCase() +
  391. FileName.SubString(2, FileName.Length()-1).LowerCase(); break;
  392. case ncLowerCaseShort:
  393. if ((FileName.Length() <= 12) && (FileName.Pos(".") <= 9) &&
  394. (FileName == FileName.UpperCase()))
  395. {
  396. FileName = FileName.LowerCase();
  397. }
  398. break;
  399. case ncNoChange:
  400. default:
  401. /*nothing*/
  402. break;
  403. }
  404. if (Side == osRemote)
  405. {
  406. FileName = ValidLocalFileName(FileName);
  407. }
  408. else
  409. {
  410. FileName = RestoreChars(FileName);
  411. }
  412. return FileName;
  413. }
  414. //---------------------------------------------------------------------------
  415. bool __fastcall TCopyParamType::UseAsciiTransfer(AnsiString FileName,
  416. TOperationSide Side, const TFileMasks::TParams & Params) const
  417. {
  418. switch (TransferMode) {
  419. case tmBinary: return false;
  420. case tmAscii: return true;
  421. case tmAutomatic: return AsciiFileMask.Matches(FileName, (Side == osLocal),
  422. false, &Params);
  423. default: assert(false); return false;
  424. }
  425. }
  426. //---------------------------------------------------------------------------
  427. TRights __fastcall TCopyParamType::RemoteFileRights(Integer Attrs) const
  428. {
  429. TRights R = Rights;
  430. if ((Attrs & faDirectory) && AddXToDirectories)
  431. R.AddExecute();
  432. return R;
  433. }
  434. //---------------------------------------------------------------------------
  435. AnsiString __fastcall TCopyParamType::GetLogStr() const
  436. {
  437. char CaseC[] = "NULFS";
  438. char ModeC[] = "BAM";
  439. char ResumeC[] = "YSN";
  440. return FORMAT(
  441. " PrTime: %s; PrRO: %s; Rght: %s; PrR: %s (%s); FnCs: %s; RIC: %s; "
  442. "Resume: %s (%d); CalcS: %s; Mask: %s\n"
  443. " TM: %s; ClAr: %s; CPS: %u; ExclM(%s): %s\n"
  444. " AscM: %s\n",
  445. (BooleanToEngStr(PreserveTime),
  446. BooleanToEngStr(PreserveReadOnly),
  447. Rights.Text,
  448. BooleanToEngStr(PreserveRights),
  449. BooleanToEngStr(IgnorePermErrors),
  450. CaseC[FileNameCase],
  451. CharToHex(InvalidCharsReplacement),
  452. ResumeC[ResumeSupport],
  453. (int)ResumeThreshold,
  454. BooleanToEngStr(CalculateSize),
  455. FileMask,
  456. ModeC[TransferMode],
  457. BooleanToEngStr(ClearArchive),
  458. int(CPSLimit),
  459. BooleanToEngStr(NegativeExclude),
  460. ExcludeFileMask.Masks,
  461. AsciiFileMask.Masks));
  462. }
  463. //---------------------------------------------------------------------------
  464. int __fastcall TCopyParamType::LocalFileAttrs(const TRights & Rights) const
  465. {
  466. int Result = 0;
  467. if (PreserveReadOnly && !Rights.Right[TRights::rrUserWrite])
  468. {
  469. Result |= faReadOnly;
  470. }
  471. return Result;
  472. }
  473. //---------------------------------------------------------------------------
  474. bool __fastcall TCopyParamType::AllowResume(__int64 Size) const
  475. {
  476. switch (ResumeSupport) {
  477. case rsOn: return true;
  478. case rsOff: return false;
  479. case rsSmart: return (Size >= ResumeThreshold);
  480. default: assert(false); return false;
  481. }
  482. }
  483. //---------------------------------------------------------------------------
  484. bool __fastcall TCopyParamType::AllowTransfer(AnsiString FileName,
  485. TOperationSide Side, bool Directory, const TFileMasks::TParams & Params) const
  486. {
  487. bool Result = true;
  488. if (!ExcludeFileMask.Masks.IsEmpty())
  489. {
  490. Result = (ExcludeFileMask.Matches(FileName, (Side == osLocal),
  491. Directory, &Params) == NegativeExclude);
  492. }
  493. return Result;
  494. }
  495. //---------------------------------------------------------------------------
  496. void __fastcall TCopyParamType::Load(THierarchicalStorage * Storage)
  497. {
  498. AddXToDirectories = Storage->ReadBool("AddXToDirectories", AddXToDirectories);
  499. AsciiFileMask.Masks = Storage->ReadString("Masks", AsciiFileMask.Masks);
  500. FileNameCase = (TFileNameCase)Storage->ReadInteger("FileNameCase", FileNameCase);
  501. PreserveReadOnly = Storage->ReadBool("PreserveReadOnly", PreserveReadOnly);
  502. PreserveTime = Storage->ReadBool("PreserveTime", PreserveTime);
  503. PreserveRights = Storage->ReadBool("PreserveRights", PreserveRights);
  504. IgnorePermErrors = Storage->ReadBool("IgnorePermErrors", IgnorePermErrors);
  505. Rights.Text = Storage->ReadString("Text", Rights.Text);
  506. TransferMode = (TTransferMode)Storage->ReadInteger("TransferMode", TransferMode);
  507. ResumeSupport = (TResumeSupport)Storage->ReadInteger("ResumeSupport", ResumeSupport);
  508. ResumeThreshold = Storage->ReadInt64("ResumeThreshold", ResumeThreshold);
  509. InvalidCharsReplacement = (char)Storage->ReadInteger("ReplaceInvalidChars",
  510. (unsigned char)InvalidCharsReplacement);
  511. LocalInvalidChars = Storage->ReadString("LocalInvalidChars", LocalInvalidChars);
  512. CalculateSize = Storage->ReadBool("CalculateSize", CalculateSize);
  513. ExcludeFileMask.Masks = Storage->ReadString("ExcludeFileMask", ExcludeFileMask.Masks);
  514. NegativeExclude = Storage->ReadBool("NegativeExclude", NegativeExclude);
  515. ClearArchive = Storage->ReadBool("ClearArchive", ClearArchive);
  516. CPSLimit = Storage->ReadInteger("CPSLimit", CPSLimit);
  517. }
  518. //---------------------------------------------------------------------------
  519. void __fastcall TCopyParamType::Save(THierarchicalStorage * Storage) const
  520. {
  521. Storage->WriteBool("AddXToDirectories", AddXToDirectories);
  522. Storage->WriteString("Masks", AsciiFileMask.Masks);
  523. Storage->WriteInteger("FileNameCase", FileNameCase);
  524. Storage->WriteBool("PreserveReadOnly", PreserveReadOnly);
  525. Storage->WriteBool("PreserveTime", PreserveTime);
  526. Storage->WriteBool("PreserveRights", PreserveRights);
  527. Storage->WriteBool("IgnorePermErrors", IgnorePermErrors);
  528. Storage->WriteString("Text", Rights.Text);
  529. Storage->WriteInteger("TransferMode", TransferMode);
  530. Storage->WriteInteger("ResumeSupport", ResumeSupport);
  531. Storage->WriteInt64("ResumeThreshold", ResumeThreshold);
  532. Storage->WriteInteger("ReplaceInvalidChars", (unsigned char)InvalidCharsReplacement);
  533. Storage->WriteString("LocalInvalidChars", LocalInvalidChars);
  534. Storage->WriteBool("CalculateSize", CalculateSize);
  535. Storage->WriteString("ExcludeFileMask", ExcludeFileMask.Masks);
  536. Storage->WriteBool("NegativeExclude", NegativeExclude);
  537. Storage->WriteBool("ClearArchive", ClearArchive);
  538. Storage->WriteInteger("CPSLimit", CPSLimit);
  539. }
  540. //---------------------------------------------------------------------------
  541. #define C(Property) (Property == rhp.Property)
  542. bool __fastcall TCopyParamType::operator==(const TCopyParamType & rhp) const
  543. {
  544. return
  545. C(AddXToDirectories) &&
  546. C(AsciiFileMask) &&
  547. C(FileNameCase) &&
  548. C(PreserveReadOnly) &&
  549. C(PreserveTime) &&
  550. C(PreserveRights) &&
  551. C(IgnorePermErrors) &&
  552. C(Rights) &&
  553. C(TransferMode) &&
  554. C(ResumeSupport) &&
  555. C(ResumeThreshold) &&
  556. C(InvalidCharsReplacement) &&
  557. C(LocalInvalidChars) &&
  558. C(CalculateSize) &&
  559. C(ExcludeFileMask) &&
  560. C(NegativeExclude) &&
  561. C(ClearArchive) &&
  562. C(CPSLimit) &&
  563. true;
  564. }
  565. #undef C
  566. //---------------------------------------------------------------------------
  567. unsigned long __fastcall GetSpeedLimit(const AnsiString & Text)
  568. {
  569. unsigned long Speed;
  570. if (AnsiSameText(Text, LoadStr(SPEED_UNLIMITED)))
  571. {
  572. Speed = 0;
  573. }
  574. else
  575. {
  576. int SSpeed;
  577. if (!TryStrToInt(Text, SSpeed) ||
  578. (SSpeed < 0))
  579. {
  580. throw Exception(FMTLOAD(SPEED_INVALID, (Text)));
  581. }
  582. Speed = SSpeed;
  583. }
  584. return Speed * 1024;
  585. }
  586. //---------------------------------------------------------------------------
  587. AnsiString __fastcall SetSpeedLimit(unsigned long Limit)
  588. {
  589. AnsiString Text;
  590. if (Limit == 0)
  591. {
  592. Text = LoadStr(SPEED_UNLIMITED);
  593. }
  594. else
  595. {
  596. Text = IntToStr(Limit / 1024);
  597. }
  598. return Text;
  599. }