diff --git a/projects/mtg/include/DeckManager.h b/projects/mtg/include/DeckManager.h index b3cf8d9dd..6765105e6 100644 --- a/projects/mtg/include/DeckManager.h +++ b/projects/mtg/include/DeckManager.h @@ -27,7 +27,8 @@ public: vector * getPlayerDeckOrderList(); vector * getAIDeckOrderList(); - void saveDeck ( MTGDeck *deck, int deckId, MTGAllCards *collection ); + void saveDeck ( const string& deckFilename, MTGAllCards *collection ); + void saveDeck ( MTGDeck *deck, MTGAllCards *collection ); void AddMetaData( const std::string& filename, bool isAI); DeckMetaData* getDeckMetaDataById(int deckId, bool isAI); DeckMetaData* getDeckMetaDataByFilename(const std::string& filename, bool isAI); diff --git a/projects/mtg/include/MTGDeck.h b/projects/mtg/include/MTGDeck.h index c0a87726e..f106c6406 100644 --- a/projects/mtg/include/MTGDeck.h +++ b/projects/mtg/include/MTGDeck.h @@ -132,6 +132,9 @@ private: class MTGDeck { +private: + string getCardBlockText( const string& title, const string& textBlock ); + void printDetailedDeckText(std::ofstream& file ); protected: string filename; int total_cards; @@ -141,6 +144,7 @@ public: map cards; string meta_desc; string meta_name; + int meta_id; string meta_deck_colors; int totalCards(); int totalPrice(); @@ -157,7 +161,7 @@ public: int remove(MTGCard * card); string getFilename(); int save(); - int save(string destFileName, bool useExpandedDescriptions, string &deckTitle, string &deckDesc); + int save(const string& destFileName, bool useExpandedDescriptions, const string& deckTitle, const string& deckDesc); MTGCard * getCardById(int id); }; diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index c312d8fc6..11b6ef38c 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -13,6 +13,11 @@ class MTGCardInstance; class Player; class ManaCost{ + + friend std::ostream& operator<<(std::ostream& out, ManaCost& m); + friend std::ostream& operator<<(std::ostream& out, ManaCost* m); + friend std::ostream& operator<<(std::ostream& out, ManaCost m); + protected: int cost[Constants::MTG_NB_COLORS+1]; ManaCostHybrid * hybrids[10]; @@ -80,9 +85,9 @@ class ManaCost{ #ifdef WIN32 void Dump(); #endif -}; -std::ostream& operator<<(std::ostream& out, const ManaCost& m); + +}; class ManaPool:public ManaCost{ protected: diff --git a/projects/mtg/include/ManaCostHybrid.h b/projects/mtg/include/ManaCostHybrid.h index 5b83528d1..a9a7f55ac 100644 --- a/projects/mtg/include/ManaCostHybrid.h +++ b/projects/mtg/include/ManaCostHybrid.h @@ -3,16 +3,23 @@ class ManaCostHybrid { + public: int color1; int color2; int value1; int value2; ManaCostHybrid(); - int hasColor(int color); ManaCostHybrid(int c1, int v1, int c2, int v2); + void init(int c1, int v1, int c2, int v2); + int hasColor(int color); + string toString(); int getConvertedCost(); + + friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid& m); + friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid* m); + }; #endif diff --git a/projects/mtg/include/utils.h b/projects/mtg/include/utils.h index 949466b6d..61cfd555d 100644 --- a/projects/mtg/include/utils.h +++ b/projects/mtg/include/utils.h @@ -74,7 +74,15 @@ namespace wagic using std::string; +#define SPACES " \t\r\n" //string manipulation methods + +// for trimming strings on the fly +string trim (const string & s, const string & t = SPACES); +string trim_right (const string & s, const string & t = SPACES); +string trim_left (const string & s, const string & t = SPACES); + +// trimmning strings inplace string& trim(string& str); string& ltrim(string& str); string& rtrim(string& str); diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 7f8730ebd..91e1af6f4 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -1182,7 +1182,6 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, Player * op MTGDeck * tempDeck = NEW MTGDeck(deckFile, collection); AIPlayerBaka * baka = NEW AIPlayerBaka(tempDeck, deckFile, deckFileSmall, avatarFile); baka->deckId = deckid; - DeckManager::GetInstance()->saveDeck( tempDeck, deckid, collection); SAFE_DELETE(tempDeck); return baka; } diff --git a/projects/mtg/src/DeckManager.cpp b/projects/mtg/src/DeckManager.cpp index 033c9a8e8..adf3570ef 100644 --- a/projects/mtg/src/DeckManager.cpp +++ b/projects/mtg/src/DeckManager.cpp @@ -105,12 +105,12 @@ DeckMetaData* DeckManager::getDeckMetaDataByFilename(const string& filename, boo return deck; } -void DeckManager::saveDeck( MTGDeck *deck, int deckId, MTGAllCards *collection ) +void DeckManager::saveDeck( MTGDeck *deck, MTGAllCards *collection ) { if ( deck->meta_deck_colors == "" ) { bool isAI = deck->getFilename().find("baka") != string::npos; - StatsWrapper *stats = getExtendedStatsForDeckId( deckId, collection, isAI ); + StatsWrapper *stats = getExtendedStatsForDeckId( deck->meta_id, collection, isAI ); ostringstream manaColorIndex; for (int i = Constants::MTG_COLOR_ARTIFACT; i < Constants::MTG_COLOR_LAND; ++i) { @@ -128,6 +128,18 @@ void DeckManager::saveDeck( MTGDeck *deck, int deckId, MTGAllCards *collection ) } } +void DeckManager::saveDeck( const string& deckFilename, MTGAllCards *collection ) +{ + bool isAI = deckFilename.find("baka") != string::npos; + DeckMetaData *metaData = getDeckMetaDataByFilename( deckFilename, isAI ); + if ( metaData->getColorIndex() == "" ) + { + MTGDeck *tempDeck = NEW MTGDeck( deckFilename.c_str(), collection, 0 ); + saveDeck(tempDeck, collection); + SAFE_DELETE( tempDeck ); + } +} + void DeckManager::AddMetaData( const string& filename, bool isAI ) { diff --git a/projects/mtg/src/DeckMenu.cpp b/projects/mtg/src/DeckMenu.cpp index f6eb3176f..315ad21a5 100644 --- a/projects/mtg/src/DeckMenu.cpp +++ b/projects/mtg/src/DeckMenu.cpp @@ -113,7 +113,8 @@ void DeckMenu::RenderDeckManaColors() { string deckManaColors = mSelectedDeck->getColorIndex(); if ( deckManaColors.compare("") != 0 && ( deckManaColors.length() == 6 )) - { + { + // due to space constraints don't display icons for colorless mana. for( int colorIdx = Constants::MTG_COLOR_GREEN; colorIdx < Constants::MTG_COLOR_LAND; ++colorIdx ) { if ( (deckManaColors.at(colorIdx) == '1') != 0) diff --git a/projects/mtg/src/DeckMetaData.cpp b/projects/mtg/src/DeckMetaData.cpp index 8502f04ed..0520da750 100644 --- a/projects/mtg/src/DeckMetaData.cpp +++ b/projects/mtg/src/DeckMetaData.cpp @@ -62,7 +62,7 @@ void DeckMetaData::LoadStats() } else { - if (fileExists(mStatsFilename.c_str())) + if (FileExists(mStatsFilename)) { stats->load(mStatsFilename); mGamesPlayed = stats->nbGames(); diff --git a/projects/mtg/src/DeckStats.cpp b/projects/mtg/src/DeckStats.cpp index 983c13f43..cd99c0ceb 100644 --- a/projects/mtg/src/DeckStats.cpp +++ b/projects/mtg/src/DeckStats.cpp @@ -260,7 +260,7 @@ void StatsWrapper::initStatistics(string deckstats) aiDeckNames.clear(); aiDeckStats.clear(); - if (fileExists(deckstats.c_str())) + if (FileExists(deckstats)) { stats->load(deckstats.c_str()); percentVictories = stats->percentVictories(); @@ -302,7 +302,7 @@ void StatsWrapper::initStatistics(string deckstats) void StatsWrapper::updateStats(string filename, MTGAllCards *collection) { - if (fileExists(filename.c_str())) + if (FileExists(filename)) { MTGDeck * mtgd = NEW MTGDeck(filename.c_str(), collection); DeckDataWrapper *deckDataWrapper = NEW DeckDataWrapper(mtgd); diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 0e0557b7f..ff355a594 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -171,8 +171,7 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI) sprintf(deckFileSmall, "player_deck%i", decknb); MTGDeck * tempDeck = NEW MTGDeck(deckFile, mParent->collection); mPlayers[playerId] = NEW HumanPlayer(tempDeck, deckFile, deckFileSmall); - DeckManager::GetInstance()->saveDeck( tempDeck, decknb, mParent->collection); - delete tempDeck; + SAFE_DELETE( tempDeck ); } else { //AI Player, chooses deck @@ -224,9 +223,15 @@ void GameStateDuel::End() DebugTrace("Ending GameStateDuel"); JRenderer::GetInstance()->EnableVSync(false); - - if (!premadeDeck && mPlayers[0] && mPlayers[1]) // save the stats for the game + if (!premadeDeck && mPlayers[0] && mPlayers[1]) + { // save the stats for the game mPlayers[0]->End(); + if (mParent->players[1] != PLAYER_TYPE_TESTSUITE) + { + DeckManager::GetInstance()->saveDeck( mPlayers[1]->deckFile, mParent->collection); + DeckManager::GetInstance()->saveDeck( mPlayers[0]->deckFile, mParent->collection); + } + } else if ( !mPlayers[1] && mPlayers[0] ) // clean up player object SAFE_DELETE( mPlayers[0] ); diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 26ba871cb..95378c145 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -10,6 +10,7 @@ #include "MTGPack.h" #include "utils.h" #include "DeckManager.h" +#include #if defined (WIN32) || defined (LINUX) #include @@ -91,7 +92,7 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi attribute = value; value = ""; } - + for (int j = Constants::NB_BASIC_ABILITIES - 1; j >= 0; --j) { size_t found = attribute.find(Constants::MTGBasicAbilities[j]); @@ -144,12 +145,12 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi } else { - if (ManaCost * cost = primitive->getManaCost()) - { - string value = val; - std::transform(value.begin(), value.end(), value.begin(), ::tolower); - cost->alternative = ManaCost::parseManaCost(value); - } + if (ManaCost * cost = primitive->getManaCost()) + { + string value = val; + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + cost->alternative = ManaCost::parseManaCost(value); + } } break; @@ -329,7 +330,7 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi } else { - primitive->setType(val); + primitive->setType(val); break; } } @@ -656,7 +657,7 @@ MTGCard * MTGAllCards::getCardByName(string name) if (setId != -1 && setId != c->setId) continue; string cardName = c->data->name; std::transform(cardName.begin(), cardName.end(), cardName.begin(), ::tolower); - if (cardName.compare(name) == 0) return c; + if (cardName.compare(name) == 0) return c; } return NULL; @@ -693,6 +694,7 @@ MTGDeck::MTGDeck(const char * config_file, MTGAllCards * _allcards, int meta_onl size_t slash = filename.find_last_of("/"); size_t dot = filename.find("."); meta_name = filename.substr(slash + 1, dot - slash - 1); + meta_id = atoi(meta_name.substr(4).c_str()); wagic::ifstream file(config_file); std::string s; @@ -807,8 +809,8 @@ int MTGDeck::addRandomCards(int howmany, int * setIds, int nbSets, int rarity, c MTGCard * card = database->_(i); int r = card->getRarity(); if (r != Constants::RARITY_T && (rarity == -1 || r == rarity) && // remove tokens - card->setId != MTGSets::INTERNAL_SET && //remove cards that are defined in primitives. Those are workarounds (usually tokens) and should only be used internally - (!_subtype || card->data->hasSubtype(subtype))) + card->setId != MTGSets::INTERNAL_SET && //remove cards that are defined in primitives. Those are workarounds (usually tokens) and should only be used internally + (!_subtype || card->data->hasSubtype(subtype))) { int ok = 0; @@ -843,8 +845,7 @@ int MTGDeck::addRandomCards(int howmany, int * setIds, int nbSets, int rarity, c } if (subtotal == 0) { - if (rarity == Constants::RARITY_M) return addRandomCards(howmany, setIds, nbSets, Constants::RARITY_R, _subtype, colors, - nbcolors); + if (rarity == Constants::RARITY_M) return addRandomCards(howmany, setIds, nbSets, Constants::RARITY_R, _subtype, colors, nbcolors); return 0; } for (int i = 0; i < howmany; i++) @@ -893,8 +894,8 @@ int MTGDeck::add(MTGCard * card) int MTGDeck::complete() { /* (PSY) adds cards to the deck/collection. Makes sure that the deck - or collection has at least 4 of every implemented card. Does not - change the number of cards of which already 4 or more are present. */ + or collection has at least 4 of every implemented card. Does not + change the number of cards of which already 4 or more are present. */ int id, n; bool StypeIsNothing; size_t databaseSize = database->ids.size(); @@ -955,7 +956,7 @@ int MTGDeck::save() return save(filename, false, meta_name, meta_desc); } -int MTGDeck::save(string destFileName, bool useExpandedDescriptions, string &deckTitle, string &deckDesc) +int MTGDeck::save(const string& destFileName, bool useExpandedDescriptions, const string& deckTitle, const string& deckDesc) { string tmp = destFileName; tmp.append(".tmp"); //not thread safe @@ -982,18 +983,19 @@ int MTGDeck::save(string destFileName, bool useExpandedDescriptions, string &dec } file << "#DESC:" << desc << "\n"; } - - // add in color information + bool saveDetailedDeckInfo = options.get( Options::SAVEDETAILEDDECKINFO )->number == 1; if ( filename.find("collection.dat") == string::npos ) { + // add in color information DeckManager *deckManager = DeckManager::GetInstance(); file <<"#MANA:"; + string deckId = filename.substr( filename.find("/deck")+5, filename.find(".txt") - (filename.find("/deck")+5) ); bool isAI = filename.find("ai/baka") != string::npos; StatsWrapper *stats = deckManager->getExtendedStatsForDeckId( atoi(deckId.c_str()), this->database, isAI ); - + for (int i = Constants::MTG_COLOR_ARTIFACT; i < Constants::MTG_COLOR_LAND; ++i) { if (stats->totalCostPerColor[i] != 0) @@ -1005,24 +1007,10 @@ int MTGDeck::save(string destFileName, bool useExpandedDescriptions, string &dec } else saveDetailedDeckInfo = false; - + if (useExpandedDescriptions || saveDetailedDeckInfo) { - map::iterator it; - for (it = cards.begin(); it != cards.end(); it++) - { - int nbCards = it->second; - MTGCard *card = this->getCardById(it->first); - if (card == NULL) - { - continue; - } - MTGSetInfo *setInfo = setlist.getInfo(card->setId); - string setName = setInfo->id; - string cardName = card->data->getName(); - file << cardName << "\t " << "(" << setName << ") *" << nbCards << endl; - setInfo = NULL; - } + printDetailedDeckText(file); } else { @@ -1043,6 +1031,92 @@ int MTGDeck::save(string destFileName, bool useExpandedDescriptions, string &dec return 1; } +/*** + print out an expanded version of the deck to file. + This save meta data about each card to allow easy reading of the deck file. It will + also save each card by id, to speed up the loading of the deck next time. +*/ +void MTGDeck::printDetailedDeckText(std::ofstream& file ) +{ + ostringstream currentCard, creatures, lands, spells, types; + map::iterator it; + for (it = cards.begin(); it != cards.end(); it++) + { + int cardId = it->first; + int nbCards = it->second; + MTGCard *card = this->getCardById( cardId ); + if (card == NULL) + { + continue; + } + MTGSetInfo *setInfo = setlist.getInfo(card->setId); + string setName = setInfo->id; + string cardName = card->data->getName(); + string description = card->data->getText(); + + currentCard << "#" << nbCards << " x " << cardName << " (" << setName << "), "; + + if ( !card->data->isLand() ) + currentCard << card->data->getManaCost() << ", "; + + // Add the card's types + vector::iterator typeIter; + for ( typeIter = card->data->types.begin(); typeIter != card->data->types.end(); ++typeIter ) + types << Subtypes::subtypesList->find( *typeIter ) << " "; + + currentCard << trim(types.str()) << ", "; + types.str(""); // reset the buffer. + + // Add P/T if a creature + if ( card->data->isCreature() ) + currentCard << card->data->getPower() << "/" << card->data->getToughness() << ", "; + + + if ( card->data->hasRestriction ) + currentCard << ", " << card->data->otherrestriction; + + map::iterator abilityIter; + for ( abilityIter = card->data->basicAbilities.begin(); abilityIter != card->data->basicAbilities.end(); ++abilityIter ) + currentCard << Constants::MTGBasicAbilities[ abilityIter->first ] << "; "; + currentCard <data->isLand() ) + lands<< currentCard.str(); + else if ( card->data->isCreature() ) + creatures << currentCard.str(); + else + spells << currentCard.str(); + currentCard.str(""); + } + file << getCardBlockText( "Creatures", creatures.str() ) << endl; + file << getCardBlockText( "Spells", spells.str() ) << endl; + file << getCardBlockText( "Lands", lands.str() ) << endl; + creatures.str(""); + spells.str(""); + lands.str(""); +} + +/*** +* Convience method to print out blocks of card descriptions +*/ +string MTGDeck::getCardBlockText( const string& title, const string& text ) +{ + ostringstream oss; + string textBlock (text); + + oss << setfill('#') << setw( 40 ) << "#" << endl; + oss << "# " << setfill(' ') << setw(34) << left << title << "#" << endl; + oss << setfill('#') << setw( 40 ) << "#" << endl; + oss << trim(textBlock) << endl; + + return oss.str(); +} + //MTGSets MTGSets setlist; //Our global. @@ -1082,7 +1156,7 @@ MTGSetInfo* MTGSets::randomSet(int blockId, int atleast) for (int i = a; i < size(); i++) { if (unlocked[i] && (blockId == -1 || setinfo[i]->block == blockId) && - (atleast == -1 || setinfo[i]->totalCards() >= atleast)) + (atleast == -1 || setinfo[i]->totalCards() >= atleast)) { free(unlocked); return setinfo[i]; @@ -1091,7 +1165,7 @@ MTGSetInfo* MTGSets::randomSet(int blockId, int atleast) for (int i = 0; i < a; i++) { if (unlocked[i] && (blockId == -1 || setinfo[i]->block == blockId) && - (atleast == -1 || setinfo[i]->totalCards() >= atleast)) + (atleast == -1 || setinfo[i]->totalCards() >= atleast)) { free(unlocked); return setinfo[i]; diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index e8cc98c79..d052be601 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -626,36 +626,49 @@ ManaCost * ManaCost::Diff(ManaCost * _cost) string ManaCost::toString() { ostringstream oss; - oss << "\n===ManaCost===\n"; for (int i = 0; i <= Constants::MTG_NB_COLORS; i++) { if (cost[i]) { - oss << Constants::MTGColorChars[i] << ":" << cost[i] << " - "; + if ( i == Constants::MTG_COLOR_ARTIFACT) + oss << "{" << cost[i] << "}"; + else + for (int colorCount = 0; colorCount < cost[i]; colorCount++ ) + oss << "{" << Constants::MTGColorChars[i] << "}"; } } for (unsigned int i = 0; i < nbhybrids; i++) { - ManaCostHybrid * h = hybrids[i]; - oss << "H:{" << Constants::MTGColorChars[h->color1] << ":" << h->value1 << "}/{" << Constants::MTGColorChars[h->color2] - << ":" << h->value2 << "}"; + oss << hybrids[i]; } - oss << "\n=============\n"; return oss.str(); } #ifdef WIN32 void ManaCost::Dump() { + DebugTrace( "\n===ManaCost===" ); DebugTrace( this->toString() ); + DebugTrace( "\n=============" ); } #endif -ostream& operator<<(ostream& out, const ManaCost& m) +ostream& operator<<(ostream& out, ManaCost& m) { - return out << "(manacost)"; + return out << m.toString(); +} + + +ostream& operator<<(ostream& out, ManaCost* m) +{ + return out << m->toString(); +} + +ostream& operator<<(ostream& out, ManaCost m) +{ + return out << m.toString(); } void ManaPool::init() diff --git a/projects/mtg/src/ManaCostHybrid.cpp b/projects/mtg/src/ManaCostHybrid.cpp index b407e1a9d..0c9eaf2f5 100644 --- a/projects/mtg/src/ManaCostHybrid.cpp +++ b/projects/mtg/src/ManaCostHybrid.cpp @@ -1,6 +1,7 @@ #include "PrecompiledHeader.h" #include "ManaCostHybrid.h" +#include "MTGDefinitions.h" ManaCostHybrid::ManaCostHybrid() { @@ -33,3 +34,21 @@ int ManaCostHybrid::hasColor(int color) return 1; return 0; } + +string ManaCostHybrid::toString() +{ + ostringstream oss; + if ( color1 != 0 && color2 != 0) + oss << "{" << Constants::MTGColorChars[color1] << "/" << Constants::MTGColorChars[color2] << "}"; + return oss.str(); +} + +ostream& operator<<(ostream& out, ManaCostHybrid& r) +{ + return out<< r.toString(); +} + +ostream& operator<<(ostream& out, ManaCostHybrid* r) +{ + return out<< r->toString(); +} diff --git a/projects/mtg/src/utils.cpp b/projects/mtg/src/utils.cpp index f410d2c31..b6969a59d 100644 --- a/projects/mtg/src/utils.cpp +++ b/projects/mtg/src/utils.cpp @@ -76,6 +76,8 @@ int filesize(const char * filename) return file_size; } + +// check to see if a file exists on the file system. int fileExists(const char * filename) { wagic::ifstream fichier(filename); @@ -94,6 +96,42 @@ int fileExists(const char * filename) return 0; } +// check to see if a file exists on the file system. +// this can be used to extract last modified date of a file. +bool FileExists(const string& strFilename) +{ + struct stat stFileInfo; + bool blnReturn = false; + int intStat; + + // Attempt to get the file attributes + intStat = stat(strFilename.c_str(),&stFileInfo); + if(intStat == 0) + { + // We were able to get the file attributes + // so the file obviously exists. + blnReturn = true; + } + else + { + // We were not able to get the file attributes. + // This may mean that we don't have permission to + // access the folder which contains this file. If you + // need to do that level of checking, lookup the + // return values of stat which will give you + // more details on why stat failed. + + // try to search in the resource directory + if ( stat( JGE_GET_RES(strFilename).c_str(), &stFileInfo ) == 0) + blnReturn = true; + else + blnReturn = false; + } + + return(blnReturn); +} + + /* #ifdef LINUX @@ -198,6 +236,29 @@ u32 ramAvailable(void) return size; } +/* String manipulation functions */ +string trim_right (const string & s, const string & t) +{ + string d (s); + string::size_type i (d.find_last_not_of (t)); + if (i == string::npos) + return ""; + else + return d.erase (d.find_last_not_of (t) + 1) ; +} + +string trim_left (const string & s, const string & t) +{ + string d (s); + return d.erase (0, s.find_first_not_of (t)) ; +} + +string trim (const string & s, const string & t) +{ + string d (s); + return trim_left (trim_right (d, t), t) ; +} + string& trim(string& str) { str = ltrim(str); @@ -298,31 +359,4 @@ std::string wordWrap(const std::string& sentence, float width, int fontId) return retVal; } -bool FileExists(const string& strFilename) -{ - struct stat stFileInfo; - bool blnReturn; - int intStat; - - // Attempt to get the file attributes - intStat = stat(strFilename.c_str(),&stFileInfo); - if(intStat == 0) - { - // We were able to get the file attributes - // so the file obviously exists. - blnReturn = true; - } - else - { - // We were not able to get the file attributes. - // This may mean that we don't have permission to - // access the folder which contains this file. If you - // need to do that level of checking, lookup the - // return values of stat which will give you - // more details on why stat failed. - blnReturn = false; - } - - return(blnReturn); -}