Path.cpp 17 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. //
  2. // Path.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/Path.cpp#5 $
  5. //
  6. // Library: Foundation
  7. // Package: Filesystem
  8. // Module: Path
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/Path.h"
  16. #include "Poco/File.h"
  17. #include "Poco/Exception.h"
  18. #include "Poco/StringTokenizer.h"
  19. #if defined(_WIN32) && defined(POCO_WIN32_UTF8)
  20. #include "Poco/UnicodeConverter.h"
  21. #include "Poco/Buffer.h"
  22. #endif
  23. #include <algorithm>
  24. #if defined(POCO_OS_FAMILY_VMS)
  25. #include "Path_VMS.cpp"
  26. #elif defined(POCO_OS_FAMILY_UNIX)
  27. #include "Path_UNIX.cpp"
  28. #elif defined(POCO_OS_FAMILY_WINDOWS) && defined(POCO_WIN32_UTF8)
  29. #if defined(_WIN32_WCE)
  30. #include "Path_WINCE.cpp"
  31. #else
  32. #include "Path_WIN32U.cpp"
  33. #endif
  34. #elif defined(POCO_OS_FAMILY_WINDOWS)
  35. #include "Path_WIN32.cpp"
  36. #endif
  37. namespace Poco {
  38. Path::Path(): _absolute(false)
  39. {
  40. }
  41. Path::Path(bool absolute): _absolute(absolute)
  42. {
  43. }
  44. Path::Path(const std::string& path)
  45. {
  46. assign(path);
  47. }
  48. Path::Path(const std::string& path, Style style)
  49. {
  50. assign(path, style);
  51. }
  52. Path::Path(const char* path)
  53. {
  54. poco_check_ptr(path);
  55. assign(path);
  56. }
  57. Path::Path(const char* path, Style style)
  58. {
  59. poco_check_ptr(path);
  60. assign(path, style);
  61. }
  62. Path::Path(const Path& path):
  63. _node(path._node),
  64. _device(path._device),
  65. _name(path._name),
  66. _version(path._version),
  67. _dirs(path._dirs),
  68. _absolute(path._absolute)
  69. {
  70. }
  71. Path::Path(const Path& parent, const std::string& fileName):
  72. _node(parent._node),
  73. _device(parent._device),
  74. _name(parent._name),
  75. _version(parent._version),
  76. _dirs(parent._dirs),
  77. _absolute(parent._absolute)
  78. {
  79. makeDirectory();
  80. _name = fileName;
  81. }
  82. Path::Path(const Path& parent, const char* fileName):
  83. _node(parent._node),
  84. _device(parent._device),
  85. _name(parent._name),
  86. _version(parent._version),
  87. _dirs(parent._dirs),
  88. _absolute(parent._absolute)
  89. {
  90. makeDirectory();
  91. _name = fileName;
  92. }
  93. Path::Path(const Path& parent, const Path& relative):
  94. _node(parent._node),
  95. _device(parent._device),
  96. _name(parent._name),
  97. _version(parent._version),
  98. _dirs(parent._dirs),
  99. _absolute(parent._absolute)
  100. {
  101. resolve(relative);
  102. }
  103. Path::~Path()
  104. {
  105. }
  106. Path& Path::operator = (const Path& path)
  107. {
  108. return assign(path);
  109. }
  110. Path& Path::operator = (const std::string& path)
  111. {
  112. return assign(path);
  113. }
  114. Path& Path::operator = (const char* path)
  115. {
  116. poco_check_ptr(path);
  117. return assign(path);
  118. }
  119. void Path::swap(Path& path)
  120. {
  121. std::swap(_node, path._node);
  122. std::swap(_device, path._device);
  123. std::swap(_name, path._name);
  124. std::swap(_version, path._version);
  125. std::swap(_dirs, path._dirs);
  126. std::swap(_absolute, path._absolute);
  127. }
  128. Path& Path::assign(const Path& path)
  129. {
  130. if (&path != this)
  131. {
  132. _node = path._node;
  133. _device = path._device;
  134. _name = path._name;
  135. _version = path._version;
  136. _dirs = path._dirs;
  137. _absolute = path._absolute;
  138. }
  139. return *this;
  140. }
  141. Path& Path::assign(const std::string& path)
  142. {
  143. #if defined(POCO_OS_FAMILY_VMS)
  144. parseVMS(path);
  145. #elif defined(POCO_OS_FAMILY_WINDOWS)
  146. parseWindows(path);
  147. #else
  148. parseUnix(path);
  149. #endif
  150. return *this;
  151. }
  152. Path& Path::assign(const std::string& path, Style style)
  153. {
  154. switch (style)
  155. {
  156. case PATH_UNIX:
  157. parseUnix(path);
  158. break;
  159. case PATH_WINDOWS:
  160. parseWindows(path);
  161. break;
  162. case PATH_VMS:
  163. parseVMS(path);
  164. break;
  165. case PATH_NATIVE:
  166. assign(path);
  167. break;
  168. case PATH_GUESS:
  169. parseGuess(path);
  170. break;
  171. default:
  172. poco_bugcheck();
  173. }
  174. return *this;
  175. }
  176. Path& Path::assign(const char* path)
  177. {
  178. return assign(std::string(path));
  179. }
  180. std::string Path::toString() const
  181. {
  182. #if defined(POCO_OS_FAMILY_UNIX)
  183. return buildUnix();
  184. #elif defined(POCO_OS_FAMILY_WINDOWS)
  185. return buildWindows();
  186. #else
  187. return buildVMS();
  188. #endif
  189. }
  190. std::string Path::toString(Style style) const
  191. {
  192. switch (style)
  193. {
  194. case PATH_UNIX:
  195. return buildUnix();
  196. case PATH_WINDOWS:
  197. return buildWindows();
  198. case PATH_VMS:
  199. return buildVMS();
  200. case PATH_NATIVE:
  201. case PATH_GUESS:
  202. return toString();
  203. default:
  204. poco_bugcheck();
  205. }
  206. return std::string();
  207. }
  208. bool Path::tryParse(const std::string& path)
  209. {
  210. try
  211. {
  212. Path p;
  213. p.parse(path);
  214. assign(p);
  215. return true;
  216. }
  217. catch (...)
  218. {
  219. return false;
  220. }
  221. }
  222. bool Path::tryParse(const std::string& path, Style style)
  223. {
  224. try
  225. {
  226. Path p;
  227. p.parse(path, style);
  228. assign(p);
  229. return true;
  230. }
  231. catch (...)
  232. {
  233. return false;
  234. }
  235. }
  236. Path& Path::parseDirectory(const std::string& path)
  237. {
  238. assign(path);
  239. return makeDirectory();
  240. }
  241. Path& Path::parseDirectory(const std::string& path, Style style)
  242. {
  243. assign(path, style);
  244. return makeDirectory();
  245. }
  246. Path& Path::makeDirectory()
  247. {
  248. #if defined(POCO_OS_FAMILY_VMS)
  249. pushDirectory(getBaseName());
  250. #else
  251. pushDirectory(_name);
  252. #endif
  253. _name.clear();
  254. _version.clear();
  255. return *this;
  256. }
  257. Path& Path::makeFile()
  258. {
  259. if (!_dirs.empty() && _name.empty())
  260. {
  261. _name = _dirs.back();
  262. _dirs.pop_back();
  263. #if defined(POCO_OS_FAMILY_VMS)
  264. setExtension("DIR");
  265. #endif
  266. }
  267. return *this;
  268. }
  269. Path& Path::makeAbsolute()
  270. {
  271. return makeAbsolute(current());
  272. }
  273. Path& Path::makeAbsolute(const Path& base)
  274. {
  275. if (!_absolute)
  276. {
  277. Path tmp = base;
  278. tmp.makeDirectory();
  279. for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
  280. {
  281. tmp.pushDirectory(*it);
  282. }
  283. _node = tmp._node;
  284. _device = tmp._device;
  285. _dirs = tmp._dirs;
  286. _absolute = base._absolute;
  287. }
  288. return *this;
  289. }
  290. Path Path::absolute() const
  291. {
  292. Path result(*this);
  293. if (!result._absolute)
  294. {
  295. result.makeAbsolute();
  296. }
  297. return result;
  298. }
  299. Path Path::absolute(const Path& base) const
  300. {
  301. Path result(*this);
  302. if (!result._absolute)
  303. {
  304. result.makeAbsolute(base);
  305. }
  306. return result;
  307. }
  308. Path Path::parent() const
  309. {
  310. Path p(*this);
  311. return p.makeParent();
  312. }
  313. Path& Path::makeParent()
  314. {
  315. if (_name.empty())
  316. {
  317. if (_dirs.empty())
  318. {
  319. if (!_absolute)
  320. _dirs.push_back("..");
  321. }
  322. else
  323. {
  324. if (_dirs.back() == "..")
  325. _dirs.push_back("..");
  326. else
  327. _dirs.pop_back();
  328. }
  329. }
  330. else
  331. {
  332. _name.clear();
  333. _version.clear();
  334. }
  335. return *this;
  336. }
  337. Path& Path::append(const Path& path)
  338. {
  339. makeDirectory();
  340. _dirs.insert(_dirs.end(), path._dirs.begin(), path._dirs.end());
  341. _name = path._name;
  342. _version = path._version;
  343. return *this;
  344. }
  345. Path& Path::resolve(const Path& path)
  346. {
  347. if (path.isAbsolute())
  348. {
  349. assign(path);
  350. }
  351. else
  352. {
  353. for (int i = 0; i < path.depth(); ++i)
  354. pushDirectory(path[i]);
  355. _name = path._name;
  356. }
  357. return *this;
  358. }
  359. Path& Path::setNode(const std::string& node)
  360. {
  361. _node = node;
  362. _absolute = _absolute || !node.empty();
  363. return *this;
  364. }
  365. Path& Path::setDevice(const std::string& device)
  366. {
  367. _device = device;
  368. _absolute = _absolute || !device.empty();
  369. return *this;
  370. }
  371. const std::string& Path::directory(int n) const
  372. {
  373. poco_assert (0 <= n && n <= _dirs.size());
  374. if (n < _dirs.size())
  375. return _dirs[n];
  376. else
  377. return _name;
  378. }
  379. const std::string& Path::operator [] (int n) const
  380. {
  381. poco_assert (0 <= n && n <= _dirs.size());
  382. if (n < _dirs.size())
  383. return _dirs[n];
  384. else
  385. return _name;
  386. }
  387. Path& Path::pushDirectory(const std::string& dir)
  388. {
  389. if (!dir.empty() && dir != ".")
  390. {
  391. #if defined(POCO_OS_FAMILY_VMS)
  392. if (dir == ".." || dir == "-")
  393. {
  394. if (!_dirs.empty() && _dirs.back() != ".." && _dirs.back() != "-")
  395. _dirs.pop_back();
  396. else if (!_absolute)
  397. _dirs.push_back(dir);
  398. }
  399. else _dirs.push_back(dir);
  400. #else
  401. if (dir == "..")
  402. {
  403. if (!_dirs.empty() && _dirs.back() != "..")
  404. _dirs.pop_back();
  405. else if (!_absolute)
  406. _dirs.push_back(dir);
  407. }
  408. else _dirs.push_back(dir);
  409. #endif
  410. }
  411. return *this;
  412. }
  413. Path& Path::popDirectory()
  414. {
  415. poco_assert (!_dirs.empty());
  416. _dirs.pop_back();
  417. return *this;
  418. }
  419. Path& Path::popFrontDirectory()
  420. {
  421. poco_assert (!_dirs.empty());
  422. StringVec::iterator it = _dirs.begin();
  423. _dirs.erase(it);
  424. return *this;
  425. }
  426. Path& Path::setFileName(const std::string& name)
  427. {
  428. _name = name;
  429. return *this;
  430. }
  431. Path& Path::setBaseName(const std::string& name)
  432. {
  433. std::string ext = getExtension();
  434. _name = name;
  435. if (!ext.empty())
  436. {
  437. _name.append(".");
  438. _name.append(ext);
  439. }
  440. return *this;
  441. }
  442. std::string Path::getBaseName() const
  443. {
  444. std::string::size_type pos = _name.rfind('.');
  445. if (pos != std::string::npos)
  446. return _name.substr(0, pos);
  447. else
  448. return _name;
  449. }
  450. Path& Path::setExtension(const std::string& extension)
  451. {
  452. _name = getBaseName();
  453. if (!extension.empty())
  454. {
  455. _name.append(".");
  456. _name.append(extension);
  457. }
  458. return *this;
  459. }
  460. std::string Path::getExtension() const
  461. {
  462. std::string::size_type pos = _name.rfind('.');
  463. if (pos != std::string::npos)
  464. return _name.substr(pos + 1);
  465. else
  466. return std::string();
  467. }
  468. Path& Path::clear()
  469. {
  470. _node.clear();
  471. _device.clear();
  472. _name.clear();
  473. _dirs.clear();
  474. _version.clear();
  475. _absolute = false;
  476. return *this;
  477. }
  478. std::string Path::current()
  479. {
  480. return PathImpl::currentImpl();
  481. }
  482. std::string Path::home()
  483. {
  484. return PathImpl::homeImpl();
  485. }
  486. std::string Path::temp()
  487. {
  488. return PathImpl::tempImpl();
  489. }
  490. std::string Path::null()
  491. {
  492. return PathImpl::nullImpl();
  493. }
  494. std::string Path::expand(const std::string& path)
  495. {
  496. return PathImpl::expandImpl(path);
  497. }
  498. void Path::listRoots(std::vector<std::string>& roots)
  499. {
  500. PathImpl::listRootsImpl(roots);
  501. }
  502. bool Path::find(StringVec::const_iterator it, StringVec::const_iterator end, const std::string& name, Path& path)
  503. {
  504. while (it != end)
  505. {
  506. #if defined(WIN32)
  507. std::string cleanPath(*it);
  508. if (cleanPath.size() > 1 && cleanPath[0] == '"' && cleanPath[cleanPath.size() - 1] == '"')
  509. {
  510. cleanPath = cleanPath.substr(1, cleanPath.size() - 2);
  511. }
  512. Path p(cleanPath);
  513. #else
  514. Path p(*it);
  515. #endif
  516. p.makeDirectory();
  517. p.resolve(Path(name));
  518. File f(p);
  519. if (f.exists())
  520. {
  521. path = p;
  522. return true;
  523. }
  524. ++it;
  525. }
  526. return false;
  527. }
  528. bool Path::find(const std::string& pathList, const std::string& name, Path& path)
  529. {
  530. StringTokenizer st(pathList, std::string(1, pathSeparator()), StringTokenizer::TOK_IGNORE_EMPTY + StringTokenizer::TOK_TRIM);
  531. return find(st.begin(), st.end(), name, path);
  532. }
  533. void Path::parseUnix(const std::string& path)
  534. {
  535. clear();
  536. std::string::const_iterator it = path.begin();
  537. std::string::const_iterator end = path.end();
  538. if (it != end)
  539. {
  540. if (*it == '/')
  541. {
  542. _absolute = true; ++it;
  543. }
  544. else if (*it == '~')
  545. {
  546. ++it;
  547. if (it == end || *it == '/')
  548. {
  549. Path cwd(home());
  550. _dirs = cwd._dirs;
  551. _absolute = true;
  552. }
  553. else --it;
  554. }
  555. while (it != end)
  556. {
  557. std::string name;
  558. while (it != end && *it != '/') name += *it++;
  559. if (it != end)
  560. {
  561. if (_dirs.empty())
  562. {
  563. if (!name.empty() && *(name.rbegin()) == ':')
  564. {
  565. _absolute = true;
  566. _device.assign(name, 0, name.length() - 1);
  567. }
  568. else
  569. {
  570. pushDirectory(name);
  571. }
  572. }
  573. else pushDirectory(name);
  574. }
  575. else _name = name;
  576. if (it != end) ++it;
  577. }
  578. }
  579. }
  580. void Path::parseWindows(const std::string& path)
  581. {
  582. clear();
  583. std::string::const_iterator it = path.begin();
  584. std::string::const_iterator end = path.end();
  585. if (it != end)
  586. {
  587. if (*it == '\\' || *it == '/') { _absolute = true; ++it; }
  588. if (_absolute && it != end && (*it == '\\' || *it == '/')) // UNC
  589. {
  590. ++it;
  591. while (it != end && *it != '\\' && *it != '/') _node += *it++;
  592. if (it != end) ++it;
  593. }
  594. else if (it != end)
  595. {
  596. char d = *it++;
  597. if (it != end && *it == ':') // drive letter
  598. {
  599. if (_absolute || !((d >= 'a' && d <= 'z') || (d >= 'A' && d <= 'Z'))) throw PathSyntaxException(path);
  600. _absolute = true;
  601. _device += d;
  602. ++it;
  603. if (it == end || (*it != '\\' && *it != '/')) throw PathSyntaxException(path);
  604. ++it;
  605. }
  606. else --it;
  607. }
  608. while (it != end)
  609. {
  610. std::string name;
  611. while (it != end && *it != '\\' && *it != '/') name += *it++;
  612. if (it != end)
  613. pushDirectory(name);
  614. else
  615. _name = name;
  616. if (it != end) ++it;
  617. }
  618. }
  619. if (!_node.empty() && _dirs.empty() && !_name.empty())
  620. makeDirectory();
  621. }
  622. void Path::parseVMS(const std::string& path)
  623. {
  624. clear();
  625. std::string::const_iterator it = path.begin();
  626. std::string::const_iterator end = path.end();
  627. if (it != end)
  628. {
  629. std::string name;
  630. while (it != end && *it != ':' && *it != '[' && *it != ';') name += *it++;
  631. if (it != end)
  632. {
  633. if (*it == ':')
  634. {
  635. ++it;
  636. if (it != end && *it == ':')
  637. {
  638. _node = name;
  639. ++it;
  640. }
  641. else _device = name;
  642. _absolute = true;
  643. name.clear();
  644. }
  645. if (it != end)
  646. {
  647. if (_device.empty() && *it != '[')
  648. {
  649. while (it != end && *it != ':' && *it != ';') name += *it++;
  650. if (it != end)
  651. {
  652. if (*it == ':')
  653. {
  654. _device = name;
  655. _absolute = true;
  656. name.clear();
  657. ++it;
  658. }
  659. }
  660. }
  661. }
  662. if (name.empty())
  663. {
  664. if (it != end && *it == '[')
  665. {
  666. ++it;
  667. if (it != end)
  668. {
  669. _absolute = true;
  670. if (*it == '.')
  671. { _absolute = false; ++it; }
  672. else if (*it == ']' || *it == '-')
  673. _absolute = false;
  674. while (it != end && *it != ']')
  675. {
  676. name.clear();
  677. if (*it == '-')
  678. name = "-";
  679. else
  680. while (it != end && *it != '.' && *it != ']') name += *it++;
  681. if (!name.empty())
  682. {
  683. if (name == "-")
  684. {
  685. if (_dirs.empty() || _dirs.back() == "..")
  686. _dirs.push_back("..");
  687. else
  688. _dirs.pop_back();
  689. }
  690. else _dirs.push_back(name);
  691. }
  692. if (it != end && *it != ']') ++it;
  693. }
  694. if (it == end) throw PathSyntaxException(path);
  695. ++it;
  696. if (it != end && *it == '[')
  697. {
  698. if (!_absolute) throw PathSyntaxException(path);
  699. ++it;
  700. if (it != end && *it == '.') throw PathSyntaxException(path);
  701. int d = int(_dirs.size());
  702. while (it != end && *it != ']')
  703. {
  704. name.clear();
  705. if (*it == '-')
  706. name = "-";
  707. else
  708. while (it != end && *it != '.' && *it != ']') name += *it++;
  709. if (!name.empty())
  710. {
  711. if (name == "-")
  712. {
  713. if (_dirs.size() > d)
  714. _dirs.pop_back();
  715. }
  716. else _dirs.push_back(name);
  717. }
  718. if (it != end && *it != ']') ++it;
  719. }
  720. if (it == end) throw PathSyntaxException(path);
  721. ++it;
  722. }
  723. }
  724. _name.clear();
  725. }
  726. while (it != end && *it != ';') _name += *it++;
  727. }
  728. else _name = name;
  729. if (it != end && *it == ';')
  730. {
  731. ++it;
  732. while (it != end) _version += *it++;
  733. }
  734. }
  735. else _name = name;
  736. }
  737. }
  738. void Path::parseGuess(const std::string& path)
  739. {
  740. bool hasBackslash = false;
  741. bool hasSlash = false;
  742. bool hasOpenBracket = false;
  743. bool hasClosBracket = false;
  744. bool isWindows = path.length() > 2 && path[1] == ':' && (path[2] == '/' || path[2] == '\\');
  745. std::string::const_iterator end = path.end();
  746. std::string::const_iterator semiIt = end;
  747. if (!isWindows)
  748. {
  749. for (std::string::const_iterator it = path.begin(); it != end; ++it)
  750. {
  751. switch (*it)
  752. {
  753. case '\\': hasBackslash = true; break;
  754. case '/': hasSlash = true; break;
  755. case '[': hasOpenBracket = true;
  756. case ']': hasClosBracket = hasOpenBracket;
  757. case ';': semiIt = it; break;
  758. }
  759. }
  760. }
  761. if (hasBackslash || isWindows)
  762. {
  763. parseWindows(path);
  764. }
  765. else if (hasSlash)
  766. {
  767. parseUnix(path);
  768. }
  769. else
  770. {
  771. bool isVMS = hasClosBracket;
  772. if (!isVMS && semiIt != end)
  773. {
  774. isVMS = true;
  775. ++semiIt;
  776. while (semiIt != end)
  777. {
  778. if (*semiIt < '0' || *semiIt > '9')
  779. {
  780. isVMS = false; break;
  781. }
  782. ++semiIt;
  783. }
  784. }
  785. if (isVMS)
  786. parseVMS(path);
  787. else
  788. parseUnix(path);
  789. }
  790. }
  791. std::string Path::buildUnix() const
  792. {
  793. std::string result;
  794. if (!_device.empty())
  795. {
  796. result.append("/");
  797. result.append(_device);
  798. result.append(":/");
  799. }
  800. else if (_absolute)
  801. {
  802. result.append("/");
  803. }
  804. for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
  805. {
  806. result.append(*it);
  807. result.append("/");
  808. }
  809. result.append(_name);
  810. return result;
  811. }
  812. std::string Path::buildWindows() const
  813. {
  814. std::string result;
  815. if (!_node.empty())
  816. {
  817. result.append("\\\\");
  818. result.append(_node);
  819. result.append("\\");
  820. }
  821. else if (!_device.empty())
  822. {
  823. result.append(_device);
  824. result.append(":\\");
  825. }
  826. else if (_absolute)
  827. {
  828. result.append("\\");
  829. }
  830. for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
  831. {
  832. result.append(*it);
  833. result.append("\\");
  834. }
  835. result.append(_name);
  836. return result;
  837. }
  838. std::string Path::buildVMS() const
  839. {
  840. std::string result;
  841. if (!_node.empty())
  842. {
  843. result.append(_node);
  844. result.append("::");
  845. }
  846. if (!_device.empty())
  847. {
  848. result.append(_device);
  849. result.append(":");
  850. }
  851. if (!_dirs.empty())
  852. {
  853. result.append("[");
  854. if (!_absolute && _dirs[0] != "..")
  855. result.append(".");
  856. for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
  857. {
  858. if (it != _dirs.begin() && *it != "..")
  859. result.append(".");
  860. if (*it == "..")
  861. result.append("-");
  862. else
  863. result.append(*it);
  864. }
  865. result.append("]");
  866. }
  867. result.append(_name);
  868. if (!_version.empty())
  869. {
  870. result.append(";");
  871. result.append(_version);
  872. }
  873. return result;
  874. }
  875. std::string Path::transcode(const std::string& path)
  876. {
  877. #if defined(_WIN32) && defined(POCO_WIN32_UTF8)
  878. std::wstring uniPath;
  879. UnicodeConverter::toUTF16(path, uniPath);
  880. DWORD len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, uniPath.c_str(), static_cast<int>(uniPath.length()), NULL, 0, NULL, NULL);
  881. if (len > 0)
  882. {
  883. Buffer<char> buffer(len);
  884. DWORD rc = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, uniPath.c_str(), static_cast<int>(uniPath.length()), buffer.begin(), static_cast<int>(buffer.size()), NULL, NULL);
  885. if (rc)
  886. {
  887. return std::string(buffer.begin(), buffer.size());
  888. }
  889. }
  890. #endif
  891. return path;
  892. }
  893. } // namespace Poco