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_module_directory.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_module_directory.h
00003  *
00004  * Purpose:     Simple class that gets, and makes accessible, the module's
00005  *              directory.
00006  *
00007  * Created:     5th June 2003
00008  * Updated:     11th September 2004
00009  *
00010  * Home:        http://stlsoft.org/
00011  *
00012  * Copyright (c) 2003-2004, Matthew Wilson and Synesis Software
00013  * All rights reserved.
00014  *
00015  * Redistribution and use in source and binary forms, with or without
00016  * modification, are permitted provided that the following conditions are met:
00017  *
00018  * - Redistributions of source code must retain the above copyright notice, this
00019  *   list of conditions and the following disclaimer.
00020  * - Redistributions in binary form must reproduce the above copyright notice,
00021  *   this list of conditions and the following disclaimer in the documentation
00022  *   and/or other materials provided with the distribution.
00023  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00024  *   any contributors may be used to endorse or promote products derived from
00025  *   this software without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  *
00039  * 
00040 
00041 
00045 
00046 #ifndef WINSTL_INCL_H_WINSTL_MODULE_DIRECTORY
00047 #define WINSTL_INCL_H_WINSTL_MODULE_DIRECTORY
00048 
00049 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00050 # define WINSTL_VER_H_WINSTL_MODULE_DIRECTORY_MAJOR     2
00051 # define WINSTL_VER_H_WINSTL_MODULE_DIRECTORY_MINOR     0
00052 # define WINSTL_VER_H_WINSTL_MODULE_DIRECTORY_REVISION  1
00053 # define WINSTL_VER_H_WINSTL_MODULE_DIRECTORY_EDIT      23
00054 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00055 
00056 /* 
00057  * Compatibility
00058  */
00059 
00060 /*
00061 [Incompatibilies-start]
00062 __STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
00063 [Incompatibilies-end]
00064  */
00065 
00066 /* 
00067  * Includes
00068  */
00069 
00070 #ifndef WINSTL_INCL_H_WINSTL
00071 # include "winstl.h"                    // Include the WinSTL root header
00072 #endif /* !WINSTL_INCL_H_WINSTL */
00073 
00074 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00075     _MSC_VER < 1200
00076 # error winstl_module_directory.h is not compatible with Visual C++ 5.0 or earlier
00077 #endif /* _MSC_VER < 1200 */
00078 
00079 #ifndef WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS
00080 # include "winstl_filesystem_traits.h"  // filesystem_traits
00081 #endif /* !WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS */
00082 #ifndef WINSTL_INCL_H_WINSTL_STRING_ACCESS
00083 # include "winstl_string_access.h"                  // winstl::string_access
00084 #endif /* WINSTL_INCL_H_WINSTL_STRING_ACCESS */
00085 #ifndef WINSTL_INCL_H_WINSTL_FILE_PATH_BUFFER
00086 # include "winstl_file_path_buffer.h"   // basic_file_path_buffer
00087 #endif /* !WINSTL_INCL_H_WINSTL_FILE_PATH_BUFFER */
00088 #ifdef STLSOFT_UNITTEST
00089 # include <stdlib.h>                    // malloc(), free()
00090 #endif /* STLSOFT_UNITTEST */
00091 
00092 /* 
00093  * Namespace
00094  */
00095 
00096 #ifndef _WINSTL_NO_NAMESPACE
00097 # if defined(_STLSOFT_NO_NAMESPACE) || \
00098      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00099 /* There is no stlsoft namespace, so must define ::winstl */
00100 namespace winstl
00101 {
00102 # else
00103 /* Define stlsoft::winstl_project */
00104 
00105 namespace stlsoft
00106 {
00107 
00108 namespace winstl_project
00109 {
00110 
00111 # endif /* _STLSOFT_NO_NAMESPACE */
00112 #endif /* !_WINSTL_NO_NAMESPACE */
00113 
00114 /* 
00115 
00118 
00122 
00127 
00128 /* 
00129  * basic_module_directory
00130  *
00131  * This class determines the directory of a module, and effectively acts as a
00132  * C-string of its value.
00133  */
00134 
00174 template<   ss_typename_param_k C
00175 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00176         ,   ss_typename_param_k T = filesystem_traits<C>
00177 #else
00178         ,   ss_typename_param_k T /* = filesystem_traits<C> */
00179 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00180         >
00181 class basic_module_directory
00182 {
00183 public:
00185     typedef C                               char_type;
00187     typedef T                               traits_type;
00189     typedef basic_module_directory<C, T>   class_type;
00191     typedef ws_size_t                       size_type;
00192 
00193 // Construction
00194 public:
00196     ss_explicit_k basic_module_directory(HINSTANCE hinst = NULL);
00197 
00198 // Operations
00199 public:
00201     static size_type   get_path(HINSTANCE hinst, ws_char_a_t *buffer, size_type cchBuffer);
00203     static size_type   get_path(HINSTANCE hinst, ws_char_w_t *buffer, size_type cchBuffer);
00204 
00205 // Attributes
00206 public:
00208     char_type const *get_path() const;
00210     char_type const *c_str() const;
00212     size_type       length() const;
00213 
00214 // Conversions
00215 public:
00217     operator char_type const *() const
00218     {
00219         return get_path();
00220     }
00221 
00222 // Members
00223 private:
00224     basic_file_path_buffer<char_type>   m_dir;
00225     size_type const                     m_len;
00226 
00227 // Not to be implemented
00228 private:
00229     basic_module_directory(const class_type &);
00230     basic_module_directory &operator =(const class_type &);
00231 };
00232 
00233 /* 
00234  * Typedefs for commonly encountered types
00235  */
00236 
00238 typedef basic_module_directory<ws_char_a_t, filesystem_traits<ws_char_a_t> >     module_directory_a;
00240 typedef basic_module_directory<ws_char_w_t, filesystem_traits<ws_char_w_t> >     module_directory_w;
00242 typedef basic_module_directory<TCHAR, filesystem_traits<TCHAR> >                 module_directory;
00243 
00244 /* 
00245  * Shims
00246  */
00247 
00248 template<   ss_typename_param_k C
00249         ,   ss_typename_param_k T
00250         >
00251 inline C const *c_str_ptr_null(basic_module_directory<C, T> const &b)
00252 {
00253     return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00254 }
00255 
00256 template<   ss_typename_param_k C
00257         ,   ss_typename_param_k T
00258         >
00259 inline C const *c_str_ptr(basic_module_directory<C, T> const &b)
00260 {
00261     return stlsoft_ns_qual(c_str_ptr)(b.c_str());
00262 }
00263 
00264 template<   ss_typename_param_k C
00265         ,   ss_typename_param_k T
00266         >
00267 inline ws_size_t c_str_len(basic_module_directory<C, T> const &b)
00268 {
00269     return stlsoft_ns_qual(c_str_len)(b.c_str());
00270 }
00271 
00272 template<   ss_typename_param_k C
00273         ,   ss_typename_param_k T
00274         >
00275 inline ws_size_t c_str_size(basic_module_directory<C, T> const &b)
00276 {
00277     return stlsoft_ns_qual(c_str_size)(b.c_str());
00278 }
00279 
00280 template<   ss_typename_param_k S
00281         ,   ss_typename_param_k C
00282         ,   ss_typename_param_k T
00283         >
00284 inline S &operator <<(S & s, basic_module_directory<C, T> const &b)
00285 {
00286     s << b.c_str();
00287 
00288     return s;
00289 }
00290 
00291 /* 
00292  * Unit-testing
00293  */
00294 
00295 #ifdef STLSOFT_UNITTEST
00296 
00297 namespace unittest
00298 {
00299     ss_bool_t test_winstl_module_directory(unittest_reporter *r)
00300     {
00301         using stlsoft::unittest::unittest_initialiser;
00302 
00303         ss_bool_t               bSuccess    =   true;
00304 
00305         unittest_initialiser    init(r, "WinSTL", "module_directory", __FILE__);
00306 
00307         HINSTANCE               hinst   =   ::GetModuleHandle(NULL);
00308 
00309         //
00310         if(module_directory_a(hinst).length() != module_directory_w(hinst).length())
00311         {
00312             r->report("Disagreement on length() between ANSI and Unicode instantiations", __LINE__);
00313             bSuccess = false;
00314         }
00315 
00316         module_directory        mw(hinst);
00317 
00318         //
00319         if(module_directory_a(hinst).length() != module_directory_w(hinst).length())
00320         {
00321             r->report("Disagreement on length() between ANSI and Unicode instantiations", __LINE__);
00322             bSuccess = false;
00323         }
00324 
00325         module_directory::size_type cch     =   module_directory::get_path(hinst, static_cast<ws_char_a_t*>(NULL), 0);
00326         char                        *buff   =   (char*)malloc(1 + cch);
00327 
00328         if(NULL == buff)
00329         {
00330             r->report("Could not allocate buffer", __LINE__);
00331             bSuccess = false;
00332         }
00333         else
00334         {
00335             module_directory::get_path(hinst, buff, 1 + cch);
00336 
00337             if(0 != strcmp(buff, mw.get_path()))
00338             {
00339                 r->report("Disagreement on contents between get_path (static) and get_path()", __LINE__);
00340                 bSuccess = false;
00341             }
00342 
00343             if(0 != strcmp(buff, mw.c_str()))
00344             {
00345                 r->report("Disagreement on contents between get_path (static) and c_str()", __LINE__);
00346                 bSuccess = false;
00347             }
00348 
00349             if(0 != strcmp(buff, mw))
00350             {
00351                 r->report("Disagreement on contents between get_path (static) and implicit conversion operator", __LINE__);
00352                 bSuccess = false;
00353             }
00354 
00355             free(buff);
00356         }
00357 
00358         return bSuccess;
00359     }
00360 
00361     unittest_registrar    unittest_winstl_module_directory(test_winstl_module_directory);
00362 
00363 } // namespace unittest
00364 
00365 #endif /* STLSOFT_UNITTEST */
00366 
00367 /* 
00368  * Implementation
00369  */
00370 
00371 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00372 
00373 template<   ss_typename_param_k C
00374         ,   ss_typename_param_k T
00375         >
00376 inline basic_module_directory<C, T>::basic_module_directory(HINSTANCE hinst /* = NULL */)
00377     : m_len(get_path(hinst, &m_dir[0], m_dir.size()))
00378 {}
00379 
00380 template<   ss_typename_param_k C
00381         ,   ss_typename_param_k T
00382         >
00383 inline /* static */ ss_typename_type_k basic_module_directory<C, T>::size_type basic_module_directory<C, T>::get_path(HINSTANCE hinst, ws_char_a_t *buffer, ss_typename_type_k basic_module_directory<C, T>::size_type cchBuffer)
00384 {
00385     basic_file_path_buffer<ws_char_a_t> path;
00386     ws_dword_t                          dw  =   ::GetModuleFileNameA(hinst, &path[0], path.size());
00387 
00388     if(0 == dw)
00389     {
00390         path[0] = '\0';
00391     }
00392     else
00393     {
00394         basic_file_path_buffer<ws_char_a_t> directory;
00395         ws_char_a_t                         *filePart;
00396 
00397         dw = ::GetFullPathNameA(stlsoft_ns_qual(c_str_ptr)(path), directory.size(), &directory[0], &filePart);
00398 
00399         if(0 == dw)
00400         {
00401             path[0] = '\0';
00402         }
00403         else
00404         {
00405             *filePart = '\0';
00406 
00407             lstrcpynA(buffer, stlsoft_ns_qual(c_str_ptr)(directory), cchBuffer);
00408         }
00409     }
00410 
00411     return dw;
00412 }
00413 
00414 template<   ss_typename_param_k C
00415         ,   ss_typename_param_k T
00416         >
00417 inline /* static */ ss_typename_type_k basic_module_directory<C, T>::size_type basic_module_directory<C, T>::get_path(HINSTANCE hinst, ws_char_w_t *buffer, ss_typename_type_k basic_module_directory<C, T>::size_type cchBuffer)
00418 {
00419     basic_file_path_buffer<ws_char_w_t> path;
00420     ws_dword_t                          dw  =   ::GetModuleFileNameW(hinst, &path[0], path.size());
00421 
00422     if(0 == dw)
00423     {
00424         path[0] = '\0';
00425     }
00426     else
00427     {
00428         basic_file_path_buffer<ws_char_w_t> directory;
00429         ws_char_w_t                         *filePart;
00430 
00431         dw = ::GetFullPathNameW(stlsoft_ns_qual(c_str_ptr)(path), directory.size(), &directory[0], &filePart);
00432 
00433         if(0 == dw)
00434         {
00435             path[0] = '\0';
00436         }
00437         else
00438         {
00439             *filePart = '\0';
00440 
00441             lstrcpynW(buffer, stlsoft_ns_qual(c_str_ptr)(directory), cchBuffer);
00442         }
00443     }
00444 
00445     return dw;
00446 }
00447 
00448 template<   ss_typename_param_k C
00449         ,   ss_typename_param_k T
00450         >
00451 inline ss_typename_type_k basic_module_directory<C, T>::char_type const *basic_module_directory<C, T>::get_path() const
00452 {
00453     return stlsoft_ns_qual(c_str_ptr)(m_dir);
00454 }
00455 
00456 template<   ss_typename_param_k C
00457         ,   ss_typename_param_k T
00458         >
00459 inline ss_typename_type_k basic_module_directory<C, T>::char_type const *basic_module_directory<C, T>::c_str() const
00460 {
00461     return get_path();
00462 }
00463 
00464 template<   ss_typename_param_k C
00465         ,   ss_typename_param_k T
00466         >
00467 inline ss_typename_type_k basic_module_directory<C, T>::size_type basic_module_directory<C, T>::length() const
00468 {
00469     return m_len;
00470 }
00471 
00472 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00473 
00474 /* 
00475 
00477 
00478 /* 
00479 
00480 #ifndef _WINSTL_NO_NAMESPACE
00481 # if defined(_STLSOFT_NO_NAMESPACE) || \
00482      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00483 } // namespace winstl
00484 # else
00485 } // namespace winstl_project
00486 } // namespace stlsoft
00487 # endif /* _STLSOFT_NO_NAMESPACE */
00488 #endif /* !_WINSTL_NO_NAMESPACE */
00489 
00490 /* 
00491  * Namespace
00492  *
00493  * The string access shims exist either in the stlsoft namespace, or in the
00494  * global namespace. This is required by the lookup rules.
00495  *
00496  */
00497 
00498 #ifndef _WINSTL_NO_NAMESPACE
00499 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00500      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00501 namespace stlsoft
00502 {
00503 # else /* ? _STLSOFT_NO_NAMESPACE */
00504 /* There is no stlsoft namespace, so must define in the global namespace */
00505 # endif /* !_STLSOFT_NO_NAMESPACE */
00506 
00507 using ::winstl::c_str_ptr_null;
00508 
00509 using ::winstl::c_str_ptr;
00510 
00511 using ::winstl::c_str_len;
00512 
00513 using ::winstl::c_str_size;
00514 
00515 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00516      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00517 } // namespace stlsoft
00518 # else /* ? _STLSOFT_NO_NAMESPACE */
00519 /* There is no stlsoft namespace, so must define in the global namespace */
00520 # endif /* !_STLSOFT_NO_NAMESPACE */
00521 #endif /* !_WINSTL_NO_NAMESPACE */
00522 
00523 /* 
00524 
00525 #endif /* WINSTL_INCL_H_WINSTL_MODULE_DIRECTORY */
00526 
00527 /* 

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