source: XMLIO_V2/external/src/POCO/Foundation/Path.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

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