HierarchicalStorage.cpp 24 KB

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