LCOV - code coverage report
Current view: top level - gfx/vr/openvr/src - pathtools_public.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 264 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 32 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //========= Copyright Valve Corporation ============//
       2             : #include "strtools_public.h"
       3             : #include "pathtools_public.h"
       4             : 
       5             : #if defined( _WIN32)
       6             : #include <windows.h>
       7             : #include <direct.h>
       8             : #include <shobjidl.h>
       9             : #include <knownfolders.h>
      10             : #include <shlobj.h>
      11             : #include <share.h>
      12             : 
      13             : #undef GetEnvironmentVariable
      14             : #else
      15             : #include <dlfcn.h>
      16             : #include <stdio.h>
      17             : #include <unistd.h>
      18             : #include <stdlib.h>
      19             : #endif
      20             : #if defined OSX
      21             : #include <Foundation/Foundation.h>
      22             : #include <AppKit/AppKit.h>
      23             : #include <mach-o/dyld.h>
      24             : #define _S_IFDIR S_IFDIR     // really from tier0/platform.h which we dont have yet
      25             : #endif
      26             : 
      27             : #include <sys/stat.h>
      28             : 
      29             : #include <algorithm>
      30             : 
      31             : /** Returns the path (including filename) to the current executable */
      32           0 : std::string Path_GetExecutablePath()
      33             : {
      34             : #if defined( _WIN32 )
      35             :         wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
      36             :         char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8];
      37             :         ::GetModuleFileNameW( NULL, pwchPath, MAX_UNICODE_PATH );
      38             :         WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
      39             :         delete[] pwchPath;
      40             : 
      41             :         std::string sPath = pchPath;
      42             :         delete[] pchPath;
      43             :         return sPath;
      44             : #elif defined( OSX )
      45             :         char rchPath[1024];
      46             :         uint32_t nBuff = sizeof( rchPath );
      47             :         bool bSuccess = _NSGetExecutablePath(rchPath, &nBuff) == 0;
      48             :         rchPath[nBuff-1] = '\0';
      49             :         if( bSuccess )
      50             :                 return rchPath;
      51             :         else
      52             :                 return "";
      53             : #elif defined LINUX
      54             :         char rchPath[1024];
      55           0 :         size_t nBuff = sizeof( rchPath );
      56           0 :         ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 );
      57           0 :         if ( nRead != -1 )
      58             :         {
      59           0 :                 rchPath[ nRead ] = 0;
      60           0 :                 return rchPath;
      61             :         }
      62             :         else
      63             :         {
      64           0 :                 return "";
      65             :         }
      66             : #else
      67             :         AssertMsg( false, "Implement Plat_GetExecutablePath" );
      68             :         return "";
      69             : #endif
      70             : 
      71             : }
      72             : 
      73             : /** Returns the path of the current working directory */
      74           0 : std::string Path_GetWorkingDirectory()
      75             : {
      76           0 :         std::string sPath;
      77             : #if defined( _WIN32 )
      78             :         wchar_t buf[MAX_UNICODE_PATH];
      79             :         sPath = UTF16to8( _wgetcwd( buf, MAX_UNICODE_PATH ) );
      80             : #else
      81             :         char buf[ 1024 ];
      82           0 :         sPath = getcwd( buf, sizeof( buf ) );
      83             : #endif
      84           0 :         return sPath;
      85             : }
      86             : 
      87             : /** Sets the path of the current working directory. Returns true if this was successful. */
      88           0 : bool Path_SetWorkingDirectory( const std::string & sPath )
      89             : {
      90             :         bool bSuccess;
      91             : #if defined( _WIN32 )
      92             :         std::wstring wsPath = UTF8to16( sPath.c_str() );
      93             :         bSuccess = 0 == _wchdir( wsPath.c_str() );
      94             : #else
      95           0 :         bSuccess = 0 == chdir( sPath.c_str() );
      96             : #endif
      97           0 :         return bSuccess;
      98             : }
      99             : 
     100             : /** Returns the specified path without its filename */
     101           0 : std::string Path_StripFilename( const std::string & sPath, char slash )
     102             : {
     103           0 :         if( slash == 0 )
     104           0 :                 slash = Path_GetSlash();
     105             : 
     106           0 :         std::string::size_type n = sPath.find_last_of( slash );
     107           0 :         if( n == std::string::npos )
     108           0 :                 return sPath;
     109             :         else
     110           0 :                 return std::string( sPath.begin(), sPath.begin() + n );
     111             : }
     112             : 
     113             : /** returns just the filename from the provided full or relative path. */
     114           0 : std::string Path_StripDirectory( const std::string & sPath, char slash )
     115             : {
     116           0 :         if( slash == 0 )
     117           0 :                 slash = Path_GetSlash();
     118             : 
     119           0 :         std::string::size_type n = sPath.find_last_of( slash );
     120           0 :         if( n == std::string::npos )
     121           0 :                 return sPath;
     122             :         else
     123           0 :                 return std::string( sPath.begin() + n + 1, sPath.end() );
     124             : }
     125             : 
     126             : /** returns just the filename with no extension of the provided filename. 
     127             : * If there is a path the path is left intact. */
     128           0 : std::string Path_StripExtension( const std::string & sPath )
     129             : {
     130           0 :         for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
     131             :         {
     132           0 :                 if( *i == '.' )
     133             :                 {
     134           0 :                         return std::string( sPath.begin(), i.base() - 1 );
     135             :                 }
     136             : 
     137             :                 // if we find a slash there is no extension
     138           0 :                 if( *i == '\\' || *i == '/' )
     139           0 :                         break;
     140             :         }
     141             : 
     142             :         // we didn't find an extension
     143           0 :         return sPath;
     144             : }
     145             : 
     146             : /** returns just extension of the provided filename (if any). */
     147           0 : std::string Path_GetExtension( const std::string & sPath )
     148             : {
     149           0 :         for ( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
     150             :         {
     151           0 :                 if ( *i == '.' )
     152             :                 {
     153           0 :                         return std::string( i.base(), sPath.end() );
     154             :                 }
     155             : 
     156             :                 // if we find a slash there is no extension
     157           0 :                 if ( *i == '\\' || *i == '/' )
     158           0 :                         break;
     159             :         }
     160             : 
     161             :         // we didn't find an extension
     162           0 :         return "";
     163             : }
     164             : 
     165           0 : bool Path_IsAbsolute( const std::string & sPath )
     166             : {
     167           0 :         if( sPath.empty() )
     168           0 :                 return false;
     169             : 
     170             : #if defined( WIN32 )
     171             :         if ( sPath.size() < 3 ) // must be c:\x or \\x at least
     172             :                 return false;
     173             : 
     174             :         if ( sPath[1] == ':' ) // drive letter plus slash, but must test both slash cases
     175             :         {
     176             :                 if ( sPath[2] == '\\' || sPath[2] == '/' )
     177             :                         return true;
     178             :         }
     179             :         else if ( sPath[0] == '\\' && sPath[1] == '\\' ) // UNC path
     180             :                 return true;
     181             : #else
     182           0 :         if( sPath[0] == '\\' || sPath[0] == '/' ) // any leading slash
     183           0 :                 return true;
     184             : #endif
     185             : 
     186           0 :         return false;
     187             : }
     188             : 
     189             : 
     190             : /** Makes an absolute path from a relative path and a base path */
     191           0 : std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash )
     192             : {
     193           0 :         if( slash == 0 )
     194           0 :                 slash = Path_GetSlash();
     195             : 
     196           0 :         if( Path_IsAbsolute( sRelativePath ) )
     197           0 :                 return sRelativePath;
     198             :         else
     199             :         {
     200           0 :                 if( !Path_IsAbsolute( sBasePath ) )
     201           0 :                         return "";
     202             : 
     203           0 :                 std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath, slash ), slash );
     204           0 :                 if( Path_IsAbsolute( sCompacted ) )
     205           0 :                         return sCompacted;
     206             :                 else
     207           0 :                         return "";
     208             :         }
     209             : }
     210             : 
     211             : 
     212             : /** Fixes the directory separators for the current platform */
     213           0 : std::string Path_FixSlashes( const std::string & sPath, char slash )
     214             : {
     215           0 :         if( slash == 0 )
     216           0 :                 slash = Path_GetSlash();
     217             : 
     218           0 :         std::string sFixed = sPath;
     219           0 :         for( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ )
     220             :         {
     221           0 :                 if( *i == '/' || *i == '\\' )
     222           0 :                         *i = slash;
     223             :         }
     224             : 
     225           0 :         return sFixed;
     226             : }
     227             : 
     228             : 
     229           0 : char Path_GetSlash()
     230             : {
     231             : #if defined(_WIN32)
     232             :         return '\\';
     233             : #else
     234           0 :         return '/';
     235             : #endif
     236             : }
     237             : 
     238             : /** Jams two paths together with the right kind of slash */
     239           0 : std::string Path_Join( const std::string & first, const std::string & second, char slash )
     240             : {
     241           0 :         if( slash == 0 )
     242           0 :                 slash = Path_GetSlash();
     243             : 
     244             :         // only insert a slash if we don't already have one
     245           0 :         std::string::size_type nLen = first.length();
     246           0 :         if( !nLen )
     247           0 :                 return second;
     248             : #if defined(_WIN32)
     249             :         if( first.back() == '\\' || first.back() == '/' )
     250             :             nLen--;
     251             : #else
     252           0 :         char last_char = first[first.length()-1];
     253           0 :         if (last_char == '\\' || last_char == '/')
     254           0 :             nLen--;
     255             : #endif
     256             : 
     257           0 :         return first.substr( 0, nLen ) + std::string( 1, slash ) + second;
     258             : }
     259             : 
     260             : 
     261           0 : std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash )
     262             : {
     263           0 :         return Path_Join( Path_Join( first, second, slash ), third, slash );
     264             : }
     265             : 
     266           0 : std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash )
     267             : {
     268           0 :         return Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash );
     269             : }
     270             : 
     271           0 : std::string Path_Join( 
     272             :         const std::string & first, 
     273             :         const std::string & second, 
     274             :         const std::string & third, 
     275             :         const std::string & fourth, 
     276             :         const std::string & fifth, 
     277             :         char slash )
     278             : {
     279           0 :         return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash );
     280             : }
     281             : 
     282             : 
     283           0 : std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash )
     284             : {
     285           0 :         if ( slash == 0 )
     286           0 :                 slash = Path_GetSlash();
     287             : 
     288           0 :         std::string sPath = sRawPath;
     289           0 :         std::string::size_type nCurrent = sRawPath.length();
     290           0 :         if ( nCurrent == 0 )
     291           0 :                 return sPath;
     292             : 
     293           0 :         int nLastFound = -1;
     294           0 :         nCurrent--;
     295           0 :         while( nCurrent != 0 )
     296             :         {
     297           0 :                 if ( sRawPath[ nCurrent ] == slash )
     298             :                 {
     299           0 :                         nLastFound = (int)nCurrent;
     300           0 :                         nCurrent--;
     301             :                 }
     302             :                 else
     303             :                 {
     304           0 :                         break;
     305             :                 }
     306             :         }
     307             :                 
     308           0 :         if ( nLastFound >= 0 )
     309             :         {
     310           0 :                 sPath.erase( nLastFound, std::string::npos );
     311             :         }
     312             :         
     313           0 :         return sPath;
     314             : }
     315             : 
     316             : 
     317             : /** Removes redundant <dir>/.. elements in the path. Returns an empty path if the 
     318             : * specified path has a broken number of directories for its number of ..s */
     319           0 : std::string Path_Compact( const std::string & sRawPath, char slash )
     320             : {
     321           0 :         if( slash == 0 )
     322           0 :                 slash = Path_GetSlash();
     323             : 
     324           0 :         std::string sPath = Path_FixSlashes( sRawPath, slash );
     325           0 :         std::string sSlashString( 1, slash );
     326             : 
     327             :         // strip out all /./
     328           0 :         for( std::string::size_type i = 0; (i + 3) < sPath.length();  )
     329             :         {
     330           0 :                 if( sPath[ i ] == slash && sPath[ i+1 ] == '.' && sPath[ i+2 ] == slash )
     331             :                 {
     332           0 :                         sPath.replace( i, 3, sSlashString );
     333             :                 }
     334             :                 else
     335             :                 {
     336           0 :                         ++i;
     337             :                 }
     338             :         }
     339             : 
     340             : 
     341             :         // get rid of trailing /. but leave the path separator
     342           0 :         if( sPath.length() > 2 )
     343             :         {
     344           0 :                 std::string::size_type len = sPath.length();
     345           0 :                 if( sPath[ len-1 ] == '.'  && sPath[ len-2 ] == slash )
     346             :                 {
     347             :                   // sPath.pop_back();
     348           0 :                   sPath[len-1] = 0;  // for now, at least
     349             :                 }
     350             :         }
     351             : 
     352             :         // get rid of leading ./ 
     353           0 :         if( sPath.length() > 2 )
     354             :         {
     355           0 :                 if( sPath[ 0 ] == '.'  && sPath[ 1 ] == slash )
     356             :                 {
     357           0 :                         sPath.replace( 0, 2, "" );
     358             :                 }
     359             :         }
     360             : 
     361             :         // each time we encounter .. back up until we've found the previous directory name
     362             :         // then get rid of both
     363           0 :         std::string::size_type i = 0;
     364           0 :         while( i < sPath.length() )
     365             :         {
     366           0 :                 if( i > 0 && sPath.length() - i >= 2 
     367           0 :                         && sPath[i] == '.'
     368           0 :                         && sPath[i+1] == '.'
     369           0 :                         && ( i + 2 == sPath.length() || sPath[ i+2 ] == slash )
     370           0 :                         && sPath[ i-1 ] == slash )
     371             :                 {
     372             :                         // check if we've hit the start of the string and have a bogus path
     373           0 :                         if( i == 1 )
     374           0 :                                 return "";
     375             :                         
     376             :                         // find the separator before i-1
     377           0 :                         std::string::size_type iDirStart = i-2;
     378           0 :                         while( iDirStart > 0 && sPath[ iDirStart - 1 ] != slash )
     379           0 :                                 --iDirStart;
     380             : 
     381             :                         // remove everything from iDirStart to i+2
     382           0 :                         sPath.replace( iDirStart, (i - iDirStart) + 3, "" );
     383             : 
     384             :                         // start over
     385           0 :                         i = 0;
     386             :                 }
     387             :                 else
     388             :                 {
     389           0 :                         ++i;
     390             :                 }
     391             :         }
     392             : 
     393           0 :         return sPath;
     394             : }
     395             : 
     396             : 
     397             : /** Returns the path to the current DLL or exe */
     398           0 : std::string Path_GetThisModulePath()
     399             : {
     400             :         // gets the path of vrclient.dll itself
     401             : #ifdef WIN32
     402             :         HMODULE hmodule = NULL;
     403             : 
     404             :         ::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(Path_GetThisModulePath), &hmodule );
     405             : 
     406             :         wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
     407             :         char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ];
     408             :         ::GetModuleFileNameW( hmodule, pwchPath, MAX_UNICODE_PATH );
     409             :         WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
     410             :         delete[] pwchPath;
     411             : 
     412             :         std::string sPath = pchPath;
     413             :         delete [] pchPath;
     414             :         return sPath;
     415             : 
     416             : #elif defined( OSX ) || defined( LINUX )
     417             :         // get the addr of a function in vrclient.so and then ask the dlopen system about it
     418             :         Dl_info info;
     419           0 :         dladdr( (void *)Path_GetThisModulePath, &info );
     420           0 :         return info.dli_fname;
     421             : #endif
     422             : 
     423             : }
     424             : 
     425             : 
     426             : /** returns true if the specified path exists and is a directory */
     427           0 : bool Path_IsDirectory( const std::string & sPath )
     428             : {
     429           0 :         std::string sFixedPath = Path_FixSlashes( sPath );
     430           0 :         if( sFixedPath.empty() )
     431           0 :                 return false;
     432           0 :         char cLast = sFixedPath[ sFixedPath.length() - 1 ];
     433           0 :         if( cLast == '/' || cLast == '\\' )
     434           0 :                 sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() );
     435             : 
     436             :         // see if the specified path actually exists.
     437             : 
     438             : #if defined(POSIX)
     439             :         struct  stat    buf;
     440           0 :         if ( stat( sFixedPath.c_str(), &buf ) == -1 )
     441             :         {
     442           0 :                 return false;
     443             :         }
     444             : 
     445             : #if defined( LINUX ) || defined( OSX )
     446           0 :         return S_ISDIR( buf.st_mode );
     447             : #else
     448             :         return (buf.st_mode & _S_IFDIR) != 0;
     449             : #endif
     450             : 
     451             : #else
     452             :         struct  _stat   buf;
     453             :         std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
     454             :         if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
     455             :         {
     456             :                 return false;
     457             :         }
     458             : 
     459             :         return (buf.st_mode & _S_IFDIR) != 0;
     460             : #endif
     461             : }
     462             : 
     463             : /** returns true if the specified path represents an app bundle */
     464           0 : bool Path_IsAppBundle( const std::string & sPath )
     465             : {
     466             : #if defined(OSX)
     467             :         NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ];
     468             :         bool bisAppBundle = ( nullptr != bundle );
     469             :         [ bundle release ];
     470             :         return bisAppBundle;
     471             : #else
     472           0 :         return false;
     473             : #endif
     474             : }
     475             : 
     476             : //-----------------------------------------------------------------------------
     477             : // Purpose: returns true if the the path exists
     478             : //-----------------------------------------------------------------------------
     479           0 : bool Path_Exists( const std::string & sPath )
     480             : {
     481           0 :         std::string sFixedPath = Path_FixSlashes( sPath );
     482           0 :         if( sFixedPath.empty() )
     483           0 :                 return false;
     484             : 
     485             : #if defined( WIN32 )
     486             :         struct  _stat   buf;
     487             :         std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
     488             :         if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
     489             :         {
     490             :                 return false;
     491             :         }
     492             : #else
     493             :         struct stat buf;
     494           0 :         if ( stat ( sFixedPath.c_str(), &buf ) == -1)
     495             :         {
     496           0 :                 return false;
     497             :         }
     498             : #endif
     499             : 
     500           0 :         return true;
     501             : }
     502             : 
     503             : 
     504             : //-----------------------------------------------------------------------------
     505             : // Purpose: helper to find a directory upstream from a given path
     506             : //-----------------------------------------------------------------------------
     507           0 : std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
     508             : {
     509           0 :         std::string strFoundPath = "";
     510           0 :         std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
     511           0 :         if ( strCurrentPath.length() == 0 )
     512           0 :                 return "";
     513             : 
     514           0 :         bool bExists = Path_Exists( strCurrentPath );
     515           0 :         std::string strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
     516           0 :         if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
     517           0 :                 return strCurrentPath;
     518             : 
     519           0 :         while( bExists && strCurrentPath.length() != 0 )
     520             :         {
     521           0 :                 strCurrentPath = Path_StripFilename( strCurrentPath );
     522           0 :                 strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
     523           0 :                 bExists = Path_Exists( strCurrentPath );
     524           0 :                 if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
     525           0 :                         return strCurrentPath;
     526             :         }
     527             : 
     528           0 :         return "";
     529             : }
     530             : 
     531             : 
     532             : //-----------------------------------------------------------------------------
     533             : // Purpose: helper to find a subdirectory upstream from a given path
     534             : //-----------------------------------------------------------------------------
     535           0 : std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
     536             : {
     537           0 :         std::string strFoundPath = "";
     538           0 :         std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
     539           0 :         if ( strCurrentPath.length() == 0 )
     540           0 :                 return "";
     541             : 
     542           0 :         bool bExists = Path_Exists( strCurrentPath );
     543           0 :         while( bExists && strCurrentPath.length() != 0 )
     544             :         {
     545           0 :                 strCurrentPath = Path_StripFilename( strCurrentPath );
     546           0 :                 bExists = Path_Exists( strCurrentPath );
     547             : 
     548           0 :                 if( Path_Exists( Path_Join( strCurrentPath, strDirectoryName ) ) )
     549             :                 {
     550           0 :                         strFoundPath = Path_Join( strCurrentPath, strDirectoryName );
     551           0 :                         break;
     552             :                 }
     553             :         }
     554           0 :         return strFoundPath;
     555             : }
     556             : 
     557             : 
     558             : //-----------------------------------------------------------------------------
     559             : // Purpose: reading and writing files in the vortex directory
     560             : //-----------------------------------------------------------------------------
     561           0 : unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize )
     562             : {
     563             :         FILE *f;
     564             : #if defined( POSIX )
     565           0 :         f = fopen( strFilename.c_str(), "rb" );
     566             : #else
     567             :         std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
     568             :         // the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s
     569             :         f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO );
     570             : #endif
     571             :         
     572           0 :         unsigned char* buf = NULL;
     573             : 
     574           0 :         if ( f != NULL )
     575             :         {
     576           0 :                 fseek(f, 0, SEEK_END);
     577           0 :                 int size = ftell(f);
     578           0 :                 fseek(f, 0, SEEK_SET);
     579             : 
     580           0 :                 buf = new unsigned char[size];
     581           0 :                 if (buf && fread(buf, size, 1, f) == 1)
     582             :                 {
     583           0 :                         if (pSize)
     584           0 :                                 *pSize = size;
     585             :                 }
     586             :                 else
     587             :                 {
     588           0 :                         delete[] buf;
     589           0 :                         buf = 0;
     590             :                 }
     591             : 
     592           0 :                 fclose(f);
     593             :         }
     594             : 
     595           0 :         return buf;
     596             : }
     597             : 
     598           0 : uint32_t  Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize )
     599             : {
     600             :         FILE *f;
     601             : #if defined( POSIX )
     602           0 :         f = fopen( strFilename.c_str(), "rb" );
     603             : #else
     604             :         std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
     605             :         errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"rb" );
     606             :         if ( err != 0 )
     607             :         {
     608             :                 f = NULL;
     609             :         }
     610             : #endif
     611             : 
     612           0 :         uint32_t unSizeToReturn = 0;
     613             : 
     614           0 :         if ( f != NULL )
     615             :         {
     616           0 :                 fseek( f, 0, SEEK_END );
     617           0 :                 uint32_t size = (uint32_t)ftell( f );
     618           0 :                 fseek( f, 0, SEEK_SET );
     619             : 
     620           0 :                 if ( size > unSize || !pBuffer )
     621             :                 {
     622           0 :                         unSizeToReturn = (uint32_t)size;
     623             :                 }
     624             :                 else
     625             :                 {
     626           0 :                         if ( fread( pBuffer, size, 1, f ) == 1 )
     627             :                         {
     628           0 :                                 unSizeToReturn = (uint32_t)size;
     629             :                         }
     630             :                 }
     631             : 
     632           0 :                 fclose( f );
     633             :         }
     634             : 
     635           0 :         return unSizeToReturn;
     636             : }
     637             : 
     638           0 : bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize)
     639             : {
     640             :         FILE *f;
     641             : #if defined( POSIX )
     642           0 :         f = fopen(strFilename.c_str(), "wb");
     643             : #else
     644             :         std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
     645             :         errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"wb" );
     646             :         if (err != 0)
     647             :         {
     648             :                 f = NULL;
     649             :         }
     650             : #endif
     651             : 
     652           0 :         size_t written = 0;
     653           0 :         if (f != NULL) {
     654           0 :                 written = fwrite(pData, sizeof(unsigned char), nSize, f);
     655           0 :                 fclose(f);
     656             :         }
     657             : 
     658           0 :         return written = nSize ? true : false;
     659             : }
     660             : 
     661           0 : std::string Path_ReadTextFile( const std::string &strFilename )
     662             : {
     663             :         // doing it this way seems backwards, but I don't
     664             :         // see an easy way to do this with C/C++ style IO
     665             :         // that isn't worse...
     666             :         int size;
     667           0 :         unsigned char* buf = Path_ReadBinaryFile( strFilename, &size );
     668           0 :         if (!buf)
     669           0 :                 return "";
     670             : 
     671             :         // convert CRLF -> LF
     672           0 :         size_t outsize = 1;
     673           0 :         for (int i=1; i < size; i++)
     674             :         {
     675           0 :                 if (buf[i] == '\n' && buf[i-1] == '\r') // CRLF
     676           0 :                         buf[outsize-1] = '\n'; // ->LF
     677             :                 else
     678           0 :                         buf[outsize++] = buf[i]; // just copy
     679             :         }
     680             : 
     681           0 :         std::string ret((char *)buf, outsize);
     682           0 :         delete[] buf;
     683           0 :         return ret;
     684             : }
     685             : 
     686             : 
     687           0 : bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData )
     688             : {
     689             :         FILE *f;
     690             : #if defined( POSIX )
     691           0 :         f = fopen( strFilename.c_str(), "w" );
     692             : #else
     693             :         std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
     694             :         errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"w" );
     695             :         if ( err != 0 )
     696             :         {
     697             :                 f = NULL;
     698             :         }
     699             : #endif
     700             :         
     701           0 :         bool ok = false;
     702             : 
     703           0 :         if ( f != NULL )
     704             :         {
     705           0 :                 ok = fputs( pchData, f) >= 0;
     706           0 :                 fclose(f);
     707             :         }
     708             : 
     709           0 :         return ok;
     710             : }
     711             : 
     712           0 : bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData )
     713             : {
     714           0 :         std::string strTmpFilename = strFilename + ".tmp";
     715             : 
     716           0 :         if ( !Path_WriteStringToTextFile( strTmpFilename, pchData ) )
     717           0 :                 return false;
     718             : 
     719             :         // Platform specific atomic file replacement
     720             : #if defined( _WIN32 )
     721             :         std::wstring wsFilename = UTF8to16( strFilename.c_str() );
     722             :         std::wstring wsTmpFilename = UTF8to16( strTmpFilename.c_str() );
     723             :         if ( !::ReplaceFileW( wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0 ) )
     724             :         {
     725             :                 // if we couldn't ReplaceFile, try a non-atomic write as a fallback
     726             :                 if ( !Path_WriteStringToTextFile( strFilename, pchData ) )
     727             :                         return false;
     728             :         }
     729             : #elif defined( POSIX )
     730           0 :         if ( rename( strTmpFilename.c_str(), strFilename.c_str() ) == -1 )
     731           0 :                 return false;
     732             : #else
     733             : #error Do not know how to write atomic file
     734             : #endif
     735             : 
     736           0 :         return true;
     737             : }
     738             : 
     739             : 
     740             : #if defined(WIN32)
     741             : #define FILE_URL_PREFIX "file:///"
     742             : #else
     743             : #define FILE_URL_PREFIX "file://"
     744             : #endif
     745             : 
     746             : // ----------------------------------------------------------------------------------------------------------------------------
     747             : // Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL)
     748             : // ----------------------------------------------------------------------------------------------------------------------------
     749           0 : std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath )
     750             : {
     751           0 :         if ( !strnicmp( sRelativePath.c_str(), "http://", 7 )
     752           0 :                 || !strnicmp( sRelativePath.c_str(), "https://", 8 )
     753           0 :                 || !strnicmp( sRelativePath.c_str(), "file://", 7 ) )
     754             :         {
     755           0 :                 return sRelativePath;
     756             :         }
     757             :         else
     758             :         {
     759           0 :                 std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath );
     760           0 :                 if ( sAbsolute.empty() )
     761           0 :                         return sAbsolute;
     762           0 :                 return std::string( FILE_URL_PREFIX ) + sAbsolute;
     763             :         }
     764             : }
     765             : 
     766             : // -----------------------------------------------------------------------------------------------------
     767             : // Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned
     768             : // -----------------------------------------------------------------------------------------------------
     769           0 : std::string Path_UrlToFilePath( const std::string & sFileUrl )
     770             : {
     771           0 :         if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) )
     772             :         {
     773           0 :                 return sFileUrl.c_str() + strlen( FILE_URL_PREFIX );
     774             :         }
     775             :         else
     776             :         {
     777           0 :                 return "";
     778             :         }
     779             : }
     780             : 
     781             : 
     782             : // -----------------------------------------------------------------------------------------------------
     783             : // Purpose: Returns the root of the directory the system wants us to store user documents in
     784             : // -----------------------------------------------------------------------------------------------------
     785           0 : std::string GetUserDocumentsPath()
     786             : {
     787             : #if defined( WIN32 )
     788             :         WCHAR rwchPath[MAX_PATH];
     789             : 
     790             :         if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
     791             :         {
     792             :                 return "";
     793             :         }
     794             : 
     795             :         // Convert the path to UTF-8 and store in the output
     796             :         std::string sUserPath = UTF16to8( rwchPath );
     797             : 
     798             :         return sUserPath;
     799             : #elif defined( OSX )
     800             :         @autoreleasepool {
     801             :                 NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
     802             :                 if ( [paths count] == 0 )
     803             :                 {
     804             :                         return "";
     805             :                 }
     806             :                 
     807             :                 return [[paths objectAtIndex:0] UTF8String];
     808             :         }
     809             : #elif defined( LINUX )
     810             :         // @todo: not solved/changed as part of OSX - still not real - just removed old class based steam cut and paste
     811           0 :         const char *pchHome = getenv( "HOME" );
     812           0 :         if ( pchHome == NULL )
     813             :         {
     814           0 :                 return "";
     815             :         }
     816           0 :         return pchHome;
     817             : #endif
     818             : }
     819             : 

Generated by: LCOV version 1.13