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