linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06013
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3037: plugins: add a hook to ease chat message tagging; merge 2 formatting hooks
------------------------------------------------------------
revno: 3037
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sat 2012-09-08 15:54:40 +0200
message:
plugins: add a hook to ease chat message tagging; merge 2 formatting hooks
added:
dcpp/Tagger.cpp
dcpp/Tagger.h
modified:
dcpp/ChatMessage.cpp
dcpp/PluginApiImpl.cpp
dcpp/PluginApiImpl.h
dcpp/PluginDefs.h
dcpp/PluginEntity.h
dcpp/PluginManager.cpp
dcpp/PluginManager.h
dcpp/stdinc.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 2012-08-02 17:11:14 +0000
+++ dcpp/ChatMessage.cpp 2012-09-08 13:54:40 +0000
@@ -23,17 +23,14 @@
#include "format.h"
#include "Magnet.h"
#include "OnlineUser.h"
+#include "PluginManager.h"
#include "SettingsManager.h"
#include "SimpleXML.h"
+#include "Tagger.h"
#include "Util.h"
-#include "PluginManager.h"
-
-#include <boost/range/adaptor/reversed.hpp>
namespace dcpp {
-using std::list;
-
ChatMessage::ChatMessage(const string& text, OnlineUser* from,
const OnlineUser* to, const OnlineUser* replyTo,
bool thirdPerson, time_t messageTimestamp) :
@@ -98,28 +95,16 @@
message += tmp;
- /* format the message; this will involve adding custom tags. this table holds the tags to be
- added along with their position. */
+ /* format the message; this will involve adding custom tags. use the Tagger class to that end. */
- struct Tag { size_t pos; string s; bool opening; Tag* otherTag; };
- list<Tag> tags;
+ Tagger tags;
/* link formatting - optimize the lookup a bit by using the fact that every link identifier
(except www ones) contains a colon. */
/// @todo add support for spaces within links enclosed by brackets / quotes (see URI RFC)
auto addLinkStr = [&xmlTmp, &tags](size_t begin, size_t end, const string& link) {
- Tag openingTag = { begin, "<a href=\"" + SimpleXML::escape(link, xmlTmp, true) + "\">", true },
- closingTag = { end, "</a>", false };
-
- tags.push_back(std::move(openingTag));
- auto& opening = tags.back();
-
- tags.push_back(std::move(closingTag));
- auto& closing = tags.back();
-
- opening.otherTag = &closing;
- closing.otherTag = &opening;
+ tags.add(begin, end, "a", "href=\"" + SimpleXML::escape(link, xmlTmp, true) + "\"");
};
auto addLink = [&tmp, &addLinkStr](size_t begin, size_t end) {
@@ -184,50 +169,12 @@
i += 5;
}
- htmlMessage += "<span id=\"text\">";
-
- /* write tags and the message data. support entangled tags, such as:
- <a> <b> </a> </b> -> <a> <b> </b></a><b> </b> */
-
- tags.sort([](const Tag& a, const Tag& b) { return a.pos < b.pos; });
-
- size_t pos = 0;
- vector<Tag*> openTags;
-
- for(auto& tag: tags) {
- htmlMessage += SimpleXML::escape(tmp.substr(pos, tag.pos - pos), xmlTmp, false);
- pos = tag.pos;
-
- if(tag.opening) {
- htmlMessage += tag.s;
- openTags.push_back(&tag);
-
- } else {
- if(openTags.back() == tag.otherTag) {
- // common case: no entangled tag; just write the closing tag.
- htmlMessage += tag.s;
- openTags.pop_back();
-
- } else {
- // there are entangled tags: write closing & opening tags of currently open tags.
- for(auto openTag: openTags | boost::adaptors::reversed) { if(openTag->pos >= tag.otherTag->pos) {
- htmlMessage += openTag->otherTag->s;
- } }
- openTags.erase(remove(openTags.begin(), openTags.end(), tag.otherTag), openTags.end());
- for(auto openTag: openTags) { if(openTag->pos >= tag.otherTag->pos) {
- htmlMessage += openTag->s;
- } }
- }
- }
- }
-
- if(pos != n) {
- htmlMessage += SimpleXML::escape(tmp.substr(pos), xmlTmp, false);
- }
-
- htmlMessage += "</span></span>";
-
- /// forward to plugins
+ // let plugins play with the tag list
+ PluginManager::getInstance()->onChatTags(tmp, tags, from);
+
+ htmlMessage += "<span id=\"text\">" + tags.merge(tmp, xmlTmp) + "</span></span>";
+
+ // forward to plugins
PluginManager::getInstance()->onChatDisplay(htmlMessage, from);
}
=== modified file 'dcpp/PluginApiImpl.cpp'
--- dcpp/PluginApiImpl.cpp 2012-08-02 17:49:34 +0000
+++ dcpp/PluginApiImpl.cpp 2012-09-08 13:54:40 +0000
@@ -36,6 +36,7 @@
#include "LogManager.h"
#include "PluginManager.h"
#include "QueueManager.h"
+#include "Tagger.h"
#include "UserConnection.h"
#include "version.h"
@@ -66,8 +67,8 @@
HOOK_QUEUE_FINISHED,
HOOK_UI_CREATED,
+ HOOK_UI_CHAT_TAGS,
HOOK_UI_CHAT_DISPLAY,
- HOOK_UI_LOCAL_CHAT_DISPLAY,
HOOK_UI_PROCESS_CHAT_CMD
};
@@ -160,6 +161,12 @@
&PluginApiImpl::fromBase32
};
+DCTagger PluginApiImpl::dcTagger = {
+ DCINTF_DCPP_TAGGER_VER,
+
+ &PluginApiImpl::addTag
+};
+
Socket* PluginApiImpl::udpSocket = nullptr;
Socket& PluginApiImpl::getUdpSocket() {
if(!udpSocket) {
@@ -189,6 +196,7 @@
dcCore.register_interface(DCINTF_DCPP_HUBS, &dcHub);
dcCore.register_interface(DCINTF_DCPP_QUEUE, &dcQueue);
dcCore.register_interface(DCINTF_DCPP_UTILS, &dcUtils);
+ dcCore.register_interface(DCINTF_DCPP_TAGGER, &dcTagger);
// Create provided hooks (since these outlast any plugin they don't need to be explictly released)
for(int i = 0; i < IMPL_HOOKS_COUNT; ++i)
@@ -471,6 +479,11 @@
return n;
}
+// 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);
+}
+
// Functions for DCQueue
QueueDataPtr PluginApiImpl::addList(UserDataPtr user, Bool silent) {
auto u = ClientManager::getInstance()->findUser(CID(user->cid));
@@ -703,8 +716,3 @@
}
} // namespace dcpp
-
-/**
- * @file
- * $Id: PluginApiImpl.cpp 1248 2012-01-22 01:49:30Z crise $
- */
=== modified file 'dcpp/PluginApiImpl.h'
--- dcpp/PluginApiImpl.h 2012-08-02 17:49:34 +0000
+++ dcpp/PluginApiImpl.h 2012-09-08 13:54:40 +0000
@@ -90,6 +90,9 @@
static size_t DCAPI toBase32(char* dst, const uint8_t* src, size_t n);
static size_t DCAPI fromBase32(uint8_t* dst, const char* src, size_t n);
+ // Functions for DCTagger
+ static void DCAPI addTag(TagDataPtr hTags, size_t start, size_t end, const char* id, const char* attributes);
+
// Functions for DCQueue
static QueueDataPtr DCAPI addList(UserDataPtr user, Bool silent);
static QueueDataPtr DCAPI addDownload(const char* hash, uint64_t size, const char* target);
@@ -120,6 +123,7 @@
static DCHub dcHub;
static DCQueue dcQueue;
static DCUtils dcUtils;
+ static DCTagger dcTagger;
static Socket* udpSocket;
static Socket& getUdpSocket();
@@ -128,8 +132,3 @@
} // namepsace dcpp
#endif // !defined(DCPLUSPLUS_DCPP_PLUGIN_API_H)
-
-/**
- * @file
- * $Id: PluginApiImpl.h 1248 2012-01-22 01:49:30Z crise $
- */
=== modified file 'dcpp/PluginDefs.h'
--- dcpp/PluginDefs.h 2012-08-02 17:49:34 +0000
+++ dcpp/PluginDefs.h 2012-09-08 13:54:40 +0000
@@ -24,7 +24,7 @@
#endif
/* Version of the plugin api (must change if old plugins simply can't be seen as viably working) */
-#define DCAPI_CORE_VER 4
+#define DCAPI_CORE_VER 5
#ifdef _WIN32
# define DCAPI __stdcall
@@ -62,12 +62,15 @@
#define DCINTF_DCPP_HUBS "dcpp.network.DCHub" /* Hubs */
#define DCINTF_DCPP_HUBS_VER 1
-#define DCINTF_DCPP_QUEUE "dcpp.queue.DCQueue" /* Download Queue (TODO: expand) */
+#define DCINTF_DCPP_QUEUE "dcpp.queue.DCQueue" /* Download Queue */
#define DCINTF_DCPP_QUEUE_VER 1
#define DCINTF_DCPP_UTILS "dcpp.utils.DCUtils" /* Utility and convenience functions */
#define DCINTF_DCPP_UTILS_VER 1
+#define DCINTF_DCPP_TAGGER "dcpp.xml.Tagger" /* Manipulation of an XML tagger */
+#define DCINTF_DCPP_TAGGER_VER 1
+
/* Hook GUID's for Hooks (events) system */
#define HOOK_CHAT_IN "dcpp.chat.onIncomingChat" /* Incoming chat from hub (obj: HubData) */
#define HOOK_CHAT_OUT "dcpp.chat.onOutgoingChat" /* Outgoing chat (obj: HubData) */
@@ -93,8 +96,8 @@
#define HOOK_QUEUE_FINISHED "dcpp.queue.onFinished" /* Item has just finished downloading (obj: QueueData) */
#define HOOK_UI_CREATED "dcpp.ui.onCreated" /* Host application UI has been created (obj: if any, impl. dependant) */
-#define HOOK_UI_CHAT_DISPLAY "dcpp.ui.onChatDisplay" /* Chat messages before displayed in chat (obj: UserData; data: StringData) */
-#define HOOK_UI_LOCAL_CHAT_DISPLAY "dcpp.ui.onLocalChatDisplay" /* Local chat messages (such as system messages) before they are displayed in chat (obj: NULL; data: StringData) */
+#define HOOK_UI_CHAT_TAGS "dcpp.ui.onTags" /* Chat message tags before tag merging (obj: UserData; data: TagData) */
+#define HOOK_UI_CHAT_DISPLAY "dcpp.ui.onChatDisplay" /* Chat messages before they are displayed in chat (obj: UserData; data: StringData) */
#define HOOK_UI_PROCESS_CHAT_CMD "dcpp.ui.onProcessCmd" /* Client side commands in chat (obj: HubData/UserData; data: CommandData) */
/* Main hook events (returned by pluginInit) */
@@ -244,6 +247,13 @@
Bool isManaged; /* False if plugin has to call release(...) for this object */
} QueueData, *QueueDataPtr;
+/* 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;
+
/* Plugin meta data */
typedef struct tagMetaData {
const char* name; /* Name of the plugin */
@@ -363,7 +373,7 @@
void (DCAPI *release) (HubDataPtr hCopy);
} DCHub, *DCHubPtr;
-/* Download Queue (TODO: expand) */
+/* Download Queue */
typedef struct tagDCQueue {
/* Queue API version */
uint32_t apiVersion;
@@ -394,13 +404,16 @@
size_t (DCAPI *from_base32) (uint8_t* dst, const char* src, size_t n);
} DCUtils, *DCUtilsPtr;
+/* Manipulation of an XML tagger */
+typedef struct tagDCTagger {
+ /* Tagger API version */
+ uint32_t apiVersion;
+
+ void (DCAPI *add_tag) (TagDataPtr hTags, size_t start, size_t end, const char* id, const char* attributes);
+} DCTagger, *DCTaggerPtr;
+
#ifdef __cplusplus
}
#endif
#endif /* !defined(DCPLUSPLUS_DCPP_PLUGIN_DEFS_H) */
-
-/**
- * @file
- * $Id: PluginDefs.h 1248 2012-01-22 01:49:30Z crise $
- */
=== modified file 'dcpp/PluginEntity.h'
--- dcpp/PluginEntity.h 2012-07-02 18:13:18 +0000
+++ dcpp/PluginEntity.h 2012-09-08 13:54:40 +0000
@@ -21,6 +21,7 @@
#include <list>
+#include "CriticalSection.h"
#include "PluginApiImpl.h"
namespace dcpp {
@@ -31,7 +32,14 @@
class PluginEntity
{
public:
- PluginEntity() { memzero(&pod, sizeof(PluginType)); pod.isManaged = True; }
+ PluginEntity() {
+#ifndef _MSC_VER
+ pod = { };
+#else
+ memset(&pod, 0, sizeof(PluginType));
+#endif
+ pod.isManaged = True;
+ }
virtual ~PluginEntity() { psCache.clear(); }
PluginType* copyPluginObject() {
=== modified file 'dcpp/PluginManager.cpp'
--- dcpp/PluginManager.cpp 2012-08-02 17:49:34 +0000
+++ dcpp/PluginManager.cpp 2012-09-08 13:54:40 +0000
@@ -62,6 +62,19 @@
}
}
+PluginManager::PluginManager() : shutdown(false), secNum(Util::rand()) {
+#ifndef _MSC_VER
+ dcCore = { };
+#else
+ memset(&dcCore, 0, sizeof(DCCore));
+#endif
+ SettingsManager::getInstance()->addListener(this);
+}
+
+PluginManager::~PluginManager() {
+ SettingsManager::getInstance()->removeListener(this);
+}
+
void PluginManager::loadPlugins(function<void (const string&)> f) {
PluginApiImpl::initAPI(dcCore);
@@ -91,11 +104,9 @@
PluginInfo::PLUGIN_INIT pluginInfo = reinterpret_cast<PluginInfo::PLUGIN_INIT>(GET_ADDRESS(hr, "pluginInit"));
if(pluginInfo != NULL) {
- MetaData info;
- memzero(&info, sizeof(MetaData));
-
+ MetaData info = { 0 };
DCMAIN dcMain;
- if((dcMain = pluginInfo(&info)) != NULL) {
+ if((dcMain = pluginInfo(&info))) {
if(checkPlugin(info, err)) {
if(dcMain((install ? ON_INSTALL : ON_LOAD), &dcCore, NULL) != False) {
plugins.emplace_back(new PluginInfo(fileName, hr, info, dcMain));
@@ -203,27 +214,24 @@
}
// 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 };
+ return runHook(HOOK_UI_CHAT_TAGS, from, &data);
+}
+
bool PluginManager::onChatDisplay(string& htmlMessage, OnlineUser* from) {
- StringData data;
- memzero(&data, sizeof(StringData));
-
- data.in = htmlMessage.c_str();
-
- bool handled = from ? runHook(HOOK_UI_CHAT_DISPLAY, from, &data) : runHook(HOOK_UI_LOCAL_CHAT_DISPLAY, NULL, &data);
- if(handled && data.out != NULL) {
+ StringData data = { htmlMessage.c_str() };
+ bool handled = runHook(HOOK_UI_CHAT_DISPLAY, from, &data);
+ if(handled && data.out) {
htmlMessage = data.out;
return true;
}
-
return false;
}
bool PluginManager::onChatCommand(Client* client, const string& line) {
- CommandData data;
- memzero(&data, sizeof(CommandData));
-
string cmd, param;
- string::size_type si = line.find(' ');
+ auto si = line.find(' ');
if(si != string::npos) {
param = line.substr(si + 1);
cmd = line.substr(1, si - 1);
@@ -231,10 +239,7 @@
cmd = line.substr(1);
}
- data.command = cmd.c_str();
- data.params = param.c_str();
- data.isPrivate = False;
-
+ CommandData data = { cmd.c_str(), param.c_str(), False };
return runHook(HOOK_UI_PROCESS_CHAT_CMD, client, &data);
}
@@ -245,11 +250,8 @@
OnlineUser* ou = ClientManager::getInstance()->findOnlineUser(user.user->getCID(), user.hint);
if(ou) {
- CommandData data;
- memzero(&data, sizeof(CommandData));
-
string cmd, param;
- string::size_type si = line.find(' ');
+ auto si = line.find(' ');
if(si != string::npos) {
param = line.substr(si + 1);
cmd = line.substr(1, si - 1);
@@ -257,10 +259,7 @@
cmd = line.substr(1);
}
- data.command = cmd.c_str();
- data.params = param.c_str();
- data.isPrivate = True;
-
+ CommandData data = { cmd.c_str(), param.c_str(), True };
res = runHook(HOOK_UI_PROCESS_CHAT_CMD, ou, &data);
}
@@ -513,8 +512,3 @@
}
} // namespace dcpp
-
-/**
- * @file
- * $Id: PluginManager.cpp 1245 2012-01-21 15:09:54Z crise $
- */
=== modified file 'dcpp/PluginManager.h'
--- dcpp/PluginManager.h 2012-07-08 03:48:50 +0000
+++ dcpp/PluginManager.h 2012-09-08 13:54:40 +0000
@@ -19,24 +19,23 @@
#ifndef DCPLUSPLUS_DCPP_PLUGIN_MANAGER_H
#define DCPLUSPLUS_DCPP_PLUGIN_MANAGER_H
-#include "typedefs.h"
-
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>
+#include "typedefs.h"
+
+#include "ClientManagerListener.h"
+#include "PluginApiImpl.h"
+#include "PluginEntity.h"
+#include "QueueManagerListener.h"
+#include "SettingsManager.h"
#include "Singleton.h"
-#include "SettingsManager.h"
+#include "Tagger.h"
#include "TimerManager.h"
-#include "QueueManagerListener.h"
-#include "ClientManagerListener.h"
-
-#include "PluginEntity.h"
-#include "PluginApiImpl.h"
-
#ifdef _WIN32
typedef HMODULE PluginHandle;
#else
@@ -92,14 +91,8 @@
private ClientManagerListener, private QueueManagerListener, private SettingsManagerListener
{
public:
- PluginManager() : shutdown(false), secNum(Util::rand()) {
- memzero(&dcCore, sizeof(DCCore));
- SettingsManager::getInstance()->addListener(this);
- }
-
- ~PluginManager() {
- SettingsManager::getInstance()->removeListener(this);
- }
+ PluginManager();
+ ~PluginManager();
void loadPlugins(function<void (const string&)> f);
bool loadPlugin(const string& fileName, function<void (const string&)> err, bool install = false);
@@ -118,7 +111,8 @@
DCCorePtr getCore() { return &dcCore; }
// Functions that call the plugin
- bool onChatDisplay(string& htmlMessage, OnlineUser* from = NULL);
+ bool onChatTags(const string& text, 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);
@@ -132,8 +126,11 @@
template<class T>
bool runHook(const string& guid, PluginEntity<T>* entity, dcptr_t pData = NULL) {
- Lock l(entity->cs);
- return runHook(guid, entity->getPluginObject(), pData);
+ if(entity) {
+ Lock l(entity->cs);
+ return runHook(guid, entity->getPluginObject(), pData);
+ }
+ return runHook(guid, nullptr, pData);
}
template<class T>
@@ -199,8 +196,3 @@
} // namespace dcpp
#endif // !defined(DCPLUSPLUS_DCPP_PLUGIN_MANAGER_H)
-
-/**
- * @file
- * $Id: PluginManager.h 1245 2012-01-21 15:09:54Z crise $
- */
=== added file 'dcpp/Tagger.cpp'
--- dcpp/Tagger.cpp 1970-01-01 00:00:00 +0000
+++ dcpp/Tagger.cpp 2012-09-08 13:54:40 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdinc.h"
+#include "Tagger.h"
+
+#include "SimpleXML.h"
+
+#include <vector>
+
+#include <boost/range/adaptor/reversed.hpp>
+
+namespace dcpp {
+
+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));
+ auto& opening = tags.back();
+
+ tags.push_back(std::move(closingTag));
+ auto& closing = tags.back();
+
+ opening.otherTag = &closing;
+ closing.otherTag = &opening;
+}
+
+string Tagger::merge(const string& text, string& tmp) {
+ tags.sort([](const Tag& a, const Tag& b) { return a.pos < b.pos; });
+
+ string ret;
+
+ size_t pos = 0;
+ vector<Tag*> openTags;
+
+ for(auto& tag: tags) {
+ ret += SimpleXML::escape(text.substr(pos, tag.pos - pos), tmp, false);
+ pos = tag.pos;
+
+ if(tag.opening) {
+ ret += tag.s;
+ openTags.push_back(&tag);
+
+ } else {
+ if(openTags.back() == tag.otherTag) {
+ // common case: no entangled tag; just write the closing tag.
+ ret += tag.s;
+ openTags.pop_back();
+
+ } else {
+ // there are entangled tags: write closing & opening tags of currently open tags.
+ for(auto openTag: openTags | boost::adaptors::reversed) { if(openTag->pos >= tag.otherTag->pos) {
+ ret += openTag->otherTag->s;
+ } }
+ openTags.erase(remove(openTags.begin(), openTags.end(), tag.otherTag), openTags.end());
+ for(auto openTag: openTags) { if(openTag->pos >= tag.otherTag->pos) {
+ ret += openTag->s;
+ } }
+ }
+ }
+ }
+
+ if(pos != text.size()) {
+ ret += SimpleXML::escape(text.substr(pos), tmp, false);
+ }
+
+ return ret;
+}
+
+} // namespace dcpp
=== added file 'dcpp/Tagger.h'
--- dcpp/Tagger.h 1970-01-01 00:00:00 +0000
+++ dcpp/Tagger.h 2012-09-08 13:54:40 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DCPLUSPLUS_DCPP_TAGGER_H
+#define DCPLUSPLUS_DCPP_TAGGER_H
+
+#include "forward.h"
+
+#include <list>
+#include <string>
+
+namespace dcpp {
+
+using std::list;
+using std::string;
+
+/** Adds XML tags to a plain text string. The tags are added all at once. The tagger supports
+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);
+
+private:
+ 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.
+};
+
+} // namespace dcpp
+
+#endif
=== modified file 'dcpp/stdinc.h'
--- dcpp/stdinc.h 2012-07-01 18:41:13 +0000
+++ dcpp/stdinc.h 2012-09-08 13:54:40 +0000
@@ -29,10 +29,6 @@
#define DCAPI_HOST 1
#endif
-#ifndef memzero
-#define memzero(dest, n) memset(dest, 0, n)
-#endif
-
#ifdef HAS_PCH
#ifdef _WIN32