------------------------------------------------------------ revno: 3196 committer: poy <p...@123gen.com> branch nick: trunk timestamp: Tue 2013-01-29 19:08:36 +0100 message: add a text replacement function to the XML tagger modified: dcpp/ChatMessage.cpp dcpp/ChatMessage.h dcpp/PluginApiImpl.cpp dcpp/PluginApiImpl.h dcpp/PluginDefs.h dcpp/PluginManager.cpp dcpp/PluginManager.h dcpp/Tagger.cpp dcpp/Tagger.h win32/AspectChat.h
-- lp:dcplusplus https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk Your team Dcplusplus-team is subscribed to branch lp:dcplusplus. To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/ChatMessage.cpp' --- dcpp/ChatMessage.cpp 2013-01-18 21:28:38 +0000 +++ dcpp/ChatMessage.cpp 2013-01-29 18:08:36 +0000 @@ -96,13 +96,13 @@ message += tmp; /* format the message; this will involve adding custom tags. use the Tagger class to that end. */ - Tagger tags; - format(tmp, tags, xmlTmp); + Tagger tags(move(tmp)); + format(tags, xmlTmp); // let plugins play with the tag list - PluginManager::getInstance()->onChatTags(tmp, tags, from); + PluginManager::getInstance()->onChatTags(tags, from); - htmlMessage += "<span id=\"text\">" + tags.merge(tmp, xmlTmp) + "</span></span>"; + htmlMessage += "<span id=\"text\">" + tags.merge(xmlTmp) + "</span></span>"; // forward to plugins PluginManager::getInstance()->onChatDisplay(htmlMessage, from); @@ -114,12 +114,14 @@ (!first && (c == '+' || c == '.' || c == '-')); } } -void ChatMessage::format(string& text, Tagger& tags, string& tmp) { +void ChatMessage::format(Tagger& tags, string& tmp) { + const auto& text = tags.getText(); + /* link formatting - optimize the lookup a bit by using the fact that every link identifier (except www ones) contains a colon. */ auto addLinkStr = [&tmp, &tags](size_t begin, size_t end, const string& link) { - tags.add(begin, end, "a", "href=\"" + SimpleXML::escape(link, tmp, true) + "\""); + tags.addTag(begin, end, "a", "href=\"" + SimpleXML::escape(link, tmp, true) + "\""); }; auto addLink = [&text, &addLinkStr](size_t begin, size_t end) { @@ -154,10 +156,10 @@ if(!name.empty()) { // magnet link: replace with the friendly name name += " (magnet)"; - text.replace(begin, end - begin, name); + tags.replaceText(begin, end, name); // the size of the string has changed; update counts. - auto delta = name.size() - link.size(); + const auto delta = static_cast<int>(name.size()) - static_cast<int>(link.size()); end += delta; n += delta; } === modified file 'dcpp/ChatMessage.h' --- dcpp/ChatMessage.h 2013-01-18 21:28:38 +0000 +++ dcpp/ChatMessage.h 2013-01-29 18:08:36 +0000 @@ -61,7 +61,7 @@ /** Store context-agnostic formattings that can be applied to the given message in the tagger. Note that the string may be modified. */ - static void format(string& text, Tagger& tags, string& tmp); + static void format(Tagger& tags, string& tmp); }; } // namespace dcpp === modified file 'dcpp/PluginApiImpl.cpp' --- dcpp/PluginApiImpl.cpp 2013-01-18 21:28:38 +0000 +++ dcpp/PluginApiImpl.cpp 2013-01-29 18:08:36 +0000 @@ -168,7 +168,10 @@ DCTagger PluginApiImpl::dcTagger = { DCINTF_DCPP_TAGGER_VER, - &PluginApiImpl::addTag + &PluginApiImpl::addTag, + + &PluginApiImpl::getText, + &PluginApiImpl::replaceText }; Socket* PluginApiImpl::udpSocket = nullptr; @@ -497,7 +500,15 @@ // Functions for DCTagger void PluginApiImpl::addTag(TagDataPtr hTags, size_t start, size_t end, const char* id, const char* attributes) { - reinterpret_cast<Tagger*>(hTags->object)->add(start, end, id, attributes); + reinterpret_cast<Tagger*>(hTags->object)->addTag(start, end, id, attributes); +} + +const char* PluginApiImpl::getText(TagDataPtr hTags) { + return reinterpret_cast<Tagger*>(hTags->object)->getText().c_str(); +} + +void PluginApiImpl::replaceText(TagDataPtr hTags, size_t start, size_t end, const char* replacement) { + reinterpret_cast<Tagger*>(hTags->object)->replaceText(start, end, replacement); } // Functions for DCQueue === modified file 'dcpp/PluginApiImpl.h' --- dcpp/PluginApiImpl.h 2013-01-18 21:28:38 +0000 +++ dcpp/PluginApiImpl.h 2013-01-29 18:08:36 +0000 @@ -94,6 +94,9 @@ // Functions for DCTagger static void DCAPI addTag(TagDataPtr hTags, size_t start, size_t end, const char* id, const char* attributes); + static const char* DCAPI getText(TagDataPtr hTags); + static void DCAPI replaceText(TagDataPtr hTags, size_t start, size_t end, const char* replacement); + // Functions for DCQueue static QueueDataPtr DCAPI addList(UserDataPtr user, Bool silent); static QueueDataPtr DCAPI addDownload(const char* hash, uint64_t size, const char* target); === modified file 'dcpp/PluginDefs.h' --- dcpp/PluginDefs.h 2013-01-18 21:28:38 +0000 +++ dcpp/PluginDefs.h 2013-01-29 18:08:36 +0000 @@ -77,7 +77,7 @@ #define DCINTF_DCPP_UTILS_VER 1 #define DCINTF_DCPP_TAGGER "dcpp.xml.DCTagger" /* Manipulation of an XML tagger */ -#define DCINTF_DCPP_TAGGER_VER 1 +#define DCINTF_DCPP_TAGGER_VER 2 #define DCINTF_DCPP_UI "dcpp.ui.DCUI" /* User interface */ #define DCINTF_DCPP_UI_VER 1 @@ -259,7 +259,6 @@ /* Tagging intentions */ typedef struct tagTagData { - const char* text; /* Plain text string to apply tags on */ dcptr_t object; /* Internal */ Bool isManaged; /* Always True for now */ } TagData, *TagDataPtr; @@ -426,6 +425,10 @@ uint32_t apiVersion; void (DCAPI *add_tag) (TagDataPtr hTags, size_t start, size_t end, const char* id, const char* attributes); + + /* Version 2 functions */ + const char* (DCAPI *get_text) (TagDataPtr hTags); + void (DCAPI *replace_text) (TagDataPtr hTags, size_t start, size_t end, const char* replacement); } DCTagger, *DCTaggerPtr; /* User interface */ === modified file 'dcpp/PluginManager.cpp' --- dcpp/PluginManager.cpp 2013-01-18 21:28:38 +0000 +++ dcpp/PluginManager.cpp 2013-01-29 18:08:36 +0000 @@ -207,8 +207,8 @@ } // Functions that call the plugin -bool PluginManager::onChatTags(const string& text, Tagger& tagger, OnlineUser* from) { - TagData data = { text.c_str(), reinterpret_cast<dcptr_t>(&tagger), True }; +bool PluginManager::onChatTags(Tagger& tagger, OnlineUser* from) { + TagData data = { reinterpret_cast<dcptr_t>(&tagger), True }; return runHook(HOOK_UI_CHAT_TAGS, from, &data); } === modified file 'dcpp/PluginManager.h' --- dcpp/PluginManager.h 2013-01-18 21:28:38 +0000 +++ dcpp/PluginManager.h 2013-01-29 18:08:36 +0000 @@ -111,7 +111,7 @@ DCCorePtr getCore() { return &dcCore; } // Functions that call the plugin - bool onChatTags(const string& text, Tagger& tagger, OnlineUser* from = nullptr); + bool onChatTags(Tagger& tagger, OnlineUser* from = nullptr); bool onChatDisplay(string& htmlMessage, OnlineUser* from = nullptr); bool onChatCommand(Client* client, const string& line); bool onChatCommandPM(const HintedUser& user, const string& line); === modified file 'dcpp/Tagger.cpp' --- dcpp/Tagger.cpp 2013-01-18 21:28:38 +0000 +++ dcpp/Tagger.cpp 2013-01-29 18:08:36 +0000 @@ -29,21 +29,47 @@ using std::vector; -void Tagger::add(size_t start, size_t end, string id, string attributes) { - Tag openingTag = { start, "<" + id + " " + move(attributes) + ">", true }, - closingTag = { end, "</" + move(id) + ">", false }; - - tags.push_back(std::move(openingTag)); +Tagger::Tagger(const string& text) : text(text) +{ +} + +Tagger::Tagger(string&& text) : text(move(text)) +{ +} + +const string& Tagger::getText() const { + return text; +} + +void Tagger::addTag(size_t start, size_t end, string id, string attributes) { + Tag openingTag { start, "<" + id + " " + move(attributes) + ">", true }; + Tag closingTag { end, "</" + move(id) + ">", false }; + + tags.push_back(move(openingTag)); auto& opening = tags.back(); - tags.push_back(std::move(closingTag)); + tags.push_back(move(closingTag)); auto& closing = tags.back(); opening.otherTag = &closing; closing.otherTag = &opening; } -string Tagger::merge(const string& text, string& tmp) { +void Tagger::replaceText(size_t start, size_t end, const string& replacement) { + text.replace(start, end - start, replacement); + + const auto delta = static_cast<int>(replacement.size()) - static_cast<int>(end - start); + + for(auto& tag: tags) { + if(tag.pos >= end) { + tag.pos -= delta; + } else if(tag.pos > start) { + tag.pos = start; + } + } +} + +string Tagger::merge(string& tmp) { tags.sort([](const Tag& a, const Tag& b) { return a.pos < b.pos; }); string ret; === modified file 'dcpp/Tagger.h' --- dcpp/Tagger.h 2013-01-18 21:28:38 +0000 +++ dcpp/Tagger.h 2013-01-29 18:08:36 +0000 @@ -33,10 +33,18 @@ entangled tags, such as: <a> <b> </a> </b> -> <a> <b> </b></a><b> </b> */ class Tagger { public: - void add(size_t start, size_t end, string id, string attributes); - string merge(const string& text, string& tmp); + Tagger(const string& text); + Tagger(string&& text); + + const string& getText() const; + + void addTag(size_t start, size_t end, string id, string attributes); + void replaceText(size_t start, size_t end, const string& replacement); + string merge(string& tmp); private: + string text; + struct Tag { size_t pos; string s; bool opening; Tag* otherTag; }; list<Tag> tags; // this table holds the tags to be added along with their position. }; === modified file 'win32/AspectChat.h' --- win32/AspectChat.h 2013-01-18 21:28:38 +0000 +++ win32/AspectChat.h 2013-01-29 18:08:36 +0000 @@ -75,16 +75,16 @@ /// add a chat message with some formatting and call addedChat. void addChat(const tstring& message) { - string xmlTmp, tmp = Text::fromT(message); - - Tagger tags; - ChatMessage::format(tmp, tags, xmlTmp); - - PluginManager::getInstance()->onChatTags(tmp, tags); + string tmp; + + Tagger tags(Text::fromT(message)); + ChatMessage::format(tags, tmp); + + PluginManager::getInstance()->onChatTags(tags); string htmlMessage = "<span id=\"message\" style=\"white-space: pre-wrap;\">" - "<span id=\"timestamp\">" + SimpleXML::escape("[" + Util::getShortTimeString() + "]", xmlTmp, false) + "</span> " - "<span id=\"text\">" + tags.merge(tmp, xmlTmp) + "</span></span>"; + "<span id=\"timestamp\">" + SimpleXML::escape("[" + Util::getShortTimeString() + "]", tmp, false) + "</span> " + "<span id=\"text\">" + tags.merge(tmp) + "</span></span>"; PluginManager::getInstance()->onChatDisplay(htmlMessage);
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp