CopyParam.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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 = true;
  28. PreserveTime = true;
  29. Rights.Number = TRights::rfDefault;
  30. PreserveRights = false; // Was True until #106
  31. AsciiFileMask.Masks = "*.*html; *.htm; *.txt; *.php*; *.cgi; *.c; *.cpp; *.h; *.pas; "
  32. "*.bas; *.tex; *.pl; .htaccess; *.xtml; *.css; *.cfg; *.ini; *.sh; *.xml";
  33. TransferMode = tmAutomatic;
  34. AddXToDirectories = true;
  35. ResumeSupport = rsSmart;
  36. ResumeThreshold = 100 * 1024; // (100 kB)
  37. InvalidCharsReplacement = TokenReplacement;
  38. LocalInvalidChars = "/\\:*?\"<>|";
  39. CalculateSize = true;
  40. FileMask = "*.*";
  41. ExcludeFileMask.Masks = "";
  42. NegativeExclude = false;
  43. ClearArchive = false;
  44. }
  45. //---------------------------------------------------------------------------
  46. AnsiString __fastcall TCopyParamType::GetInfoStr(AnsiString Separator, int Options) const
  47. {
  48. TCopyParamType Defaults;
  49. AnsiString Result;
  50. #define ADD(STR) Result += (Result.IsEmpty() ? AnsiString() : Separator) + (STR)
  51. if (FLAGCLEAR(Options, cpiExcludeMaskOnly))
  52. {
  53. if ((TransferMode != Defaults.TransferMode) ||
  54. ((TransferMode == tmAutomatic) && !(AsciiFileMask == Defaults.AsciiFileMask)))
  55. {
  56. AnsiString S = FORMAT(LoadStrPart(COPY_INFO_TRANSFER_TYPE, 1),
  57. (LoadStrPart(COPY_INFO_TRANSFER_TYPE, TransferMode + 2)));
  58. if (TransferMode == tmAutomatic)
  59. {
  60. S = FORMAT(S, (AsciiFileMask.Masks));
  61. }
  62. ADD(S);
  63. }
  64. if (FileNameCase != Defaults.FileNameCase)
  65. {
  66. ADD(FORMAT(LoadStrPart(COPY_INFO_FILENAME, 1),
  67. (LoadStrPart(COPY_INFO_FILENAME, FileNameCase + 2))));
  68. }
  69. if ((InvalidCharsReplacement == NoReplacement) !=
  70. (Defaults.InvalidCharsReplacement == NoReplacement))
  71. {
  72. assert(InvalidCharsReplacement == NoReplacement);
  73. if (InvalidCharsReplacement == NoReplacement)
  74. {
  75. ADD(LoadStr(COPY_INFO_DONT_REPLACE_INV_CHARS));
  76. }
  77. }
  78. if ((PreserveRights != Defaults.PreserveRights) ||
  79. (PreserveRights &&
  80. ((Rights != Defaults.Rights) || (AddXToDirectories != Defaults.AddXToDirectories))))
  81. {
  82. assert(PreserveRights);
  83. if (PreserveRights)
  84. {
  85. AnsiString RightsStr = Rights.Text;
  86. if (AddXToDirectories)
  87. {
  88. RightsStr += ", " + LoadStr(COPY_INFO_ADD_X_TO_DIRS);
  89. }
  90. ADD(FORMAT(LoadStr(COPY_INFO_PERMISSIONS), (RightsStr)));
  91. }
  92. }
  93. if (PreserveReadOnly != Defaults.PreserveReadOnly)
  94. {
  95. assert(!PreserveReadOnly);
  96. if (!PreserveReadOnly)
  97. {
  98. ADD(LoadStr(COPY_INFO_DONT_PRESERVE_READONLY));
  99. }
  100. }
  101. if (PreserveTime != Defaults.PreserveTime)
  102. {
  103. ADD(LoadStr(PreserveTime ? COPY_INFO_TIMESTAMP : COPY_INFO_DONT_PRESERVE_TIME));
  104. }
  105. if (CalculateSize != Defaults.CalculateSize)
  106. {
  107. assert(!CalculateSize);
  108. if (!CalculateSize)
  109. {
  110. ADD(LoadStr(COPY_INFO_DONT_CALCULATE_SIZE));
  111. }
  112. }
  113. if (ClearArchive != Defaults.ClearArchive)
  114. {
  115. assert(ClearArchive);
  116. if (ClearArchive)
  117. {
  118. ADD(LoadStr(COPY_INFO_CLEAR_ARCHIVE));
  119. }
  120. }
  121. }
  122. if ((NegativeExclude != Defaults.NegativeExclude) ||
  123. !(ExcludeFileMask == Defaults.ExcludeFileMask))
  124. {
  125. ADD(FORMAT(LoadStr(NegativeExclude ? COPY_INFO_INCLUDE_MASK : COPY_INFO_EXCLUDE_MASK),
  126. (ExcludeFileMask.Masks)));
  127. }
  128. #undef ADD
  129. if (Result.IsEmpty())
  130. {
  131. Result = LoadStr(COPY_INFO_DEFAULT);
  132. }
  133. return Result;
  134. }
  135. //---------------------------------------------------------------------------
  136. void __fastcall TCopyParamType::Assign(const TCopyParamType * Source)
  137. {
  138. assert(Source != NULL);
  139. #define COPY(Prop) Prop = Source->Prop
  140. COPY(FileNameCase);
  141. COPY(PreserveReadOnly);
  142. COPY(PreserveTime);
  143. COPY(Rights);
  144. COPY(AsciiFileMask);
  145. COPY(TransferMode);
  146. COPY(AddXToDirectories);
  147. COPY(PreserveRights);
  148. COPY(ResumeSupport);
  149. COPY(ResumeThreshold);
  150. COPY(InvalidCharsReplacement);
  151. COPY(LocalInvalidChars);
  152. COPY(CalculateSize);
  153. COPY(FileMask);
  154. COPY(ExcludeFileMask);
  155. COPY(NegativeExclude);
  156. COPY(ClearArchive);
  157. #undef COPY
  158. }
  159. //---------------------------------------------------------------------------
  160. TCopyParamType & __fastcall TCopyParamType::operator =(const TCopyParamType & rhp)
  161. {
  162. Assign(&rhp);
  163. return *this;
  164. }
  165. //---------------------------------------------------------------------------
  166. void __fastcall TCopyParamType::SetLocalInvalidChars(AnsiString value)
  167. {
  168. if (value != LocalInvalidChars)
  169. {
  170. FLocalInvalidChars = value;
  171. FTokenizibleChars = FLocalInvalidChars + TokenPrefix;
  172. }
  173. }
  174. //---------------------------------------------------------------------------
  175. bool __fastcall TCopyParamType::GetReplaceInvalidChars() const
  176. {
  177. return (InvalidCharsReplacement != NoReplacement);
  178. }
  179. //---------------------------------------------------------------------------
  180. void __fastcall TCopyParamType::SetReplaceInvalidChars(bool value)
  181. {
  182. if (ReplaceInvalidChars != value)
  183. {
  184. InvalidCharsReplacement = (value ? TokenReplacement : NoReplacement);
  185. }
  186. }
  187. //---------------------------------------------------------------------------
  188. AnsiString __fastcall TCopyParamType::ValidLocalFileName(AnsiString FileName) const
  189. {
  190. if (InvalidCharsReplacement != NoReplacement)
  191. {
  192. bool ATokenReplacement = (InvalidCharsReplacement == TokenReplacement);
  193. const char * Chars =
  194. (ATokenReplacement ? FTokenizibleChars : LocalInvalidChars).c_str();
  195. char * InvalidChar = FileName.c_str();
  196. while ((InvalidChar = strpbrk(InvalidChar, Chars)) != NULL)
  197. {
  198. int Index = InvalidChar - FileName.c_str() + 1;
  199. if (FileName.ByteType(Index) == mbSingleByte)
  200. {
  201. if (ATokenReplacement)
  202. {
  203. FileName.Insert(CharToHex(FileName[Index]), Index + 1);
  204. FileName[Index] = TokenPrefix;
  205. InvalidChar = FileName.c_str() + Index + 2;
  206. }
  207. else
  208. {
  209. FileName[Index] = InvalidCharsReplacement;
  210. InvalidChar++;
  211. }
  212. }
  213. else
  214. {
  215. InvalidChar++;
  216. }
  217. }
  218. }
  219. return FileName;
  220. }
  221. //---------------------------------------------------------------------------
  222. // not used yet
  223. AnsiString __fastcall TCopyParamType::Untokenize(AnsiString FileName)
  224. {
  225. char * Token;
  226. AnsiString Result = FileName;
  227. while ((Token = AnsiStrScan(Result.c_str(), TokenPrefix)) != NULL)
  228. {
  229. int Index = Token - Result.c_str() + 1;
  230. if (Index > Result.Length() - 2)
  231. {
  232. Result = FileName;
  233. break;
  234. }
  235. else
  236. {
  237. char Ch = (char)HexToInt(Result.SubString(Index + 1, 2), -1);
  238. if (Ch == '\0')
  239. {
  240. Result = FileName;
  241. break;
  242. }
  243. else
  244. {
  245. Result[Index] = Ch;
  246. Result.Delete(Index + 1, 2);
  247. }
  248. }
  249. }
  250. return Result;
  251. }
  252. //---------------------------------------------------------------------------
  253. AnsiString __fastcall TCopyParamType::ChangeFileName(AnsiString FileName,
  254. TOperationSide Side, bool FirstLevel) const
  255. {
  256. if (FirstLevel)
  257. {
  258. FileName = MaskFileName(FileName, FileMask);
  259. }
  260. switch (FileNameCase) {
  261. case ncUpperCase: FileName = FileName.UpperCase(); break;
  262. case ncLowerCase: FileName = FileName.LowerCase(); break;
  263. case ncFirstUpperCase: FileName = FileName.SubString(1, 1).UpperCase() +
  264. FileName.SubString(2, FileName.Length()-1).LowerCase(); break;
  265. case ncLowerCaseShort:
  266. if ((FileName.Length() <= 12) && (FileName.Pos(".") <= 9) &&
  267. (FileName == FileName.UpperCase()))
  268. {
  269. FileName = FileName.LowerCase();
  270. }
  271. break;
  272. case ncNoChange:
  273. default:
  274. /*nothing*/
  275. break;
  276. }
  277. if (Side == osRemote)
  278. {
  279. FileName = ValidLocalFileName(FileName);
  280. }
  281. return FileName;
  282. }
  283. //---------------------------------------------------------------------------
  284. bool __fastcall TCopyParamType::UseAsciiTransfer(AnsiString FileName,
  285. TOperationSide Side) const
  286. {
  287. switch (TransferMode) {
  288. case tmBinary: return false;
  289. case tmAscii: return true;
  290. case tmAutomatic: return AsciiFileMask.Matches(FileName, (Side == osLocal), false);
  291. default: assert(false); return false;
  292. }
  293. }
  294. //---------------------------------------------------------------------------
  295. TRights __fastcall TCopyParamType::RemoteFileRights(Integer Attrs) const
  296. {
  297. TRights R = Rights;
  298. /* if ((Attrs & faReadOnly) && PreserveReadOnly)
  299. R.ReadOnly = True;*/
  300. if ((Attrs & faDirectory) && AddXToDirectories)
  301. R.AddExecute();
  302. return R;
  303. }
  304. //---------------------------------------------------------------------------
  305. AnsiString __fastcall TCopyParamType::GetLogStr() const
  306. {
  307. char CaseC[] = "NULFS";
  308. char ModeC[] = "BAM";
  309. char ResumeC[] = "YSN";
  310. return FORMAT(
  311. " PrTime: %s; PrRO: %s; Rght: %s; PrR: %s; FnCs: %s; RIC: %s; "
  312. "Resume: %s (%d); CalcS: %s; Mask: %s\n"
  313. " TM: %s; ClAr: %s; ExclM(%s): %s\n"
  314. " AscM: %s\n",
  315. (BooleanToEngStr(PreserveTime),
  316. BooleanToEngStr(PreserveReadOnly),
  317. Rights.Text,
  318. BooleanToEngStr(PreserveRights),
  319. CaseC[FileNameCase],
  320. CharToHex(InvalidCharsReplacement),
  321. ResumeC[ResumeSupport],
  322. (int)ResumeThreshold,
  323. BooleanToEngStr(CalculateSize),
  324. FileMask,
  325. ModeC[TransferMode],
  326. BooleanToEngStr(ClearArchive),
  327. BooleanToEngStr(NegativeExclude),
  328. ExcludeFileMask.Masks,
  329. AsciiFileMask.Masks));
  330. }
  331. //---------------------------------------------------------------------------
  332. int __fastcall TCopyParamType::LocalFileAttrs(const TRights & Rights) const
  333. {
  334. int Result = 0;
  335. if (PreserveReadOnly && !Rights.Right[TRights::rrUserWrite])
  336. {
  337. Result |= faReadOnly;
  338. }
  339. return Result;
  340. }
  341. //---------------------------------------------------------------------------
  342. bool __fastcall TCopyParamType::AllowResume(__int64 Size) const
  343. {
  344. switch (ResumeSupport) {
  345. case rsOn: return true;
  346. case rsOff: return false;
  347. case rsSmart: return (Size >= ResumeThreshold);
  348. default: assert(false); return false;
  349. }
  350. }
  351. //---------------------------------------------------------------------------
  352. bool __fastcall TCopyParamType::AllowTransfer(AnsiString FileName,
  353. TOperationSide Side, bool Directory) const
  354. {
  355. bool Result = true;
  356. if (!ExcludeFileMask.Masks.IsEmpty())
  357. {
  358. Result = (ExcludeFileMask.Matches(FileName, (Side == osLocal), Directory) ==
  359. NegativeExclude);
  360. }
  361. return Result;
  362. }
  363. //---------------------------------------------------------------------------
  364. void __fastcall TCopyParamType::Load(THierarchicalStorage * Storage)
  365. {
  366. AddXToDirectories = Storage->ReadBool("AddXToDirectories", AddXToDirectories);
  367. AsciiFileMask.Masks = Storage->ReadString("Masks", AsciiFileMask.Masks);
  368. FileNameCase = (TFileNameCase)Storage->ReadInteger("FileNameCase", FileNameCase);
  369. PreserveReadOnly = Storage->ReadBool("PreserveReadOnly", PreserveReadOnly);
  370. PreserveTime = Storage->ReadBool("PreserveTime", PreserveTime);
  371. PreserveRights = Storage->ReadBool("PreserveRights", PreserveRights);
  372. Rights.Text = Storage->ReadString("Text", Rights.Text);
  373. TransferMode = (TTransferMode)Storage->ReadInteger("TransferMode", TransferMode);
  374. ResumeSupport = (TResumeSupport)Storage->ReadInteger("ResumeSupport", ResumeSupport);
  375. ResumeThreshold = Storage->ReadInt64("ResumeThreshold", ResumeThreshold);
  376. InvalidCharsReplacement = (char)Storage->ReadInteger("ReplaceInvalidChars",
  377. (unsigned char)InvalidCharsReplacement);
  378. LocalInvalidChars = Storage->ReadString("LocalInvalidChars", LocalInvalidChars);
  379. CalculateSize = Storage->ReadBool("CalculateSize", CalculateSize);
  380. ExcludeFileMask.Masks = Storage->ReadString("ExcludeFileMask", ExcludeFileMask.Masks);
  381. NegativeExclude = Storage->ReadBool("NegativeExclude", NegativeExclude);
  382. ClearArchive = Storage->ReadBool("ClearArchive", ClearArchive);
  383. }
  384. //---------------------------------------------------------------------------
  385. void __fastcall TCopyParamType::Save(THierarchicalStorage * Storage) const
  386. {
  387. Storage->WriteBool("AddXToDirectories", AddXToDirectories);
  388. Storage->WriteString("Masks", AsciiFileMask.Masks);
  389. Storage->WriteInteger("FileNameCase", FileNameCase);
  390. Storage->WriteBool("PreserveReadOnly", PreserveReadOnly);
  391. Storage->WriteBool("PreserveTime", PreserveTime);
  392. Storage->WriteBool("PreserveRights", PreserveRights);
  393. Storage->WriteString("Text", Rights.Text);
  394. Storage->WriteInteger("TransferMode", TransferMode);
  395. Storage->WriteInteger("ResumeSupport", ResumeSupport);
  396. Storage->WriteInt64("ResumeThreshold", ResumeThreshold);
  397. Storage->WriteInteger("ReplaceInvalidChars", (unsigned char)InvalidCharsReplacement);
  398. Storage->WriteString("LocalInvalidChars", LocalInvalidChars);
  399. Storage->WriteBool("CalculateSize", CalculateSize);
  400. Storage->WriteString("ExcludeFileMask", ExcludeFileMask.Masks);
  401. Storage->WriteBool("NegativeExclude", NegativeExclude);
  402. Storage->WriteBool("ClearArchive", ClearArchive);
  403. }
  404. //---------------------------------------------------------------------------
  405. #define C(Property) (Property == rhp.Property)
  406. bool __fastcall TCopyParamType::operator==(const TCopyParamType & rhp) const
  407. {
  408. return
  409. C(AddXToDirectories) &&
  410. C(AsciiFileMask) &&
  411. C(FileNameCase) &&
  412. C(PreserveReadOnly) &&
  413. C(PreserveTime) &&
  414. C(PreserveRights) &&
  415. C(Rights) &&
  416. C(TransferMode) &&
  417. C(ResumeSupport) &&
  418. C(ResumeThreshold) &&
  419. C(InvalidCharsReplacement) &&
  420. C(LocalInvalidChars) &&
  421. C(CalculateSize) &&
  422. C(ExcludeFileMask) &&
  423. C(NegativeExclude) &&
  424. C(ClearArchive) &&
  425. true;
  426. }
  427. #undef C
  428. //---------------------------------------------------------------------------