linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06470
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3196: add a text replacement function to the XML tagger
------------------------------------------------------------
revno: 3196
committer: poy <poy@xxxxxxxxxx>
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);