CopyParam.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  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 or dot, hence we must encode it to preserve it
  274. if (!FileName.IsEmpty() &&
  275. ((FileName[FileName.Length()] == ' ') ||
  276. (FileName[FileName.Length()] == '.')))
  277. {
  278. ReplaceChar(FileName, FileName.c_str() + FileName.Length() - 1);
  279. }
  280. if (IsReservedName(FileName))
  281. {
  282. int P = FileName.Pos(".");
  283. if (P == 0)
  284. {
  285. P = FileName.Length() + 1;
  286. }
  287. FileName.Insert("%00", P);
  288. }
  289. }
  290. return FileName;
  291. }
  292. //---------------------------------------------------------------------------
  293. AnsiString __fastcall TCopyParamType::RestoreChars(AnsiString FileName) const
  294. {
  295. if (InvalidCharsReplacement == TokenReplacement)
  296. {
  297. char * InvalidChar = FileName.c_str();
  298. while ((InvalidChar = strchr(InvalidChar, TokenPrefix)) != NULL)
  299. {
  300. int Index = InvalidChar - FileName.c_str() + 1;
  301. if ((FileName.Length() >= Index + 2) &&
  302. (FileName.ByteType(Index) == mbSingleByte) &&
  303. (FileName.ByteType(Index + 1) == mbSingleByte) &&
  304. (FileName.ByteType(Index + 2) == mbSingleByte))
  305. {
  306. AnsiString Hex = FileName.SubString(Index + 1, 2);
  307. char Char = HexToChar(Hex);
  308. if ((Char != '\0') &&
  309. ((FTokenizibleChars.Pos(Char) > 0) ||
  310. (((Char == ' ') || (Char == '.')) && (Index == FileName.Length() - 2))))
  311. {
  312. FileName[Index] = Char;
  313. FileName.Delete(Index + 1, 2);
  314. InvalidChar = FileName.c_str() + Index;
  315. }
  316. else if ((Hex == "00") &&
  317. ((Index == FileName.Length() - 2) || (FileName[Index + 3] == '.')) &&
  318. IsReservedName(FileName.SubString(1, Index - 1) + FileName.SubString(Index + 3, FileName.Length() - Index - 3 + 1)))
  319. {
  320. FileName.Delete(Index, 3);
  321. InvalidChar = FileName.c_str() + Index - 1;
  322. }
  323. else
  324. {
  325. InvalidChar++;
  326. }
  327. }
  328. else
  329. {
  330. InvalidChar++;
  331. }
  332. }
  333. }
  334. return FileName;
  335. }
  336. //---------------------------------------------------------------------------
  337. AnsiString __fastcall TCopyParamType::ValidLocalPath(AnsiString Path) const
  338. {
  339. AnsiString Result;
  340. while (!Path.IsEmpty())
  341. {
  342. if (!Result.IsEmpty())
  343. {
  344. Result += "\\";
  345. }
  346. Result += ValidLocalFileName(CutToChar(Path, '\\', false));
  347. }
  348. return Result;
  349. }
  350. //---------------------------------------------------------------------------
  351. // not used yet
  352. AnsiString __fastcall TCopyParamType::Untokenize(AnsiString FileName)
  353. {
  354. char * Token;
  355. AnsiString Result = FileName;
  356. while ((Token = AnsiStrScan(Result.c_str(), TokenPrefix)) != NULL)
  357. {
  358. int Index = Token - Result.c_str() + 1;
  359. if (Index > Result.Length() - 2)
  360. {
  361. Result = FileName;
  362. break;
  363. }
  364. else
  365. {
  366. char Ch = (char)HexToInt(Result.SubString(Index + 1, 2), -1);
  367. if (Ch == '\0')
  368. {
  369. Result = FileName;
  370. break;
  371. }
  372. else
  373. {
  374. Result[Index] = Ch;
  375. Result.Delete(Index + 1, 2);
  376. }
  377. }
  378. }
  379. return Result;
  380. }
  381. //---------------------------------------------------------------------------
  382. AnsiString __fastcall TCopyParamType::ChangeFileName(AnsiString FileName,
  383. TOperationSide Side, bool FirstLevel) const
  384. {
  385. if (FirstLevel)
  386. {
  387. FileName = MaskFileName(FileName, FileMask);
  388. }
  389. switch (FileNameCase) {
  390. case ncUpperCase: FileName = FileName.UpperCase(); break;
  391. case ncLowerCase: FileName = FileName.LowerCase(); break;
  392. case ncFirstUpperCase: FileName = FileName.SubString(1, 1).UpperCase() +
  393. FileName.SubString(2, FileName.Length()-1).LowerCase(); break;
  394. case ncLowerCaseShort:
  395. if ((FileName.Length() <= 12) && (FileName.Pos(".") <= 9) &&
  396. (FileName == FileName.UpperCase()))
  397. {
  398. FileName = FileName.LowerCase();
  399. }
  400. break;
  401. case ncNoChange:
  402. default:
  403. /*nothing*/
  404. break;
  405. }
  406. if (Side == osRemote)
  407. {
  408. FileName = ValidLocalFileName(FileName);
  409. }
  410. else
  411. {
  412. FileName = RestoreChars(FileName);
  413. }
  414. return FileName;
  415. }
  416. //---------------------------------------------------------------------------
  417. bool __fastcall TCopyParamType::UseAsciiTransfer(AnsiString FileName,
  418. TOperationSide Side, const TFileMasks::TParams & Params) const
  419. {
  420. switch (TransferMode) {
  421. case tmBinary: return false;
  422. case tmAscii: return true;
  423. case tmAutomatic: return AsciiFileMask.Matches(FileName, (Side == osLocal),
  424. false, &Params);
  425. default: assert(false); return false;
  426. }
  427. }
  428. //---------------------------------------------------------------------------
  429. TRights __fastcall TCopyParamType::RemoteFileRights(Integer Attrs) const
  430. {
  431. TRights R = Rights;
  432. if ((Attrs & faDirectory) && AddXToDirectories)
  433. R.AddExecute();
  434. return R;
  435. }
  436. //---------------------------------------------------------------------------
  437. AnsiString __fastcall TCopyParamType::GetLogStr() const
  438. {
  439. char CaseC[] = "NULFS";
  440. char ModeC[] = "BAM";
  441. char ResumeC[] = "YSN";
  442. return FORMAT(
  443. " PrTime: %s; PrRO: %s; Rght: %s; PrR: %s (%s); FnCs: %s; RIC: %s; "
  444. "Resume: %s (%d); CalcS: %s; Mask: %s\n"
  445. " TM: %s; ClAr: %s; CPS: %u; ExclM(%s): %s\n"
  446. " AscM: %s\n",
  447. (BooleanToEngStr(PreserveTime),
  448. BooleanToEngStr(PreserveReadOnly),
  449. Rights.Text,
  450. BooleanToEngStr(PreserveRights),
  451. BooleanToEngStr(IgnorePermErrors),
  452. CaseC[FileNameCase],
  453. CharToHex(InvalidCharsReplacement),
  454. ResumeC[ResumeSupport],
  455. (int)ResumeThreshold,
  456. BooleanToEngStr(CalculateSize),
  457. FileMask,
  458. ModeC[TransferMode],
  459. BooleanToEngStr(ClearArchive),
  460. int(CPSLimit),
  461. BooleanToEngStr(NegativeExclude),
  462. ExcludeFileMask.Masks,
  463. AsciiFileMask.Masks));
  464. }
  465. //---------------------------------------------------------------------------
  466. int __fastcall TCopyParamType::LocalFileAttrs(const TRights & Rights) const
  467. {
  468. int Result = 0;
  469. if (PreserveReadOnly && !Rights.Right[TRights::rrUserWrite])
  470. {
  471. Result |= faReadOnly;
  472. }
  473. return Result;
  474. }
  475. //---------------------------------------------------------------------------
  476. bool __fastcall TCopyParamType::AllowResume(__int64 Size) const
  477. {
  478. switch (ResumeSupport) {
  479. case rsOn: return true;
  480. case rsOff: return false;
  481. case rsSmart: return (Size >= ResumeThreshold);
  482. default: assert(false); return false;
  483. }
  484. }
  485. //---------------------------------------------------------------------------
  486. bool __fastcall TCopyParamType::AllowTransfer(AnsiString FileName,
  487. TOperationSide Side, bool Directory, const TFileMasks::TParams & Params) const
  488. {
  489. bool Result = true;
  490. if (!ExcludeFileMask.Masks.IsEmpty())
  491. {
  492. Result = (ExcludeFileMask.Matches(FileName, (Side == osLocal),
  493. Directory, &Params) == NegativeExclude);
  494. }
  495. return Result;
  496. }
  497. //---------------------------------------------------------------------------
  498. void __fastcall TCopyParamType::Load(THierarchicalStorage * Storage)
  499. {
  500. AddXToDirectories = Storage->ReadBool("AddXToDirectories", AddXToDirectories);
  501. AsciiFileMask.Masks = Storage->ReadString("Masks", AsciiFileMask.Masks);
  502. FileNameCase = (TFileNameCase)Storage->ReadInteger("FileNameCase", FileNameCase);
  503. PreserveReadOnly = Storage->ReadBool("PreserveReadOnly", PreserveReadOnly);
  504. PreserveTime = Storage->ReadBool("PreserveTime", PreserveTime);
  505. PreserveRights = Storage->ReadBool("PreserveRights", PreserveRights);
  506. IgnorePermErrors = Storage->ReadBool("IgnorePermErrors", IgnorePermErrors);
  507. Rights.Text = Storage->ReadString("Text", Rights.Text);
  508. TransferMode = (TTransferMode)Storage->ReadInteger("TransferMode", TransferMode);
  509. ResumeSupport = (TResumeSupport)Storage->ReadInteger("ResumeSupport", ResumeSupport);
  510. ResumeThreshold = Storage->ReadInt64("ResumeThreshold", ResumeThreshold);
  511. InvalidCharsReplacement = (char)Storage->ReadInteger("ReplaceInvalidChars",
  512. (unsigned char)InvalidCharsReplacement);
  513. LocalInvalidChars = Storage->ReadString("LocalInvalidChars", LocalInvalidChars);
  514. CalculateSize = Storage->ReadBool("CalculateSize", CalculateSize);
  515. ExcludeFileMask.Masks = Storage->ReadString("ExcludeFileMask", ExcludeFileMask.Masks);
  516. NegativeExclude = Storage->ReadBool("NegativeExclude", NegativeExclude);
  517. ClearArchive = Storage->ReadBool("ClearArchive", ClearArchive);
  518. CPSLimit = Storage->ReadInteger("CPSLimit", CPSLimit);
  519. }
  520. //---------------------------------------------------------------------------
  521. void __fastcall TCopyParamType::Save(THierarchicalStorage * Storage) const
  522. {
  523. Storage->WriteBool("AddXToDirectories", AddXToDirectories);
  524. Storage->WriteString("Masks", AsciiFileMask.Masks);
  525. Storage->WriteInteger("FileNameCase", FileNameCase);
  526. Storage->WriteBool("PreserveReadOnly", PreserveReadOnly);
  527. Storage->WriteBool("PreserveTime", PreserveTime);
  528. Storage->WriteBool("PreserveRights", PreserveRights);
  529. Storage->WriteBool("IgnorePermErrors", IgnorePermErrors);
  530. Storage->WriteString("Text", Rights.Text);
  531. Storage->WriteInteger("TransferMode", TransferMode);
  532. Storage->WriteInteger("ResumeSupport", ResumeSupport);
  533. Storage->WriteInt64("ResumeThreshold", ResumeThreshold);
  534. Storage->WriteInteger("ReplaceInvalidChars", (unsigned char)InvalidCharsReplacement);
  535. Storage->WriteString("LocalInvalidChars", LocalInvalidChars);
  536. Storage->WriteBool("CalculateSize", CalculateSize);
  537. Storage->WriteString("ExcludeFileMask", ExcludeFileMask.Masks);
  538. Storage->WriteBool("NegativeExclude", NegativeExclude);
  539. Storage->WriteBool("ClearArchive", ClearArchive);
  540. Storage->WriteInteger("CPSLimit", CPSLimit);
  541. }
  542. //---------------------------------------------------------------------------
  543. #define C(Property) (Property == rhp.Property)
  544. bool __fastcall TCopyParamType::operator==(const TCopyParamType & rhp) const
  545. {
  546. return
  547. C(AddXToDirectories) &&
  548. C(AsciiFileMask) &&
  549. C(FileNameCase) &&
  550. C(PreserveReadOnly) &&
  551. C(PreserveTime) &&
  552. C(PreserveRights) &&
  553. C(IgnorePermErrors) &&
  554. C(Rights) &&
  555. C(TransferMode) &&
  556. C(ResumeSupport) &&
  557. C(ResumeThreshold) &&
  558. C(InvalidCharsReplacement) &&
  559. C(LocalInvalidChars) &&
  560. C(CalculateSize) &&
  561. C(ExcludeFileMask) &&
  562. C(NegativeExclude) &&
  563. C(ClearArchive) &&
  564. C(CPSLimit) &&
  565. true;
  566. }
  567. #undef C
  568. //---------------------------------------------------------------------------
  569. unsigned long __fastcall GetSpeedLimit(const AnsiString & Text)
  570. {
  571. unsigned long Speed;
  572. if (AnsiSameText(Text, LoadStr(SPEED_UNLIMITED)))
  573. {
  574. Speed = 0;
  575. }
  576. else
  577. {
  578. int SSpeed;
  579. if (!TryStrToInt(Text, SSpeed) ||
  580. (SSpeed < 0))
  581. {
  582. throw Exception(FMTLOAD(SPEED_INVALID, (Text)));
  583. }
  584. Speed = SSpeed;
  585. }
  586. return Speed * 1024;
  587. }
  588. //---------------------------------------------------------------------------
  589. AnsiString __fastcall SetSpeedLimit(unsigned long Limit)
  590. {
  591. AnsiString Text;
  592. if (Limit == 0)
  593. {
  594. Text = LoadStr(SPEED_UNLIMITED);
  595. }
  596. else
  597. {
  598. Text = IntToStr(Limit / 1024);
  599. }
  600. return Text;
  601. }