CopyParam.cpp 19 KB

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