diff --git a/src/BGAnimationLayer.cpp b/src/BGAnimationLayer.cpp index 8928688a74..0caa21ccb6 100644 --- a/src/BGAnimationLayer.cpp +++ b/src/BGAnimationLayer.cpp @@ -402,16 +402,16 @@ void BGAnimationLayer::LoadFromNode( const XNode* pNode ) { m_Type = TYPE_TILES; } - else if( std::stoi(type) == 1 ) + else if( StringToInt(type) == 1 ) { m_Type = TYPE_SPRITE; bStretch = true; } - else if( std::stoi(type) == 2 ) + else if( StringToInt(type) == 2 ) { m_Type = TYPE_PARTICLES; } - else if( std::stoi(type) == 3 ) + else if( StringToInt(type) == 3 ) { m_Type = TYPE_TILES; } diff --git a/src/CourseLoaderCRS.cpp b/src/CourseLoaderCRS.cpp index 3d67fb041c..d2eee8228c 100644 --- a/src/CourseLoaderCRS.cpp +++ b/src/CourseLoaderCRS.cpp @@ -87,7 +87,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou } else if( sValueName.EqualsNoCase("LIVES") ) { - out.m_iLives = max( std::stoi(sParams[1]), 0 ); + out.m_iLives = max( StringToInt(sParams[1]), 0 ); } else if( sValueName.EqualsNoCase("GAINSECONDS") ) { @@ -97,7 +97,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou { if( sParams.params.size() == 2 ) { - out.m_iCustomMeter[Difficulty_Medium] = max( std::stoi(sParams[1]), 0 ); /* compat */ + out.m_iCustomMeter[Difficulty_Medium] = max( StringToInt(sParams[1]), 0 ); /* compat */ } else if( sParams.params.size() == 3 ) { @@ -107,7 +107,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou LOG->UserLog( "Course file", sPath, "contains an invalid #METER string: \"%s\"", sParams[1].c_str() ); continue; } - out.m_iCustomMeter[cd] = max( std::stoi(sParams[2]), 0 ); + out.m_iCustomMeter[cd] = max( StringToInt(sParams[2]), 0 ); } } @@ -168,7 +168,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou // most played if( sParams[1].Left(strlen("BEST")) == "BEST" ) { - int iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1; + int iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1; if( iChooseIndex > iNumSongs ) { // looking up a song that doesn't exist. @@ -185,7 +185,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou // least played else if( sParams[1].Left(strlen("WORST")) == "WORST" ) { - int iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1; + int iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1; if( iChooseIndex > iNumSongs ) { // looking up a song that doesn't exist. @@ -202,14 +202,14 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou // best grades else if( sParams[1].Left(strlen("GRADEBEST")) == "GRADEBEST" ) { - new_entry.iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("GRADEBEST")) ) - 1; + new_entry.iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("GRADEBEST")) ) - 1; CLAMP( new_entry.iChooseIndex, 0, 500 ); new_entry.songSort = SongSort_TopGrades; } // worst grades else if( sParams[1].Left(strlen("GRADEWORST")) == "GRADEWORST" ) { - new_entry.iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("GRADEWORST")) ) - 1; + new_entry.iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("GRADEWORST")) ) - 1; CLAMP( new_entry.iChooseIndex, 0, 500 ); new_entry.songSort = SongSort_LowestGrades; } @@ -308,7 +308,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou else if( !sMod.CompareNoCase("nodifficult") ) new_entry.bNoDifficult = true; else if( sMod.length() > 5 && !sMod.Left(5).CompareNoCase("award") ) - new_entry.iGainLives = std::stoi( sMod.substr(5) ); + new_entry.iGainLives = StringToInt( sMod.substr(5) ); else continue; mods.erase( mods.begin() + j ); @@ -330,8 +330,8 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou else if( bFromCache && !sValueName.EqualsNoCase("RADAR") ) { - StepsType st = (StepsType) std::stoi(sParams[1]); - CourseDifficulty cd = (CourseDifficulty) std::stoi( sParams[2] ); + StepsType st = (StepsType) StringToInt(sParams[1]); + CourseDifficulty cd = (CourseDifficulty) StringToInt( sParams[2] ); RadarValues rv; rv.FromString( sParams[3] ); diff --git a/src/FileDownload.cpp b/src/FileDownload.cpp index c532719969..441e31bf84 100644 --- a/src/FileDownload.cpp +++ b/src/FileDownload.cpp @@ -267,14 +267,14 @@ void FileTransfer::HTTPUpdate() m_sResponseName = "Malformed response."; return; } - m_iResponseCode = std::stoi(m_sBUFFER.substr(i+1,j-i)); + m_iResponseCode = StringToInt(m_sBUFFER.substr(i+1,j-i)); m_sResponseName = m_sBUFFER.substr( j+1, k-j ); i = m_sBUFFER.find("Content-Length:"); j = m_sBUFFER.find("\n", i+1 ); if( i != string::npos ) - m_iTotalBytes = std::stoi(m_sBUFFER.substr(i+16,j-i)); + m_iTotalBytes = StringToInt(m_sBUFFER.substr(i+16,j-i)); else m_iTotalBytes = -1; // We don't know, so go until disconnect @@ -345,7 +345,7 @@ bool FileTransfer::ParseHTTPAddress( const RString &URL, RString &sProto, RStrin sServer = asMatches[1]; if( asMatches[3] != "" ) { - iPort = std::stoi(asMatches[3]); + iPort = StringToInt(asMatches[3]); if( iPort == 0 ) return false; } diff --git a/src/Font.cpp b/src/Font.cpp index 2587e0f060..934859fd2a 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -488,7 +488,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr // If val is an integer, it's a width, eg. "10=27". if( IsAnInt(sName) ) { - cfg.m_mapGlyphWidths[std::stoi(sName)] = pValue->GetValue(); + cfg.m_mapGlyphWidths[StringToInt(sName)] = pValue->GetValue(); continue; } @@ -603,7 +603,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr row_str.c_str()); continue; } - const int row = std::stoi(row_str); + const int row = StringToInt(row_str); const int first_frame = row * num_frames_wide; if(row >= num_frames_high) diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp index c5d638d401..d737c86e5b 100644 --- a/src/GameCommand.cpp +++ b/src/GameCommand.cpp @@ -377,12 +377,12 @@ void GameCommand::LoadOne( const Command& cmd ) else if( sName == "weight" ) { - m_iWeightPounds = std::stoi( sValue ); + m_iWeightPounds = StringToInt( sValue ); } else if( sName == "goalcalories" ) { - m_iGoalCalories = std::stoi( sValue ); + m_iGoalCalories = StringToInt( sValue ); } else if( sName == "goaltype" ) diff --git a/src/GameState.cpp b/src/GameState.cpp index be32f36790..51852c9a51 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -246,7 +246,7 @@ void GameState::ApplyCmdline() RString sPlayer; for( int i = 0; GetCommandlineArgument( "player", &sPlayer, i ); ++i ) { - int pn = std::stoi( sPlayer )-1; + int pn = StringToInt( sPlayer )-1; if( !IsAnInt( sPlayer ) || pn < 0 || pn >= NUM_PLAYERS ) RageException::Throw( "Invalid argument \"--player=%s\".", sPlayer.c_str() ); diff --git a/src/NoteSkinManager.cpp b/src/NoteSkinManager.cpp index 5f72784dc8..562da9f83a 100644 --- a/src/NoteSkinManager.cpp +++ b/src/NoteSkinManager.cpp @@ -310,7 +310,7 @@ RString NoteSkinManager::GetMetric( const RString &sButtonName, const RString &s int NoteSkinManager::GetMetricI( const RString &sButtonName, const RString &sValueName ) { - return std::stoi( GetMetric(sButtonName,sValueName) ); + return StringToInt( GetMetric(sButtonName,sValueName) ); } float NoteSkinManager::GetMetricF( const RString &sButtonName, const RString &sValueName ) @@ -321,7 +321,7 @@ float NoteSkinManager::GetMetricF( const RString &sButtonName, const RString &sV bool NoteSkinManager::GetMetricB( const RString &sButtonName, const RString &sValueName ) { // Could also call GetMetricI here...hmm. - return std::stoi( GetMetric(sButtonName,sValueName) ) != 0; + return StringToInt( GetMetric(sButtonName,sValueName) ) != 0; } apActorCommands NoteSkinManager::GetMetricA( const RString &sButtonName, const RString &sValueName ) diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index b74ec6a595..0a59ed001b 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -483,7 +483,7 @@ struct bmsCommandTree while (randomStack.size() < currentNode->branchHeight + 1) // if we're on branch level N we need N+1 values. randomStack.push_back(0); - randomStack[currentNode->branchHeight] = rand() % std::stoi(value) + 1; + randomStack[currentNode->branchHeight] = rand() % StringToInt(value) + 1; } else { @@ -886,12 +886,12 @@ void BMSChartReader::ReadHeaders() } else if( it->first == "#playlevel" ) { - out->SetMeter( std::stoi(it->second) ); + out->SetMeter( StringToInt(it->second) ); } else if( it->first == "#difficulty") { // only set the difficulty if the #difficulty tag is between 1 and 6 (beginner~edit) - int diff = std::stoi(it->second)-1; // BMS uses 1 to 6, SM uses 0 to 5 + int diff = StringToInt(it->second)-1; // BMS uses 1 to 6, SM uses 0 to 5 if(diff>=0 && diffSetDifficulty( (Difficulty)diff ); } diff --git a/src/NotesLoaderDWI.cpp b/src/NotesLoaderDWI.cpp index b94ce49763..ece1b5fe1f 100644 --- a/src/NotesLoaderDWI.cpp +++ b/src/NotesLoaderDWI.cpp @@ -430,7 +430,7 @@ static bool LoadFromDWITokens( if( sNumFeet.empty() ) sNumFeet = "1"; - out.SetMeter(std::stoi(sNumFeet)); + out.SetMeter(StringToInt(sNumFeet)); out.SetDifficulty( DwiCompatibleStringToDifficulty(sDescription) ); @@ -508,7 +508,7 @@ bool DWILoader::LoadNoteDataFromSimfile( const RString &path, Steps &out ) continue; if (out.GetDifficulty() != DwiCompatibleStringToDifficulty(params[1])) continue; - if (out.GetMeter() != std::stoi(params[2])) + if (out.GetMeter() != StringToInt(params[2])) continue; RString step1 = params[3]; RString step2 = (iNumParams==5) ? params[4] : RString(""); @@ -626,7 +626,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla else if( sValueName.EqualsNoCase("GAP") ) // the units of GAP is 1/1000 second - out.m_SongTiming.m_fBeat0OffsetInSeconds = -std::stoi(sParams[1]) / 1000.0f; + out.m_SongTiming.m_fBeat0OffsetInSeconds = -StringToInt(sParams[1]) / 1000.0f; else if( sValueName.EqualsNoCase("SAMPLESTART") ) out.m_fMusicSampleStartSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]); diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index e75665a529..5b063956e5 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -130,7 +130,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool else if( sValueName=="TICKCOUNT" ) { - iTickCount = std::stoi( sParams[1] ); + iTickCount = StringToInt( sParams[1] ); if( iTickCount <= 0 ) { LOG->UserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount ); @@ -141,7 +141,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool else if( sValueName=="DIFFICULTY" ) { - out.SetMeter( max(std::stoi(sParams[1]), 1) ); + out.SetMeter( max(StringToInt(sParams[1]), 1) ); } // new cases from Aldo_MX's fork: else if( sValueName=="PLAYER" ) @@ -515,7 +515,7 @@ static void ProcessTickcounts( const RString & value, int & ticks, TimingData & /* TICKCOUNT will be used below if there are DM compliant BPM changes * and stops. It will be called again in LoadFromKSFFile for the * actual steps. */ - ticks = std::stoi( value ); + ticks = StringToInt( value ); CLAMP( ticks, 0, ROWS_PER_BEAT ); if( ticks == 0 ) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index b0b52148a2..d874543a42 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -156,7 +156,7 @@ void SMSetSelectable(SMSongTagInfo& info) * used 3.9+ features are not excluded here */ else if((*info.params)[1].EqualsNoCase("ES") || (*info.params)[1].EqualsNoCase("OMES")) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } - else if(std::stoi((*info.params)[1]) > 0) + else if(StringToInt((*info.params)[1]) > 0) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } else { LOG->UserLog("Song file", info.path, "has an unknown #SELECTABLE value, \"%s\"; ignored.", (*info.params)[1].c_str()); } @@ -337,7 +337,7 @@ void SMLoader::LoadFromTokens( // have a meter on certain steps. Make the meter 1 in these instances. sMeter = "1"; } - out.SetMeter( std::stoi(sMeter) ); + out.SetMeter( StringToInt(sMeter) ); out.SetSMNoteData( sNoteData ); @@ -786,8 +786,8 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const } const float fBeat = RowToBeat( vs2[0], rowsPerBeat ); - const int iNumerator = std::stoi( vs2[1] ); - const int iDenominator = std::stoi( vs2[2] ); + const int iNumerator = StringToInt( vs2[1] ); + const int iDenominator = StringToInt( vs2[2] ); if( fBeat < 0 ) { @@ -879,7 +879,7 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row const float fDelay = StringToFloat( vs2[2] ); // XXX: ugly... - int iUnit = std::stoi(vs2[3]); + int iUnit = StringToInt(vs2[3]); SpeedSegment::BaseUnit unit = (iUnit == 0) ? SpeedSegment::UNIT_BEATS : SpeedSegment::UNIT_SECONDS; diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index f60090ed90..67c672a107 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -33,11 +33,11 @@ void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, con continue; } const float fComboBeat = RowToBeat( arrayMultiplierValues[0], iRowsPerBeat ); - const int iCombos = std::stoi( arrayMultiplierValues[1] ); // always true. + const int iCombos = StringToInt( arrayMultiplierValues[1] ); // always true. // hoping I'm right here: SMA files can use 6 values after the row/beat. const int iMisses = (size == 2 || size == 4 ? iCombos : - std::stoi(arrayMultiplierValues[2])); + StringToInt(arrayMultiplierValues[2])); out.AddSegment( ComboSegment(BeatToNoteRow(fComboBeat), iCombos, iMisses) ); } } @@ -61,7 +61,7 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) continue; } const float fBeat = StringToFloat( vs2[0] ); - const int iNumerator = std::stoi( vs2[1] ); + const int iNumerator = StringToInt( vs2[1] ); if( fBeat < 0 ) { @@ -296,7 +296,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach vector arrayBeatChangeValues; split( arrayBeatChangeExpressions[0], "=", arrayBeatChangeValues ); - iRowsPerBeat = std::stoi(arrayBeatChangeValues[1]); + iRowsPerBeat = StringToInt(arrayBeatChangeValues[1]); } else { @@ -328,7 +328,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach * used 3.9+ features are not excluded here */ else if(sParams[1].EqualsNoCase("ES") || sParams[1].EqualsNoCase("OMES")) out.m_SelectionDisplay = out.SHOW_ALWAYS; - else if( std::stoi(sParams[1]) > 0 ) + else if( StringToInt(sParams[1]) > 0 ) out.m_SelectionDisplay = out.SHOW_ALWAYS; else LOG->UserLog("Song file", diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 4d65761983..dca74e2acc 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -199,7 +199,7 @@ void SetSelectable(SongTagInfo& info) * used 3.9+ features are not excluded here */ else if((*info.params)[1].EqualsNoCase("ES") || (*info.params)[1].EqualsNoCase("OMES")) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } - else if(std::stoi((*info.params)[1]) > 0) + else if(StringToInt((*info.params)[1]) > 0) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } else { LOG->UserLog("Song file", info.path, "has an unknown #SELECTABLE value, \"%s\"; ignored.", (*info.params)[1].c_str()); } @@ -298,12 +298,12 @@ void SetSongFilename(SongTagInfo& info) void SetHasMusic(SongTagInfo& info) { if(info.from_cache) - { info.song->m_bHasMusic = std::stoi((*info.params)[1]) != 0; } + { info.song->m_bHasMusic = StringToInt((*info.params)[1]) != 0; } } void SetHasBanner(SongTagInfo& info) { if(info.from_cache) - { info.song->m_bHasBanner = std::stoi((*info.params)[1]) != 0; } + { info.song->m_bHasBanner = StringToInt((*info.params)[1]) != 0; } } // Functions for steps tags go below this line. -Kyz @@ -350,7 +350,7 @@ void SetDifficulty(StepsTagInfo& info) } void SetMeter(StepsTagInfo& info) { - info.steps->SetMeter(std::stoi((*info.params)[1])); + info.steps->SetMeter(StringToInt((*info.params)[1])); info.ssc_format= true; } void SetRadarValues(StepsTagInfo& info) @@ -797,8 +797,8 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int ro continue; } const float fComboBeat = std::stof( arrayComboValues[0] ); - const int iCombos = std::stoi( arrayComboValues[1] ); - const int iMisses = (size == 2 ? iCombos : std::stoi(arrayComboValues[2])); + const int iCombos = StringToInt( arrayComboValues[1] ); + const int iMisses = (size == 2 ? iCombos : StringToInt(arrayComboValues[2])); out.AddSegment( ComboSegment( BeatToNoteRow(fComboBeat), iCombos, iMisses ) ); } } @@ -905,7 +905,7 @@ bool SSCLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out ) { tryingSteps = false; } break; case LNDID_meter: - if(out.GetMeter() != std::stoi(matcher)) + if(out.GetMeter() != StringToInt(matcher)) { tryingSteps = false; } break; case LNDID_credit: diff --git a/src/OptionRowHandler.cpp b/src/OptionRowHandler.cpp index d066a0ad54..7eaeae7314 100644 --- a/src/OptionRowHandler.cpp +++ b/src/OptionRowHandler.cpp @@ -162,7 +162,7 @@ public: m_Def.m_bOneChoiceForAllPlayers = false; ROW_INVALID_IF(lCmds.v[0].m_vsArgs.size() != 1, "Row command has invalid args to number of entries.", false); - const int NumCols = std::stoi( lCmds.v[0].m_vsArgs[0] ); + const int NumCols = StringToInt( lCmds.v[0].m_vsArgs[0] ); ROW_INVALID_IF(NumCols < 1, "Not enough entries in list.", false); for( unsigned i=1; i= 0 && pn < NUM_PLAYERS ); m_Def.m_vEnabledForPlayers.insert( pn ); } diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp index c777164df6..193dab8abd 100644 --- a/src/PlayerOptions.cpp +++ b/src/PlayerOptions.cpp @@ -607,7 +607,7 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut { // XXX: We know what they want, is there any reason not to handle it? // Yes. We should be strict in handling the format. -Chris - sErrorOut = ssprintf("Invalid player options \"%s\"; did you mean '*%d'?", s.c_str(), std::stoi(s) ); + sErrorOut = ssprintf("Invalid player options \"%s\"; did you mean '*%d'?", s.c_str(), StringToInt(s) ); return false; } else diff --git a/src/Profile.cpp b/src/Profile.cpp index f5837bf4c9..83875362a6 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -2523,7 +2523,7 @@ RString Profile::MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameB continue; ASSERT( matches.size() == 1 ); - iIndex = std::stoi( matches[0] )+1; + iIndex = StringToInt( matches[0] )+1; break; } diff --git a/src/RageBitmapTexture.cpp b/src/RageBitmapTexture.cpp index 60ae4f4f95..419d9ea85d 100644 --- a/src/RageBitmapTexture.cpp +++ b/src/RageBitmapTexture.cpp @@ -27,8 +27,8 @@ static void GetResolutionFromFileName( RString sPath, int &iWidth, int &iHeight return; // Check for nonsense values. Some people might not intend the hint. -Kyz - int maybe_width= std::stoi(asMatches[0]); - int maybe_height= std::stoi(asMatches[1]); + int maybe_width= StringToInt(asMatches[0]); + int maybe_height= StringToInt(asMatches[1]); if(maybe_width <= 0 || maybe_height <= 0) { return; diff --git a/src/RageTexture.cpp b/src/RageTexture.cpp index f1502d9846..55586ef849 100644 --- a/src/RageTexture.cpp +++ b/src/RageTexture.cpp @@ -52,8 +52,8 @@ void RageTexture::GetFrameDimensionsFromFileName( RString sPath, int* piFramesWi return; } // Check for nonsense values. Some people might not intend the hint. -Kyz - int maybe_width= std::stoi(asMatch[0]); - int maybe_height= std::stoi(asMatch[1]); + int maybe_width= StringToInt(asMatch[0]); + int maybe_height= StringToInt(asMatch[1]); if(maybe_width <= 0 || maybe_height <= 0) { *piFramesWide = *piFramesHigh = 1; diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index 71cdef73a9..51f054f1aa 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -276,8 +276,8 @@ float HHMMSSToSeconds( const RString &sHHMMSS ) arrayBits.insert(arrayBits.begin(), "0" ); // pad missing bits float fSeconds = 0; - fSeconds += std::stoi( arrayBits[0] ) * 60 * 60; - fSeconds += std::stoi( arrayBits[1] ) * 60; + fSeconds += StringToInt( arrayBits[0] ) * 60 * 60; + fSeconds += StringToInt( arrayBits[1] ) * 60; fSeconds += StringToFloat( arrayBits[2] ); return fSeconds; @@ -1900,6 +1900,51 @@ RString FloatToString( const float &num ) return ss.str(); } +int StringToInt( const std::string& str, std::size_t* pos, int base, int exceptVal ) +{ + try + { + return std::stoi(str, pos, base); + } + catch (const std::invalid_argument & e) { + LOG->Warn( "stoi(%s): %s", str.c_str(), e.what() ); + } + catch (const std::out_of_range & e) { + LOG->Warn( "stoi(%s): %s", str.c_str(), e.what() ); + } + return exceptVal; +} + +long StringToLong( const std::string& str, std::size_t* pos, int base, long exceptVal ) +{ + try + { + return std::stol(str, pos, base); + } + catch (const std::invalid_argument & e) { + LOG->Warn( "stol(%s): %s", str.c_str(), e.what() ); + } + catch (const std::out_of_range & e) { + LOG->Warn( "stol(%s): %s", str.c_str(), e.what() ); + } + return exceptVal; +} + +long long StringToLLong( const std::string& str, std::size_t* pos, int base, long long exceptVal ) +{ + try + { + return std::stoll(str, pos, base); + } + catch (const std::invalid_argument & e) { + LOG->Warn( "stoll(%s): %s", str.c_str(), e.what() ); + } + catch (const std::out_of_range & e) { + LOG->Warn( "stoll(%s): %s", str.c_str(), e.what() ); + } + return exceptVal; +} + const wchar_t INVALID_CHAR = 0xFFFD; /* U+FFFD REPLACEMENT CHARACTER */ wstring RStringToWstring( const RString &s ) @@ -2324,7 +2369,7 @@ namespace StringConversion if( sValue.size() == 0 ) return false; - out = (std::stoi(sValue) != 0); + out = StringToInt(sValue) != 0; return true; } diff --git a/src/RageUtil.h b/src/RageUtil.h index a909259f65..ba2c4cc42e 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -418,6 +418,12 @@ inline bool operator>>(const RString& lhs, T& rhs) return !!(istringstream(lhs) >> rhs); } +// Exception-safe wrappers around stoi and friends +// Additional argument exceptVal will be returned if the conversion couldn't be performed +int StringToInt( const std::string& str, std::size_t* pos = 0, int base = 10, int exceptVal = 0 ); +long StringToLong( const std::string& str, std::size_t* pos = 0, int base = 10, long exceptVal = 0 ); +long long StringToLLong( const std::string& str, std::size_t* pos = 0, int base = 10, long long exceptVal = 0 ); + RString WStringToRString( const wstring &sString ); RString WcharToUTF8( wchar_t c ); wstring RStringToWstring( const RString &sString ); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index c25d416978..cd078af3ca 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3679,7 +3679,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else if( SM == SM_BackFromDifficultyMeterChange ) { - int i = std::stoi( ScreenTextEntry::s_sLastAnswer ); + int i = StringToInt( ScreenTextEntry::s_sLastAnswer ); GAMESTATE->m_pCurSteps[PLAYER_1]->SetMeter(i); SetDirty( true ); } @@ -3733,7 +3733,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else if ( SM == SM_BackFromTickcountChange && !ScreenTextEntry::s_bCancelledLast ) { - int iTick = std::stoi( ScreenTextEntry::s_sLastAnswer ); + int iTick = StringToInt( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) GetAppropriateTimingForUpdate().AddSegment( TickcountSegment( GetRow(), iTick) ); @@ -3798,7 +3798,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else { - int tmp = std::stoi(ScreenTextEntry::s_sLastAnswer ); + int tmp = StringToInt(ScreenTextEntry::s_sLastAnswer ); SpeedSegment::BaseUnit unit = (tmp == 0 ) ? SpeedSegment::UNIT_BEATS : SpeedSegment::UNIT_SECONDS; @@ -4571,7 +4571,7 @@ static void ChangeStepCredit( const RString &sNew ) static void ChangeStepMeter( const RString &sNew ) { - int diff = std::stoi(sNew); + int diff = StringToInt(sNew); GAMESTATE->m_pCurSteps[PLAYER_1]->SetMeter(max(diff, 1)); } diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index e8baea8435..c821c77b6a 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -3234,7 +3234,7 @@ void ScreenGameplay::SaveReplay() continue; ASSERT( matches.size() == 1 ); - iIndex = std::stoi( matches[0] )+1; + iIndex = StringToInt( matches[0] )+1; break; } diff --git a/src/ScreenPackages.cpp b/src/ScreenPackages.cpp index a7409e0ec4..b9d1562938 100644 --- a/src/ScreenPackages.cpp +++ b/src/ScreenPackages.cpp @@ -630,14 +630,14 @@ void ScreenPackages::HTTPUpdate() m_sResponseName = "Malformed response."; return; } - m_iResponseCode = std::stoi(m_sBUFFER.substr(i+1,j-i)); + m_iResponseCode = StringToInt(m_sBUFFER.substr(i+1,j-i)); m_sResponseName = m_sBUFFER.substr( j+1, k-j ); i = m_sBUFFER.find("Content-Length:"); j = m_sBUFFER.find("\n", i+1 ); if( i != string::npos ) - m_iTotalBytes = std::stoi(m_sBUFFER.substr(i+16,j-i)); + m_iTotalBytes = StringToInt(m_sBUFFER.substr(i+16,j-i)); else m_iTotalBytes = -1; //We don't know, so go until disconnect @@ -704,7 +704,7 @@ bool ScreenPackages::ParseHTTPAddress( const RString &URL, RString &sProto, RStr sServer = asMatches[1]; if( asMatches[3] != "" ) { - iPort = std::stoi(asMatches[3]); + iPort = StringToInt(asMatches[3]); if( iPort == 0 ) return false; } diff --git a/src/XmlFile.cpp b/src/XmlFile.cpp index 728e6cdd0e..2179abaa77 100644 --- a/src/XmlFile.cpp +++ b/src/XmlFile.cpp @@ -50,9 +50,9 @@ void XNode::Free() } void XNodeStringValue::GetValue( RString &out ) const { out = m_sValue; } -void XNodeStringValue::GetValue( int &out ) const { out = std::stoi(m_sValue); } +void XNodeStringValue::GetValue( int &out ) const { out = StringToInt(m_sValue); } void XNodeStringValue::GetValue( float &out ) const { out = StringToFloat(m_sValue); } -void XNodeStringValue::GetValue( bool &out ) const { out = std::stoi(m_sValue) != 0; } +void XNodeStringValue::GetValue( bool &out ) const { out = StringToInt(m_sValue) != 0; } void XNodeStringValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,nullptr,0); } void XNodeStringValue::PushValue( lua_State *L ) const { diff --git a/src/XmlToLua.cpp b/src/XmlToLua.cpp index 13cd54994c..b53af0ffa7 100644 --- a/src/XmlToLua.cpp +++ b/src/XmlToLua.cpp @@ -452,13 +452,13 @@ void actor_template_t::load_frames_from_file(RString const& fname, RString const RString field_type= attr->first.Left(5); if(field_type == "Frame") { - int id= std::stoi(attr->first.Right(attr->first.size()-5)); + int id= StringToInt(attr->first.Right(attr->first.size()-5)); make_space_for_frame(id); attr->second->GetValue(frames[id].frame); } else if(field_type == "Delay") { - int id= std::stoi(attr->first.Right(attr->first.size()-5)); + int id= StringToInt(attr->first.Right(attr->first.size()-5)); make_space_for_frame(id); attr->second->GetValue(frames[id].delay); }