diff options
Diffstat (limited to 'src')
33 files changed, 171 insertions, 81 deletions
diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp index a7821699..1104d810 100644 --- a/src/actorsprite.cpp +++ b/src/actorsprite.cpp @@ -43,6 +43,7 @@ ImageSet *ActorSprite::targetCursorImages[2][NUM_TC]; SimpleAnimation *ActorSprite::targetCursor[2][NUM_TC]; +bool ActorSprite::loaded = false; ActorSprite::ActorSprite(int id): mId(id), @@ -345,12 +346,21 @@ void ActorSprite::setupSpriteDisplay(const SpriteDisplay &display, void ActorSprite::load() { + if (loaded) + unload(); + initTargetCursor(); + + loaded = true; } void ActorSprite::unload() { + if (!loaded) + return; + cleanupTargetCursors(); + loaded = false; } static const char *cursorType(int type) diff --git a/src/actorsprite.h b/src/actorsprite.h index 6c5885e6..e218ef74 100644 --- a/src/actorsprite.h +++ b/src/actorsprite.h @@ -223,6 +223,8 @@ private: /** Animated target cursors. */ static SimpleAnimation *targetCursor[NUM_TCT][NUM_TC]; + static bool loaded; + /** Target cursor being used */ SimpleAnimation *mUsedTargetCursor; }; diff --git a/src/client.cpp b/src/client.cpp index 323d5b49..35292d22 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -433,6 +433,14 @@ Client::~Client() SDL_RemoveTimer(mLogicCounterId); SDL_RemoveTimer(mSecondsCounterId); + // Unload XML databases + ColorDB::unload(); + EmoteDB::unload(); + ItemDB::unload(); + MonsterDB::unload(); + NPCDB::unload(); + StatusEffect::unload(); + // Before config.write() since it writes the shortcuts to the config delete itemShortcut; delete emoteShortcut; @@ -586,19 +594,6 @@ int Client::exec() { delete game; game = 0; - - if (mState != STATE_CHANGE_MAP) - { - // Unload XML databases - ColorDB::unload(); - EmoteDB::unload(); - ItemDB::unload(); - MonsterDB::unload(); - NPCDB::unload(); - StatusEffect::unload(); - - ActorSprite::unload(); - } } mOldState = mState; @@ -973,6 +968,7 @@ int Client::exec() case STATE_ERROR: logger->log("State: ERROR"); + logger->log("Error: %s\n", errorMessage.c_str()); mCurrentDialog = new OkDialog(_("Error"), errorMessage); mCurrentDialog->addActionListener(&errorListener); mCurrentDialog = NULL; // OkDialog deletes itself @@ -1159,6 +1155,10 @@ void Client::initUpdatesDir() mUpdateHost = config.getValue("updatehost", ""); } + // Don't go out of range int he next check + if (mUpdateHost.length() < 2) + return; + // Remove any trailing slash at the end of the update host if (!mUpdateHost.empty() && mUpdateHost.at(mUpdateHost.size() - 1) == '/') mUpdateHost.resize(mUpdateHost.size() - 1); diff --git a/src/gui/login.cpp b/src/gui/login.cpp index bfad5c32..b243fd04 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -91,7 +91,8 @@ LoginDialog::LoginDialog(LoginData *loginData): mPassField->requestFocus(); mLoginButton->setEnabled(canSubmit()); - mRegisterButton->setEnabled(Net::getLoginHandler()->isRegistrationEnabled()); + mRegisterButton->setEnabled(Net::getLoginHandler() + ->isRegistrationEnabled()); } LoginDialog::~LoginDialog() diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index e973fa54..1d01f48c 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -97,15 +97,13 @@ void Minimap::setMap(Map *map) if (map) { std::string tempname = - "graphics/minimaps/"+(*map->getFilename())+".png"; + "graphics/minimaps/" + map->getFilename() + ".png"; ResourceManager *resman = ResourceManager::getInstance(); minimapName = map->getProperty("minimap"); if (minimapName.empty() && resman->exists(tempname)) - { minimapName = tempname; - } mMapImage = resman->getImage(minimapName); } diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 25725a80..ad8ab3c8 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -26,6 +26,7 @@ #include "configuration.h" #include "gui.h" #include "log.h" +#include "main.h" #include "gui/okdialog.h" #include "gui/sdlinput.h" @@ -527,6 +528,15 @@ void ServerDialog::loadServers() std::string type = XML::getProperty(serverNode, "type", "unknown"); server.type = ServerInfo::parseType(type); + + // Ignore unknown server types + if (server.type == ServerInfo::UNKNOWN) + { + logger->log("Ignoring server entry with unknown type: %s", + type.c_str()); + continue; + } + server.name = XML::getProperty(serverNode, "name", std::string()); std::string version = XML::getProperty(serverNode, "minimumVersion", @@ -538,15 +548,11 @@ void ServerDialog::loadServers() // For display in the list if (meetsMinimumVersion) version.clear(); + else if (version.empty()) + version = _("requires a newer version"); else version = strprintf(_("requires v%s"), version.c_str()); - if (server.type == ServerInfo::UNKNOWN) - { - logger->log("Unknown server type: %s", type.c_str()); - continue; - } - for_each_xml_child_node(subNode, serverNode) { if (xmlStrEqual(subNode->name, BAD_CAST "connection")) diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 15cc787a..f7a39240 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -35,6 +35,7 @@ #include "gui/widgets/scrollarea.h" #include "gui/widgets/table.h" +#include "utils/dtor.h" #include "utils/gettext.h" #include <string> @@ -88,7 +89,8 @@ class PlayerTableModel : public TableModel { public: PlayerTableModel() : - mPlayers(NULL) + mPlayers(NULL), + mListModel(new PlayerRelationListModel) { playerRelationsUpdated(); } @@ -96,6 +98,7 @@ public: virtual ~PlayerTableModel() { freeWidgets(); + delete mListModel; if (mPlayers) delete mPlayers; } @@ -139,9 +142,8 @@ public: std::string name = (*player_names)[r]; gcn::Widget *widget = new Label(name); mWidgets.push_back(widget); - gcn::ListModel *playerRelation = new PlayerRelationListModel; - gcn::DropDown *choicebox = new DropDown(playerRelation); + gcn::DropDown *choicebox = new DropDown(mListModel); choicebox->setSelected(player_relations.getRelation(name)); mWidgets.push_back(choicebox); } @@ -170,12 +172,7 @@ public: delete mPlayers; mPlayers = NULL; - for (std::vector<gcn::Widget *>::const_iterator it = mWidgets.begin(); - it != mWidgets.end(); it++) - { - delete *it; - } - + delete_all(mWidgets); mWidgets.clear(); } @@ -187,6 +184,7 @@ public: protected: std::vector<std::string> *mPlayers; std::vector<gcn::Widget *> mWidgets; + PlayerRelationListModel *mListModel; }; /** diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index ebe53261..81ce8107 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -380,6 +380,7 @@ Setup_Video::Setup_Video(): Setup_Video::~Setup_Video() { delete mModeListModel; + delete mModeList; delete mFontSizeListModel; } diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 1a265589..683a6d43 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -185,6 +185,12 @@ public: setCaption(name); } + ~SkillTab() + { + delete mListBox; + mListBox = 0; + } + SkillInfo *getSelectedInfo() { return mListBox->getSelectedInfo(); diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 2043da52..25447f30 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -61,7 +61,7 @@ protected: mConfirmDialog(NULL) {} - ~SocialTab() + virtual ~SocialTab() { // Cleanup dialogs if (mInviteDialog) @@ -106,6 +106,14 @@ public: mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); } + ~GuildTab() + { + delete mList; + mList = 0; + delete mScroll; + mScroll = 0; + } + void action(const gcn::ActionEvent &event) { if (event.getId() == "do invite") @@ -179,6 +187,14 @@ public: mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); } + ~PartyTab() + { + delete mList; + mList = 0; + delete mScroll; + mScroll = 0; + } + void action(const gcn::ActionEvent &event) { if (event.getId() == "do invite") @@ -350,6 +366,7 @@ SocialWindow::~SocialWindow() mPartyInviter = ""; } + delete mCreatePopup; } bool SocialWindow::addTab(Guild *guild) diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index ad9c0ed7..c8ebdc98 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -51,6 +51,8 @@ class AttrDisplay : public Container DERIVED, CHANGEABLE, UNKNOWN }; + ~AttrDisplay(); + virtual std::string update(); virtual Type getType() { return UNKNOWN; } @@ -404,6 +406,11 @@ AttrDisplay::AttrDisplay(int id, const std::string &name): mLayout = new LayoutHelper(this); } +AttrDisplay::~AttrDisplay() +{ + delete mLayout; +} + std::string AttrDisplay::update() { int base = player_node->getAttributeBase(mId); diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index 1406a0d0..e46616e0 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -228,6 +228,7 @@ Skin *Theme::readSkin(const std::string &filename) Image *dBorders = Theme::getImageFromTheme(skinSetImage); ImageRect border; + memset(&border, 0, sizeof(ImageRect)); // iterate <widget>'s for_each_xml_child_node(widgetNode, rootNode) diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp index 3bf1febe..e2ae5b93 100644 --- a/src/gui/truetypefont.cpp +++ b/src/gui/truetypefont.cpp @@ -26,9 +26,11 @@ #include "resources/image.h" +#include "utils/stringutils.h" + #include <guichan/exception.hpp> -#define CACHE_SIZE 256 +const unsigned int CACHE_SIZE = 256; class TextChunk { @@ -55,8 +57,10 @@ class TextChunk sdlCol.r = color.r; sdlCol.g = color.g; + const char* str = getSafeUtf8String(text); SDL_Surface *surface = TTF_RenderUTF8_Blended( - font, text.c_str(), sdlCol); + font, str, sdlCol); + delete[] str; if (!surface) { @@ -175,7 +179,9 @@ int TrueTypeFont::getWidth(const std::string &text) const } int w, h; - TTF_SizeUTF8(mFont, text.c_str(), &w, &h); + const char* str = getSafeUtf8String(text); + TTF_SizeUTF8(mFont, str, &w, &h); + delete[] str; return w; } diff --git a/src/map.cpp b/src/map.cpp index 7b62746b..33bbccb1 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -580,16 +580,13 @@ const std::string Map::getName() const return getProperty("mapname"); } -const std::string *Map::getFilename() const +const std::string Map::getFilename() const { std::string fileName = getProperty("_filename"); int lastSlash = fileName.rfind("/") + 1; int lastDot = fileName.rfind("."); - std::string *sub = new std::string( - fileName.substr(lastSlash, lastDot - lastSlash)); - - return sub; + return fileName.substr(lastSlash, lastDot - lastSlash); } Position Map::checkNodeOffsets(int radius, unsigned char walkMask, @@ -266,7 +266,7 @@ class Map : public Properties /** * Gives the map id based on filepath (ex: 009-1) */ - const std::string *getFilename() const; + const std::string getFilename() const; /** * Check the current position against surrounding blocking tiles, and diff --git a/src/net/download.cpp b/src/net/download.cpp index 2b96a6b9..a2cd4910 100644 --- a/src/net/download.cpp +++ b/src/net/download.cpp @@ -122,7 +122,7 @@ void Download::setWriteFunction(WriteFunction write) bool Download::start() { - logger->log("Starting download: %s\n", mUrl.c_str()); + logger->log("Starting download: %s", mUrl.c_str()); mThread = SDL_CreateThread(downloadThread, this); @@ -140,7 +140,7 @@ bool Download::start() void Download::cancel() { - logger->log("Canceling download: %s\n", mUrl.c_str()); + logger->log("Canceling download: %s", mUrl.c_str()); mOptions.cancel = true; if (mThread && SDL_GetThreadID(mThread) != 0) diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index 721780d2..e2c67f35 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -37,6 +37,7 @@ #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" #include "net/manaserv/protocol.h" +#include "net/manaserv/stats.h" #include "resources/colordb.h" @@ -258,15 +259,7 @@ void CharHandler::setCharCreateDialog(CharCreateDialog *window) if (!mCharCreateDialog) return; - std::vector<std::string> attributes; - attributes.push_back(_("Strength:")); - attributes.push_back(_("Agility:")); - attributes.push_back(_("Dexterity:")); - attributes.push_back(_("Vitality:")); - attributes.push_back(_("Intelligence:")); - attributes.push_back(_("Willpower:")); - - mCharCreateDialog->setAttributes(attributes, 60, 1, 20); + mCharCreateDialog->setAttributes(Stats::getLabelVector(), 60, 1, 20); } void CharHandler::requestCharacters() @@ -304,12 +297,10 @@ void CharHandler::newCharacter(const std::string &name, msg.writeInt8(hairstyle); msg.writeInt8(hairColor); msg.writeInt8(gender); - msg.writeInt16(stats[0]); - msg.writeInt16(stats[1]); - msg.writeInt16(stats[2]); - msg.writeInt16(stats[3]); - msg.writeInt16(stats[4]); - msg.writeInt16(stats[5]); + + std::vector<int>::const_iterator it, it_end; + for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) + msg.writeInt16((*it)); accountServerConnection->send(msg); } diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp index 09f68c1e..0d3073f1 100644 --- a/src/net/manaserv/generalhandler.cpp +++ b/src/net/manaserv/generalhandler.cpp @@ -108,9 +108,6 @@ void GeneralHandler::load() registerHandler(mPartyHandler.get()); registerHandler(mPlayerHandler.get()); registerHandler(mTradeHandler.get()); - - Stats::load(); - Stats::informItemDB(); } void GeneralHandler::reload() @@ -194,6 +191,11 @@ void GeneralHandler::stateChanged(State oldState, State newState) GameHandler *game = static_cast<GameHandler*>(Net::getGameHandler()); game->gameLoading(); } + else if (newState == STATE_LOAD_DATA) + { + Stats::load(); + Stats::informItemDB(); + } } } // namespace ManaServ diff --git a/src/net/manaserv/stats.cpp b/src/net/manaserv/stats.cpp index b79b1fd9..f109a232 100644 --- a/src/net/manaserv/stats.cpp +++ b/src/net/manaserv/stats.cpp @@ -198,5 +198,16 @@ namespace Stats { it->second.modifiable, it->second.description); } + + std::vector<std::string> getLabelVector() + { + std::vector<std::string> attributes; + StatMap::const_iterator it, it_end; + for (it = stats.begin(), it_end = stats.end(); it != it_end; it++) + if (it->second.modifiable) + attributes.push_back(it->second.name + ":"); + + return attributes; + } } // namespace Stats } // namespace ManaServ diff --git a/src/net/manaserv/stats.h b/src/net/manaserv/stats.h index c4afbd79..63349095 100644 --- a/src/net/manaserv/stats.h +++ b/src/net/manaserv/stats.h @@ -21,6 +21,9 @@ #ifndef NET_MANASERV_STATS_H #define NET_MANASERV_STATS_H +#include <string> +#include <vector> + namespace ManaServ { namespace Stats { void load(); @@ -30,6 +33,8 @@ namespace Stats { void informItemDB(); void informStatusWindow(); + + std::vector<std::string> getLabelVector(); } // namespace Stats } // namespace ManaServ diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 843e5c9f..8f15691c 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -70,9 +70,6 @@ CharServerHandler::CharServerHandler() void CharServerHandler::handleMessage(Net::MessageIn &msg) { - logger->log("CharServerHandler: Packet ID: %x, Length: %d", - msg.getId(), msg.getLength()); - switch (msg.getId()) { case SMSG_CHAR_LOGIN: @@ -102,16 +99,17 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) switch (msg.readInt8()) { case 0: - errorMessage = _("Access denied."); + errorMessage = _("Access denied. Most likely, there are " + "too many players on this server."); break; case 1: errorMessage = _("Cannot use this ID."); break; default: - errorMessage = _("Unknown failure to select character."); + errorMessage = _("Unknown char-server failure."); break; } - unlockCharSelectDialog(); + Client::setState(STATE_ERROR); break; case SMSG_CHAR_CREATE_SUCCEEDED: diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp index 7d973ba3..e58acb4d 100644 --- a/src/net/tmwa/loginhandler.cpp +++ b/src/net/tmwa/loginhandler.cpp @@ -42,6 +42,7 @@ namespace TmwAthena { extern ServerInfo charServer; LoginHandler::LoginHandler(): + mVersionResponse(false), mRegistrationEnabled(true) { static const Uint16 _messages[] = { @@ -187,6 +188,7 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) case SMSG_SERVER_VERSION_RESPONSE: { // TODO: verify these! + msg.readInt8(); // -1 msg.readInt8(); // T msg.readInt8(); // M @@ -194,13 +196,10 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) unsigned int options = msg.readInt32(); - if (options & 1) - { - // Registeration not allowed - mRegistrationEnabled = false; - } + mRegistrationEnabled = (options & 1); - //state = STATE_LOGIN; + // Leave this last + mVersionResponse = true; } break; } @@ -214,7 +213,7 @@ void LoginHandler::connect() bool LoginHandler::isConnected() { - return mNetwork->isConnected(); + return mVersionResponse && mNetwork->isConnected(); } void LoginHandler::disconnect() diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h index 455c75f1..8f6ea321 100644 --- a/src/net/tmwa/loginhandler.h +++ b/src/net/tmwa/loginhandler.h @@ -83,6 +83,7 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler void sendLoginRegister(const std::string &username, const std::string &password); + bool mVersionResponse; bool mRegistrationEnabled; std::string mUpdateHost; Worlds mWorlds; diff --git a/src/playerrelations.cpp b/src/playerrelations.cpp index 77d3fddd..f5d3d01b 100644 --- a/src/playerrelations.cpp +++ b/src/playerrelations.cpp @@ -90,13 +90,20 @@ PlayerRelation::PlayerRelation(Relation relation) PlayerRelationsManager::PlayerRelationsManager() : mPersistIgnores(false), mDefaultPermissions(PlayerRelation::DEFAULT), - mIgnoreStrategy(NULL) + mIgnoreStrategy(0) { } PlayerRelationsManager::~PlayerRelationsManager() { delete_all(mIgnoreStrategies); + + for (std::map<std::string, + PlayerRelation *>::const_iterator it = mRelations.begin(); + it != mRelations.end(); it++) + { + delete it->second; + } } void PlayerRelationsManager::clear() @@ -104,7 +111,9 @@ void PlayerRelationsManager::clear() std::vector<std::string> *names = getPlayers(); for (std::vector<std::string>::const_iterator it = names->begin(); it != names->end(); it++) + { removePlayer(*it); + } delete names; } diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp index 0041cee4..c35a5660 100644 --- a/src/resources/colordb.cpp +++ b/src/resources/colordb.cpp @@ -36,7 +36,7 @@ namespace void ColorDB::load() { if (mLoaded) - return; + unload(); XML::Document *doc = new XML::Document("hair.xml"); xmlNodePtr root = doc->rootNode(); diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp index 117c0bab..fddab500 100644 --- a/src/resources/emotedb.cpp +++ b/src/resources/emotedb.cpp @@ -36,7 +36,7 @@ namespace void EmoteDB::load() { if (mLoaded) - return; + unload(); mLastEmote = 0; diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 57df6143..205268e5 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -109,7 +109,7 @@ static std::string normalized(const std::string &name) void ItemDB::load() { if (mLoaded) - return; + unload(); logger->log("Initializing item database..."); diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp index da89302d..0732bb19 100644 --- a/src/resources/monsterdb.cpp +++ b/src/resources/monsterdb.cpp @@ -42,7 +42,7 @@ namespace void MonsterDB::load() { if (mLoaded) - return; + unload(); logger->log("Initializing monster database..."); diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp index 03581e13..4f0ee10d 100644 --- a/src/resources/npcdb.cpp +++ b/src/resources/npcdb.cpp @@ -37,7 +37,7 @@ namespace void NPCDB::load() { if (mLoaded) - return; + unload(); logger->log("Initializing NPC database..."); diff --git a/src/statuseffect.cpp b/src/statuseffect.cpp index 49619f8a..6ab0b8fa 100644 --- a/src/statuseffect.cpp +++ b/src/statuseffect.cpp @@ -32,6 +32,8 @@ #define STATUS_EFFECTS_FILE "status-effects.xml" +bool StatusEffect::mLoaded = false; + StatusEffect::StatusEffect() : mPersistentParticleEffect(false) {} @@ -113,6 +115,9 @@ StatusEffect *StatusEffect::getStunEffect(int index, bool enabling) void StatusEffect::load() { + if (mLoaded) + unload(); + XML::Document doc(STATUS_EFFECTS_FILE); xmlNodePtr rootNode = doc.rootNode(); @@ -175,8 +180,13 @@ void unloadMap(std::map<int, StatusEffect *> map) void StatusEffect::unload() { + if (!mLoaded) + return; + unloadMap(statusEffects[0]); unloadMap(statusEffects[1]); unloadMap(stunEffects[0]); unloadMap(stunEffects[1]); + + mLoaded = false; } diff --git a/src/statuseffect.h b/src/statuseffect.h index 0fed5748..fc0e7336 100644 --- a/src/statuseffect.h +++ b/src/statuseffect.h @@ -98,6 +98,7 @@ public: static void unload(); private: + static bool mLoaded; std::string mMessage; std::string mSFXEffect; diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp index 01bf0d3c..9fe3de14 100644 --- a/src/utils/stringutils.cpp +++ b/src/utils/stringutils.cpp @@ -21,10 +21,13 @@ #include "utils/stringutils.h" +#include <string.h> #include <algorithm> #include <cstdarg> #include <cstdio> +const int UTF8_MAX_SIZE = 10; + std::string &trim(std::string &str) { std::string::size_type pos = str.find_last_not_of(' '); @@ -164,3 +167,11 @@ const std::string findSameSubstring(const std::string &str1, const std::string & } return str1.substr(0, minLength); } + +const char* getSafeUtf8String(std::string text) +{ + char* buf = new char[text.size() + UTF8_MAX_SIZE]; + memcpy(buf, text.c_str(), text.size()); + memset(buf + text.size(), 0, UTF8_MAX_SIZE); + return buf; +}
\ No newline at end of file diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index 5e4718c0..ec82e240 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -123,4 +123,6 @@ bool isWordSeparator(char chr); const std::string findSameSubstring(const std::string &str1, const std::string &str2); +const char* getSafeUtf8String(std::string text); + #endif // UTILS_STRINGUTILS_H |