HierarchicalStorage.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Common.h"
  5. #include "PuttyIntf.h"
  6. #include "HierarchicalStorage.h"
  7. #include <vector>
  8. //---------------------------------------------------------------------------
  9. #pragma package(smart_init)
  10. //---------------------------------------------------------------------------
  11. #define READ_REGISTRY(Method) \
  12. if (FRegistry->ValueExists(Name)) \
  13. try { return FRegistry->Method(Name); } catch(...) { FFailed++; return Default; } \
  14. else return Default;
  15. #define WRITE_REGISTRY(Method) \
  16. try { FRegistry->Method(Name, Value); } catch(...) { FFailed++; }
  17. //---------------------------------------------------------------------------
  18. AnsiString __fastcall MungeStr(const AnsiString Str)
  19. {
  20. AnsiString Result;
  21. Result.SetLength(Str.Length() * 3 + 1);
  22. putty_mungestr(Str.c_str(), Result.c_str());
  23. PackStr(Result);
  24. return Result;
  25. }
  26. //---------------------------------------------------------------------------
  27. AnsiString __fastcall UnMungeStr(const AnsiString Str)
  28. {
  29. AnsiString Result;
  30. Result.SetLength(Str.Length() * 3 + 1);
  31. putty_unmungestr(Str.c_str(), Result.c_str(), Result.Length());
  32. PackStr(Result);
  33. return Result;
  34. }
  35. //---------------------------------------------------------------------------
  36. AnsiString __fastcall SimpleMungeStr(const AnsiString Str)
  37. {
  38. AnsiString Result = Str;
  39. for (int i = 1; i < Result.Length(); i++)
  40. {
  41. if ((Result[i] == '\\') || (Result[i] == '[') || (Result[i] == ']'))
  42. {
  43. Result[i] = '_';
  44. }
  45. }
  46. return Result;
  47. }
  48. //===========================================================================
  49. __fastcall THierarchicalStorage::THierarchicalStorage(const AnsiString AStorage)
  50. {
  51. FStorage = AStorage;
  52. FKeyHistory = new TStringList();
  53. AccessMode = smRead;
  54. }
  55. //---------------------------------------------------------------------------
  56. __fastcall THierarchicalStorage::~THierarchicalStorage()
  57. {
  58. delete FKeyHistory;
  59. }
  60. //---------------------------------------------------------------------------
  61. void __fastcall THierarchicalStorage::SetAccessMode(TStorageAccessMode value)
  62. {
  63. FAccessMode = value;
  64. }
  65. //---------------------------------------------------------------------------
  66. AnsiString __fastcall THierarchicalStorage::GetCurrentSubKey()
  67. {
  68. if (FKeyHistory->Count) return FKeyHistory->Strings[FKeyHistory->Count-1];
  69. else return "";
  70. }
  71. //---------------------------------------------------------------------------
  72. bool __fastcall THierarchicalStorage::OpenRootKey(bool CanCreate)
  73. {
  74. return OpenSubKey("", CanCreate);
  75. }
  76. //---------------------------------------------------------------------------
  77. bool __fastcall THierarchicalStorage::OpenSubKey(const AnsiString SubKey, bool )
  78. {
  79. FKeyHistory->Add(IncludeTrailingBackslash(CurrentSubKey+SubKey));
  80. return true;
  81. }
  82. //---------------------------------------------------------------------------
  83. bool __fastcall THierarchicalStorage::CreateSubKey(const AnsiString SubKey)
  84. {
  85. FKeyHistory->Add(IncludeTrailingBackslash(CurrentSubKey+SubKey));
  86. return true;
  87. }
  88. //---------------------------------------------------------------------------
  89. void __fastcall THierarchicalStorage::CloseSubKey()
  90. {
  91. if (FKeyHistory->Count == 0) throw Exception("");
  92. else FKeyHistory->Delete(FKeyHistory->Count-1);
  93. }
  94. //---------------------------------------------------------------------------
  95. void __fastcall THierarchicalStorage::ClearSubKeys()
  96. {
  97. TStringList *SubKeys = new TStringList();
  98. try
  99. {
  100. GetSubKeyNames(SubKeys);
  101. for (int Index = 0; Index < SubKeys->Count; Index++)
  102. {
  103. RecursiveDeleteSubKey(SubKeys->Strings[Index]);
  104. }
  105. }
  106. __finally
  107. {
  108. delete SubKeys;
  109. }
  110. }
  111. //---------------------------------------------------------------------------
  112. void __fastcall THierarchicalStorage::RecursiveDeleteSubKey(const AnsiString Key)
  113. {
  114. if (OpenSubKey(Key, false))
  115. {
  116. ClearSubKeys();
  117. CloseSubKey();
  118. }
  119. DeleteSubKey(Key);
  120. }
  121. //---------------------------------------------------------------------------
  122. bool __fastcall THierarchicalStorage::HasSubKeys()
  123. {
  124. bool Result;
  125. TStrings * SubKeys = new TStringList();
  126. try
  127. {
  128. GetSubKeyNames(SubKeys);
  129. Result = (SubKeys->Count > 0);
  130. }
  131. __finally
  132. {
  133. delete SubKeys;
  134. }
  135. return Result;
  136. }
  137. //---------------------------------------------------------------------------
  138. void __fastcall THierarchicalStorage::ReadValues(Classes::TStrings* Strings,
  139. bool MaintainKeys)
  140. {
  141. TStrings * Names = new TStringList();
  142. try
  143. {
  144. GetValueNames(Names);
  145. for (int Index = 0; Index < Names->Count; Index++)
  146. {
  147. if (MaintainKeys)
  148. {
  149. Strings->Add(FORMAT("%s=%s", (Names->Strings[Index],
  150. ReadString(Names->Strings[Index], ""))));
  151. }
  152. else
  153. {
  154. Strings->Add(ReadString(Names->Strings[Index], ""));
  155. }
  156. }
  157. }
  158. __finally
  159. {
  160. delete Names;
  161. }
  162. }
  163. //---------------------------------------------------------------------------
  164. void __fastcall THierarchicalStorage::ClearValues()
  165. {
  166. TStrings * Names = new TStringList();
  167. try
  168. {
  169. GetValueNames(Names);
  170. for (int Index = 0; Index < Names->Count; Index++)
  171. {
  172. DeleteValue(Names->Strings[Index]);
  173. }
  174. }
  175. __finally
  176. {
  177. delete Names;
  178. }
  179. }
  180. //---------------------------------------------------------------------------
  181. void __fastcall THierarchicalStorage::WriteValues(Classes::TStrings * Strings,
  182. bool MaintainKeys)
  183. {
  184. ClearValues();
  185. if (Strings)
  186. {
  187. for (int Index = 0; Index < Strings->Count; Index++)
  188. {
  189. if (MaintainKeys)
  190. {
  191. assert(Strings->Strings[Index].Pos("=") > 1);
  192. WriteString(Strings->Names[Index], Strings->Values[Strings->Names[Index]]);
  193. }
  194. else
  195. {
  196. WriteString(IntToStr(Index), Strings->Strings[Index]);
  197. }
  198. }
  199. }
  200. }
  201. //---------------------------------------------------------------------------
  202. AnsiString __fastcall THierarchicalStorage::ReadString(const AnsiString Name, const AnsiString Default)
  203. {
  204. return UnMungeStr(ReadStringRaw(Name, MungeStr(Default)));
  205. }
  206. //---------------------------------------------------------------------------
  207. AnsiString __fastcall THierarchicalStorage::ReadBinaryData(const AnsiString Name)
  208. {
  209. int Size = BinaryDataSize(Name);
  210. AnsiString Value;
  211. Value.SetLength(Size);
  212. ReadBinaryData(Name, Value.c_str(), Size);
  213. return Value;
  214. }
  215. //---------------------------------------------------------------------------
  216. void __fastcall THierarchicalStorage::WriteString(const AnsiString Name, const AnsiString Value)
  217. {
  218. WriteStringRaw(Name, MungeStr(Value));
  219. }
  220. //---------------------------------------------------------------------------
  221. void __fastcall THierarchicalStorage::WriteBinaryData(const AnsiString Name,
  222. const AnsiString Value)
  223. {
  224. WriteBinaryData(Name, Value.c_str(), Value.Length());
  225. }
  226. //---------------------------------------------------------------------------
  227. AnsiString __fastcall THierarchicalStorage::IncludeTrailingBackslash(const AnsiString & S)
  228. {
  229. // expanded from ?: as it caused memory leaks
  230. if (S.IsEmpty())
  231. {
  232. return S;
  233. }
  234. else
  235. {
  236. return ::IncludeTrailingBackslash(S);
  237. }
  238. }
  239. //---------------------------------------------------------------------------
  240. AnsiString __fastcall THierarchicalStorage::ExcludeTrailingBackslash(const AnsiString & S)
  241. {
  242. // expanded from ?: as it caused memory leaks
  243. if (S.IsEmpty())
  244. {
  245. return S;
  246. }
  247. else
  248. {
  249. return ::ExcludeTrailingBackslash(S);
  250. }
  251. }
  252. //===========================================================================
  253. __fastcall TRegistryStorage::TRegistryStorage(const AnsiString AStorage):
  254. THierarchicalStorage(IncludeTrailingBackslash(AStorage))
  255. {
  256. Init();
  257. };
  258. //---------------------------------------------------------------------------
  259. __fastcall TRegistryStorage::TRegistryStorage(const AnsiString AStorage, HKEY ARootKey):
  260. THierarchicalStorage(IncludeTrailingBackslash(AStorage))
  261. {
  262. Init();
  263. FRegistry->RootKey = ARootKey;
  264. }
  265. //---------------------------------------------------------------------------
  266. void __fastcall TRegistryStorage::Init()
  267. {
  268. FFailed = 0;
  269. FRegistry = new TRegistry();
  270. FRegistry->Access = KEY_READ;
  271. }
  272. //---------------------------------------------------------------------------
  273. __fastcall TRegistryStorage::~TRegistryStorage()
  274. {
  275. delete FRegistry;
  276. };
  277. //---------------------------------------------------------------------------
  278. bool __fastcall TRegistryStorage::Copy(TRegistryStorage * Storage)
  279. {
  280. TRegistry * Registry = Storage->FRegistry;
  281. bool Result = true;
  282. TStrings * Names = new TStringList();
  283. try
  284. {
  285. Registry->GetValueNames(Names);
  286. std::vector<unsigned char> Buffer(1024, 0);
  287. int Index = 0;
  288. while ((Index < Names->Count) && Result)
  289. {
  290. AnsiString Name = Names->Strings[Index];
  291. unsigned long Size = Buffer.size();
  292. unsigned long Type;
  293. int RegResult;
  294. do
  295. {
  296. RegResult = RegQueryValueEx(Registry->CurrentKey, Name.c_str(), NULL,
  297. &Type, &Buffer[0], &Size);
  298. if (Result == ERROR_MORE_DATA)
  299. {
  300. Buffer.resize(Size);
  301. }
  302. } while (RegResult == ERROR_MORE_DATA);
  303. Result = (RegResult == ERROR_SUCCESS);
  304. if (Result)
  305. {
  306. RegResult = RegSetValueEx(FRegistry->CurrentKey, Name.c_str(), NULL, Type,
  307. &Buffer[0], Size);
  308. Result = (RegResult == ERROR_SUCCESS);
  309. }
  310. ++Index;
  311. }
  312. }
  313. __finally
  314. {
  315. delete Names;
  316. }
  317. return Result;
  318. }
  319. //---------------------------------------------------------------------------
  320. void __fastcall TRegistryStorage::SetAccessMode(TStorageAccessMode value)
  321. {
  322. THierarchicalStorage::SetAccessMode(value);
  323. if (FRegistry)
  324. {
  325. switch (AccessMode) {
  326. case smRead:
  327. FRegistry->Access = KEY_READ;
  328. break;
  329. case smReadWrite:
  330. default:
  331. FRegistry->Access = KEY_READ | KEY_WRITE;
  332. break;
  333. }
  334. }
  335. }
  336. //---------------------------------------------------------------------------
  337. bool __fastcall TRegistryStorage::OpenSubKey(const AnsiString SubKey, bool CanCreate)
  338. {
  339. bool Result;
  340. if (FKeyHistory->Count > 0) FRegistry->CloseKey();
  341. Result = FRegistry->OpenKey(
  342. ExcludeTrailingBackslash(Storage + CurrentSubKey + SubKey), CanCreate);
  343. if (Result) Result = THierarchicalStorage::OpenSubKey(SubKey, CanCreate);
  344. return Result;
  345. }
  346. //---------------------------------------------------------------------------
  347. bool __fastcall TRegistryStorage::CreateSubKey(const AnsiString SubKey)
  348. {
  349. bool Result;
  350. if (FKeyHistory->Count) FRegistry->CloseKey();
  351. Result = FRegistry->CreateKey(ExcludeTrailingBackslash(Storage + CurrentSubKey + SubKey));
  352. if (Result) Result = THierarchicalStorage::CreateSubKey(CurrentSubKey + SubKey);
  353. return Result;
  354. }
  355. //---------------------------------------------------------------------------
  356. void __fastcall TRegistryStorage::CloseSubKey()
  357. {
  358. FRegistry->CloseKey();
  359. THierarchicalStorage::CloseSubKey();
  360. if (FKeyHistory->Count)
  361. {
  362. FRegistry->OpenKey(Storage + CurrentSubKey, True);
  363. }
  364. }
  365. //---------------------------------------------------------------------------
  366. bool __fastcall TRegistryStorage::DeleteSubKey(const AnsiString SubKey)
  367. {
  368. AnsiString K;
  369. if (FKeyHistory->Count == 0) K = Storage + CurrentSubKey;
  370. K += SubKey;
  371. return FRegistry->DeleteKey(K);
  372. }
  373. //---------------------------------------------------------------------------
  374. void __fastcall TRegistryStorage::GetSubKeyNames(Classes::TStrings* Strings)
  375. {
  376. FRegistry->GetKeyNames(Strings);
  377. }
  378. //---------------------------------------------------------------------------
  379. void __fastcall TRegistryStorage::GetValueNames(Classes::TStrings* Strings)
  380. {
  381. FRegistry->GetValueNames(Strings);
  382. }
  383. //---------------------------------------------------------------------------
  384. bool __fastcall TRegistryStorage::DeleteValue(const AnsiString Name)
  385. {
  386. return FRegistry->DeleteValue(Name);
  387. }
  388. //---------------------------------------------------------------------------
  389. bool __fastcall TRegistryStorage::KeyExists(const AnsiString SubKey)
  390. {
  391. return FRegistry->KeyExists(SubKey);
  392. }
  393. //---------------------------------------------------------------------------
  394. bool __fastcall TRegistryStorage::ValueExists(const AnsiString Value)
  395. {
  396. return FRegistry->ValueExists(Value);
  397. }
  398. //---------------------------------------------------------------------------
  399. int __fastcall TRegistryStorage::BinaryDataSize(const AnsiString Name)
  400. {
  401. return FRegistry->GetDataSize(Name);
  402. }
  403. //---------------------------------------------------------------------------
  404. bool __fastcall TRegistryStorage::ReadBool(const AnsiString Name, bool Default)
  405. {
  406. READ_REGISTRY(ReadBool);
  407. }
  408. //---------------------------------------------------------------------------
  409. TDateTime __fastcall TRegistryStorage::ReadDateTime(const AnsiString Name, TDateTime Default)
  410. {
  411. READ_REGISTRY(ReadDateTime);
  412. }
  413. //---------------------------------------------------------------------------
  414. double __fastcall TRegistryStorage::ReadFloat(const AnsiString Name, double Default)
  415. {
  416. READ_REGISTRY(ReadFloat);
  417. }
  418. //---------------------------------------------------------------------------
  419. int __fastcall TRegistryStorage::ReadInteger(const AnsiString Name, int Default)
  420. {
  421. READ_REGISTRY(ReadInteger);
  422. }
  423. //---------------------------------------------------------------------------
  424. __int64 __fastcall TRegistryStorage::ReadInt64(const AnsiString Name, __int64 Default)
  425. {
  426. __int64 Result = Default;
  427. if (FRegistry->ValueExists(Name))
  428. {
  429. try
  430. {
  431. FRegistry->ReadBinaryData(Name, &Result, sizeof(Result));
  432. }
  433. catch(...)
  434. {
  435. FFailed++;
  436. }
  437. }
  438. return Result;
  439. }
  440. //---------------------------------------------------------------------------
  441. AnsiString __fastcall TRegistryStorage::ReadStringRaw(const AnsiString Name, const AnsiString Default)
  442. {
  443. READ_REGISTRY(ReadString);
  444. }
  445. //---------------------------------------------------------------------------
  446. int __fastcall TRegistryStorage::ReadBinaryData(const AnsiString Name,
  447. void * Buffer, int Size)
  448. {
  449. int Result;
  450. if (FRegistry->ValueExists(Name))
  451. {
  452. try
  453. {
  454. Result = FRegistry->ReadBinaryData(Name, Buffer, Size);
  455. }
  456. catch(...)
  457. {
  458. Result = 0;
  459. FFailed++;
  460. }
  461. }
  462. else
  463. {
  464. Result = 0;
  465. }
  466. return Result;
  467. }
  468. //---------------------------------------------------------------------------
  469. void __fastcall TRegistryStorage::WriteBool(const AnsiString Name, bool Value)
  470. {
  471. WRITE_REGISTRY(WriteBool);
  472. }
  473. //---------------------------------------------------------------------------
  474. void __fastcall TRegistryStorage::WriteDateTime(const AnsiString Name, TDateTime Value)
  475. {
  476. WRITE_REGISTRY(WriteDateTime);
  477. }
  478. //---------------------------------------------------------------------------
  479. void __fastcall TRegistryStorage::WriteFloat(const AnsiString Name, double Value)
  480. {
  481. WRITE_REGISTRY(WriteFloat);
  482. }
  483. //---------------------------------------------------------------------------
  484. void __fastcall TRegistryStorage::WriteStringRaw(const AnsiString Name, const AnsiString Value)
  485. {
  486. WRITE_REGISTRY(WriteString);
  487. }
  488. //---------------------------------------------------------------------------
  489. void __fastcall TRegistryStorage::WriteInteger(const AnsiString Name, int Value)
  490. {
  491. WRITE_REGISTRY(WriteInteger);
  492. }
  493. //---------------------------------------------------------------------------
  494. void __fastcall TRegistryStorage::WriteInt64(const AnsiString Name, __int64 Value)
  495. {
  496. try
  497. {
  498. FRegistry->WriteBinaryData(Name, &Value, sizeof(Value));
  499. }
  500. catch(...)
  501. {
  502. FFailed++;
  503. }
  504. }
  505. //---------------------------------------------------------------------------
  506. void __fastcall TRegistryStorage::WriteBinaryData(const AnsiString Name,
  507. const void * Buffer, int Size)
  508. {
  509. try
  510. {
  511. FRegistry->WriteBinaryData(Name, const_cast<void *>(Buffer), Size);
  512. }
  513. catch(...)
  514. {
  515. FFailed++;
  516. }
  517. }
  518. //---------------------------------------------------------------------------
  519. int __fastcall TRegistryStorage::GetFailed()
  520. {
  521. int Result = FFailed;
  522. FFailed = 0;
  523. return Result;
  524. }
  525. //===========================================================================
  526. __fastcall TIniFileStorage::TIniFileStorage(const AnsiString AStorage):
  527. THierarchicalStorage(AStorage)
  528. {
  529. FIniFile = new TMemIniFile(Storage);
  530. }
  531. //---------------------------------------------------------------------------
  532. __fastcall TIniFileStorage::~TIniFileStorage()
  533. {
  534. FIniFile->UpdateFile();
  535. delete FIniFile;
  536. }
  537. //---------------------------------------------------------------------------
  538. AnsiString __fastcall TIniFileStorage::GetCurrentSection()
  539. {
  540. return ExcludeTrailingBackslash(CurrentSubKey);
  541. }
  542. //---------------------------------------------------------------------------
  543. bool __fastcall TIniFileStorage::OpenSubKey(const AnsiString SubKey, bool CanCreate)
  544. {
  545. bool Result = CanCreate;
  546. if (!Result)
  547. {
  548. TStringList * Sections = new TStringList();
  549. try
  550. {
  551. Sections->Sorted = true;
  552. FIniFile->ReadSections(Sections);
  553. AnsiString NewKey = ExcludeTrailingBackslash(CurrentSubKey+SubKey);
  554. int Index = -1;
  555. if (Sections->Count)
  556. {
  557. Result = Sections->Find(NewKey, Index);
  558. if (!Result && Index < Sections->Count &&
  559. Sections->Strings[Index].SubString(1, NewKey.Length()+1) == NewKey + "\\")
  560. {
  561. Result = true;
  562. }
  563. }
  564. }
  565. __finally
  566. {
  567. delete Sections;
  568. }
  569. }
  570. if (Result)
  571. {
  572. Result = THierarchicalStorage::OpenSubKey(SubKey, CanCreate);
  573. }
  574. return Result;
  575. }
  576. //---------------------------------------------------------------------------
  577. bool __fastcall TIniFileStorage::DeleteSubKey(const AnsiString SubKey)
  578. {
  579. bool Result;
  580. try
  581. {
  582. FIniFile->EraseSection(CurrentSubKey + SubKey);
  583. Result = true;
  584. }
  585. catch (...)
  586. {
  587. Result = false;
  588. }
  589. return Result;
  590. }
  591. //---------------------------------------------------------------------------
  592. void __fastcall TIniFileStorage::GetSubKeyNames(Classes::TStrings* Strings)
  593. {
  594. TStrings * Sections = new TStringList();
  595. try
  596. {
  597. Strings->Clear();
  598. FIniFile->ReadSections(Sections);
  599. for (int i = 0; i < Sections->Count; i++)
  600. {
  601. AnsiString Section = Sections->Strings[i];
  602. if (AnsiCompareText(CurrentSubKey,
  603. Section.SubString(1, CurrentSubKey.Length())) == 0)
  604. {
  605. AnsiString SubSection = Section.SubString(CurrentSubKey.Length() + 1,
  606. Section.Length() - CurrentSubKey.Length());
  607. int P = SubSection.Pos("\\");
  608. if (P)
  609. {
  610. SubSection.SetLength(P - 1);
  611. }
  612. if (Strings->IndexOf(SubSection) < 0)
  613. {
  614. Strings->Add(SubSection);
  615. }
  616. }
  617. }
  618. }
  619. __finally
  620. {
  621. delete Sections;
  622. }
  623. }
  624. //---------------------------------------------------------------------------
  625. void __fastcall TIniFileStorage::GetValueNames(Classes::TStrings* Strings)
  626. {
  627. return FIniFile->ReadSection(CurrentSection, Strings);
  628. }
  629. //---------------------------------------------------------------------------
  630. bool __fastcall TIniFileStorage::KeyExists(const AnsiString SubKey)
  631. {
  632. return FIniFile->SectionExists(CurrentSubKey + SubKey);
  633. }
  634. //---------------------------------------------------------------------------
  635. bool __fastcall TIniFileStorage::ValueExists(const AnsiString Value)
  636. {
  637. return FIniFile->ValueExists(CurrentSection, Value);
  638. }
  639. //---------------------------------------------------------------------------
  640. bool __fastcall TIniFileStorage::DeleteValue(const AnsiString Name)
  641. {
  642. FIniFile->DeleteKey(CurrentSection, Name);
  643. return true;
  644. }
  645. //---------------------------------------------------------------------------
  646. int __fastcall TIniFileStorage::BinaryDataSize(const AnsiString Name)
  647. {
  648. return ReadStringRaw(Name, "").Length() / 2;
  649. }
  650. //---------------------------------------------------------------------------
  651. bool __fastcall TIniFileStorage::ReadBool(const AnsiString Name, bool Default)
  652. {
  653. return FIniFile->ReadBool(CurrentSection, Name, Default);
  654. }
  655. //---------------------------------------------------------------------------
  656. int __fastcall TIniFileStorage::ReadInteger(const AnsiString Name, int Default)
  657. {
  658. return FIniFile->ReadInteger(CurrentSection, Name, Default);
  659. }
  660. //---------------------------------------------------------------------------
  661. __int64 __fastcall TIniFileStorage::ReadInt64(const AnsiString Name, __int64 Default)
  662. {
  663. __int64 Result = Default;
  664. AnsiString Str;
  665. Str = ReadStringRaw(Name, "");
  666. if (!Str.IsEmpty())
  667. {
  668. Result = StrToInt64Def(Str, Default);
  669. }
  670. return Result;
  671. }
  672. //---------------------------------------------------------------------------
  673. TDateTime __fastcall TIniFileStorage::ReadDateTime(const AnsiString Name, TDateTime Default)
  674. {
  675. TDateTime Result;
  676. AnsiString Value = FIniFile->ReadString(CurrentSection, Name, "");
  677. if (Value.IsEmpty())
  678. {
  679. Result = Default;
  680. }
  681. else
  682. {
  683. try
  684. {
  685. AnsiString Raw = HexToStr(Value);
  686. if (Raw.Length() == sizeof(Result))
  687. {
  688. memcpy(&Result, Raw.c_str(), sizeof(Result));
  689. }
  690. else
  691. {
  692. Result = StrToDateTime(Value);
  693. }
  694. }
  695. catch(...)
  696. {
  697. Result = Default;
  698. }
  699. }
  700. return Result;
  701. }
  702. //---------------------------------------------------------------------------
  703. double __fastcall TIniFileStorage::ReadFloat(const AnsiString Name, double Default)
  704. {
  705. double Result;
  706. AnsiString Value = FIniFile->ReadString(CurrentSection, Name, "");
  707. if (Value.IsEmpty())
  708. {
  709. Result = Default;
  710. }
  711. else
  712. {
  713. try
  714. {
  715. AnsiString Raw = HexToStr(Value);
  716. if (Raw.Length() == sizeof(Result))
  717. {
  718. memcpy(&Result, Raw.c_str(), sizeof(Result));
  719. }
  720. else
  721. {
  722. Result = StrToFloat(Value);
  723. }
  724. }
  725. catch(...)
  726. {
  727. Result = Default;
  728. }
  729. }
  730. return Result;
  731. }
  732. //---------------------------------------------------------------------------
  733. AnsiString __fastcall TIniFileStorage::ReadStringRaw(const AnsiString Name, AnsiString Default)
  734. {
  735. AnsiString Section = CurrentSection;
  736. AnsiString Result;
  737. Result = FIniFile->ReadString(Section, Name, Default);
  738. // TIniFile::ReadString has limit of 2 kB.
  739. // We could straithly use our routine, but call to legacy code is preserved
  740. // until ours is proved to work and also to save memory overhead
  741. if (Result.Length() == 2047)
  742. {
  743. char Buffer[10240];
  744. GetPrivateProfileString(Section.c_str(), Name.c_str(), Default.c_str(),
  745. Buffer, sizeof(Buffer), FIniFile->FileName.c_str());
  746. Result = Buffer;
  747. }
  748. return Result;
  749. }
  750. //---------------------------------------------------------------------------
  751. int __fastcall TIniFileStorage::ReadBinaryData(const AnsiString Name,
  752. void * Buffer, int Size)
  753. {
  754. AnsiString Value = HexToStr(ReadStringRaw(Name, ""));
  755. int Len = Value.Length();
  756. if (Size > Len)
  757. {
  758. Size = Len;
  759. }
  760. assert(Buffer);
  761. memcpy(Buffer, Value.c_str(), Size);
  762. return Size;
  763. }
  764. //---------------------------------------------------------------------------
  765. void __fastcall TIniFileStorage::WriteBool(const AnsiString Name, bool Value)
  766. {
  767. FIniFile->WriteBool(CurrentSection, Name, Value);
  768. }
  769. //---------------------------------------------------------------------------
  770. void __fastcall TIniFileStorage::WriteInteger(const AnsiString Name, int Value)
  771. {
  772. FIniFile->WriteInteger(CurrentSection, Name, Value);
  773. }
  774. //---------------------------------------------------------------------------
  775. void __fastcall TIniFileStorage::WriteInt64(const AnsiString Name, __int64 Value)
  776. {
  777. WriteStringRaw(Name, IntToStr(Value));
  778. }
  779. //---------------------------------------------------------------------------
  780. void __fastcall TIniFileStorage::WriteDateTime(const AnsiString Name, TDateTime Value)
  781. {
  782. WriteBinaryData(Name, &Value, sizeof(Value));
  783. }
  784. //---------------------------------------------------------------------------
  785. void __fastcall TIniFileStorage::WriteFloat(const AnsiString Name, double Value)
  786. {
  787. WriteBinaryData(Name, &Value, sizeof(Value));
  788. }
  789. //---------------------------------------------------------------------------
  790. void __fastcall TIniFileStorage::WriteStringRaw(const AnsiString Name, const AnsiString Value)
  791. {
  792. if ((Value.Length() >= 2) && (Value[1] == '"') && (Value[Value.Length()] == '"'))
  793. {
  794. FIniFile->WriteString(CurrentSection, Name, "\"" + Value + "\"");
  795. }
  796. else
  797. {
  798. FIniFile->WriteString(CurrentSection, Name, Value);
  799. }
  800. }
  801. //---------------------------------------------------------------------------
  802. void __fastcall TIniFileStorage::WriteBinaryData(const AnsiString Name,
  803. const void * Buffer, int Size)
  804. {
  805. WriteStringRaw(Name, StrToHex(AnsiString(static_cast<const char*>(Buffer), Size)));
  806. }