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

          Line data    Source code
       1             : //========= Copyright Valve Corporation ============//
       2             : 
       3             : #include "vrpathregistry_public.h"
       4             : #include "json/json.h"
       5             : #include "pathtools_public.h"
       6             : #include "envvartools_public.h"
       7             : #include "strtools_public.h"
       8             : #include "dirtools_public.h"
       9             : 
      10             : #if defined( WIN32 )
      11             : #include <windows.h>
      12             : #include <shlobj.h>
      13             : 
      14             : #undef GetEnvironmentVariable
      15             : #elif defined OSX
      16             : #include <Foundation/Foundation.h>
      17             : #include <AppKit/AppKit.h>
      18             : #elif defined(LINUX)
      19             : #include <dlfcn.h>
      20             : #include <stdio.h>
      21             : #endif
      22             : 
      23             : #include <algorithm>
      24             : 
      25             : #ifndef VRLog
      26             :         #if defined( __MINGW32__ )
      27             :                 #define VRLog(args...)          fprintf(stderr, args)
      28             :         #elif defined( WIN32 )
      29             :                 #define VRLog(fmt, ...)         fprintf(stderr, fmt, __VA_ARGS__)
      30             :         #else
      31             :                 #define VRLog(args...)          fprintf(stderr, args)
      32             :         #endif
      33             : #endif
      34             : 
      35             : /** Returns the root of the directory the system wants us to store user config data in */
      36           0 : static std::string GetAppSettingsPath()
      37             : {
      38             : #if defined( WIN32 )
      39             :         WCHAR rwchPath[MAX_PATH];
      40             : 
      41             :         if( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
      42             :         {
      43             :                 return "";
      44             :         }
      45             : 
      46             :         // Convert the path to UTF-8 and store in the output
      47             :         std::string sUserPath = UTF16to8( rwchPath );
      48             : 
      49             :         return sUserPath;
      50             : #elif defined( OSX )
      51             :         std::string sSettingsDir;
      52             :         @autoreleasepool {
      53             :                 // Search for the path
      54             :                 NSArray *paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, YES );
      55             :                 if ( [paths count] == 0 )
      56             :                 {
      57             :                         return "";
      58             :                 }
      59             :                 
      60             :                 NSString *resolvedPath = [paths objectAtIndex:0];
      61             :                 resolvedPath = [resolvedPath stringByAppendingPathComponent: @"OpenVR"];
      62             :                 
      63             :                 if ( ![[NSFileManager new] createDirectoryAtPath: resolvedPath withIntermediateDirectories:YES attributes:nil error:nil] )
      64             :                 {
      65             :                         return "";
      66             :                 }
      67             :                 
      68             :                 sSettingsDir.assign( [resolvedPath UTF8String] );
      69             :         }
      70             :         return sSettingsDir;
      71             : #elif defined( LINUX )
      72             : 
      73             :         // As defined by XDG Base Directory Specification 
      74             :         // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
      75             : 
      76           0 :         const char *pchHome = getenv("XDG_CONFIG_HOME");
      77           0 :         if ( ( pchHome != NULL) && ( pchHome[0] != '\0' ) )
      78             :         {
      79           0 :                 return pchHome;
      80             :         }
      81             : 
      82             :         //
      83             :         // XDG_CONFIG_HOME is not defined, use ~/.config instead
      84             :         // 
      85           0 :         pchHome = getenv( "HOME" );
      86           0 :         if ( pchHome == NULL )
      87             :         {
      88           0 :                 return "";
      89             :         }
      90             : 
      91           0 :         std::string sUserPath( pchHome );
      92           0 :         sUserPath = Path_Join( sUserPath, ".config" );
      93           0 :         return sUserPath;
      94             : #else
      95             :         #warning "Unsupported platform"
      96             : #endif
      97             : }
      98             : 
      99             : 
     100             : // ---------------------------------------------------------------------------
     101             : // Purpose: Constructor
     102             : // ---------------------------------------------------------------------------
     103           0 : CVRPathRegistry_Public::CVRPathRegistry_Public()
     104             : {
     105             : 
     106           0 : }
     107             : 
     108             : // ---------------------------------------------------------------------------
     109             : // Purpose: Computes the registry filename
     110             : // ---------------------------------------------------------------------------
     111           0 : std::string CVRPathRegistry_Public::GetOpenVRConfigPath()
     112             : {
     113           0 :         std::string sConfigPath = GetAppSettingsPath();
     114           0 :         if( sConfigPath.empty() )
     115           0 :                 return "";
     116             : 
     117             : #if defined( _WIN32 ) || defined( LINUX )
     118           0 :         sConfigPath = Path_Join( sConfigPath, "openvr" );
     119             : #elif defined ( OSX ) 
     120             :         sConfigPath = Path_Join( sConfigPath, ".openvr" );
     121             : #else
     122             :         #warning "Unsupported platform"
     123             : #endif
     124           0 :         sConfigPath = Path_FixSlashes( sConfigPath );
     125           0 :         return sConfigPath;
     126             : }
     127             : 
     128             : 
     129             : 
     130             : //-----------------------------------------------------------------------------
     131             : // Purpose:
     132             : //-----------------------------------------------------------------------------
     133           0 : std::string CVRPathRegistry_Public::GetVRPathRegistryFilename()
     134             : {
     135           0 :         std::string sPath = GetOpenVRConfigPath();
     136           0 :         if ( sPath.empty() )
     137           0 :                 return "";
     138             : 
     139             : #if defined( _WIN32 )
     140             :         sPath = Path_Join( sPath, "openvrpaths.vrpath" );
     141             : #elif defined ( POSIX ) 
     142           0 :         sPath = Path_Join( sPath, "openvrpaths.vrpath" );
     143             : #else
     144             :         #error "Unsupported platform"
     145             : #endif
     146           0 :         sPath = Path_FixSlashes( sPath );
     147           0 :         return sPath;
     148             : }
     149             : 
     150             : 
     151             : // ---------------------------------------------------------------------------
     152             : // Purpose: Converts JSON to a history array
     153             : // ---------------------------------------------------------------------------
     154           0 : static void ParseStringListFromJson( std::vector< std::string > *pvecHistory, const Json::Value & root, const char *pchArrayName )
     155             : {
     156           0 :         if( !root.isMember( pchArrayName ) )
     157           0 :                 return;
     158             : 
     159           0 :         const Json::Value & arrayNode = root[ pchArrayName ];
     160           0 :         if( !arrayNode )
     161             :         {
     162           0 :                 VRLog( "VR Path Registry node %s is not an array\n", pchArrayName );
     163           0 :                 return;
     164             :         }
     165             : 
     166           0 :         pvecHistory->clear();
     167           0 :         pvecHistory->reserve( arrayNode.size() );
     168           0 :         for( uint32_t unIndex = 0; unIndex < arrayNode.size(); unIndex++ )
     169             :         {
     170           0 :                 std::string sPath( arrayNode[ unIndex ].asString() );
     171           0 :                 pvecHistory->push_back( sPath );
     172             :         }
     173             : }
     174             : 
     175             : 
     176             : // ---------------------------------------------------------------------------
     177             : // Purpose: Converts a history array to JSON
     178             : // ---------------------------------------------------------------------------
     179           0 : static void StringListToJson( const std::vector< std::string > & vecHistory, Json::Value & root, const char *pchArrayName )
     180             : {
     181           0 :         Json::Value & arrayNode = root[ pchArrayName ];
     182           0 :         for( auto i = vecHistory.begin(); i != vecHistory.end(); i++ )
     183             :         {
     184           0 :                 arrayNode.append( *i );
     185             :         }
     186           0 : }
     187             : 
     188             : 
     189             : //-----------------------------------------------------------------------------
     190             : // Purpose:
     191             : //-----------------------------------------------------------------------------
     192           0 : bool CVRPathRegistry_Public::ToJsonString( std::string &sJsonString )
     193             : {
     194           0 :         std::string sRegPath = GetVRPathRegistryFilename();
     195           0 :         if( sRegPath.empty() )
     196           0 :                 return false;
     197             :         
     198           0 :         std::string sRegistryContents = Path_ReadTextFile( sRegPath );
     199           0 :         if( sRegistryContents.empty() )
     200           0 :                 return false;
     201             : 
     202           0 :         sJsonString = sRegistryContents;
     203             : 
     204           0 :         return true;
     205             : }
     206             : 
     207             : 
     208             : // ---------------------------------------------------------------------------
     209             : // Purpose: Loads the config file from its well known location
     210             : // ---------------------------------------------------------------------------
     211           0 : bool CVRPathRegistry_Public::BLoadFromFile()
     212             : {
     213           0 :         std::string sRegPath = GetVRPathRegistryFilename();
     214           0 :         if( sRegPath.empty() )
     215             :         {
     216           0 :                 VRLog( "Unable to determine VR Path Registry filename\n" );
     217           0 :                 return false;
     218             :         }
     219             : 
     220           0 :         std::string sRegistryContents = Path_ReadTextFile( sRegPath );
     221           0 :         if( sRegistryContents.empty() )
     222             :         {
     223           0 :                 VRLog( "Unable to read VR Path Registry from %s\n", sRegPath.c_str() );
     224           0 :                 return false;
     225             :         }
     226             : 
     227           0 :         Json::Value root;
     228           0 :         Json::Reader reader;
     229             : 
     230           0 :         if( !reader.parse( sRegistryContents, root ) )
     231             :         {
     232           0 :                 VRLog( "Unable to parse %s: %s\n", sRegPath.c_str(), reader.getFormattedErrorMessages().c_str() );
     233           0 :                 return false;
     234             :         }
     235             : 
     236           0 :         ParseStringListFromJson( &m_vecRuntimePath, root, "runtime" );
     237           0 :         ParseStringListFromJson( &m_vecConfigPath, root, "config" );
     238           0 :         ParseStringListFromJson( &m_vecLogPath, root, "log" );
     239           0 :         if (root.isMember( "external_drivers" ) && root[ "external_drivers" ].isArray() )
     240             :         {
     241           0 :                 ParseStringListFromJson( &m_vecExternalDrivers, root, "external_drivers" );
     242             :         }
     243             : 
     244           0 :         return true;
     245             : }
     246             : 
     247             : 
     248             : // ---------------------------------------------------------------------------
     249             : // Purpose: Saves the config file to its well known location
     250             : // ---------------------------------------------------------------------------
     251           0 : bool CVRPathRegistry_Public::BSaveToFile() const
     252             : {
     253             : #if defined( DASHBOARD_BUILD_MODE )
     254             :         return false;
     255             : #else
     256           0 :         std::string sRegPath = GetVRPathRegistryFilename();
     257           0 :         if( sRegPath.empty() )
     258           0 :                 return false;
     259             :         
     260           0 :         Json::Value root;
     261             :         
     262           0 :         root[ "version" ] = 1;
     263           0 :         root[ "jsonid" ] = "vrpathreg";
     264             : 
     265           0 :         StringListToJson( m_vecRuntimePath, root, "runtime" );
     266           0 :         StringListToJson( m_vecConfigPath, root, "config" );
     267           0 :         StringListToJson( m_vecLogPath, root, "log" );
     268           0 :         StringListToJson( m_vecExternalDrivers, root, "external_drivers" );
     269             : 
     270           0 :         Json::StyledWriter writer;
     271           0 :         std::string sRegistryContents = writer.write( root );
     272             : 
     273             :         // make sure the directory we're writing into actually exists
     274           0 :         std::string sRegDirectory = Path_StripFilename( sRegPath );
     275           0 :         if( !BCreateDirectoryRecursive( sRegDirectory.c_str() ) )
     276             :         {
     277           0 :                 VRLog( "Unable to create path registry directory %s\n", sRegDirectory.c_str() );
     278           0 :                 return false;
     279             :         }
     280             : 
     281           0 :         if( !Path_WriteStringToTextFile( sRegPath, sRegistryContents.c_str() ) )
     282             :         {
     283           0 :                 VRLog( "Unable to write VR path registry to %s\n", sRegPath.c_str() );
     284           0 :                 return false;
     285             :         }
     286             : 
     287           0 :         return true;
     288             : #endif
     289             : }
     290             : 
     291             : 
     292             : // ---------------------------------------------------------------------------
     293             : // Purpose: Returns the current runtime path or NULL if no path is configured.
     294             : // ---------------------------------------------------------------------------
     295           0 : std::string CVRPathRegistry_Public::GetRuntimePath() const
     296             : {
     297           0 :         if( m_vecRuntimePath.empty() )
     298           0 :                 return "";
     299             :         else
     300           0 :                 return m_vecRuntimePath.front().c_str();
     301             : }
     302             : 
     303             : 
     304             : // ---------------------------------------------------------------------------
     305             : // Purpose: Returns the current config path or NULL if no path is configured.
     306             : // ---------------------------------------------------------------------------
     307           0 : std::string CVRPathRegistry_Public::GetConfigPath() const
     308             : {
     309           0 :         if( m_vecConfigPath.empty() )
     310           0 :                 return "";
     311             :         else
     312           0 :                 return m_vecConfigPath.front().c_str();
     313             : }
     314             : 
     315             : 
     316             : // ---------------------------------------------------------------------------
     317             : // Purpose: Returns the current log path or NULL if no path is configured.
     318             : // ---------------------------------------------------------------------------
     319           0 : std::string CVRPathRegistry_Public::GetLogPath() const
     320             : {
     321           0 :         if( m_vecLogPath.empty() )
     322           0 :                 return "";
     323             :         else
     324           0 :                 return m_vecLogPath.front().c_str();
     325             : }
     326             : 
     327             : 
     328             : 
     329             : // ---------------------------------------------------------------------------
     330             : // Purpose: Returns paths using the path registry and the provided override 
     331             : //                      values. Pass NULL for any paths you don't care about.
     332             : // ---------------------------------------------------------------------------
     333           0 : bool CVRPathRegistry_Public::GetPaths( std::string *psRuntimePath, std::string *psConfigPath, std::string *psLogPath, const char *pchConfigPathOverride, const char *pchLogPathOverride, std::vector<std::string> *pvecExternalDrivers )
     334             : {
     335           0 :         CVRPathRegistry_Public pathReg;
     336           0 :         bool bLoadedRegistry = pathReg.BLoadFromFile();
     337           0 :         int nCountEnvironmentVariables = 0;
     338             : 
     339           0 :         if( psRuntimePath )
     340             :         {
     341           0 :                 if ( GetEnvironmentVariable( k_pchRuntimeOverrideVar ).length() != 0 )
     342             :                 {
     343           0 :                         *psRuntimePath = GetEnvironmentVariable( k_pchRuntimeOverrideVar );
     344           0 :                         nCountEnvironmentVariables++;
     345             :                 }
     346           0 :                 else if( !pathReg.GetRuntimePath().empty() )
     347             :                 {
     348           0 :                         *psRuntimePath = pathReg.GetRuntimePath();
     349             :                 }
     350             :                 else
     351             :                 {
     352           0 :                         *psRuntimePath = "";
     353             :                 }
     354             :         }
     355             : 
     356           0 :         if( psConfigPath )
     357             :         {
     358           0 :                 if ( GetEnvironmentVariable( k_pchConfigOverrideVar ).length() != 0 )
     359             :                 {
     360           0 :                         *psConfigPath = GetEnvironmentVariable( k_pchConfigOverrideVar );
     361           0 :                         nCountEnvironmentVariables++;
     362             :                 }
     363           0 :                 else if( pchConfigPathOverride )
     364             :                 {
     365           0 :                         *psConfigPath = pchConfigPathOverride;
     366             :                 }
     367           0 :                 else if( !pathReg.GetConfigPath().empty() )
     368             :                 {
     369           0 :                         *psConfigPath = pathReg.GetConfigPath();
     370             :                 }
     371             :                 else
     372             :                 {
     373           0 :                         *psConfigPath = "";
     374             :                 }
     375             :         }
     376             : 
     377           0 :         if( psLogPath )
     378             :         {
     379           0 :                 if ( GetEnvironmentVariable( k_pchLogOverrideVar ).length() != 0 )
     380             :                 {
     381           0 :                         *psLogPath = GetEnvironmentVariable( k_pchLogOverrideVar );
     382           0 :                         nCountEnvironmentVariables++;
     383             :                 }
     384           0 :                 else if( pchLogPathOverride )
     385             :                 {
     386           0 :                         *psLogPath = pchLogPathOverride;
     387             :                 }
     388           0 :                 else if( !pathReg.GetLogPath().empty() )
     389             :                 {
     390           0 :                         *psLogPath = pathReg.GetLogPath();
     391             :                 }
     392             :                 else
     393             :                 {
     394           0 :                         *psLogPath = "";
     395             :                 }
     396             :         }
     397             : 
     398           0 :         if ( pvecExternalDrivers )
     399             :         {
     400           0 :                 *pvecExternalDrivers = pathReg.m_vecExternalDrivers;
     401             :         }
     402             : 
     403           0 :         if ( nCountEnvironmentVariables == 3 )
     404             :         {
     405             :                 // all three environment variables where set, so we don't need the physical file
     406           0 :                 return true;
     407             :         }
     408             : 
     409           0 :         return bLoadedRegistry;
     410             : }
     411             : 

Generated by: LCOV version 1.13