STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

winstl_path.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_path.h (formerly MLPath.h, ::SynesisStd)
00003  *
00004  * Purpose:     Simple class that represents a path.
00005  *
00006  * Created:     1st May 1993
00007  * Updated:     12th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 1993-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef WINSTL_INCL_H_WINSTL_PATH
00046 #define WINSTL_INCL_H_WINSTL_PATH
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define WINSTL_VER_H_WINSTL_PATH_MAJOR     4
00050 # define WINSTL_VER_H_WINSTL_PATH_MINOR     0
00051 # define WINSTL_VER_H_WINSTL_PATH_REVISION  1
00052 # define WINSTL_VER_H_WINSTL_PATH_EDIT      154
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef WINSTL_INCL_H_WINSTL
00060 # include "winstl.h"                        // Include the WinSTL root header
00061 #endif /* !WINSTL_INCL_H_WINSTL */
00062 #ifndef WINSTL_INCL_H_WINSTL_SYSTEM_VERSION
00063 # include "winstl_filesystem_traits.h"      // filesystem_traits
00064 #endif /* !WINSTL_INCL_H_WINSTL_SYSTEM_VERSION */
00065 #ifndef WINSTL_INCL_H_WINSTL_FILE_PATH_BUFFER
00066 # include "winstl_file_path_buffer.h"       // basic_file_path_buffer
00067 #endif /* !WINSTL_INCL_H_WINSTL_FILE_PATH_BUFFER */
00068 #ifndef WINSTL_INCL_H_WINSTL_PROCESSHEAP_ALLOCATOR
00069 # include "winstl_processheap_allocator.h"  // processheap_allocator
00070 #endif /* !WINSTL_INCL_H_WINSTL_PROCESSHEAP_ALLOCATOR */
00071 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_ACCESS
00072 # include "stlsoft_string_access.h"         // stlsoft::c_str_ptr
00073 #endif /* !STLSOFT_INCL_H_STLSOFT_STRING_ACCESS */
00074 #ifndef WINSTL_INCL_H_WINSTL_STRING_ACCESS
00075 # include "winstl_string_access.h"          // winstl::c_str_ptr
00076 #endif /* !WINSTL_INCL_H_WINSTL_STRING_ACCESS */
00077 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_TOKENISER
00078 # include "stlsoft_string_tokeniser.h"      // stlsoft::string_tokeniser
00079 #endif /* !STLSOFT_INCL_H_STLSOFT_STRING_TOKENISER */
00080 
00081 /* 
00082  * Namespace
00083  */
00084 
00085 #ifndef _WINSTL_NO_NAMESPACE
00086 # if defined(_STLSOFT_NO_NAMESPACE) || \
00087      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00088 /* There is no stlsoft namespace, so must define ::winstl */
00089 namespace winstl
00090 {
00091 # else
00092 /* Define stlsoft::winstl_project */
00093 
00094 namespace stlsoft
00095 {
00096 
00097 namespace winstl_project
00098 {
00099 
00100 # endif /* _STLSOFT_NO_NAMESPACE */
00101 #endif /* !_WINSTL_NO_NAMESPACE */
00102 
00103 #if !defined(__STLSOFT_COMPILER_IS_MWERKS)
00104 stlsoft_ns_using(c_str_ptr)
00105 #endif /* compiler */
00106 
00107 /* 
00108 
00111 
00115 
00120 
00121 /* 
00122  * basic_path
00123  *
00124  * This class represents a path, and effectively acts as a C-string of its value.
00125  */
00126 
00139 template<   ss_typename_param_k C
00140 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00141         ,   ss_typename_param_k T = filesystem_traits<C>
00142         ,   ss_typename_param_k A = processheap_allocator<C>
00143 #else
00144         ,   ss_typename_param_k T /* = filesystem_traits<C> */
00145         ,   ss_typename_param_k A /* = processheap_allocator<C> */
00146 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00147         >
00148 class basic_path
00149 {
00152 public:
00154     typedef C                           char_type;
00156     typedef T                           traits_type;
00158     typedef A                           allocator_type;
00160     typedef basic_path<C, T, A>         class_type;
00162     typedef ws_size_t                   size_type;
00163 
00164 #if 0
00165     class directory_iterator
00166     {
00167     private:
00168         friend class
00169         directory_iterator(class_type const
00170     };
00171 #endif /* 0 */
00172 
00173 // TODO: Use the slice string, and provide iterators over the directory parts
00174 
00176 
00179 public:
00181     ss_explicit_k basic_path(char_type const *path);
00182 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00183 
00184     template<ss_typename_param_k S>
00185     ss_explicit_k basic_path(S const &s)
00186     {
00187         traits_type::str_copy(&m_buffer[0], stlsoft_ns_qual(c_str_ptr)(s));
00188 
00189         m_len = stlsoft_ns_qual(c_str_len)(s);
00190     }
00191 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00192 
00193     basic_path(char_type const *path, size_type cch);
00194 
00195     basic_path(class_type const &rhs);
00196 
00197     class_type &operator =(class_type const &rhs);
00198     class_type &operator =(char_type const *rhs);
00199 
00200     // Creates a root path
00201     static class_type root(char_type const *s);
00202 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00203     // Creates a root path
00204     template<ss_typename_param_k S>
00205     static class_type root(S const &s)
00206     {
00207         return root(stlsoft_ns_qual(c_str_ptr)(s));
00208     }
00209 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00210 
00211 
00214 public:
00215     class_type &push(class_type const &rhs, ws_bool_t bAddPathNameSeparator = false);
00216     class_type &push(char_type const *rhs, ws_bool_t bAddPathNameSeparator = false);
00217     class_type &push_ext(class_type const &rhs, ws_bool_t bAddPathNameSeparator = false);
00218     class_type &push_ext(char_type const *rhs, ws_bool_t bAddPathNameSeparator = false);
00219     class_type &push_sep();
00220     class_type &pop();
00221     class_type &pop_sep();
00222 
00223     class_type &operator /=(class_type const &rhs);
00224     class_type &operator /=(char_type const *rhs);
00225     template <ss_typename_param_k S>
00226     class_type &operator /=(S const &rhs)
00227     {
00228         return operator /=(stlsoft_ns_qual(c_str_ptr)(rhs));
00229     }
00230 
00231     class_type &make_absolute(ws_bool_t bRemoveTrailingPathNameSeparator = true);
00232     class_type &canonicalise(ws_bool_t bRemoveTrailingPathNameSeparator = true);
00234 
00237 public:
00239     size_type length() const;
00241     char_type const *c_str() const;
00243 
00246 public:
00247     ws_bool_t equivalent(char_type const *rhs) const;
00248     ws_bool_t equivalent(class_type const &rhs) const;
00249 
00250     ws_bool_t equal(char_type const *rhs) const;
00251     ws_bool_t equal(class_type const &rhs) const;
00253 
00256 public:
00257 #if 0
00258     directory_iterator  dir_begin() const;
00259     directory_iterator  dir_end() const;
00260 #endif /* 0 */
00261 
00262 
00263 // Implementation
00264 private:
00265     void        swap(class_type &rhs);
00266     class_type  &concat_(char_type const *rhs);
00267     class_type  &concat_(class_type const &rhs);
00268 
00269 // Members
00270 private:
00271     typedef basic_file_path_buffer<char_type>   buffer_type;
00272 
00273     buffer_type m_buffer;
00274     size_type   m_len;
00275 };
00276 
00277 /* 
00278  * Typedefs for commonly encountered types
00279  */
00280 
00282 typedef basic_path<ws_char_a_t, filesystem_traits<ws_char_a_t> >       path_a;
00284 typedef basic_path<ws_char_w_t, filesystem_traits<ws_char_w_t> >       path_w;
00286 typedef basic_path<TCHAR, filesystem_traits<TCHAR> >                   path;
00287 
00288 /* 
00289  * Operators
00290  */
00291 
00292 template<   ss_typename_param_k C
00293         ,   ss_typename_param_k T
00294         ,   ss_typename_param_k A
00295         >
00296 inline ws_bool_t operator ==(basic_path<C, T, A> const &lhs, ss_typename_type_k basic_path<C, T, A>::char_type const *rhs)
00297 {
00298     return lhs.equal(rhs);
00299 }
00300 
00301 template<   ss_typename_param_k C
00302         ,   ss_typename_param_k T
00303         ,   ss_typename_param_k A
00304         >
00305 inline ws_bool_t operator !=(basic_path<C, T, A> const &lhs, ss_typename_type_k basic_path<C, T, A>::char_type const *rhs)
00306 {
00307     return !lhs.equal(rhs);
00308 }
00309 
00310 template<   ss_typename_param_k C
00311         ,   ss_typename_param_k T
00312         ,   ss_typename_param_k A
00313         >
00314 inline ws_bool_t operator ==(ss_typename_type_k basic_path<C, T, A>::char_type const *lhs, basic_path<C, T, A> const &rhs)
00315 {
00316     return rhs.equal(lhs);
00317 }
00318 
00319 template<   ss_typename_param_k C
00320         ,   ss_typename_param_k T
00321         ,   ss_typename_param_k A
00322         >
00323 inline ws_bool_t operator !=(ss_typename_type_k basic_path<C, T, A>::char_type const *lhs, basic_path<C, T, A> const &rhs)
00324 {
00325     return !rhs.equal(lhs);
00326 }
00327 
00328 template<   ss_typename_param_k C
00329         ,   ss_typename_param_k T
00330         ,   ss_typename_param_k A
00331         >
00332 inline ws_bool_t operator ==(basic_path<C, T, A> const &lhs, basic_path<C, T, A> const &rhs)
00333 {
00334     return lhs.equal(rhs);
00335 }
00336 
00337 template<   ss_typename_param_k C
00338         ,   ss_typename_param_k T
00339         ,   ss_typename_param_k A
00340         >
00341 inline ws_bool_t operator !=(basic_path<C, T, A> const &lhs, basic_path<C, T, A> const &rhs)
00342 {
00343     return !lhs.equal(rhs);
00344 }
00345 
00346 // operator /
00347 template<   ss_typename_param_k C
00348         ,   ss_typename_param_k T
00349         ,   ss_typename_param_k A
00350         >
00351 inline basic_path<C, T, A> operator /(basic_path<C, T, A> const &lhs, ss_typename_type_k basic_path<C, T, A>::char_type const *rhs)
00352 {
00353     return basic_path<C, T, A>(lhs) /= rhs;
00354 }
00355 
00356 template<   ss_typename_param_k C
00357         ,   ss_typename_param_k T
00358         ,   ss_typename_param_k A
00359         >
00360 inline basic_path<C, T, A> operator /(ss_typename_type_k basic_path<C, T, A>::char_type const *lhs, basic_path<C, T, A> const &rhs)
00361 {
00362     return basic_path<C, T, A>(lhs) /= rhs;
00363 }
00364 
00365 template<   ss_typename_param_k C
00366         ,   ss_typename_param_k T
00367         ,   ss_typename_param_k A
00368         >
00369 inline basic_path<C, T, A> operator /(basic_path<C, T, A> const &lhs, basic_path<C, T, A> const &rhs)
00370 {
00371     return basic_path<C, T, A>(lhs) /= rhs;
00372 }
00373 
00374 /* 
00375  * Helper functions
00376  */
00377 
00378 #if !defined(__STLSOFT_COMPILER_IS_MSVC) || \
00379     _MSC_VER >= 1100
00380 
00383 template<ss_typename_param_k C>
00384 inline basic_path<C> make_path(C const *path)
00385 {
00386     return basic_path<C>(path);
00387 }
00388 
00389 #endif /* !(_MSC_VER < 1100) */
00390 
00391 /* 
00392  * Shims
00393  */
00394 
00395 template<   ss_typename_param_k C
00396         ,   ss_typename_param_k T
00397         ,   ss_typename_param_k A
00398         >
00399 inline C const *c_str_ptr_null(basic_path<C, T, A> const &b)
00400 {
00401     return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00402 }
00403 
00404 template<   ss_typename_param_k C
00405         ,   ss_typename_param_k T
00406         ,   ss_typename_param_k A
00407         >
00408 inline C const *c_str_ptr(basic_path<C, T, A> const &b)
00409 {
00410     return stlsoft_ns_qual(c_str_ptr)(b.c_str());
00411 }
00412 
00413 template<   ss_typename_param_k C
00414         ,   ss_typename_param_k T
00415         ,   ss_typename_param_k A
00416         >
00417 inline ws_size_t c_str_len(basic_path<C, T, A> const &b)
00418 {
00419     return stlsoft_ns_qual(c_str_len)(b.c_str());
00420 }
00421 
00422 template<   ss_typename_param_k C
00423         ,   ss_typename_param_k T
00424         ,   ss_typename_param_k A
00425         >
00426 inline ws_size_t c_str_size(basic_path<C, T, A> const &b)
00427 {
00428     return stlsoft_ns_qual(c_str_size)(b.c_str());
00429 }
00430 
00431 template<   ss_typename_param_k S
00432         ,   ss_typename_param_k C
00433         ,   ss_typename_param_k T
00434         ,   ss_typename_param_k A
00435         >
00436 inline S &operator <<(S & s, basic_path<C, T, A> const &b)
00437 {
00438     s << b.c_str();
00439 
00440     return s;
00441 }
00442 
00444 // Unit-testing
00445 
00446 #ifdef STLSOFT_UNITTEST
00447 
00448 namespace unittest
00449 {
00450     ss_bool_t test_winstl_path(unittest_reporter *r)
00451     {
00452         using stlsoft::unittest::unittest_initialiser;
00453 
00454         ss_bool_t               bSuccess    =   true;
00455 
00456         unittest_initialiser    init(r, "UNIXSTL", "path", __FILE__);
00457 
00458         path_a  path1("..");
00459         path_a  path2(".\\..");
00460 
00461         if(!path1.equivalent(path2))
00462         {
00463             r->report("equivalence test failed ", __LINE__);
00464             bSuccess = false;
00465         }
00466 
00467         path_a  path3(path1);
00468 
00469         if(path1 != path3)
00470         {
00471             r->report("copy-construction failed ", __LINE__);
00472             bSuccess = false;
00473         }
00474 
00475         path3 /= "sub1";
00476 
00477         path_a  path4("..\\sub1");
00478 
00479         if(path4 != path3)
00480         {
00481             r->report("concatenation failed ", __LINE__);
00482             bSuccess = false;
00483         }
00484 
00485         return bSuccess;
00486     }
00487 
00488     unittest_registrar    unittest_winstl_path(test_winstl_path);
00489 
00490 } // namespace unittest
00491 
00492 #endif /* STLSOFT_UNITTEST */
00493 
00495 // Implementation
00496 
00497 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00498 
00499 template<   ss_typename_param_k C
00500         ,   ss_typename_param_k T
00501         ,   ss_typename_param_k A
00502         >
00503 inline void basic_path<C, T, A>::swap(basic_path<C, T, A> &rhs)
00504 {
00505     m_buffer.swap(rhs.m_buffer);
00506     std::swap(m_len, rhs.m_len);
00507 }
00508 
00509 template<   ss_typename_param_k C
00510         ,   ss_typename_param_k T
00511         ,   ss_typename_param_k A
00512         >
00513 inline ss_typename_param_k basic_path<C, T, A>::class_type &basic_path<C, T, A>::concat_(ss_typename_param_k basic_path<C, T, A>::char_type const *rhs)
00514 {
00515     m_len = traits_type::str_len(traits_type::str_cat(&m_buffer[0], rhs));
00516 
00517     return *this;
00518 }
00519 
00520 template<   ss_typename_param_k C
00521         ,   ss_typename_param_k T
00522         ,   ss_typename_param_k A
00523         >
00524 inline ss_typename_param_k basic_path<C, T, A>::class_type &basic_path<C, T, A>::concat_(basic_path<C, T, A> const &rhs)
00525 {
00526     m_len = traits_type::str_len(traits_type::str_cat(&m_buffer[0], rhs.c_str()));
00527 
00528     return *this;
00529 }
00530 
00531 template<   ss_typename_param_k C
00532         ,   ss_typename_param_k T
00533         ,   ss_typename_param_k A
00534         >
00535 inline /* ss_explicit_k */ basic_path<C, T, A>::basic_path(ss_typename_type_k basic_path<C, T, A>::char_type const *path)
00536     : m_len(0)
00537 {
00538     if(NULL != path)
00539     {
00540         ws_size_t   cch =   traits_type::str_len(path);
00541 
00542         winstl_assert(cch < m_buffer.size());
00543 
00544         traits_type::str_copy(&m_buffer[0], path);
00545 
00546         m_len = cch;
00547     }
00548 }
00549 
00550 template<   ss_typename_param_k C
00551     ,   ss_typename_param_k T
00552     ,   ss_typename_param_k A
00553     >
00554 inline basic_path<C, T, A>::basic_path(ss_typename_type_k basic_path<C, T, A>::char_type const *path, ss_typename_type_k basic_path<C, T, A>::size_type cch)
00555     : m_len(cch)
00556 {
00557     stlsoft_assert((NULL == path) == (0 == cch));
00558 
00559     if(0 != cch)
00560     {
00561         winstl_assert(cch < m_buffer.size());
00562 
00563         traits_type::str_n_copy(&m_buffer[0], path, cch);
00564         m_buffer[cch] = '\0';
00565     }
00566 }
00567 
00568 template<   ss_typename_param_k C
00569         ,   ss_typename_param_k T
00570         ,   ss_typename_param_k A
00571         >
00572 inline basic_path<C, T, A>::basic_path(basic_path<C, T, A> const &rhs)
00573     : m_len(rhs.m_len)
00574 {
00575     traits_type::str_copy(&m_buffer[0], stlsoft_ns_qual(c_str_ptr)(rhs.m_buffer));
00576 }
00577 
00578 template<   ss_typename_param_k C
00579         ,   ss_typename_param_k T
00580         ,   ss_typename_param_k A
00581         >
00582 inline basic_path<C, T, A> &basic_path<C, T, A>::operator =(basic_path<C, T, A> const &path)
00583 {
00584     class_type  newPath(path);
00585 
00586     swap(newPath);
00587 
00588     return *this;
00589 }
00590 
00591 template<   ss_typename_param_k C
00592         ,   ss_typename_param_k T
00593         ,   ss_typename_param_k A
00594         >
00595 inline basic_path<C, T, A> &basic_path<C, T, A>::operator =(ss_typename_type_k basic_path<C, T, A>::char_type const *path)
00596 {
00597     class_type  newPath(path);
00598 
00599     swap(newPath);
00600 
00601     return *this;
00602 }
00603 
00604 template<   ss_typename_param_k C
00605         ,   ss_typename_param_k T
00606         ,   ss_typename_param_k A
00607         >
00608 inline /* static */ ss_typename_type_k basic_path<C, T, A>::class_type basic_path<C, T, A>::root(ss_typename_type_k basic_path<C, T, A>::char_type const *s)
00609 {
00610     return class_type(s);
00611 }
00612 
00613 template<   ss_typename_param_k C
00614         ,   ss_typename_param_k T
00615         ,   ss_typename_param_k A
00616         >
00617 inline basic_path<C, T, A> &basic_path<C, T, A>::push(class_type const &rhs, ws_bool_t bAddPathNameSeparator /* = false */)
00618 {
00619     return push(rhs.c_str(), bAddPathNameSeparator);
00620 }
00621 
00622 template<   ss_typename_param_k C
00623         ,   ss_typename_param_k T
00624         ,   ss_typename_param_k A
00625         >
00626 inline basic_path<C, T, A> &basic_path<C, T, A>::push(char_type const *rhs, ws_bool_t bAddPathNameSeparator /* = false */)
00627 {
00628     class_type  newPath(*this);
00629 
00630     newPath.push_sep();
00631     newPath.concat_(rhs);
00632     if(bAddPathNameSeparator)
00633     {
00634         newPath.push_sep();
00635     }
00636 
00637     swap(newPath);
00638 
00639     return *this;
00640 }
00641 
00642 #if 0
00643 template<   ss_typename_param_k C
00644         ,   ss_typename_param_k T
00645         ,   ss_typename_param_k A
00646         >
00647 inline basic_path<C, T, A> &basic_path<C, T, A>::push_ext(class_type const &rhs, ws_bool_t bAddPathNameSeparator /* = false */)
00648 {
00649 }
00650 #endif /* 0 */
00651 
00652 template<   ss_typename_param_k C
00653         ,   ss_typename_param_k T
00654         ,   ss_typename_param_k A
00655         >
00656 inline basic_path<C, T, A> &basic_path<C, T, A>::push_ext(char_type const *rhs, ws_bool_t bAddPathNameSeparator /* = false */)
00657 {
00658     winstl_assert(NULL != rhs);
00659 
00660     class_type  newPath(*this);
00661 
00662     newPath.pop_sep();
00663     if('.' != *rhs)
00664     {
00665         newPath.concat_(".");
00666     }
00667     newPath.concat_(rhs);
00668     if(bAddPathNameSeparator)
00669     {
00670         newPath.push_sep();
00671     }
00672 
00673     swap(newPath);
00674 
00675     return *this;
00676 }
00677 
00678 template<   ss_typename_param_k C
00679         ,   ss_typename_param_k T
00680         ,   ss_typename_param_k A
00681         >
00682 inline basic_path<C, T, A> &basic_path<C, T, A>::push_sep()
00683 {
00684     if(0 != m_len)
00685     {
00686         if( traits_type::path_name_separator() != m_buffer[m_len - 1] &&
00687             '/' != m_buffer[m_len - 1])
00688         {
00689             winstl_assert(m_len + 1 < m_buffer.size());
00690 
00691             m_buffer[m_len]     =   '\\';
00692             m_buffer[m_len + 1] =   '\0';
00693             ++m_len;
00694         }
00695     }
00696 
00697     return *this;
00698 }
00699 
00700 template<   ss_typename_param_k C
00701         ,   ss_typename_param_k T
00702         ,   ss_typename_param_k A
00703         >
00704 inline basic_path<C, T, A> &basic_path<C, T, A>::pop()
00705 {
00706     char_type   *bslash =   traits_type::str_rchr(c_str_ptr(m_buffer), traits_type::path_name_separator());
00707     char_type   *fslash =   traits_type::str_rchr(c_str_ptr(m_buffer), '/');
00708 
00709     if(fslash > bslash)
00710     {
00711         bslash = fslash;
00712     }
00713 
00714     if(NULL != bslash)
00715     {
00716         *(bslash + 1) = '\0';
00717         m_len = (bslash + 1) - c_str_ptr(m_buffer);
00718     }
00719 
00720     return *this;
00721 }
00722 
00723 template<   ss_typename_param_k C
00724         ,   ss_typename_param_k T
00725         ,   ss_typename_param_k A
00726         >
00727 inline basic_path<C, T, A> &basic_path<C, T, A>::pop_sep()
00728 {
00729     if(0 != m_len)
00730     {
00731         char_type *last = &m_buffer[m_len - 1];
00732 
00733         if(traits_type::has_dir_end(last))
00734         {
00735             m_buffer[m_len-- - 1] = '\0';
00736         }
00737     }
00738 
00739     return *this;
00740 }
00741 
00742 
00743 template<   ss_typename_param_k C
00744         ,   ss_typename_param_k T
00745         ,   ss_typename_param_k A
00746         >
00747 inline basic_path<C, T, A> &basic_path<C, T, A>::operator /=(basic_path<C, T, A> const &path)
00748 {
00749     return push(path);
00750 }
00751 
00752 template<   ss_typename_param_k C
00753         ,   ss_typename_param_k T
00754         ,   ss_typename_param_k A
00755         >
00756 inline basic_path<C, T, A> &basic_path<C, T, A>::operator /=(ss_typename_type_k basic_path<C, T, A>::char_type const *path)
00757 {
00758     return push(path);
00759 }
00760 
00761 template<   ss_typename_param_k C
00762         ,   ss_typename_param_k T
00763         ,   ss_typename_param_k A
00764         >
00765 inline basic_path<C, T, A> &basic_path<C, T, A>::make_absolute(ws_bool_t bRemoveTrailingPathNameSeparator /* = true */)
00766 {
00767     buffer_type buffer;
00768     ws_dword_t  cch = traits_type::get_full_path_name(c_str(), buffer.size(), &buffer[0]);
00769     class_type  newPath(stlsoft_ns_qual(c_str_ptr)(buffer), cch);
00770 
00771     if(bRemoveTrailingPathNameSeparator)
00772     {
00773         newPath.pop_sep();
00774     }
00775 
00776     swap(newPath);
00777 
00778     return *this;
00779 }
00780 
00781 template<   ss_typename_param_k C
00782         ,   ss_typename_param_k T
00783         ,   ss_typename_param_k A
00784         >
00785 inline basic_path<C, T, A> &basic_path<C, T, A>::canonicalise(ws_bool_t bRemoveTrailingPathNameSeparator /* = true */)
00786 {
00787     class_type  newPath(*this);
00788 
00789 #if 0
00790 
00791     ws_dword_t  cchRhs  =   traits_type::get_full_path_name(rhs, rhs_.size(), &rhs_[0]);
00792 
00793 #if 0
00794     if( cchLhs == cchRhs + 1 &&
00795         !traits_type)
00796 #endif /* 0 */
00797 
00798     return cchLhs == cchRhs && 0 == traits_type::str_compare_no_case(stlsoft_ns_qual(c_str_ptr)(lhs_), stlsoft_ns_qual(c_str_ptr)(rhs_));
00799 #endif /* 0 */
00800 
00801     if(bRemoveTrailingPathNameSeparator)
00802     {
00803         newPath.pop_sep();
00804     }
00805 
00806     swap(newPath);
00807 
00808     return *this;
00809 }
00810 
00811 
00812 
00813 template<   ss_typename_param_k C
00814         ,   ss_typename_param_k T
00815         ,   ss_typename_param_k A
00816         >
00817 inline ss_typename_type_k basic_path<C, T, A>::size_type basic_path<C, T, A>::length() const
00818 {
00819     return m_len;
00820 }
00821 
00822 template<   ss_typename_param_k C
00823         ,   ss_typename_param_k T
00824         ,   ss_typename_param_k A
00825         >
00826 inline ss_typename_type_k basic_path<C, T, A>::char_type const *basic_path<C, T, A>::c_str() const
00827 {
00828     return stlsoft_ns_qual(c_str_ptr)(m_buffer);
00829 }
00830 
00831 template<   ss_typename_param_k C
00832         ,   ss_typename_param_k T
00833         ,   ss_typename_param_k A
00834         >
00835 inline ws_bool_t basic_path<C, T, A>::equivalent(basic_path<C, T, A> const &rhs) const
00836 {
00837     return equivalent(rhs.c_str());
00838 }
00839 
00840 template<   ss_typename_param_k C
00841         ,   ss_typename_param_k T
00842         ,   ss_typename_param_k A
00843         >
00844 inline ws_bool_t basic_path<C, T, A>::equivalent(ss_typename_type_k basic_path<C, T, A>::char_type const *rhs) const
00845 {
00846     class_type  lhs_(*this);
00847     class_type  rhs_(rhs);
00848 
00849     return lhs_.canonicalise(false).make_absolute(true) == rhs_.canonicalise(false).make_absolute(true);
00850 }
00851 
00852 template<   ss_typename_param_k C
00853         ,   ss_typename_param_k T
00854         ,   ss_typename_param_k A
00855         >
00856 inline ws_bool_t basic_path<C, T, A>::equal(basic_path<C, T, A> const &rhs) const
00857 {
00858     return equal(rhs.c_str());
00859 }
00860 
00861 template<   ss_typename_param_k C
00862         ,   ss_typename_param_k T
00863         ,   ss_typename_param_k A
00864         >
00865 inline ws_bool_t basic_path<C, T, A>::equal(ss_typename_type_k basic_path<C, T, A>::char_type const *rhs) const
00866 {
00867     return 0 == traits_type::str_compare_no_case(stlsoft_ns_qual(c_str_ptr)(m_buffer), stlsoft_ns_qual(c_str_ptr)(rhs));
00868 }
00869 
00870 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00871 
00872 /* 
00873 
00875 
00876 /* 
00877 
00878 #ifndef _WINSTL_NO_NAMESPACE
00879 # if defined(_STLSOFT_NO_NAMESPACE) || \
00880      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00881 } // namespace winstl
00882 # else
00883 } // namespace winstl_project
00884 } // namespace stlsoft
00885 # endif /* _STLSOFT_NO_NAMESPACE */
00886 #endif /* !_WINSTL_NO_NAMESPACE */
00887 
00888 /* 
00889  * Namespace
00890  *
00891  * The string access shims exist either in the stlsoft namespace, or in the
00892  * global namespace. This is required by the lookup rules.
00893  *
00894  */
00895 
00896 #ifndef _WINSTL_NO_NAMESPACE
00897 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00898      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00899 namespace stlsoft
00900 {
00901 # else /* ? _STLSOFT_NO_NAMESPACE */
00902 /* There is no stlsoft namespace, so must define in the global namespace */
00903 # endif /* !_STLSOFT_NO_NAMESPACE */
00904 
00905 using ::winstl::c_str_ptr_null;
00906 
00907 using ::winstl::c_str_ptr;
00908 
00909 using ::winstl::c_str_len;
00910 
00911 using ::winstl::c_str_size;
00912 
00913 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00914      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00915 } // namespace stlsoft
00916 # else /* ? _STLSOFT_NO_NAMESPACE */
00917 /* There is no stlsoft namespace, so must define in the global namespace */
00918 # endif /* !_STLSOFT_NO_NAMESPACE */
00919 #endif /* !_WINSTL_NO_NAMESPACE */
00920 
00921 /* 
00922 
00923 #endif /* WINSTL_INCL_H_WINSTL_PATH */
00924 
00925 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004