Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  pathtools_public.cpp   Sprache: C

 
//========= Copyright Valve Corporation ============//
#include "strtools_public.h"
#include "pathtools_public.h"

#if defined( _WIN32)
#include <windows.h>
#include <direct.h>
#include <shobjidl.h>
#include <knownfolders.h>
#include <shlobj.h>
#include <share.h>

#undef GetEnvironmentVariable
#else
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <alloca.h>
#endif

#if defined OSX
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
#include <mach-o/dyld.h>
#define _S_IFDIR S_IFDIR     // really from tier0/platform.h which we dont have yet
#endif

#include <sys/stat.h>

#include <algorithm>

/** Returns the path (including filename) to the current executable */
std::string Path_GetExecutablePath()
{
#if defined( _WIN32 )
 wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
 char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8];
 ::GetModuleFileNameW( NULL, pwchPath, MAX_UNICODE_PATH );
 WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
 delete[] pwchPath;

 std::string sPath = pchPath;
 delete[] pchPath;
 return sPath;
#elif defined( OSX )
 char rchPath[1024];
 uint32_t nBuff = sizeof( rchPath );
 bool bSuccess = _NSGetExecutablePath(rchPath, &nBuff) == 0;
 rchPath[nBuff-1] = '\0';
 if( bSuccess )
  return rchPath;
 else
  return "";
#elif defined LINUX
 char rchPath[1024];
 size_t nBuff = sizeof( rchPath );
 ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 );
 if ( nRead != -1 )
 {
  rchPath[ nRead ] = 0;
  return rchPath;
 }
 else
 {
  return "";
 }
#else
 AssertMsg( false"Implement Plat_GetExecutablePath" );
 return "";
#endif

}

/** Returns the path of the current working directory */
std::string Path_GetWorkingDirectory()
{
 std::string sPath;
#if defined( _WIN32 )
 wchar_t buf[MAX_UNICODE_PATH];
 sPath = UTF16to8( _wgetcwd( buf, MAX_UNICODE_PATH ) );
#else
 char buf[ 1024 ];
 sPath = getcwd( buf, sizeof( buf ) );
#endif
 return sPath;
}

/** Sets the path of the current working directory. Returns true if this was successful. */
bool Path_SetWorkingDirectory( const std::string & sPath )
{
 bool bSuccess;
#if defined( _WIN32 )
 std::wstring wsPath = UTF8to16( sPath.c_str() );
 bSuccess = 0 == _wchdir( wsPath.c_str() );
#else
 bSuccess = 0 == chdir( sPath.c_str() );
#endif
 return bSuccess;
}

/** Gets the path to a temporary directory. */
std::string Path_GetTemporaryDirectory()
{
#if defined( _WIN32 )
 wchar_t buf[MAX_UNICODE_PATH];
 if ( GetTempPathW( MAX_UNICODE_PATH, buf ) == 0 )
  return Path_GetWorkingDirectory();
 return UTF16to8( buf );
#else
 const char *pchTmpDir = getenv( "TMPDIR" );
 if ( pchTmpDir == NULL )
 {
  return "";
 }
 return pchTmpDir;
#endif
}

/** Returns the specified path without its filename */
std::string Path_StripFilename( const std::string & sPath, char slash )
{
 if( slash == 0 )
  slash = Path_GetSlash();

 std::string::size_type n = sPath.find_last_of( slash );
 if( n == std::string::npos )
  return sPath;
 else
  return std::string( sPath.begin(), sPath.begin() + n );
}

/** returns just the filename from the provided full or relative path. */
std::string Path_StripDirectory( const std::string & sPath, char slash )
{
 if( slash == 0 )
  slash = Path_GetSlash();

 std::string::size_type n = sPath.find_last_of( slash );
 if( n == std::string::npos )
  return sPath;
 else
  return std::string( sPath.begin() + n + 1, sPath.end() );
}

/** returns just the filename with no extension of the provided filename. 
* If there is a path the path is left intact. */

std::string Path_StripExtension( const std::string & sPath )
{
 for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
 {
  if( *i == '.' )
  {
   return std::string( sPath.begin(), i.base() - 1 );
  }

  // if we find a slash there is no extension
  if( *i == '\\' || *i == '/' )
   break;
 }

 // we didn't find an extension
 return sPath;
}

/** returns just extension of the provided filename (if any). */
std::string Path_GetExtension( const std::string & sPath )
{
 for ( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
 {
  if ( *i == '.' )
  {
   return std::string( i.base(), sPath.end() );
  }

  // if we find a slash there is no extension
  if ( *i == '\\' || *i == '/' )
   break;
 }

 // we didn't find an extension
 return "";
}

bool Path_IsAbsolute( const std::string & sPath )
{
 if( sPath.empty() )
  return false;

#if defined( WIN32 )
 if ( sPath.size() < 3 ) // must be c:\x or \\x at least
  return false;

 if ( sPath[1] == ':' ) // drive letter plus slash, but must test both slash cases
 {
  if ( sPath[2] == '\\' || sPath[2] == '/' )
   return true;
 }
 else if ( sPath[0] == '\\' && sPath[1] == '\\' ) // UNC path
  return true;
#else
 if( sPath[0] == '\\' || sPath[0] == '/' ) // any leading slash
  return true;
#endif

 return false;
}


/** Makes an absolute path from a relative path and a base path */
std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string &&nbsp;sBasePath )
{
 if( Path_IsAbsolute( sRelativePath ) )
  return Path_Compact( sRelativePath );
 else
 {
  if( !Path_IsAbsolute( sBasePath ) )
   return "";

  std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath ) );
  if( Path_IsAbsolute( sCompacted ) )
   return sCompacted;
  else
   return "";
 }
}


/** Fixes the directory separators for the current platform */
std::string Path_FixSlashes( const std::string & sPath, char slash )
{
 if( slash == 0 )
  slash = Path_GetSlash();

 std::string sFixed = sPath;
 for( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ )
 {
  if( *i == '/' || *i == '\\' )
   *i = slash;
 }

 return sFixed;
}


char Path_GetSlash()
{
#if defined(_WIN32)
 return '\\';
#else
 return '/';
#endif
}

/** Jams two paths together with the right kind of slash */
std::string Path_Join( const std::string & first, const std::string & second, char slash )
{
 if( slash == 0 )
  slash = Path_GetSlash();

 // only insert a slash if we don't already have one
 std::string::size_type nLen = first.length();
 if( !nLen )
  return second;
#if defined(_WIN32)
 if( first.back() == '\\' || first.back() == '/' )
     nLen--;
#else
 char last_char = first[first.length()-1];
 if (last_char == '\\' || last_char == '/')
     nLen--;
#endif

 return first.substr( 0, nLen ) + std::string( 1, slash ) + second;
}


std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash )
{
 return Path_Join( Path_Join( first, second, slash ), third, slash );
}

std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash )
{
 return Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash );
}

std::string Path_Join( 
 const std::string & first, 
 const std::string & second, 
 const std::string & third, 
 const std::string & fourth, 
 const std::string & fifth, 
 char slash )
{
 return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash );
}


std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash )
{
 if ( slash == 0 )
  slash = Path_GetSlash();

 std::string sPath = sRawPath;
 std::string::size_type nCurrent = sRawPath.length();
 if ( nCurrent == 0 )
  return sPath;

 int nLastFound = -1;
 nCurrent--;
 while( nCurrent != 0 )
 {
  if ( sRawPath[ nCurrent ] == slash )
  {
   nLastFound = (int)nCurrent;
   nCurrent--;
  }
  else
  {
   break;
  }
 }
  
 if ( nLastFound >= 0 )
 {
  sPath.erase( nLastFound, std::string::npos );
 }
 
 return sPath;
}


/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the 
* specified path has a broken number of directories for its number of ..s */

std::string Path_Compact( const std::string & sRawPath, char slash )
{
 if( slash == 0 )
  slash = Path_GetSlash();

 std::string sPath = Path_FixSlashes( sRawPath, slash );
 std::string sSlashString( 1, slash );

 // strip out all /./
 for( std::string::size_type i = 0; (i + 3) < sPath.length();  )
 {
  if( sPath[ i ] == slash && sPath[ i+1 ] == '.' && sPath[ i+2 ] == slash )
  {
   sPath.replace( i, 3, sSlashString );
  }
  else
  {
   ++i;
  }
 }


 // get rid of trailing /. but leave the path separator
 if( sPath.length() > 2 )
 {
  std::string::size_type len = sPath.length();
  if( sPath[ len-1 ] == '.'  && sPath[ len-2 ] == slash )
  {
   sPath.pop_back();
   //Not sure why the following line of code was used for a while.  It causes problems with strlen.
   //sPath[len-1] = 0;  // for now, at least 
  }
 }

 // get rid of leading ./ 
 if( sPath.length() > 2 )
 {
  if( sPath[ 0 ] == '.'  && sPath[ 1 ] == slash )
  {
   sPath.replace( 0, 2, "" );
  }
 }

 // each time we encounter .. back up until we've found the previous directory name
 // then get rid of both
 std::string::size_type i = 0;
 while( i < sPath.length() )
 {
  if( i > 0 && sPath.length() - i >= 2 
   && sPath[i] == '.'
   && sPath[i+1] == '.'
   && ( i + 2 == sPath.length() || sPath[ i+2 ] == slash )
   && sPath[ i-1 ] == slash )
  {
   // check if we've hit the start of the string and have a bogus path
   if( i == 1 )
    return "";
   
   // find the separator before i-1
   std::string::size_type iDirStart = i-2;
   while( iDirStart > 0 && sPath[ iDirStart - 1 ] != slash )
    --iDirStart;

   // remove everything from iDirStart to i+2
   sPath.replace( iDirStart, (i - iDirStart) + 3, "" );

   // start over
   i = 0;
  }
  else
  {
   ++i;
  }
 }

 return sPath;
}


/** Returns true if these two paths are the same without respect for internal . or ..
* sequences, slash type, or case (on case-insensitive platforms). */

bool Path_IsSamePath( const std::string & sPath1, const std::string & sPath2 )
{
 std::string sCompact1 = Path_Compact( sPath1 );
 std::string sCompact2 = Path_Compact( sPath2 );
#if defined(WIN32)
 return !stricmp( sCompact1.c_str(), sCompact2.c_str() );
#else
 return !strcmp( sCompact1.c_str(), sCompact2.c_str() );
#endif
}


/** Returns the path to the current DLL or exe */
std::string Path_GetThisModulePath()
{
 // gets the path of vrclient.dll itself
#ifdef WIN32
 HMODULE hmodule = NULL;

 ::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(Path_GetThisModulePath), &hmodule );

 wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
 char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ];
 ::GetModuleFileNameW( hmodule, pwchPath, MAX_UNICODE_PATH );
 WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
 delete[] pwchPath;

 std::string sPath = pchPath;
 delete [] pchPath;
 return sPath;

#elif defined( OSX ) || defined( LINUX )
 // get the addr of a function in vrclient.so and then ask the dlopen system about it
 Dl_info info;
 dladdr( (void *)Path_GetThisModulePath, &info );
 return info.dli_fname;
#endif

}


/** returns true if the specified path exists and is a directory */
bool Path_IsDirectory( const std::string & sPath )
{
 std::string sFixedPath = Path_FixSlashes( sPath );
 if( sFixedPath.empty() )
  return false;
 char cLast = sFixedPath[ sFixedPath.length() - 1 ];
 if( cLast == '/' || cLast == '\\' )
  sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() );

 // see if the specified path actually exists.

#if defined(POSIX)
 struct stat buf;
 if ( stat( sFixedPath.c_str(), &buf ) == -1 )
 {
  return false;
 }

#if defined( LINUX ) || defined( OSX )
 return S_ISDIR( buf.st_mode );
#else
 return (buf.st_mode & _S_IFDIR) != 0;
#endif

#else
 struct _stat buf;
 std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
 if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
 {
  return false;
 }

 return (buf.st_mode & _S_IFDIR) != 0;
#endif
}

/** returns true if the specified path represents an app bundle */
bool Path_IsAppBundle( const std::string & sPath )
{
#if defined(OSX)
 @autoreleasepool {
  NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ];
  bool bisAppBundle = ( nullptr != bundle );
  return bisAppBundle;
 }
#else
 return false;
#endif
}

//-----------------------------------------------------------------------------
// Purpose: returns true if the the path exists
//-----------------------------------------------------------------------------
bool Path_Exists( const std::string & sPath )
{
 std::string sFixedPath = Path_FixSlashes( sPath );
 if( sFixedPath.empty() )
  return false;

#if defined( WIN32 )
 struct _stat buf;
 std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
 if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
 {
  return false;
 }
#else
 struct stat buf;
 if ( stat ( sFixedPath.c_str(), &buf ) == -1)
 {
  return false;
 }
#endif

 return true;
}


//-----------------------------------------------------------------------------
// Purpose: helper to find a directory upstream from a given path
//-----------------------------------------------------------------------------
std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
{
 std::string strFoundPath = "";
 std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
 if ( strCurrentPath.length() == 0 )
  return "";

 bool bExists = Path_Exists( strCurrentPath );
 std::string strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
 if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
  return strCurrentPath;

 while( bExists && strCurrentPath.length() != 0 )
 {
  strCurrentPath = Path_StripFilename( strCurrentPath );
  strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
  bExists = Path_Exists( strCurrentPath );
  if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
   return strCurrentPath;
 }

 return "";
}


//-----------------------------------------------------------------------------
// Purpose: helper to find a subdirectory upstream from a given path
//-----------------------------------------------------------------------------
std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
{
 std::string strFoundPath = "";
 std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
 if ( strCurrentPath.length() == 0 )
  return "";

 bool bExists = Path_Exists( strCurrentPath );
 while( bExists && strCurrentPath.length() != 0 )
 {
  strCurrentPath = Path_StripFilename( strCurrentPath );
  bExists = Path_Exists( strCurrentPath );

  if( Path_Exists( Path_Join( strCurrentPath, strDirectoryName ) ) )
  {
   strFoundPath = Path_Join( strCurrentPath, strDirectoryName );
   break;
  }
 }
 return strFoundPath;
}


//-----------------------------------------------------------------------------
// Purpose: reading and writing files in the vortex directory
//-----------------------------------------------------------------------------
unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize )
{
 FILE *f;
#if defined( POSIX )
 f = fopen( strFilename.c_str(), "rb" );
#else
 std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 // the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s
 f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO );
#endif
 
 unsigned char* buf = NULL;

 if ( f != NULL )
 {
  fseek(f, 0, SEEK_END);
  int size = ftell(f);
  fseek(f, 0, SEEK_SET);

  buf = new unsigned char[size];
  if (buf && fread(buf, size, 1, f) == 1)
  {
   if (pSize)
    *pSize = size;
  }
  else
  {
   delete[] buf;
   buf = 0;
  }

  fclose(f);
 }

 return buf;
}

uint32_t  Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize )
{
 FILE *f;
#if defined( POSIX )
 f = fopen( strFilename.c_str(), "rb" );
#else
 std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"rb" );
 if ( err != 0 )
 {
  f = NULL;
 }
#endif

 uint32_t unSizeToReturn = 0;

 if ( f != NULL )
 {
  fseek( f, 0, SEEK_END );
  uint32_t size = (uint32_t)ftell( f );
  fseek( f, 0, SEEK_SET );

  if ( size > unSize || !pBuffer )
  {
   unSizeToReturn = (uint32_t)size;
  }
  else
  {
   if ( fread( pBuffer, size, 1, f ) == 1 )
   {
    unSizeToReturn = (uint32_t)size;
   }
  }

  fclose( f );
 }

 return unSizeToReturn;
}

bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize)
{
 FILE *f;
#if defined( POSIX )
 f = fopen(strFilename.c_str(), "wb");
#else
 std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"wb" );
 if (err != 0)
 {
  f = NULL;
 }
#endif

 size_t written = 0;
 if (f != NULL) {
  written = fwrite(pData, sizeof(unsigned char), nSize, f);
  fclose(f);
 }

 return written == nSize ? true : false;
}

std::string Path_ReadTextFile( const std::string &strFilename )
{
 // doing it this way seems backwards, but I don't
 // see an easy way to do this with C/C++ style IO
 // that isn't worse...
 int size;
 unsigned char* buf = Path_ReadBinaryFile( strFilename, &size );
 if (!buf)
  return "";

 // convert CRLF -> LF
 size_t outsize = 1;
 for (int i=1; i < size; i++)
 {
  if (buf[i] == '\n' && buf[i-1] == '\r'// CRLF
   buf[outsize-1] = '\n'// ->LF
  else
   buf[outsize++] = buf[i]; // just copy
 }

 std::string ret((char *)buf, outsize);
 delete[] buf;
 return ret;
}


bool Path_MakeWritable( const std::string &strFilename )
{
#if defined ( _WIN32 )
 std::wstring wstrFilename = UTF8to16( strFilename.c_str() );

 DWORD dwAttrs = GetFileAttributesW( wstrFilename.c_str() );
 if ( dwAttrs != INVALID_FILE_ATTRIBUTES && ( dwAttrs & FILE_ATTRIBUTE_READONLY ) )
 {
  return SetFileAttributesW( wstrFilename.c_str(), dwAttrs & ~FILE_ATTRIBUTE_READONLY );
 }
#else
 struct stat sb;

 if ( stat( strFilename.c_str(), &sb ) == 0 && !( sb.st_mode & S_IWUSR ) )
 {
  return ( chmod( strFilename.c_str(), sb.st_mode | S_IWUSR ) == 0 );
 }
#endif

 return true;
}

bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData )
{
 FILE *f;
#if defined( POSIX )
 f = fopen( strFilename.c_str(), "w" );
#else
 std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"w" );
 if ( err != 0 )
 {
  f = NULL;
 }
#endif
 
 bool ok = false;

 if ( f != NULL )
 {
  ok = fputs( pchData, f) >= 0;
  fclose(f);
 }

 return ok;
}

bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData )
{
 std::string strTmpFilename = strFilename + ".tmp";

 if ( !Path_WriteStringToTextFile( strTmpFilename, pchData ) )
  return false;

 // Platform specific atomic file replacement
#if defined( _WIN32 )
 std::wstring wsFilename = UTF8to16( strFilename.c_str() );
 std::wstring wsTmpFilename = UTF8to16( strTmpFilename.c_str() );
 if ( !::ReplaceFileW( wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0 ) )
 {
  // if we couldn't ReplaceFile, try a non-atomic write as a fallback
  if ( !Path_WriteStringToTextFile( strFilename, pchData ) )
   return false;
 }
#elif defined( POSIX )
 if ( rename( strTmpFilename.c_str(), strFilename.c_str() ) == -1 )
  return false;
#else
#error Do not know how to write atomic file
#endif

 return true;
}


#if defined(WIN32)
#define FILE_URL_PREFIX "file:///"
#else
#define FILE_URL_PREFIX "file://"
#endif

// Mozilla: see mozilla.patch for more details
// ----------------------------------------------------------------------------------------------------------------------------
// Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL)
// ----------------------------------------------------------------------------------------------------------------------------
// std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath )
// {
//  if ( StringHasPrefix( sRelativePath, "http://" )
//  || StringHasPrefix( sRelativePath, "https://" )
//  || StringHasPrefix( sRelativePath, "vr-input-workshop://" )
//  || StringHasPrefix( sRelativePath, "file://" )
//     )
//  {
//  return sRelativePath;
//  }
//  else
//  {
//  std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath );
//  if ( sAbsolute.empty() )
//  return sAbsolute;
//  sAbsolute = Path_FixSlashes( sAbsolute, '/' );

//  size_t unBufferSize = sAbsolute.length() * 3;
//  char *pchBuffer = (char *)alloca( unBufferSize );
//  V_URLEncodeFullPath( pchBuffer, (int)unBufferSize, sAbsolute.c_str(), (int)sAbsolute.length() );

//  return std::string( FILE_URL_PREFIX ) + pchBuffer;
//  }
// }

// Mozilla: see mozilla.patch for more details
// -----------------------------------------------------------------------------------------------------
// Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned
// -----------------------------------------------------------------------------------------------------
// std::string Path_UrlToFilePath( const std::string & sFileUrl )
// {
//  if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) )
//  {
//  char *pchBuffer = (char *)alloca( sFileUrl.length() );
//  V_URLDecodeNoPlusForSpace( pchBuffer, (int)sFileUrl.length(), 
//  sFileUrl.c_str() + strlen( FILE_URL_PREFIX ), (int)( sFileUrl.length() - strlen( FILE_URL_PREFIX ) ) );

//  return Path_FixSlashes( pchBuffer );
//  }
//  else
//  {
//  return "";
//  }
// }


// -----------------------------------------------------------------------------------------------------
// Purpose: Returns the root of the directory the system wants us to store user documents in
// -----------------------------------------------------------------------------------------------------
std::string GetUserDocumentsPath()
{
#if defined( WIN32 )
 WCHAR rwchPath[MAX_PATH];

 if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
 {
  return "";
 }

 // Convert the path to UTF-8 and store in the output
 std::string sUserPath = UTF16to8( rwchPath );

 return sUserPath;
#elif defined( OSX )
 @autoreleasepool {
  NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
  if ( [paths count] == 0 )
  {
   return "";
  }
  
  return [[paths objectAtIndex:0] UTF8String];
 }
#elif defined( LINUX )
 // @todo: not solved/changed as part of OSX - still not real - just removed old class based steam cut and paste
 const char *pchHome = getenv( "HOME" );
 if ( pchHome == NULL )
 {
  return "";
 }
 return pchHome;
#endif
}


// -----------------------------------------------------------------------------------------------------
// Purpose: deletes / unlinks a single file
// -----------------------------------------------------------------------------------------------------
bool Path_UnlinkFile( const std::string &strFilename )
{
#if defined( WIN32 )
 std::wstring wsFilename = UTF8to16( strFilename.c_str() );
 return ( 0 != DeleteFileW( wsFilename.c_str() ) );
#else
 return ( 0 == unlink( strFilename.c_str() ) );
#endif
}

Messung V0.5
C=88 H=95 G=91

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge