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  

unixstl_path.h

Go to the documentation of this file.
00001 /* 
00002  * File:        unixstl_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 UNIXSTL_INCL_H_UNIXSTL_PATH
00046 #define UNIXSTL_INCL_H_UNIXSTL_PATH
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define UNIXSTL_VER_H_UNIXSTL_PATH_MAJOR     4
00050 # define UNIXSTL_VER_H_UNIXSTL_PATH_MINOR     0
00051 # define UNIXSTL_VER_H_UNIXSTL_PATH_REVISION  1
00052 # define UNIXSTL_VER_H_UNIXSTL_PATH_EDIT      149
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef UNIXSTL_INCL_H_UNIXSTL
00060 # include "unixstl.h"                       // Include the UNIXSTL root header
00061 #endif /* !UNIXSTL_INCL_H_UNIXSTL */
00062 #ifndef UNIXSTL_INCL_H_UNIXSTL_SYSTEM_VERSION
00063 # include "unixstl_filesystem_traits.h"     // filesystem_traits
00064 #endif /* !UNIXSTL_INCL_H_UNIXSTL_SYSTEM_VERSION */
00065 #ifndef UNIXSTL_INCL_H_UNIXSTL_FILE_PATH_BUFFER
00066 # include "unixstl_file_path_buffer.h"      // basic_file_path_buffer
00067 #endif /* !UNIXSTL_INCL_H_UNIXSTL_FILE_PATH_BUFFER */
00068 #ifndef UNIXSTL_INCL_H_STLSOFT_MALLOC_ALLOCATOR
00069 # include "stlsoft_malloc_allocator.h"      // malloc_allocator
00070 #endif /* !UNIXSTL_INCL_H_STLSOFT_MALLOC_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 UNIXSTL_INCL_H_UNIXSTL_STRING_ACCESS
00075 # include "unixstl_string_access.h"         // unixstl::c_str_ptr
00076 #endif /* !UNIXSTL_INCL_H_UNIXSTL_STRING_ACCESS */
00077 
00078 /* 
00079  * Namespace
00080  */
00081 
00082 #ifndef _UNIXSTL_NO_NAMESPACE
00083 # if defined(_STLSOFT_NO_NAMESPACE) || \
00084      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00085 /* There is no stlsoft namespace, so must define ::unixstl */
00086 namespace unixstl
00087 {
00088 # else
00089 /* Define stlsoft::unixstl_project */
00090 
00091 namespace stlsoft
00092 {
00093 
00094 namespace unixstl_project
00095 {
00096 
00097 # endif /* _STLSOFT_NO_NAMESPACE */
00098 #endif /* !_UNIXSTL_NO_NAMESPACE */
00099 
00100 #if !defined(__STLSOFT_COMPILER_IS_MWERKS)
00101 stlsoft_ns_using(c_str_ptr)
00102 #endif /* compiler */
00103 
00104 /* 
00105 
00108 
00112 
00117 
00118 /* 
00119  * basic_path
00120  *
00121  * This class represents a path, and effectively acts as a C-string of its value.
00122  */
00123 
00136 template<   ss_typename_param_k C
00137 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00138         ,   ss_typename_param_k T = filesystem_traits<C>
00139         ,   ss_typename_param_k A = malloc_allocator<C>
00140 #else
00141         ,   ss_typename_param_k T /* = filesystem_traits<C> */
00142         ,   ss_typename_param_k A /* = malloc_allocator<C> */
00143 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00144         >
00145 class basic_path
00146 {
00149 public:
00151     typedef C                           char_type;
00153     typedef T                           traits_type;
00155     typedef A                           allocator_type;
00157     typedef basic_path<C, T, A>         class_type;
00159     typedef us_size_t                   size_type;
00160 
00161 // TODO: Use the slice string, and provide iterators over the directory parts
00162 
00164 
00167 public:
00169     ss_explicit_k basic_path(char_type const *path);
00170 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00171 
00172     template<ss_typename_param_k S>
00173     ss_explicit_k basic_path(S const &s)
00174     {
00175         traits_type::str_copy(&m_buffer[0], stlsoft_ns_qual(c_str_ptr)(s));
00176 
00177         m_len = stlsoft_ns_qual(c_str_len)(s);
00178     }
00179 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00180 
00181     basic_path(char_type const *path, size_type cch);
00182 
00183     basic_path(class_type const &rhs);
00184 
00185     class_type &operator =(class_type const &rhs);
00186     class_type &operator =(char_type const *rhs);
00187 
00188     // Creates a root path
00189     static class_type root(char_type const *s);
00190 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00191     // Creates a root path
00192     template<ss_typename_param_k S>
00193     static class_type root(S const &s)
00194     {
00195         return root(stlsoft_ns_qual(c_str_ptr)(s));
00196     }
00197 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
00198 
00199 
00202 public:
00203     class_type &push(class_type const &rhs, us_bool_t bAddPathNameSeparator = false);
00204     class_type &push(char_type const *rhs, us_bool_t bAddPathNameSeparator = false);
00205     class_type &push_ext(class_type const &rhs, us_bool_t bAddPathNameSeparator = false);
00206     class_type &push_ext(char_type const *rhs, us_bool_t bAddPathNameSeparator = false);
00207     class_type &push_sep();
00208     class_type &pop();
00209     class_type &pop_sep();
00210 
00211     class_type &operator /=(class_type const &rhs);
00212     class_type &operator /=(char_type const *rhs);
00213 
00214     class_type &make_absolute(us_bool_t bRemoveTrailingPathNameSeparator = true);
00215     class_type &canonicalise(us_bool_t bRemoveTrailingPathNameSeparator = true);
00216 
00218 
00221 public:
00223     size_type length() const;
00225     char_type const *c_str() const;
00227 
00230 public:
00231     us_bool_t equivalent(char_type const *rhs) const;
00232     us_bool_t equivalent(class_type const &rhs) const;
00233 
00234     us_bool_t equal(char_type const *rhs) const;
00235     us_bool_t equal(class_type const &rhs) const;
00237 
00240 public:
00241 #if 0
00242     directory_iterator  dir_begin() const;
00243     directory_iterator  dir_end() const;
00244 #endif /* 0 */
00245 
00246 
00247 // Implementation
00248 private:
00249     void        swap(class_type &rhs);
00250     class_type  &concat_(char_type const *rhs);
00251     class_type  &concat_(class_type const &rhs);
00252 
00253 // Members
00254 private:
00255     typedef basic_file_path_buffer<char_type>   buffer_type;
00256 
00257     buffer_type m_buffer;
00258     size_type   m_len;
00259 };
00260 
00261 /* 
00262  * Typedefs for commonly encountered types
00263  */
00264 
00266 typedef basic_path<us_char_a_t, filesystem_traits<us_char_a_t> >       path_a;
00268 typedef basic_path<us_char_w_t, filesystem_traits<us_char_w_t> >       path_w;
00269 
00270 /* 
00271  * Operators
00272  */
00273 
00274 template<   ss_typename_param_k C
00275         ,   ss_typename_param_k T
00276         ,   ss_typename_param_k A
00277         >
00278 inline us_bool_t operator ==(basic_path<C, T, A> const &lhs, ss_typename_type_k basic_path<C, T, A>::char_type const *rhs)
00279 {
00280     return lhs.equal(rhs);
00281 }
00282 
00283 template<   ss_typename_param_k C
00284         ,   ss_typename_param_k T
00285         ,   ss_typename_param_k A
00286         >
00287 inline us_bool_t operator !=(basic_path<C, T, A> const &lhs, ss_typename_type_k basic_path<C, T, A>::char_type const *rhs)
00288 {
00289     return !lhs.equal(rhs);
00290 }
00291 
00292 template<   ss_typename_param_k C
00293         ,   ss_typename_param_k T
00294         ,   ss_typename_param_k A
00295         >
00296 inline us_bool_t operator ==(ss_typename_type_k basic_path<C, T, A>::char_type const *lhs, basic_path<C, T, A> const &rhs)
00297 {
00298     return rhs.equal(lhs);
00299 }
00300 
00301 template<   ss_typename_param_k C
00302         ,   ss_typename_param_k T
00303         ,   ss_typename_param_k A
00304         >
00305 inline us_bool_t operator !=(ss_typename_type_k basic_path<C, T, A>::char_type const *lhs, basic_path<C, T, A> const &rhs)
00306 {
00307     return !rhs.equal(lhs);
00308 }
00309 
00310 template<   ss_typename_param_k C
00311         ,   ss_typename_param_k T
00312         ,   ss_typename_param_k A
00313         >
00314 inline us_bool_t operator ==(basic_path<C, T, A> const &lhs, basic_path<C, T, A> const &rhs)
00315 {
00316     return lhs.equal(rhs);
00317 }
00318 
00319 template<   ss_typename_param_k C
00320         ,   ss_typename_param_k T
00321         ,   ss_typename_param_k A
00322         >
00323 inline us_bool_t operator !=(basic_path<C, T, A> const &lhs, basic_path<C, T, A> const &rhs)
00324 {
00325     return !lhs.equal(rhs);
00326 }
00327 
00328 // operator /
00329 template<   ss_typename_param_k C
00330         ,   ss_typename_param_k T
00331         ,   ss_typename_param_k A
00332         >
00333 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)
00334 {
00335     return basic_path<C, T, A>(lhs) /= rhs;
00336 }
00337 
00338 template<   ss_typename_param_k C
00339         ,   ss_typename_param_k T
00340         ,   ss_typename_param_k A
00341         >
00342 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)
00343 {
00344     return basic_path<C, T, A>(lhs) /= rhs;
00345 }
00346 
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, basic_path<C, T, A> const &rhs)
00352 {
00353     return basic_path<C, T, A>(lhs) /= rhs;
00354 }
00355 
00356 /* 
00357  * Helper functions
00358  */
00359 
00360 #if !defined(__STLSOFT_COMPILER_IS_MSVC) || \
00361     _MSC_VER >= 1100
00362 
00365 template<ss_typename_param_k C>
00366 inline basic_path<C> make_path(C const *path)
00367 {
00368     return basic_path<C>(path);
00369 }
00370 
00371 #endif /* !(_MSC_VER < 1100) */
00372 
00373 /* 
00374  * Shims
00375  */
00376 
00377 template<   ss_typename_param_k C
00378         ,   ss_typename_param_k T
00379         ,   ss_typename_param_k A
00380         >
00381 inline C const *c_str_ptr_null(basic_path<C, T, A> const &b)
00382 {
00383     return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00384 }
00385 
00386 template<   ss_typename_param_k C
00387         ,   ss_typename_param_k T
00388         ,   ss_typename_param_k A
00389         >
00390 inline C const *c_str_ptr(basic_path<C, T, A> const &b)
00391 {
00392     return stlsoft_ns_qual(c_str_ptr)(b.c_str());
00393 }
00394 
00395 template<   ss_typename_param_k C
00396         ,   ss_typename_param_k T
00397         ,   ss_typename_param_k A
00398         >
00399 inline us_size_t c_str_len(basic_path<C, T, A> const &b)
00400 {
00401     return stlsoft_ns_qual(c_str_len)(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 us_size_t c_str_size(basic_path<C, T, A> const &b)
00409 {
00410     return stlsoft_ns_qual(c_str_size)(b.c_str());
00411 }
00412 
00413 template<   ss_typename_param_k S
00414         ,   ss_typename_param_k C
00415         ,   ss_typename_param_k T
00416         ,   ss_typename_param_k A
00417         >
00418 inline S &operator <<(S & s, basic_path<C, T, A> const &b)
00419 {
00420     s << b.c_str();
00421 
00422     return s;
00423 }
00424 
00426 // Unit-testing
00427 
00428 #ifdef STLSOFT_UNITTEST
00429 
00430 namespace unittest
00431 {
00432     ss_bool_t test_unixstl_path(unittest_reporter *r)
00433     {
00434         using stlsoft::unittest::unittest_initialiser;
00435 
00436         ss_bool_t               bSuccess    =   true;
00437 
00438         unittest_initialiser    init(r, "UNIXSTL", "path", __FILE__);
00439 
00440         path_a  path1("..");
00441         path_a  path2(".\\..");
00442 
00443         if(!path1.equivalent(path2))
00444         {
00445             r->report("equivalence test failed ", __LINE__);
00446             bSuccess = false;
00447         }
00448 
00449         path_a  path3(path1);
00450 
00451         if(path1 != path3)
00452         {
00453             r->report("copy-construction failed ", __LINE__);
00454             bSuccess = false;
00455         }
00456 
00457         path3 /= "sub1";
00458 
00459         path_a  path4("..\\sub1");
00460 
00461         if(path4 != path3)
00462         {
00463             r->report("concatenation failed ", __LINE__);
00464             bSuccess = false;
00465         }
00466 
00467         return bSuccess;
00468     }
00469 
00470     unittest_registrar    unittest_unixstl_path(test_unixstl_path);
00471 
00472 } // namespace unittest
00473 
00474 #endif /* STLSOFT_UNITTEST */
00475 
00477 // Implementation
00478 
00479 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00480 
00481 template<   ss_typename_param_k C
00482         ,   ss_typename_param_k T
00483         ,   ss_typename_param_k A
00484         >
00485 inline void basic_path<C, T, A>::swap(basic_path<C, T, A> &rhs)
00486 {
00487     m_buffer.swap(rhs.m_buffer);
00488     std::swap(m_len, rhs.m_len);
00489 }
00490 
00491 template<   ss_typename_param_k C
00492         ,   ss_typename_param_k T
00493         ,   ss_typename_param_k A
00494         >
00495 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)
00496 {
00497     m_len = traits_type::str_len(traits_type::str_cat(&m_buffer[0], rhs));
00498 
00499     return *this;
00500 }
00501 
00502 template<   ss_typename_param_k C
00503         ,   ss_typename_param_k T
00504         ,   ss_typename_param_k A
00505         >
00506 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)
00507 {
00508     m_len = traits_type::str_len(traits_type::str_cat(&m_buffer[0], .c_str()));
00509 
00510     return *this;
00511 }
00512 
00513 template<   ss_typename_param_k C
00514         ,   ss_typename_param_k T
00515         ,   ss_typename_param_k A
00516         >
00517 inline /* ss_explicit_k */ basic_path<C, T, A>::basic_path(ss_typename_type_k basic_path<C, T, A>::char_type const *path)
00518     : m_len(0)
00519 {
00520     if(NULL != path)
00521     {
00522         us_size_t   cch =   traits_type::str_len(path);
00523 
00524         unixstl_assert(cch < m_buffer.size());
00525 
00526         traits_type::str_copy(&m_buffer[0], path);
00527 
00528         m_len = cch;
00529     }
00530 }
00531 
00532 template<   ss_typename_param_k C
00533     ,   ss_typename_param_k T
00534     ,   ss_typename_param_k A
00535     >
00536 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)
00537     : m_len(cch)
00538 {
00539     stlsoft_assert((NULL == path) == (0 == cch));
00540 
00541     if(0 != cch)
00542     {
00543         unixstl_assert(cch < m_buffer.size());
00544 
00545         traits_type::str_n_copy(&m_buffer[0], path, cch);
00546         m_buffer[cch] = '\0';
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(basic_path<C, T, A> const &rhs)
00555     : m_len(rhs.m_len)
00556 {
00557     traits_type::str_copy(&m_buffer[0], stlsoft_ns_qual(c_str_ptr)(rhs.m_buffer));
00558 }
00559 
00560 template<   ss_typename_param_k C
00561         ,   ss_typename_param_k T
00562         ,   ss_typename_param_k A
00563         >
00564 inline basic_path<C, T, A> &basic_path<C, T, A>::operator =(basic_path<C, T, A> const &path)
00565 {
00566     class_type  newPath(path);
00567 
00568     swap(newPath);
00569 
00570     return *this;
00571 }
00572 
00573 template<   ss_typename_param_k C
00574         ,   ss_typename_param_k T
00575         ,   ss_typename_param_k A
00576         >
00577 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)
00578 {
00579     class_type  newPath(path);
00580 
00581     swap(newPath);
00582 
00583     return *this;
00584 }
00585 
00586 template<   ss_typename_param_k C
00587         ,   ss_typename_param_k T
00588         ,   ss_typename_param_k A
00589         >
00590 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)
00591 {
00592     return class_type(s);
00593 }
00594 
00595 template<   ss_typename_param_k C
00596         ,   ss_typename_param_k T
00597         ,   ss_typename_param_k A
00598         >
00599 inline basic_path<C, T, A> &basic_path<C, T, A>::push(class_type const &rhs, us_bool_t bAddPathNameSeparator /* = false */)
00600 {
00601     return push(rhs.c_str(), bAddPathNameSeparator);
00602 }
00603 
00604 template<   ss_typename_param_k C
00605         ,   ss_typename_param_k T
00606         ,   ss_typename_param_k A
00607         >
00608 inline basic_path<C, T, A> &basic_path<C, T, A>::push(char_type const *rhs, us_bool_t bAddPathNameSeparator /* = false */)
00609 {
00610     class_type  newPath(*this);
00611 
00612     newPath.push_sep();
00613     newPath.concat_(rhs);
00614     if(bAddPathNameSeparator)
00615     {
00616         newPath.push_sep();
00617     }
00618 
00619     swap(newPath);
00620 
00621     return *this;
00622 }
00623 
00624 #if 0
00625 template<   ss_typename_param_k C
00626         ,   ss_typename_param_k T
00627         ,   ss_typename_param_k A
00628         >
00629 inline basic_path<C, T, A> &basic_path<C, T, A>::push_ext(class_type const &rhs, us_bool_t bAddPathNameSeparator /* = false */)
00630 {
00631 }
00632 #endif /* 0 */
00633 
00634 template<   ss_typename_param_k C
00635         ,   ss_typename_param_k T
00636         ,   ss_typename_param_k A
00637         >
00638 inline basic_path<C, T, A> &basic_path<C, T, A>::push_ext(char_type const *rhs, us_bool_t bAddPathNameSeparator /* = false */)
00639 {
00640     unixstl_assert(NULL != rhs);
00641 
00642     class_type  newPath(*this);
00643 
00644     newPath.pop_sep();
00645     if('.' != *rhs)
00646     {
00647         newPath.concat_(".");
00648     }
00649     newPath.concat_(rhs);
00650     if(bAddPathNameSeparator)
00651     {
00652         newPath.push_sep();
00653     }
00654 
00655     swap(newPath);
00656 
00657     return *this;
00658 }
00659 
00660 template<   ss_typename_param_k C
00661         ,   ss_typename_param_k T
00662         ,   ss_typename_param_k A
00663         >
00664 inline basic_path<C, T, A> &basic_path<C, T, A>::push_sep()
00665 {
00666     if(0 != m_len)
00667     {
00668         if(traits_type::path_name_separator() != m_buffer[m_len - 1])
00669         {
00670             unixstl_assert(m_len + 1 < m_buffer.size());
00671 
00672             m_buffer[m_len]     =   '\\';
00673             m_buffer[m_len + 1] =   '\0';
00674             ++m_len;
00675         }
00676     }
00677 
00678     return *this;
00679 }
00680 
00681 template<   ss_typename_param_k C
00682         ,   ss_typename_param_k T
00683         ,   ss_typename_param_k A
00684         >
00685 inline basic_path<C, T, A> &basic_path<C, T, A>::pop();
00686 
00687 template<   ss_typename_param_k C
00688         ,   ss_typename_param_k T
00689         ,   ss_typename_param_k A
00690         >
00691 inline basic_path<C, T, A> &basic_path<C, T, A>::pop_sep()
00692 {
00693     if(0 != m_len)
00694     {
00695         char_type *last = &m_buffer[m_len - 1];
00696 
00697         if(traits_type::has_dir_end(last))
00698         {
00699             m_buffer[m_len-- - 1] = '\0';
00700         }
00701     }
00702 
00703     return *this;
00704 }
00705 
00706 
00707 template<   ss_typename_param_k C
00708         ,   ss_typename_param_k T
00709         ,   ss_typename_param_k A
00710         >
00711 inline basic_path<C, T, A> &basic_path<C, T, A>::operator /=(basic_path<C, T, A> const &path)
00712 {
00713     return push(path);
00714 }
00715 
00716 template<   ss_typename_param_k C
00717         ,   ss_typename_param_k T
00718         ,   ss_typename_param_k A
00719         >
00720 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)
00721 {
00722     return push(path);
00723 }
00724 
00725 template<   ss_typename_param_k C
00726         ,   ss_typename_param_k T
00727         ,   ss_typename_param_k A
00728         >
00729 inline basic_path<C, T, A> &basic_path<C, T, A>::make_absolute(us_bool_t bRemoveTrailingPathNameSeparator /* = true */)
00730 {
00731     buffer_type buffer;
00732     us_dword_t  cch = traits_type::get_full_path_name(c_str(), buffer.size(), &buffer[0]);
00733     class_type  newPath(stlsoft_ns_qual(c_str_ptr)(buffer), cch);
00734 
00735     if(bRemoveTrailingPathNameSeparator)
00736     {
00737         newPath.pop_sep();
00738     }
00739 
00740     swap(newPath);
00741 
00742     return *this;
00743 }
00744 
00745 template<   ss_typename_param_k C
00746         ,   ss_typename_param_k T
00747         ,   ss_typename_param_k A
00748         >
00749 inline basic_path<C, T, A> &basic_path<C, T, A>::canonicalise(us_bool_t bRemoveTrailingPathNameSeparator /* = true */)
00750 {
00751     class_type  newPath(*this);
00752 
00753 #if 0
00754 
00755     us_dword_t  cchRhs  =   traits_type::get_full_path_name(rhs, rhs_.size(), &rhs_[0]);
00756 
00757 #if 0
00758     if( cchLhs == cchRhs + 1 &&
00759         !traits_type)
00760 #endif /* 0 */
00761 
00762     return cchLhs == cchRhs && 0 == traits_type::str_compare_no_case(stlsoft_ns_qual(c_str_ptr)(lhs_), stlsoft_ns_qual(c_str_ptr)(rhs_));
00763 #endif /* 0 */
00764 
00765     if(bRemoveTrailingPathNameSeparator)
00766     {
00767         newPath.pop_sep();
00768     }
00769 
00770     swap(newPath);
00771 
00772     return *this;
00773 }
00774 
00775 
00776 
00777 template<   ss_typename_param_k C
00778         ,   ss_typename_param_k T
00779         ,   ss_typename_param_k A
00780         >
00781 inline ss_typename_type_k basic_path<C, T, A>::size_type basic_path<C, T, A>::length() const
00782 {
00783     return m_len;
00784 }
00785 
00786 template<   ss_typename_param_k C
00787         ,   ss_typename_param_k T
00788         ,   ss_typename_param_k A
00789         >
00790 inline ss_typename_type_k basic_path<C, T, A>::char_type const *basic_path<C, T, A>::c_str() const
00791 {
00792     return stlsoft_ns_qual(c_str_ptr)(m_buffer);
00793 }
00794 
00795 template<   ss_typename_param_k C
00796         ,   ss_typename_param_k T
00797         ,   ss_typename_param_k A
00798         >
00799 inline us_bool_t basic_path<C, T, A>::equivalent(basic_path<C, T, A> const &rhs) const
00800 {
00801     return equivalent(rhs.c_str());
00802 }
00803 
00804 template<   ss_typename_param_k C
00805         ,   ss_typename_param_k T
00806         ,   ss_typename_param_k A
00807         >
00808 inline us_bool_t basic_path<C, T, A>::equivalent(ss_typename_type_k basic_path<C, T, A>::char_type const *rhs) const
00809 {
00810     class_type  lhs_(*this);
00811     class_type  rhs_(rhs);
00812 
00813     return lhs_.canonicalise(false).make_absolute(true) == rhs_.canonicalise(false).make_absolute(true);
00814 }
00815 
00816 template<   ss_typename_param_k C
00817         ,   ss_typename_param_k T
00818         ,   ss_typename_param_k A
00819         >
00820 inline us_bool_t basic_path<C, T, A>::equal(basic_path<C, T, A> const &rhs) const
00821 {
00822     return equal(rhs.c_str());
00823 }
00824 
00825 template<   ss_typename_param_k C
00826         ,   ss_typename_param_k T
00827         ,   ss_typename_param_k A
00828         >
00829 inline us_bool_t basic_path<C, T, A>::equal(ss_typename_type_k basic_path<C, T, A>::char_type const *rhs) const
00830 {
00831     return 0 == traits_type::str_compare_no_case(stlsoft_ns_qual(c_str_ptr)(m_buffer), stlsoft_ns_qual(c_str_ptr)(rhs));
00832 }
00833 
00834 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00835 
00836 /* 
00837 
00839 
00840 /* 
00841 
00842 #ifndef _UNIXSTL_NO_NAMESPACE
00843 # if defined(_STLSOFT_NO_NAMESPACE) || \
00844      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00845 } // namespace unixstl
00846 # else
00847 } // namespace unixstl_project
00848 } // namespace stlsoft
00849 # endif /* _STLSOFT_NO_NAMESPACE */
00850 #endif /* !_UNIXSTL_NO_NAMESPACE */
00851 
00852 /* 
00853  * Namespace
00854  *
00855  * The string access shims exist either in the stlsoft namespace, or in the
00856  * global namespace. This is required by the lookup rules.
00857  *
00858  */
00859 
00860 #ifndef _UNIXSTL_NO_NAMESPACE
00861 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00862      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00863 namespace stlsoft
00864 {
00865 # else /* ? _STLSOFT_NO_NAMESPACE */
00866 /* There is no stlsoft namespace, so must define in the global namespace */
00867 # endif /* !_STLSOFT_NO_NAMESPACE */
00868 
00869 using ::unixstl::c_str_ptr_null;
00870 
00871 using ::unixstl::c_str_ptr;
00872 
00873 using ::unixstl::c_str_len;
00874 
00875 using ::unixstl::c_str_size;
00876 
00877 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00878      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00879 } // namespace stlsoft
00880 # else /* ? _STLSOFT_NO_NAMESPACE */
00881 /* There is no stlsoft namespace, so must define in the global namespace */
00882 # endif /* !_STLSOFT_NO_NAMESPACE */
00883 #endif /* !_UNIXSTL_NO_NAMESPACE */
00884 
00885 /* 
00886 
00887 #endif /* UNIXSTL_INCL_H_UNIXSTL_PATH */
00888 
00889 /* 

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