Registry.cxx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
  5. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  8. PURPOSE. See the above copyright notices for more information.
  9. =========================================================================*/
  10. #include "kwsysPrivate.h"
  11. #include KWSYS_HEADER(Registry.hxx)
  12. #include KWSYS_HEADER(Configure.hxx)
  13. #include KWSYS_HEADER(ios/iostream)
  14. #include KWSYS_HEADER(stl/string)
  15. #include KWSYS_HEADER(stl/map)
  16. #include KWSYS_HEADER(ios/iostream)
  17. #include KWSYS_HEADER(ios/fstream)
  18. #include KWSYS_HEADER(ios/sstream)
  19. // Work-around CMake dependency scanning limitation. This must
  20. // duplicate the above list of headers.
  21. #if 0
  22. # include "Registry.hxx.in"
  23. # include "Configure.hxx.in"
  24. # include "kwsys_stl.hxx.in"
  25. # include "kwsys_stl_string.hxx.in"
  26. # include "kwsys_stl_map.hxx.in"
  27. # include "kwsys_ios_iostream.h.in"
  28. # include "kwsys_ios_fstream.h.in"
  29. # include "kwsys_ios_sstream.h.in"
  30. #endif
  31. #include <ctype.h> // for isspace
  32. #include <stdio.h>
  33. #ifdef _WIN32
  34. # include <windows.h>
  35. #endif
  36. namespace KWSYS_NAMESPACE
  37. {
  38. class RegistryHelper {
  39. public:
  40. RegistryHelper(Registry::RegistryType registryType);
  41. virtual ~RegistryHelper();
  42. // Read a value from the registry.
  43. virtual bool ReadValue(const char *key, const char **value);
  44. // Delete a key from the registry.
  45. virtual bool DeleteKey(const char *key);
  46. // Delete a value from a given key.
  47. virtual bool DeleteValue(const char *key);
  48. // Set value in a given key.
  49. virtual bool SetValue(const char *key,
  50. const char *value);
  51. // Open the registry at toplevel/subkey.
  52. virtual bool Open(const char *toplevel, const char *subkey,
  53. int readonly);
  54. // Close the registry.
  55. virtual bool Close();
  56. // Set the value of changed
  57. void SetChanged(bool b) { m_Changed = b; }
  58. void SetTopLevel(const char* tl);
  59. const char* GetTopLevel() { return m_TopLevel.c_str(); }
  60. //! Read from local or global scope. On Windows this mean from local machine
  61. // or local user. On unix this will read from $HOME/.Projectrc or
  62. // /etc/Project
  63. void SetGlobalScope(bool b);
  64. bool GetGlobalScope();
  65. kwsys_stl::string EncodeKey(const char* str);
  66. kwsys_stl::string EncodeValue(const char* str);
  67. kwsys_stl::string DecodeValue(const char* str);
  68. protected:
  69. bool m_Changed;
  70. kwsys_stl::string m_TopLevel;
  71. bool m_GlobalScope;
  72. #ifdef _WIN32
  73. HKEY HKey;
  74. #endif
  75. // Strip trailing and ending spaces.
  76. char *Strip(char *str);
  77. void SetSubKey(const char* sk);
  78. kwsys_stl::string CreateKey(const char *key);
  79. typedef kwsys_stl::map<kwsys_stl::string, kwsys_stl::string> StringToStringMap;
  80. StringToStringMap EntriesMap;
  81. kwsys_stl::string m_SubKey;
  82. bool m_Empty;
  83. bool m_SubKeySpecified;
  84. kwsys_stl::string m_HomeDirectory;
  85. Registry::RegistryType m_RegistryType;
  86. };
  87. //----------------------------------------------------------------------------
  88. #define Registry_BUFFER_SIZE 8192
  89. //----------------------------------------------------------------------------
  90. Registry::Registry(Registry::RegistryType registryType)
  91. {
  92. m_Opened = false;
  93. m_Locked = false;
  94. this->Helper = 0;
  95. this->Helper = new RegistryHelper(registryType);
  96. }
  97. //----------------------------------------------------------------------------
  98. Registry::~Registry()
  99. {
  100. if ( m_Opened )
  101. {
  102. kwsys_ios::cerr << "Registry::Close should be "
  103. "called here. The registry is not closed."
  104. << kwsys_ios::endl;
  105. }
  106. delete this->Helper;
  107. }
  108. //----------------------------------------------------------------------------
  109. void Registry::SetGlobalScope(bool b)
  110. {
  111. this->Helper->SetGlobalScope(b);
  112. }
  113. //----------------------------------------------------------------------------
  114. bool Registry::GetGlobalScope()
  115. {
  116. return this->Helper->GetGlobalScope();
  117. }
  118. //----------------------------------------------------------------------------
  119. bool Registry::Open(const char *toplevel,
  120. const char *subkey, int readonly)
  121. {
  122. bool res = false;
  123. if ( m_Locked )
  124. {
  125. return res;
  126. }
  127. if ( m_Opened )
  128. {
  129. if ( !this->Close() )
  130. {
  131. return res;
  132. }
  133. }
  134. if ( !toplevel || !*toplevel )
  135. {
  136. kwsys_ios::cerr << "Registry::Opened() Toplevel not defined" << kwsys_ios::endl;
  137. return res;
  138. }
  139. if ( isspace(toplevel[0]) ||
  140. isspace(toplevel[strlen(toplevel)-1]) )
  141. {
  142. kwsys_ios::cerr << "Toplevel has to start with letter or number and end"
  143. " with one" << kwsys_ios::endl;
  144. return res;
  145. }
  146. res = this->Helper->Open(toplevel, subkey, readonly);
  147. if ( readonly != Registry::READONLY )
  148. {
  149. m_Locked = true;
  150. }
  151. if ( res )
  152. {
  153. m_Opened = true;
  154. this->Helper->SetTopLevel(toplevel);
  155. }
  156. return res;
  157. }
  158. //----------------------------------------------------------------------------
  159. bool Registry::Close()
  160. {
  161. bool res = false;
  162. if ( m_Opened )
  163. {
  164. res = this->Helper->Close();
  165. }
  166. if ( res )
  167. {
  168. m_Opened = false;
  169. m_Locked = false;
  170. this->Helper->SetChanged(false);
  171. }
  172. return res;
  173. }
  174. //----------------------------------------------------------------------------
  175. bool Registry::ReadValue(const char *subkey,
  176. const char *key,
  177. const char **value)
  178. {
  179. *value = 0;
  180. bool res = true;
  181. bool open = false;
  182. if ( ! value )
  183. {
  184. return res;
  185. }
  186. if ( !m_Opened )
  187. {
  188. if ( !this->Open(this->GetTopLevel(), subkey,
  189. Registry::READONLY) )
  190. {
  191. return res;
  192. }
  193. open = true;
  194. }
  195. res = this->Helper->ReadValue(key, value);
  196. if ( open )
  197. {
  198. if ( !this->Close() )
  199. {
  200. res = false;
  201. }
  202. }
  203. return res;
  204. }
  205. //----------------------------------------------------------------------------
  206. bool Registry::DeleteKey(const char *subkey, const char *key)
  207. {
  208. bool res = true;
  209. bool open = false;
  210. if ( !m_Opened )
  211. {
  212. if ( !this->Open(this->GetTopLevel(), subkey,
  213. Registry::READWRITE) )
  214. {
  215. return res;
  216. }
  217. open = true;
  218. }
  219. res = this->Helper->DeleteKey(key);
  220. if ( res )
  221. {
  222. this->Helper->SetChanged(true);
  223. }
  224. if ( open )
  225. {
  226. if ( !this->Close() )
  227. {
  228. res = false;
  229. }
  230. }
  231. return res;
  232. }
  233. //----------------------------------------------------------------------------
  234. bool Registry::DeleteValue(const char *subkey, const char *key)
  235. {
  236. bool res = true;
  237. bool open = false;
  238. if ( !m_Opened )
  239. {
  240. if ( !this->Open(this->GetTopLevel(), subkey,
  241. Registry::READWRITE) )
  242. {
  243. return res;
  244. }
  245. open = true;
  246. }
  247. res = this->Helper->DeleteValue(key);
  248. if ( res )
  249. {
  250. this->Helper->SetChanged(true);
  251. }
  252. if ( open )
  253. {
  254. if ( !this->Close() )
  255. {
  256. res = false;
  257. }
  258. }
  259. return res;
  260. }
  261. //----------------------------------------------------------------------------
  262. bool Registry::SetValue(const char *subkey, const char *key,
  263. const char *value)
  264. {
  265. bool res = false;
  266. bool open = false;
  267. if ( !m_Opened )
  268. {
  269. if ( !this->Open(this->GetTopLevel(), subkey,
  270. Registry::READWRITE) )
  271. {
  272. return res;
  273. }
  274. open = true;
  275. }
  276. res = this->Helper->SetValue( key, value );
  277. if ( res )
  278. {
  279. this->Helper->SetChanged(true);
  280. }
  281. if ( open )
  282. {
  283. if ( !this->Close() )
  284. {
  285. res = false;
  286. }
  287. }
  288. return res;
  289. }
  290. //----------------------------------------------------------------------------
  291. const char* Registry::GetTopLevel()
  292. {
  293. return this->Helper->GetTopLevel();
  294. }
  295. //----------------------------------------------------------------------------
  296. void Registry::SetTopLevel(const char* tl)
  297. {
  298. this->Helper->SetTopLevel(tl);
  299. }
  300. //----------------------------------------------------------------------------
  301. void RegistryHelper::SetTopLevel(const char* tl)
  302. {
  303. if ( tl )
  304. {
  305. m_TopLevel = tl;
  306. }
  307. else
  308. {
  309. m_TopLevel = "";
  310. }
  311. }
  312. //----------------------------------------------------------------------------
  313. RegistryHelper::RegistryHelper(Registry::RegistryType registryType)
  314. {
  315. m_Changed = false;
  316. m_TopLevel = "";
  317. m_SubKey = "";
  318. m_SubKeySpecified = false;
  319. m_Empty = true;
  320. m_GlobalScope = false;
  321. m_RegistryType = registryType;
  322. }
  323. //----------------------------------------------------------------------------
  324. RegistryHelper::~RegistryHelper()
  325. {
  326. }
  327. //----------------------------------------------------------------------------
  328. bool RegistryHelper::Open(const char *toplevel, const char *subkey,
  329. int readonly)
  330. {
  331. this->EntriesMap.clear();
  332. m_Empty = 1;
  333. #ifdef _WIN32
  334. if ( m_RegistryType == Registry::WIN32_REGISTRY)
  335. {
  336. HKEY scope = HKEY_CURRENT_USER;
  337. if ( this->GetGlobalScope() )
  338. {
  339. scope = HKEY_LOCAL_MACHINE;
  340. }
  341. int res = 0;
  342. kwsys_ios::ostringstream str;
  343. DWORD dwDummy;
  344. str << "Software\\Kitware\\" << toplevel << "\\" << subkey;
  345. if ( readonly == Registry::READONLY )
  346. {
  347. res = ( RegOpenKeyEx(scope, str.str().c_str(),
  348. 0, KEY_READ, &this->HKey) == ERROR_SUCCESS );
  349. }
  350. else
  351. {
  352. res = ( RegCreateKeyEx(scope, str.str().c_str(),
  353. 0, "", REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE,
  354. NULL, &this->HKey, &dwDummy) == ERROR_SUCCESS );
  355. }
  356. if ( res != 0 )
  357. {
  358. this->SetSubKey( subkey );
  359. }
  360. return (res != 0);
  361. }
  362. #endif
  363. if ( m_RegistryType == Registry::FILE_REGISTRY )
  364. {
  365. bool res = false;
  366. int cc;
  367. kwsys_ios::ostringstream str;
  368. const char* homeDirectory;
  369. if ( (homeDirectory = getenv("HOME")) == 0 )
  370. {
  371. if ( (homeDirectory = getenv("USERPROFILE")) == 0 )
  372. {
  373. return false;
  374. }
  375. }
  376. m_HomeDirectory = homeDirectory;
  377. str << m_HomeDirectory.c_str() << "/." << toplevel << "rc";
  378. if ( readonly == Registry::READWRITE )
  379. {
  380. kwsys_ios::ofstream ofs( str.str().c_str(), kwsys_ios::ios::out|kwsys_ios::ios::app );
  381. if ( ofs.fail() )
  382. {
  383. return false;
  384. }
  385. ofs.close();
  386. }
  387. kwsys_ios::ifstream *ifs = new kwsys_ios::ifstream(str.str().c_str(), kwsys_ios::ios::in
  388. #ifndef KWSYS_IOS_USE_ANSI
  389. | kwsys_ios::ios::nocreate
  390. #endif
  391. );
  392. if ( !ifs )
  393. {
  394. return false;
  395. }
  396. if ( ifs->fail())
  397. {
  398. delete ifs;
  399. return false;
  400. }
  401. res = true;
  402. char buffer[Registry_BUFFER_SIZE];
  403. while( !ifs->fail() )
  404. {
  405. ifs->getline(buffer, Registry_BUFFER_SIZE);
  406. if ( ifs->fail() || ifs->eof() )
  407. {
  408. break;
  409. }
  410. char *line = this->Strip(buffer);
  411. if ( *line == '#' || *line == 0 )
  412. {
  413. // Comment
  414. continue;
  415. }
  416. int linelen = static_cast<int>(strlen(line));
  417. for ( cc = 0; cc < linelen; cc++ )
  418. {
  419. if ( line[cc] == '=' )
  420. {
  421. char *key = new char[ cc+1 ];
  422. strncpy( key, line, cc );
  423. key[cc] = 0;
  424. char *value = line + cc + 1;
  425. char *nkey = this->Strip(key);
  426. char *nvalue = this->Strip(value);
  427. this->EntriesMap[nkey] = this->DecodeValue(nvalue);
  428. m_Empty = 0;
  429. delete [] key;
  430. break;
  431. }
  432. }
  433. }
  434. ifs->close();
  435. this->SetSubKey( subkey );
  436. delete ifs;
  437. return res;
  438. }
  439. return false;
  440. }
  441. //----------------------------------------------------------------------------
  442. bool RegistryHelper::Close()
  443. {
  444. #ifdef _WIN32
  445. if ( m_RegistryType == Registry::WIN32_REGISTRY)
  446. {
  447. int res;
  448. res = ( RegCloseKey(this->HKey) == ERROR_SUCCESS );
  449. return (res != 0);
  450. }
  451. #endif
  452. if ( m_RegistryType == Registry::FILE_REGISTRY )
  453. {
  454. if ( !m_Changed )
  455. {
  456. this->SetSubKey(0);
  457. return true;
  458. }
  459. kwsys_ios::ostringstream str;
  460. str << m_HomeDirectory.c_str() << "/." << this->GetTopLevel() << "rc";
  461. kwsys_ios::ofstream *ofs = new kwsys_ios::ofstream(str.str().c_str(), kwsys_ios::ios::out);
  462. if ( !ofs )
  463. {
  464. return false;
  465. }
  466. if ( ofs->fail())
  467. {
  468. delete ofs;
  469. return false;
  470. }
  471. *ofs << "# This file is automatically generated by the application" << kwsys_ios::endl
  472. << "# If you change any lines or add new lines, note that all" << kwsys_ios::endl
  473. << "# comments and empty lines will be deleted. Every line has" << kwsys_ios::endl
  474. << "# to be in format: " << kwsys_ios::endl
  475. << "# key = value" << kwsys_ios::endl
  476. << "#" << kwsys_ios::endl;
  477. if ( !this->EntriesMap.empty() )
  478. {
  479. RegistryHelper::StringToStringMap::iterator it;
  480. for ( it = this->EntriesMap.begin();
  481. it != this->EntriesMap.end();
  482. ++ it )
  483. {
  484. *ofs << it->first.c_str() << " = " << this->EncodeValue(it->second.c_str()).c_str() << kwsys_ios::endl;
  485. }
  486. }
  487. this->EntriesMap.clear();
  488. ofs->close();
  489. delete ofs;
  490. this->SetSubKey(0);
  491. m_Empty = 1;
  492. return true;
  493. }
  494. return false;
  495. }
  496. //----------------------------------------------------------------------------
  497. bool RegistryHelper::ReadValue(const char *skey, const char **value)
  498. {
  499. #ifdef _WIN32
  500. if ( m_RegistryType == Registry::WIN32_REGISTRY)
  501. {
  502. kwsys_stl::string key = this->CreateKey( skey );
  503. if ( key.empty() )
  504. {
  505. return false;
  506. }
  507. DWORD dwType, dwSize;
  508. dwType = REG_SZ;
  509. char buffer[1024]; // Replace with RegQueryInfoKey
  510. dwSize = sizeof(buffer);
  511. int res = ( RegQueryValueEx(this->HKey, skey, NULL, &dwType,
  512. (BYTE *)buffer, &dwSize) == ERROR_SUCCESS );
  513. if ( !res )
  514. {
  515. return false;
  516. }
  517. this->EntriesMap[key] = buffer;
  518. RegistryHelper::StringToStringMap::iterator it
  519. = this->EntriesMap.find(key);
  520. *value = it->second.c_str();
  521. return true;
  522. }
  523. #endif
  524. if ( m_RegistryType == Registry::FILE_REGISTRY )
  525. {
  526. bool res = false;
  527. kwsys_stl::string key = this->CreateKey( skey );
  528. if ( key.empty() )
  529. {
  530. return false;
  531. }
  532. RegistryHelper::StringToStringMap::iterator it
  533. = this->EntriesMap.find(key);
  534. if ( it != this->EntriesMap.end() )
  535. {
  536. *value = it->second.c_str();
  537. res = true;
  538. }
  539. return res;
  540. }
  541. return false;
  542. }
  543. //----------------------------------------------------------------------------
  544. bool RegistryHelper::DeleteKey(const char* skey)
  545. {
  546. #ifdef _WIN32
  547. if ( m_RegistryType == Registry::WIN32_REGISTRY)
  548. {
  549. int res = ( RegDeleteKey( this->HKey, skey ) == ERROR_SUCCESS );
  550. return (res != 0);
  551. }
  552. #endif
  553. if ( m_RegistryType == Registry::FILE_REGISTRY )
  554. {
  555. kwsys_stl::string key = this->CreateKey( skey );
  556. if ( key.empty() )
  557. {
  558. return false;
  559. }
  560. this->EntriesMap.erase(key);
  561. return true;
  562. }
  563. return false;
  564. }
  565. //----------------------------------------------------------------------------
  566. bool RegistryHelper::DeleteValue(const char *skey)
  567. {
  568. #ifdef _WIN32
  569. if ( m_RegistryType == Registry::WIN32_REGISTRY)
  570. {
  571. int res = ( RegDeleteValue( this->HKey, skey ) == ERROR_SUCCESS );
  572. return (res != 0);
  573. }
  574. #endif
  575. if ( m_RegistryType == Registry::FILE_REGISTRY )
  576. {
  577. kwsys_stl::string key = this->CreateKey( skey );
  578. if ( key.empty() )
  579. {
  580. return false;
  581. }
  582. this->EntriesMap.erase(key);
  583. return true;
  584. }
  585. return false;
  586. }
  587. //----------------------------------------------------------------------------
  588. bool RegistryHelper::SetValue(const char *skey, const char *value)
  589. {
  590. #ifdef _WIN32
  591. if ( m_RegistryType == Registry::WIN32_REGISTRY)
  592. {
  593. DWORD len = (DWORD)(value ? strlen(value) : 0);
  594. int res = ( RegSetValueEx(this->HKey, skey, 0, REG_SZ,
  595. (CONST BYTE *)(const char *)value,
  596. len+1) == ERROR_SUCCESS );
  597. return (res != 0);
  598. }
  599. #endif
  600. if ( m_RegistryType == Registry::FILE_REGISTRY )
  601. {
  602. kwsys_stl::string key = this->CreateKey( skey );
  603. if ( key.empty() )
  604. {
  605. return 0;
  606. }
  607. this->EntriesMap[key] = value;
  608. return 1;
  609. }
  610. return false;
  611. }
  612. //----------------------------------------------------------------------------
  613. kwsys_stl::string RegistryHelper::CreateKey( const char *key )
  614. {
  615. if ( !m_SubKeySpecified || m_SubKey.empty() || !key )
  616. {
  617. return "";
  618. }
  619. kwsys_ios::ostringstream ostr;
  620. ostr << this->EncodeKey(this->m_SubKey.c_str()).c_str()
  621. << "\\" << this->EncodeKey(key).c_str();
  622. return ostr.str();
  623. }
  624. //----------------------------------------------------------------------------
  625. void RegistryHelper::SetSubKey(const char* sk)
  626. {
  627. if ( !sk )
  628. {
  629. m_SubKey = "";
  630. m_SubKeySpecified = false;
  631. }
  632. else
  633. {
  634. m_SubKey = sk;
  635. m_SubKeySpecified = true;
  636. }
  637. }
  638. //----------------------------------------------------------------------------
  639. char *RegistryHelper::Strip(char *str)
  640. {
  641. int cc;
  642. int len;
  643. char *nstr;
  644. if ( !str )
  645. {
  646. return NULL;
  647. }
  648. len = strlen(str);
  649. nstr = str;
  650. for( cc=0; cc<len; cc++ )
  651. {
  652. if ( !isspace( *nstr ) )
  653. {
  654. break;
  655. }
  656. nstr ++;
  657. }
  658. for( cc=(strlen(nstr)-1); cc>=0; cc-- )
  659. {
  660. if ( !isspace( nstr[cc] ) )
  661. {
  662. nstr[cc+1] = 0;
  663. break;
  664. }
  665. }
  666. return nstr;
  667. }
  668. //----------------------------------------------------------------------------
  669. void RegistryHelper::SetGlobalScope(bool b)
  670. {
  671. m_GlobalScope = b;
  672. }
  673. //----------------------------------------------------------------------------
  674. bool RegistryHelper::GetGlobalScope()
  675. {
  676. return m_GlobalScope;
  677. }
  678. //----------------------------------------------------------------------------
  679. kwsys_stl::string RegistryHelper::EncodeKey(const char* str)
  680. {
  681. kwsys_ios::ostringstream ostr;
  682. while ( *str )
  683. {
  684. switch ( *str )
  685. {
  686. case '%': case '=': case '\n': case '\r': case '\t':
  687. char buffer[4];
  688. sprintf(buffer, "%%%02X", *str);
  689. ostr << buffer;
  690. break;
  691. default:
  692. ostr << *str;
  693. }
  694. str ++;
  695. }
  696. return ostr.str();
  697. }
  698. //----------------------------------------------------------------------------
  699. kwsys_stl::string RegistryHelper::EncodeValue(const char* str)
  700. {
  701. kwsys_ios::ostringstream ostr;
  702. while ( *str )
  703. {
  704. switch ( *str )
  705. {
  706. case '%': case '=': case '\n': case '\r': case '\t':
  707. char buffer[4];
  708. sprintf(buffer, "%%%02X", *str);
  709. ostr << buffer;
  710. break;
  711. default:
  712. ostr << *str;
  713. }
  714. str ++;
  715. }
  716. return ostr.str();
  717. }
  718. //----------------------------------------------------------------------------
  719. kwsys_stl::string RegistryHelper::DecodeValue(const char* str)
  720. {
  721. kwsys_ios::ostringstream ostr;
  722. while ( *str )
  723. {
  724. unsigned int val;
  725. switch ( *str )
  726. {
  727. case '%':
  728. if ( *(str+1) && *(str+2) && sscanf(str+1, "%x", &val) == 1 )
  729. {
  730. ostr << (char)val;
  731. str += 2;
  732. }
  733. else
  734. {
  735. ostr << *str;
  736. }
  737. break;
  738. default:
  739. ostr << *str;
  740. }
  741. str ++;
  742. }
  743. return ostr.str();
  744. }
  745. } // namespace KWSYS_NAMESPACE