00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "Poco/Path.h"
00038 #include "Poco/File.h"
00039 #include "Poco/Exception.h"
00040 #include "Poco/StringTokenizer.h"
00041 #if defined(_WIN32) && defined(POCO_WIN32_UTF8)
00042 #include "Poco/UnicodeConverter.h"
00043 #include "Poco/Buffer.h"
00044 #endif
00045 #include <algorithm>
00046
00047
00048 #if defined(POCO_OS_FAMILY_VMS)
00049 #include "Path_VMS.cpp"
00050 #elif defined(POCO_OS_FAMILY_UNIX)
00051 #include "Path_UNIX.cpp"
00052 #elif defined(POCO_OS_FAMILY_WINDOWS) && defined(POCO_WIN32_UTF8)
00053 #include "Path_WIN32U.cpp"
00054 #elif defined(POCO_OS_FAMILY_WINDOWS)
00055 #include "Path_WIN32.cpp"
00056 #endif
00057
00058
00059 namespace Poco {
00060
00061
00062 Path::Path(): _absolute(false)
00063 {
00064 }
00065
00066
00067 Path::Path(bool absolute): _absolute(absolute)
00068 {
00069 }
00070
00071
00072 Path::Path(const std::string& path)
00073 {
00074 assign(path);
00075 }
00076
00077
00078 Path::Path(const std::string& path, Style style)
00079 {
00080 assign(path, style);
00081 }
00082
00083
00084 Path::Path(const char* path)
00085 {
00086 poco_check_ptr(path);
00087 assign(path);
00088 }
00089
00090
00091 Path::Path(const char* path, Style style)
00092 {
00093 poco_check_ptr(path);
00094 assign(path, style);
00095 }
00096
00097
00098 Path::Path(const Path& path):
00099 _node(path._node),
00100 _device(path._device),
00101 _name(path._name),
00102 _version(path._version),
00103 _dirs(path._dirs),
00104 _absolute(path._absolute)
00105 {
00106 }
00107
00108
00109 Path::Path(const Path& parent, const std::string& fileName):
00110 _node(parent._node),
00111 _device(parent._device),
00112 _name(parent._name),
00113 _version(parent._version),
00114 _dirs(parent._dirs),
00115 _absolute(parent._absolute)
00116 {
00117 makeDirectory();
00118 _name = fileName;
00119 }
00120
00121
00122 Path::Path(const Path& parent, const char* fileName):
00123 _node(parent._node),
00124 _device(parent._device),
00125 _name(parent._name),
00126 _version(parent._version),
00127 _dirs(parent._dirs),
00128 _absolute(parent._absolute)
00129 {
00130 makeDirectory();
00131 _name = fileName;
00132 }
00133
00134
00135 Path::Path(const Path& parent, const Path& relative):
00136 _node(parent._node),
00137 _device(parent._device),
00138 _name(parent._name),
00139 _version(parent._version),
00140 _dirs(parent._dirs),
00141 _absolute(parent._absolute)
00142 {
00143 resolve(relative);
00144 }
00145
00146
00147 Path::~Path()
00148 {
00149 }
00150
00151
00152 Path& Path::operator = (const Path& path)
00153 {
00154 return assign(path);
00155 }
00156
00157
00158 Path& Path::operator = (const std::string& path)
00159 {
00160 return assign(path);
00161 }
00162
00163
00164 Path& Path::operator = (const char* path)
00165 {
00166 poco_check_ptr(path);
00167 return assign(path);
00168 }
00169
00170
00171 void Path::swap(Path& path)
00172 {
00173 std::swap(_node, path._node);
00174 std::swap(_device, path._device);
00175 std::swap(_name, path._name);
00176 std::swap(_version, path._version);
00177 std::swap(_dirs, path._dirs);
00178 std::swap(_absolute, path._absolute);
00179 }
00180
00181
00182 Path& Path::assign(const Path& path)
00183 {
00184 if (&path != this)
00185 {
00186 _node = path._node;
00187 _device = path._device;
00188 _name = path._name;
00189 _version = path._version;
00190 _dirs = path._dirs;
00191 _absolute = path._absolute;
00192 }
00193 return *this;
00194 }
00195
00196
00197 Path& Path::assign(const std::string& path)
00198 {
00199 #if defined(POCO_OS_FAMILY_VMS)
00200 parseVMS(path);
00201 #elif defined(POCO_OS_FAMILY_WINDOWS)
00202 parseWindows(path);
00203 #else
00204 parseUnix(path);
00205 #endif
00206 return *this;
00207 }
00208
00209
00210 Path& Path::assign(const std::string& path, Style style)
00211 {
00212 switch (style)
00213 {
00214 case PATH_UNIX:
00215 parseUnix(path);
00216 break;
00217 case PATH_WINDOWS:
00218 parseWindows(path);
00219 break;
00220 case PATH_VMS:
00221 parseVMS(path);
00222 break;
00223 case PATH_NATIVE:
00224 assign(path);
00225 break;
00226 case PATH_GUESS:
00227 parseGuess(path);
00228 break;
00229 default:
00230 poco_bugcheck();
00231 }
00232 return *this;
00233 }
00234
00235
00236 Path& Path::assign(const char* path)
00237 {
00238 return assign(std::string(path));
00239 }
00240
00241
00242 std::string Path::toString() const
00243 {
00244 #if defined(POCO_OS_FAMILY_UNIX)
00245 return buildUnix();
00246 #elif defined(POCO_OS_FAMILY_WINDOWS)
00247 return buildWindows();
00248 #else
00249 return buildVMS();
00250 #endif
00251 }
00252
00253
00254 std::string Path::toString(Style style) const
00255 {
00256 switch (style)
00257 {
00258 case PATH_UNIX:
00259 return buildUnix();
00260 case PATH_WINDOWS:
00261 return buildWindows();
00262 case PATH_VMS:
00263 return buildVMS();
00264 case PATH_NATIVE:
00265 case PATH_GUESS:
00266 return toString();
00267 default:
00268 poco_bugcheck();
00269 }
00270 return std::string();
00271 }
00272
00273
00274 bool Path::tryParse(const std::string& path)
00275 {
00276 try
00277 {
00278 Path p;
00279 p.parse(path);
00280 assign(p);
00281 return true;
00282 }
00283 catch (...)
00284 {
00285 return false;
00286 }
00287 }
00288
00289
00290 bool Path::tryParse(const std::string& path, Style style)
00291 {
00292 try
00293 {
00294 Path p;
00295 p.parse(path, style);
00296 assign(p);
00297 return true;
00298 }
00299 catch (...)
00300 {
00301 return false;
00302 }
00303 }
00304
00305
00306 Path& Path::parseDirectory(const std::string& path)
00307 {
00308 assign(path);
00309 return makeDirectory();
00310 }
00311
00312
00313 Path& Path::parseDirectory(const std::string& path, Style style)
00314 {
00315 assign(path, style);
00316 return makeDirectory();
00317 }
00318
00319
00320 Path& Path::makeDirectory()
00321 {
00322 #if defined(POCO_OS_FAMILY_VMS)
00323 pushDirectory(getBaseName());
00324 #else
00325 pushDirectory(_name);
00326 #endif
00327 _name.clear();
00328 _version.clear();
00329 return *this;
00330 }
00331
00332
00333 Path& Path::makeFile()
00334 {
00335 if (!_dirs.empty() && _name.empty())
00336 {
00337 _name = _dirs.back();
00338 _dirs.pop_back();
00339 #if defined(POCO_OS_FAMILY_VMS)
00340 setExtension("DIR");
00341 #endif
00342 }
00343 return *this;
00344 }
00345
00346
00347 Path& Path::makeAbsolute()
00348 {
00349 return makeAbsolute(current());
00350 }
00351
00352
00353 Path& Path::makeAbsolute(const Path& base)
00354 {
00355 if (!_absolute)
00356 {
00357 Path tmp = base;
00358 tmp.makeDirectory();
00359 for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
00360 {
00361 tmp.pushDirectory(*it);
00362 }
00363 _node = tmp._node;
00364 _device = tmp._device;
00365 _dirs = tmp._dirs;
00366 _absolute = base._absolute;
00367 }
00368 return *this;
00369 }
00370
00371
00372 Path Path::absolute() const
00373 {
00374 Path result(*this);
00375 if (!result._absolute)
00376 {
00377 result.makeAbsolute();
00378 }
00379 return result;
00380 }
00381
00382
00383 Path Path::absolute(const Path& base) const
00384 {
00385 Path result(*this);
00386 if (!result._absolute)
00387 {
00388 result.makeAbsolute(base);
00389 }
00390 return result;
00391 }
00392
00393
00394 Path Path::parent() const
00395 {
00396 Path p(*this);
00397 return p.makeParent();
00398 }
00399
00400
00401 Path& Path::makeParent()
00402 {
00403 if (_name.empty())
00404 {
00405 if (_dirs.empty())
00406 {
00407 if (!_absolute)
00408 _dirs.push_back("..");
00409 }
00410 else
00411 {
00412 if (_dirs.back() == "..")
00413 _dirs.push_back("..");
00414 else
00415 _dirs.pop_back();
00416 }
00417 }
00418 else
00419 {
00420 _name.clear();
00421 _version.clear();
00422 }
00423 return *this;
00424 }
00425
00426
00427 Path& Path::append(const Path& path)
00428 {
00429 makeDirectory();
00430 _dirs.insert(_dirs.end(), path._dirs.begin(), path._dirs.end());
00431 _name = path._name;
00432 _version = path._version;
00433 return *this;
00434 }
00435
00436
00437 Path& Path::resolve(const Path& path)
00438 {
00439 if (path.isAbsolute())
00440 {
00441 assign(path);
00442 }
00443 else
00444 {
00445 for (int i = 0; i < path.depth(); ++i)
00446 pushDirectory(path[i]);
00447 _name = path._name;
00448 }
00449 return *this;
00450 }
00451
00452
00453 void Path::setNode(const std::string& node)
00454 {
00455 _node = node;
00456 _absolute = _absolute || !node.empty();
00457 }
00458
00459
00460 void Path::setDevice(const std::string& device)
00461 {
00462 _device = device;
00463 _absolute = _absolute || !device.empty();
00464 }
00465
00466
00467 const std::string& Path::directory(int n) const
00468 {
00469 poco_assert (0 <= n && n <= (int)_dirs.size());
00470
00471 if (n < (int)_dirs.size())
00472 return _dirs[n];
00473 else
00474 return _name;
00475 }
00476
00477
00478 const std::string& Path::operator [] (int n) const
00479 {
00480 poco_assert (0 <= n && n <= (int)_dirs.size());
00481
00482 if (n < (int)_dirs.size())
00483 return _dirs[n];
00484 else
00485 return _name;
00486 }
00487
00488
00489 void Path::pushDirectory(const std::string& dir)
00490 {
00491 if (!dir.empty() && dir != ".")
00492 {
00493 #if defined(POCO_OS_FAMILY_VMS)
00494 if (dir == ".." || dir == "-")
00495 {
00496 if (!_dirs.empty() && _dirs.back() != ".." && _dirs.back() != "-")
00497 _dirs.pop_back();
00498 else if (!_absolute)
00499 _dirs.push_back(dir);
00500 }
00501 else _dirs.push_back(dir);
00502 #else
00503 if (dir == "..")
00504 {
00505 if (!_dirs.empty() && _dirs.back() != "..")
00506 _dirs.pop_back();
00507 else if (!_absolute)
00508 _dirs.push_back(dir);
00509 }
00510 else _dirs.push_back(dir);
00511 #endif
00512 }
00513 }
00514
00515
00516 void Path::popDirectory()
00517 {
00518 poco_assert (!_dirs.empty());
00519
00520 _dirs.pop_back();
00521 }
00522
00523
00524 void Path::setFileName(const std::string& name)
00525 {
00526 _name = name;
00527 }
00528
00529
00530 void Path::setBaseName(const std::string& name)
00531 {
00532 std::string ext = getExtension();
00533 _name = name;
00534 if (!ext.empty())
00535 {
00536 _name.append(".");
00537 _name.append(ext);
00538 }
00539 }
00540
00541
00542 std::string Path::getBaseName() const
00543 {
00544 std::string::size_type pos = _name.rfind('.');
00545 if (pos != std::string::npos)
00546 return _name.substr(0, pos);
00547 else
00548 return _name;
00549 }
00550
00551
00552 void Path::setExtension(const std::string& extension)
00553 {
00554 _name = getBaseName();
00555 if (!extension.empty())
00556 {
00557 _name.append(".");
00558 _name.append(extension);
00559 }
00560 }
00561
00562
00563 std::string Path::getExtension() const
00564 {
00565 std::string::size_type pos = _name.rfind('.');
00566 if (pos != std::string::npos)
00567 return _name.substr(pos + 1);
00568 else
00569 return std::string();
00570 }
00571
00572
00573 void Path::clear()
00574 {
00575 _node.clear();
00576 _device.clear();
00577 _name.clear();
00578 _dirs.clear();
00579 _version.clear();
00580 _absolute = false;
00581 }
00582
00583
00584 std::string Path::current()
00585 {
00586 return PathImpl::currentImpl();
00587 }
00588
00589
00590 std::string Path::home()
00591 {
00592 return PathImpl::homeImpl();
00593 }
00594
00595
00596 std::string Path::temp()
00597 {
00598 return PathImpl::tempImpl();
00599 }
00600
00601
00602 std::string Path::null()
00603 {
00604 return PathImpl::nullImpl();
00605 }
00606
00607
00608 std::string Path::expand(const std::string& path)
00609 {
00610 return PathImpl::expandImpl(path);
00611 }
00612
00613
00614 void Path::listRoots(std::vector<std::string>& roots)
00615 {
00616 PathImpl::listRootsImpl(roots);
00617 }
00618
00619
00620 bool Path::find(StringVec::const_iterator it, StringVec::const_iterator end, const std::string& name, Path& path)
00621 {
00622 while (it != end)
00623 {
00624 Path p(*it);
00625 p.makeDirectory();
00626 p.resolve(Path(name));
00627 File f(p);
00628 if (f.exists())
00629 {
00630 path = p;
00631 return true;
00632 }
00633 ++it;
00634 }
00635 return false;
00636 }
00637
00638
00639 bool Path::find(const std::string& pathList, const std::string& name, Path& path)
00640 {
00641 StringTokenizer st(pathList, std::string(1, pathSeparator()), StringTokenizer::TOK_IGNORE_EMPTY + StringTokenizer::TOK_TRIM);
00642 return find(st.begin(), st.end(), name, path);
00643 }
00644
00645
00646 void Path::parseUnix(const std::string& path)
00647 {
00648 clear();
00649
00650 std::string::const_iterator it = path.begin();
00651 std::string::const_iterator end = path.end();
00652
00653 if (it != end)
00654 {
00655 if (*it == '/')
00656 {
00657 _absolute = true; ++it;
00658 }
00659 else if (*it == '~')
00660 {
00661 ++it;
00662 if (it == end || *it == '/')
00663 {
00664 Path cwd(home());
00665 _dirs = cwd._dirs;
00666 _absolute = true;
00667 }
00668 else --it;
00669 }
00670
00671 while (it != end)
00672 {
00673 std::string name;
00674 while (it != end && *it != '/') name += *it++;
00675 if (it != end)
00676 {
00677 if (_dirs.empty())
00678 {
00679 if (!name.empty() && *(name.rbegin()) == ':')
00680 _device.assign(name, 0, name.length() - 1);
00681 else
00682 pushDirectory(name);
00683 }
00684 else pushDirectory(name);
00685 }
00686 else _name = name;
00687 if (it != end) ++it;
00688 }
00689 }
00690 }
00691
00692
00693 void Path::parseWindows(const std::string& path)
00694 {
00695 clear();
00696
00697 std::string::const_iterator it = path.begin();
00698 std::string::const_iterator end = path.end();
00699
00700 if (it != end)
00701 {
00702 if (*it == '\\' || *it == '/') { _absolute = true; ++it; }
00703 if (_absolute && it != end && (*it == '\\' || *it == '/'))
00704 {
00705 ++it;
00706 while (it != end && *it != '\\' && *it != '/') _node += *it++;
00707 if (it != end) ++it;
00708 }
00709 else if (it != end)
00710 {
00711 char d = *it++;
00712 if (it != end && *it == ':')
00713 {
00714 if (_absolute || !((d >= 'a' && d <= 'z') || (d >= 'A' && d <= 'Z'))) throw PathSyntaxException(path);
00715 _absolute = true;
00716 _device += d;
00717 ++it;
00718 if (it == end || (*it != '\\' && *it != '/')) throw PathSyntaxException(path);
00719 ++it;
00720 }
00721 else --it;
00722 }
00723 while (it != end)
00724 {
00725 std::string name;
00726 while (it != end && *it != '\\' && *it != '/') name += *it++;
00727 if (it != end)
00728 pushDirectory(name);
00729 else
00730 _name = name;
00731 if (it != end) ++it;
00732 }
00733 }
00734 if (!_node.empty() && _dirs.empty() && !_name.empty())
00735 makeDirectory();
00736 }
00737
00738
00739 void Path::parseVMS(const std::string& path)
00740 {
00741 clear();
00742
00743 std::string::const_iterator it = path.begin();
00744 std::string::const_iterator end = path.end();
00745
00746 if (it != end)
00747 {
00748 std::string name;
00749 while (it != end && *it != ':' && *it != '[' && *it != ';') name += *it++;
00750 if (it != end)
00751 {
00752 if (*it == ':')
00753 {
00754 ++it;
00755 if (it != end && *it == ':')
00756 {
00757 _node = name;
00758 ++it;
00759 }
00760 else _device = name;
00761 _absolute = true;
00762 name.clear();
00763 }
00764 if (it != end)
00765 {
00766 if (_device.empty() && *it != '[')
00767 {
00768 while (it != end && *it != ':' && *it != ';') name += *it++;
00769 if (it != end)
00770 {
00771 if (*it == ':')
00772 {
00773 _device = name;
00774 _absolute = true;
00775 name.clear();
00776 ++it;
00777 }
00778 }
00779 }
00780 }
00781 if (name.empty())
00782 {
00783 if (it != end && *it == '[')
00784 {
00785 ++it;
00786 if (it != end)
00787 {
00788 _absolute = true;
00789 if (*it == '.')
00790 { _absolute = false; ++it; }
00791 else if (*it == ']' || *it == '-')
00792 _absolute = false;
00793 while (it != end && *it != ']')
00794 {
00795 name.clear();
00796 if (*it == '-')
00797 name = "-";
00798 else
00799 while (it != end && *it != '.' && *it != ']') name += *it++;
00800 if (!name.empty())
00801 {
00802 if (name == "-")
00803 {
00804 if (_dirs.empty() || _dirs.back() == "..")
00805 _dirs.push_back("..");
00806 else
00807 _dirs.pop_back();
00808 }
00809 else _dirs.push_back(name);
00810 }
00811 if (it != end && *it != ']') ++it;
00812 }
00813 if (it == end) throw PathSyntaxException(path);
00814 ++it;
00815 if (it != end && *it == '[')
00816 {
00817 if (!_absolute) throw PathSyntaxException(path);
00818 ++it;
00819 if (it != end && *it == '.') throw PathSyntaxException(path);
00820 int d = int(_dirs.size());
00821 while (it != end && *it != ']')
00822 {
00823 name.clear();
00824 if (*it == '-')
00825 name = "-";
00826 else
00827 while (it != end && *it != '.' && *it != ']') name += *it++;
00828 if (!name.empty())
00829 {
00830 if (name == "-")
00831 {
00832 if ((int)_dirs.size() > d)
00833 _dirs.pop_back();
00834 }
00835 else _dirs.push_back(name);
00836 }
00837 if (it != end && *it != ']') ++it;
00838 }
00839 if (it == end) throw PathSyntaxException(path);
00840 ++it;
00841 }
00842 }
00843 _name.clear();
00844 }
00845 while (it != end && *it != ';') _name += *it++;
00846 }
00847 else _name = name;
00848 if (it != end && *it == ';')
00849 {
00850 ++it;
00851 while (it != end) _version += *it++;
00852 }
00853 }
00854 else _name = name;
00855 }
00856 }
00857
00858
00859 void Path::parseGuess(const std::string& path)
00860 {
00861 bool hasBackslash = false;
00862 bool hasSlash = false;
00863 bool hasOpenBracket = false;
00864 bool hasClosBracket = false;
00865 bool isWindows = path.length() > 2 && path[1] == ':' && (path[2] == '/' || path[2] == '\\');
00866 std::string::const_iterator end = path.end();
00867 std::string::const_iterator semiIt = end;
00868 if (!isWindows)
00869 {
00870 for (std::string::const_iterator it = path.begin(); it != end; ++it)
00871 {
00872 switch (*it)
00873 {
00874 case '\\': hasBackslash = true; break;
00875 case '/': hasSlash = true; break;
00876 case '[': hasOpenBracket = true;
00877 case ']': hasClosBracket = hasOpenBracket;
00878 case ';': semiIt = it; break;
00879 }
00880 }
00881 }
00882 if (hasBackslash || isWindows)
00883 {
00884 parseWindows(path);
00885 }
00886 else if (hasSlash)
00887 {
00888 parseUnix(path);
00889 }
00890 else
00891 {
00892 bool isVMS = hasClosBracket;
00893 if (!isVMS && semiIt != end)
00894 {
00895 isVMS = true;
00896 ++semiIt;
00897 while (semiIt != end)
00898 {
00899 if (*semiIt < '0' || *semiIt > '9')
00900 {
00901 isVMS = false; break;
00902 }
00903 ++semiIt;
00904 }
00905 }
00906 if (isVMS)
00907 parseVMS(path);
00908 else
00909 parseUnix(path);
00910 }
00911 }
00912
00913
00914 std::string Path::buildUnix() const
00915 {
00916 std::string result;
00917 if (!_device.empty())
00918 {
00919 result.append("/");
00920 result.append(_device);
00921 result.append(":/");
00922 }
00923 else if (_absolute)
00924 {
00925 result.append("/");
00926 }
00927 for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
00928 {
00929 result.append(*it);
00930 result.append("/");
00931 }
00932 result.append(_name);
00933 return result;
00934 }
00935
00936
00937 std::string Path::buildWindows() const
00938 {
00939 std::string result;
00940 if (!_node.empty())
00941 {
00942 result.append("\\\\");
00943 result.append(_node);
00944 result.append("\\");
00945 }
00946 else if (!_device.empty())
00947 {
00948 result.append(_device);
00949 result.append(":\\");
00950 }
00951 else if (_absolute)
00952 {
00953 result.append("\\");
00954 }
00955 for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
00956 {
00957 result.append(*it);
00958 result.append("\\");
00959 }
00960 result.append(_name);
00961 return result;
00962 }
00963
00964
00965 std::string Path::buildVMS() const
00966 {
00967 std::string result;
00968 if (!_node.empty())
00969 {
00970 result.append(_node);
00971 result.append("::");
00972 }
00973 if (!_device.empty())
00974 {
00975 result.append(_device);
00976 result.append(":");
00977 }
00978 if (!_dirs.empty())
00979 {
00980 result.append("[");
00981 if (!_absolute && _dirs[0] != "..")
00982 result.append(".");
00983 for (StringVec::const_iterator it = _dirs.begin(); it != _dirs.end(); ++it)
00984 {
00985 if (it != _dirs.begin() && *it != "..")
00986 result.append(".");
00987 if (*it == "..")
00988 result.append("-");
00989 else
00990 result.append(*it);
00991 }
00992 result.append("]");
00993 }
00994 result.append(_name);
00995 if (!_version.empty())
00996 {
00997 result.append(";");
00998 result.append(_version);
00999 }
01000 return result;
01001 }
01002
01003
01004 std::string Path::transcode(const std::string& path)
01005 {
01006 #if defined(_WIN32) && defined(POCO_WIN32_UTF8)
01007 std::wstring uniPath;
01008 UnicodeConverter::toUTF16(path, uniPath);
01009 DWORD len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, uniPath.c_str(), static_cast<int>(uniPath.length()), NULL, 0, NULL, NULL);
01010 if (len > 0)
01011 {
01012 Buffer<char> buffer(len);
01013 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);
01014 if (rc)
01015 {
01016 return std::string(buffer.begin(), buffer.size());
01017 }
01018 }
01019 #endif
01020 return path;
01021 }
01022
01023
01024 }