Free Web Hosting by Netfirms
Web Hosting by Netfirms | Free Domain Names by Netfirms


// .h: interface for the  class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX__H__AF0A26E0_1620_44F9_A9BA_28A834164E63__INCLUDED_)
#define AFX__H__AF0A26E0_1620_44F9_A9BA_28A834164E63__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "windows.h"

#include "utillib.h"



// also add  utillib.cpp
#include <tchar.h>


//---------------------------------------------------------------------------------------------------
// NOTES
// Comments on comments :)
// The comments are added to the declarations so they appear in intellisense when hovering over
// a method. Feel free to remove the comments when you have memorised all of the methods
//
// Error handling
// The error handling methodology is as follows:
// 1. If a method mirrors an API call it exposes that error handling approach whenever possible
// 2. Exceptions are caught and converted to NULL return values wherever possible
//---------------------------------------------------------------------------------------------------
template <class T> class GenPath
{
public:
   // Lifecycle
   GenPath();              // constructor

   GenPath(const wchar_t*);   // constructor
   GenPath(const char*);            // constructor

   GenPath( const T s );            // T constructor
   GenPath( const GenPath& ); // copy constructor
   ~GenPath();             // destructor

   // Operators
   bool operator==(const GenPath&) const;
   bool operator!=(const GenPath&) const;
   GenPath&  operator=(const GenPath& p) throw()
   {
      if( &p != this )
      {
         m_sPath = p.m_sPath;
      }
      return *this;
   }

   GenPath& operator=( const T& s ) throw()
   {
      if( &s != (&m_sPath) )
      {
         m_sPath = s;
      }
      return *this;
   }

   GenPath& operator=( char* p ) throw()
   {
      m_sPath = p;
      return *this;
   }
   operator wchar_t*() const throw();


   template < class U >
   inline friend bool operator==( const U* lhs, const GenPath& rhs )
   { return T(lhs) == rhs.m_sPath };

   template < class U >
   inline friend bool operator==(  const GenPath& lhs , const U* rhs)
   { return lhs.m_sPath == T(rhs) };


   template < class U >
   inline friend bool operator==( const U lhs, const GenPath& rhs ) { return lhs == rhs.m_sPath };

   template < class U >
   inline friend bool operator==(  const GenPath& lhs , const U rhs) { return lhs.m_sPath == rhs };

   // Operations
   void  Clear();                   // Resets the member string to ""

   // Getters
   const char* GetString() const;            // Returns member string
   const WCHAR*   GetWString() const;              // Returns member string as WCHAR

   T     GetDriveLetter() const;          // Gets drive letter
   int      GetDriveNo() const;              // Gets drive no.
   T     GetExtension() const;            // Gets extension not including '.'
   T     GetFilename() const;          // Gets filename component from path
   T     GetDirectory() const;            // Gets directory component from path
   bool  SplitPath( T& sDrive, T& sDir, T& sFname, T& sExt ) const;// Breaks path into it's components

   // Setters
   T     SetDriveLetter( const T& d );    // Sets path's drive letter
   bool  SetExtension(const T& sExt );    // Sets filename extension
   T     Append( const T& sAppend );         // Appends string to path

   T     ToCurrentDirectory();            // Sets path to current directory for current process
   T     ToModulePath();                  // Sets path to path of current module
   T     ToModulePathAndFilename();       // Sets path to path of current module and filename
   T     ToModulePathAndFilename(HMODULE hInst);

   T     ToTempPath();                 // Sets path to designated temp directory
   T     ToTempPathAndFilename(const T sPrefixString); // Sets to prefixed temp path and filename

   T     ToWindowsDirectory();            // Sets path to the windows directory
   T     ToSystemDirectory();          // Sets path to the system directory

   bool  MakePath( const T sDrive, const T sDir, const T sFname, const T sExt );// Constructs a path from it's components
   T     ReplaceFilename( const T& sNewFileName ); // Replaces filename component of path
   T     ReplaceExt( const T& sNewExt );     // Replaces extension component of path

   // Enquiry
   DWORD FileAttributes() const;          // Gets the file attributes
   bool  FileExists() const;              // Tests file exists
   DWORD GetFileSize() const;          // Gets file size in bytes
   bool  IsDirectoryEmpty() const;        // Tests if directory is empty
   bool  IsEmpty() const;              // Tests if path is empty string
   bool  IsValidPath() const;          // Tests for valid path components
   bool  PathExists() const;              // Tests path exists
   int      Size() const;                 // Returns size of path in characters

private:
   // Utility
   int      compare_no_case( const T& s ) const;// Compares without case
   T     Data() { return m_sPath; }                      // Returns the member class

   // Data
   T m_sPath;

   CUtilLib* m_pImpl;

};


//////////////////////////////////////////////////////////////////////////
// Constructors
//////////////////////////////////////////////////////////////////////////

/*int WideCharToMultiByte(
  UINT CodePage,            // code page
  DWORD dwFlags,            // performance and mapping flags
  LPCWSTR lpWideCharStr,    // wide-character string
  int cchWideChar,          // number of chars in string
  LPSTR lpMultiByteStr,     // buffer for new string
  int cbMultiByte,          // size of buffer
  LPCSTR lpDefaultChar,     // default for unmappable chars
  LPBOOL lpUsedDefaultChar  // set when default char used
);
*/

/*---------------------------------------------------------------*/
// Procedure....: GenPath( const wchar_t* p ) 
// Description..: const wchar_t* constructor
// Params.......: void
/*---------------------------------------------------------------*/
template <class T> GenPath<T>::GenPath( const wchar_t* p )
{
   char buf[MAX_PATH] ={0};
   ::WideCharToMultiByte(0, 0, p, -1, buf, MAX_PATH, 0, 0);
   m_sPath =buf;
}

/*---------------------------------------------------------------*/
// Procedure....: GenPath( char* p ) 
// Description..: char* constructor
// Params.......: void
/*---------------------------------------------------------------*/
template <class T> GenPath<T>::GenPath( const char* p ) : m_sPath( p )
{
}

/*---------------------------------------------------------------*/
// Procedure....: GenPath() 
// Description..: Default constructor
// Params.......: void
/*---------------------------------------------------------------*/
template <class T> GenPath<T>::GenPath() : m_sPath("")
{
}

/*---------------------------------------------------------------*/
// Procedure....: GenPath( const T _s )
// Description..: T constructor
// Params.......: T 
/*---------------------------------------------------------------*/
template <class T> GenPath<T>::GenPath( const T _s ) : m_sPath( _s)
{
}

/*---------------------------------------------------------------*/
// Procedure....: GenPath(const GenPath& p )
// Description..: Copy constructor
// Params.......: const GenPath&
/*---------------------------------------------------------------*/
template <class T> GenPath<T>::GenPath(const GenPath& p )
{
   if( &p != this )
   {
      m_sPath = p.m_sPath;
   }
}

//////////////////////////////////////////////////////////////////////////
// Destructor
//////////////////////////////////////////////////////////////////////////
template <class T> GenPath<T>::~GenPath()
{
};

//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------*/
// Procedure....: operator==(const GenPath& right) const
// Description..: equivalence operator for GenPath
// Params.......: const GenPath& 
// Returns......: bool
/*---------------------------------------------------------------*/
template <class T> bool GenPath<T>::operator==(const GenPath& right) const
{
   if ( m_sPath.size() != right.m_sPath.size() )
      return false;
   else
   {
      T::const_iterator p = m_sPath.begin();
      T::const_iterator p2 = right.m_sPath.begin();
      T::const_iterator end = m_sPath.end();
      while( p != end )
      {
         if( toupper( *p ) != toupper( *p2 ) )
            return false;
         p++;
         p2++;
      }
   }
   return true;
}

/*---------------------------------------------------------------*/
// Procedure....: operator !=( const GenPath& right ) const
// Description..: Not equivalent operator for GenPath
// Params.......: const GenPath& 
// Returns......: bool
/*---------------------------------------------------------------*/
template <class T> bool GenPath<T>::operator !=( const GenPath& right ) const
{
   if ( m_sPath.size() != right.m_sPath.size() )
      return true;
   else
   {
      T::const_iterator p = m_sPath.begin();
      T::const_iterator p2 = right.m_sPath.begin();
      T::const_iterator end = m_sPath.end();
      while( p != end )
      {
         if( toupper( *p ) != toupper( *p2 ) )
            return true;
         p++;
         p2++;
      }
   }
   return false;
}

//////////////////////////////////////////////////////////////////////////
// OPERATIONS
//////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------*/
// Procedure....: Clear()
// Description..: sets m_sPath to empty string
// Params.......: void
// Returns......: void
/*---------------------------------------------------------------*/
template <class T> void GenPath<T>::Clear()
{
   m_sPath.clear();
}

/////////////////////////////////////////////////////////////////////////////
// ACCESS
// Getters
//////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------*/
// Procedure....: GetString() const
// Description..: returns member string
// Params.......: void
// Returns......: T containing member path
/*---------------------------------------------------------------*/
template <class T> const char* GenPath<T>::GetString() const
{
   return ( m_sPath.c_str() );
}

/*---------------------------------------------------------------*/
// Procedure....: GetWString() const
// Description..: returns member string as unsigned short*
// Params.......: void
// Returns......: const WCHAR* containing member path
/*---------------------------------------------------------------*/
template <class T> const WCHAR* GenPath<T>::GetWString() const
{
   WCHAR wsz[MAX_PATH*2]={0};
   if( MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, m_sPath.c_str(), -1, wsz, MAX_PATH * 2) )
      return wsz;
   return NULL;
}

/*---------------------------------------------------------------*/
// Procedure....: GetDriveNo() const
// Description..: Gets drive no.
// Params.......: void
// Returns......: int containing drive number 
// On failure...: -1
/*---------------------------------------------------------------*/
template <class T> int GenPath<T>::GetDriveNo() const
{
   int iRet = ::PathGetDriveNumber( m_sPath.c_str() );
   if(iRet > -1 && iRet < 26)
      return iRet;

   return -1;
}

/*---------------------------------------------------------------*/
// Procedure....: GetExtension() const
// Description..: Gets extension from current path member
//            Consists of digits only not '.'
// Params.......: void
// Returns......: T containing extension 
// On failure...: empty string
/*---------------------------------------------------------------*/
template <class T> T  GenPath<T>::GetExtension() const
{
   T::size_type iFind =m_sPath.rfind('.');
   T sExt(m_sPath);
   if( iFind != ( T::npos ) )
   {
      sExt.erase(0, iFind +1);
      return   sExt;
   }

   else
   {
      return "";
   }
}

/*---------------------------------------------------------------*/
// Procedure....: GetDriveLetter() const
// Description..: Gets drive letter
// Params.......: void
// Returns......: T consisting of the drive letter 
// On failure...: T("")
/*---------------------------------------------------------------*/
template < class T > T GenPath<T>::GetDriveLetter() const
{
   T::size_type iFind =m_sPath.find(":\\");

   if( iFind != ( T::npos ) )
   {
      T sRet;
      return sRet = m_sPath.at( iFind -1 );
   }

   else
   {
      return "";

   }
}

/*---------------------------------------------------------------*/
// Procedure....: GetFilename() const
// Description..: Gets filename component from current path member
//            Removes leading '\' characters and trailing '.' characters
// Params.......: void
// Returns......: T containing filename component 
// On failure...: empty string
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::GetFilename() const
{
   if( IsValidPath() )
   {
      TCHAR szFname[MAX_PATH]={0};

      _tsplitpath( m_sPath.c_str(), NULL, NULL, szFname , NULL );

      T sFname( szFname );

      if('\\' == *(sFname.begin() ) )
      {
         sFname.erase(0, 1);
         //sFname = UtilLib::mid( sFname, 1 );
      }

      T::size_type iFind = sFname.rfind('.');

      if( iFind != T::npos )
      {
         sFname.resize( iFind );
      }

      return sFname;
   }

   else
   {
      return "";
   }
}

/*---------------------------------------------------------------*/
// Procedure....: GetDirectory() const
// Description..: Gets Directory component from current path member
//            Removes leading or trailing '\' characters
// Params.......: void
// Returns......: T containing directory component 
// On failure...: empty string
/*---------------------------------------------------------------*/
template<class T> T GenPath<T>::GetDirectory() const
{
   if( IsValidPath() )
   {
      TCHAR szDir[MAX_PATH]={0};

      _tsplitpath( m_sPath.c_str(), NULL, szDir, NULL, NULL );

      T sDir( szDir );

      if('\\' == *( sDir.begin() ) )
      {
         sDir.erase(0, 1);
      }


      if( *( sDir.end()-1 ) == '\\' )
      {
         sDir.resize( ( sDir.size() -1 ) );
      }

      return sDir;
   }
   return "";
}

/*---------------------------------------------------------------*/
// Procedure....: SplitPath( T& sDrive, T& sDir, T& sFname, T& sExt ) const
// Description..: Breaks the path into it's components
// Params.......: T sDrive, T sDir, T sFname, T sEx
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template < class T > bool GenPath<T>::SplitPath( T& sDrive, T& sDir, T& sFname, T& sExt ) const
{
   TCHAR szDrive[20]={0};
   TCHAR szDir[MAX_PATH]={0};
   TCHAR szFname[MAX_PATH]={0};
   TCHAR szExt[20]={0};

   _tsplitpath( m_sPath.c_str(), szDrive, szDir, szFname, szExt );

   sDrive   =  szDrive;
   sDir  =  szDir;
   sFname   =  szFname;
   sExt  =  szExt;

   return false;
}

/////////////////////////////////////////////////////////////////////////////
// ACCESS
// Setters
//////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------*/
// Procedure....: SetExtension(const T& sExt)
// Description..: Sets filename extension
// Params.......: const T& extension
// Returns......: bool 
// On failure...: false
/*---------------------------------------------------------------*/
template < class T > bool GenPath<T>::SetExtension(const T& sExt)
{
   int iFound = m_sPath.rfind('.');
   if(   iFound != T::npos )
   {
      m_sPath.resize( iFound );
   }
   m_sPath.append( "." );

   m_sPath.append(sExt);

   return true;
}

/*---------------------------------------------------------------*/
// Procedure....: SetDriveLetter( const T& d )
// Description..: Sets path's drive letter
// Params.......: const T& d
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template<class T> T GenPath<T>::SetDriveLetter( const T& d )
{
   if( isalpha( d.at(0) ) )
   {
      m_sPath.at(0) = d.at(0);
      return m_sPath;
   }
   return "";
}

/*---------------------------------------------------------------*/
// Procedure....: Append( const T& sAppend )
// Description..: Appends string to path
// Params.......: const T& sAppend
// Returns......: T constructed from the m_sPath with it's appended string
/*---------------------------------------------------------------*/
template<class T> T GenPath<T>::Append( const T& sAppend )
{
   return   m_sPath.append( sAppend );
}


/*---------------------------------------------------------------*/
// Procedure....: MakePath(const T sDrive, const T sDir, const T sFname, const T sExt)
// Description..: Builds a path from it's components
/*
The following arguments must contain the path elements:

sDrive

Contains a letter (A, B, and so on) corresponding to the desired drive and an optional trailing colon. 
MakePath inserts the colon automatically in the composite path if it is missing. 
If drive is a null character or an empty string, no drive letter and colon appear in the composite path string.

sDir

Contains the path of directories, not including the drive designator or the actual filename. 
The trailing slash is optional, and either a forward slash (/) or a backslash (\) or both may be used in a single dir argument. 
If a trailing slash (/ or \) is not specified, it is inserted automatically. 
If sDir is a null character or an empty string, no slash is inserted in the composite path string.

sFname

Contains the base filename without an extension. 
If fname is NULL or points to an empty string, no filename is inserted in the path.

sExt

Contains the actual filename extension, with or without a leading period (.). 
MakePath inserts the period automatically if it does not appear in ext. 
If sExt is a null character or an empty string, no period is inserted in the composite path string.
*/
// Params.......: const T sDrive, const T sDir, const T sFname, const T sExt
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template<class T> bool GenPath<T>::MakePath(const T sDrive, const T sDir, const T sFname, const T sExt)
{
   TCHAR szPath[MAX_PATH] ={ 0 };

   _tmakepath(szPath, sDrive.c_str(), sDir.c_str(), sFname.c_str(), sExt.c_str() );

   m_sPath = szPath;

   return true;

   return false;
}

/*---------------------------------------------------------------*/
// Procedure....: ToModulePath() const
// Description..: Sets path to path of current module 
//            NOT including filename or extension
// Params.......: 
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template<class T> T GenPath<T>::ToModulePath()
{
   TCHAR szBuf[MAX_PATH] ={0};

   if( GetModuleFileName( NULL, szBuf, MAX_PATH ) )
   {
      return m_sPath =szBuf;
   }
   return "";
}

/*---------------------------------------------------------------*/
// Procedure....: ToModulePathAndFilename()
// Description..: Sets path to path of current module and filename
// Params.......: 
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template<class T> T GenPath<T>::ToModulePathAndFilename()
{
   TCHAR szBuf[MAX_PATH] ={0};

   if( GetModuleFileName( NULL, szBuf, MAX_PATH ) )
   {
      return m_sPath =szBuf;
   }
   return "";
}

/*---------------------------------------------------------------*/
// Procedure....: ToTempPath()
// Description..: Sets path to the directory designated for temporary files
// Params.......: 
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::ToTempPath()
{
   TCHAR szBuf[MAX_PATH]={0};

   if( GetTempPath( MAX_PATH, szBuf) )
   {
      return m_sPath = szBuf;
   }
   return "";
}

/*---------------------------------------------------------------*/
// Procedure....: ToTempPathAndFilename(const T sPrefixString)
// Description..: Sets path to the directory designated for temporary files
//             and adds a temporary filename.
// Params.......: 
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::ToTempPathAndFilename(const T sPrefixString)
{
   TCHAR szBuf[MAX_PATH]={0};

   if( GetTempPath( MAX_PATH, szBuf ) )
   {
      m_sPath = szBuf;

      TCHAR pTempFileName[MAX_PATH]={0};
      ::GetTempFileName( m_sPath.c_str(), sPrefixString.c_str(), 0, pTempFileName );
      return m_sPath += pTempFileName;
   }
   return "";
}

/*---------------------------------------------------------------*/
// Procedure....: ToWindowsDirectory()
// Description..: Sets path the windows directory
// Params.......: 
// Returns......: T containing windows directory
// On failure...: T("")
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::ToWindowsDirectory()
{
   TCHAR szBuffer[MAX_PATH];
   if( ! GetWindowsDirectory( szBuffer,MAX_PATH ) )
   {
      return "";
   }

   return m_sPath = szBuffer;
}

/*---------------------------------------------------------------*/
// Procedure....: ToSystemDirectory()
// Description..: Sets path to the path of the system directory
// Params.......: 
// Returns......: T containing system directory
// On failure...: T("")
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::ToSystemDirectory()
{
   TCHAR szBuffer[MAX_PATH];
   if( ! GetSystemDirectory( szBuffer, MAX_PATH ) )
   {
      return "";
   }

   return m_sPath = szBuffer;
}

/*---------------------------------------------------------------*/
// Procedure....: ReplaceExt( const T& sNewExt )
// Description..: Replaces extension component of path
// Params.......: const T& sNewFileName
// Returns......: T containing new path
// On failure...: T("")
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::ReplaceExt( const T& sNewExt )
{
   m_sPath =m_pImpl->PathReplaceExt( m_sPath, sNewExt );

   return m_sPath;
}


/*---------------------------------------------------------------*/
// Procedure....: ReplaceFilename( const T& )
// Description..: Replaces filename component of path
// Params.......: const T& sNewFileName
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template <class T> T GenPath<T>::ReplaceFilename( const T& sNewFileName )
{
   TCHAR szDrive[20]={0};
   TCHAR szDir[MAX_PATH]={0};
   TCHAR szFname[MAX_PATH]={0};
   TCHAR szExt[20]={0};
   TCHAR szPath[MAX_PATH]={0};

   _tsplitpath( m_sPath.c_str(), szDrive, szDir, szFname, szExt );

   _tmakepath( szPath, szDrive, szDir, sNewFileName.c_str(), szExt);

   return m_sPath =szPath;
}

/*---------------------------------------------------------------*/
// Procedure....: ToCurrentDirectory()
// Description..: Sets path to current directory for current process
// Params.......: 
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template< class T > T GenPath<T>::ToCurrentDirectory()
{
   TCHAR szBuf[MAX_PATH]={0};

   if(!GetCurrentDirectory(MAX_PATH, szBuf) )
   {
      return "";
   }
   return m_sPath =szBuf;
}

/////////////////////////////////////////////////////////////////////////////
// ENQUIRY
//////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------*/
// Procedure....: compare_no_case(const T& s) const
// Description..: Compares ignoring case 
// Params.......: const T& s
// Returns......: int : -1 if GenPath < s; 1 if GenPath > s ; 0 if equal
/*---------------------------------------------------------------*/
template < class T > int GenPath<T>::compare_no_case(const T& s) const
{
   T::const_iterator it_path = m_sPath.begin();
   T::const_iterator it_path_end = m_sPath.end();

   T::const_iterator it_param = s.begin();
   T::const_iterator it_param_end = s.end();

   while( it_path != it_path_end && it_param != it_param_end )
   {
      if( toupper( *it_path ) != toupper( *it_param ) )
      {
         return toupper( *it_path ) < toupper( *it_param ) ? -1 : 1;
      }
      ++it_path;
      ++it_param;
   }

   return m_sPath.size() == s.size() ? 0 : (m_sPath.size() < s.size() ) ? -1 : 1;
}

/*---------------------------------------------------------------*/
// Procedure....: IsDirectoryEmpty() const
// Description..: Checks if directory is empty
// Params.......: void
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template <class T> bool GenPath<T>::IsDirectoryEmpty() const
{
   bool bRet =false;

   WIN32_FIND_DATA win32;
   ZeroMemory(&win32, sizeof(win32));

   T sDir =m_sPath + "\\*.*";
   HANDLE hFind = FindFirstFile(sDir.c_str(), &win32);      // finds "."


   ZeroMemory(&win32, sizeof(win32));
   FindNextFile(hFind,&win32);                        // finds ".."

   ZeroMemory(&win32, sizeof(win32));
   if( FindNextFile(hFind,&win32) )                // not empty
   {
      bRet = false;
   }

   else
   {
      bRet = true;
   }
   FindClose( hFind );
   return bRet;
}

/*---------------------------------------------------------------*/
// Procedure....: IsValidPath() const
// Description..: Tests that all of the necessary components for a full valid pathname from the root are present
//             e.g. drive letter, ":\" and a filename
//             NOTE: this does not test that the path or file exists see PathExists() or FileExists()
// Params.......: void
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template<class T> bool GenPath<T>::IsValidPath() const
{
   TCHAR szDrive[20]={0};
   TCHAR szDir[MAX_PATH]={0};
   TCHAR szFname[MAX_PATH]={0};
   TCHAR szExt[20]={0};
   TCHAR szPath[MAX_PATH]={0};

   _tsplitpath( m_sPath.c_str(), szDrive, szDir, szFname, szExt );

   std::string sDrive(szDrive);
   std::string sDir(szDir);
   std::string sFname(szFname);
   std::string sExt(szExt);

   if( ( sDrive == "" ) || ( sFname == "" ) )            {  return false;  }
   if( ! m_pImpl->IsValidDriveFormat( m_sPath.c_str() ) )   {  return false;  }
   if( ! m_pImpl->IsValidFilename(sDir.c_str()) )        {  return false;  }
   if( ! m_pImpl->IsValidFilename(sFname.c_str()) )      {  return false;  }

   return true;
}

/*---------------------------------------------------------------*/
// Procedure....: PathExists()
// Description..: checks if path exists
// Params.......: void
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template <class T> bool GenPath<T>::PathExists() const
{
   return PathIsDirectory( m_sPath.c_str() ) ? true : false;
}

/*---------------------------------------------------------------*/
// Procedure....: Size() const
// Description..: returns the length (number of characters) of the path.
// Params.......: void
// Returns......: int 
/*---------------------------------------------------------------*/
template <class T> int GenPath<T>::Size() const
{
   return m_sPath.size();
}

/*---------------------------------------------------------------*/
// Procedure....: GetFileSize() const
// Description..: returns the length (number of characters) of the path.
// Params.......: void
// Returns......: DWORD 
// On failure...: -1
/*---------------------------------------------------------------*/
template <class T> DWORD GenPath<T>::GetFileSize() const
{
   if( ! FileExists() )
   {
      return -1;
   }

   OFSTRUCT oFile;
   ZeroMemory( &oFile, sizeof( oFile ) );

   HANDLE hFile = CreateFile(const_cast<const char*>(m_sPath.c_str()),
                        GENERIC_READ |GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL,
                        OPEN_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL
                        );

   if(hFile == INVALID_HANDLE_VALUE)
   {
      return -1;
   }

   DWORD dwSize =::GetFileSize( hFile, NULL);

   if( ! CloseHandle( hFile ) )
   {
      return -1;
   }

   return dwSize;
}

/*---------------------------------------------------------------*/
// Procedure....: IsEmpty() const
// Description..: returns true if path is empty else false
// Params.......: void
// Returns......: bool
/*---------------------------------------------------------------*/
 template <class T> bool GenPath<T>::IsEmpty() const
{
   return m_sPath.empty();
}

/*---------------------------------------------------------------*/
// Procedure....: FileExists() const
// Description..: Checks if file exists
// Params.......: void
// Returns......: bool
// On failure...: false
/*---------------------------------------------------------------*/
template <class T> bool GenPath<T>::FileExists() const
{
   return (::PathFileExists( m_sPath.c_str() ) ) ? true : false;
}

/*---------------------------------------------------------------*/
// Procedure....: FileAttributes() const
// Description..: Gets file or directory attributes. 
//             Uses the ANSI version of the GetFileAttributes API
// Params.......: void
// Returns......: a DWORD containing the file attributes.
//             see File Attributes in MSDN
// On failure...: 0xffffffff
/*---------------------------------------------------------------*/
template <class T> DWORD GenPath<T>::FileAttributes() const
{
   return (::GetFileAttributes( m_sPath.c_str() ) );
}

/*---------------------------------------------------------------*/
// Procedure....: ToModulePathAndFilename(HMODULE hInst)
// Description..: Sets path to path of current module 
//            NOT including filename or extension
// Params.......: 
// Returns......: T
// On failure...: T("")
/*---------------------------------------------------------------*/
template<class T> T GenPath<T>::ToModulePathAndFilename(HMODULE hInst)
{
   TCHAR szBuf[MAX_PATH] ={0};
   LPTSTR   lpFilename =szBuf;
   DWORD nSize =0;

   if( GetModuleFileName( hInst, lpFilename,  MAX_PATH) )
   {
      return m_sPath =lpFilename;
   }
   return "";
}


// TODO:
// to temp filename
// ERROR HANDLING
// in mirrored API calls, same as API call.
// in utility methods return equivalent of null
// include handling for relative paths ???

#endif // !defined(AFX__H__AF0A26E0_1620_44F9_A9BA_28A834164E63__INCLUDED_)


1