diff options
Diffstat (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/examples/call/presencepushtask.cpp')
-rw-r--r-- | kopete/protocols/jabber/jingle/libjingle/talk/examples/call/presencepushtask.cpp | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/examples/call/presencepushtask.cpp b/kopete/protocols/jabber/jingle/libjingle/talk/examples/call/presencepushtask.cpp new file mode 100644 index 00000000..31d1ae77 --- /dev/null +++ b/kopete/protocols/jabber/jingle/libjingle/talk/examples/call/presencepushtask.cpp @@ -0,0 +1,172 @@ +/* + * Jingle call example + * Copyright 2004--2005, Google Inc. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "talk/examples/call/presencepushtask.h" +#include "talk/xmpp/constants.h" +#include <sstream> + + +namespace buzz { + +// string helper functions ----------------------------------------------------- +template <class T> static +bool FromString(const std::string& s, + T * t) { + std::istringstream iss(s); + return !(iss>>*t).fail(); +} + +template <class T> static +bool ToString(const T &t, + std::string* s) { + std::ostringstream oss; + oss << t; + *s = oss.str(); + return !oss.fail(); +} + +static bool +IsXmlSpace(int ch) { + return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; +} + +static bool +ListContainsToken(const std::string & list, const std::string & token) { + size_t i = list.find(token); + if (i == std::string::npos || token.empty()) + return false; + bool boundary_before = (i == 0 || IsXmlSpace(list[i - 1])); + bool boundary_after = (i == list.length() - token.length() || IsXmlSpace(list[i + token.length()])); + return boundary_before && boundary_after; +} + + +bool +PresencePushTask::HandleStanza(const XmlElement * stanza) { + if (stanza->Name() != TQN_PRESENCE) + return false; + if (stanza->HasAttr(TQN_TYPE) && stanza->Attr(TQN_TYPE) != STR_UNAVAILABLE) + return false; + QueueStanza(stanza); + return true; +} + +static bool IsUtf8FirstByte(int c) { + return (((c)&0x80)==0) || // is single byte + ((unsigned char)((c)-0xc0)<0x3e); // or is lead byte +} + +int +PresencePushTask::ProcessStart() { + const XmlElement * stanza = NextStanza(); + if (stanza == NULL) + return STATE_BLOCKED; + Status s; + + s.set_jid(Jid(stanza->Attr(TQN_FROM))); + + if (stanza->Attr(TQN_TYPE) == STR_UNAVAILABLE) { + s.set_available(false); + SignalStatusUpdate(s); + } + else { + s.set_available(true); + const XmlElement * status = stanza->FirstNamed(TQN_STATUS); + if (status != NULL) { + s.set_status(status->BodyText()); + + // Truncate status messages longer than 300 bytes + if (s.status().length() > 300) { + size_t len = 300; + + // Be careful not to split legal utf-8 chars in half + while (!IsUtf8FirstByte(s.status()[len]) && len > 0) { + len -= 1; + } + std::string truncated(s.status(), 0, len); + s.set_status(truncated); + } + } + + const XmlElement * priority = stanza->FirstNamed(TQN_PRIORITY); + if (priority != NULL) { + int pri; + if (FromString(priority->BodyText(), &pri)) { + s.set_priority(pri); + } + } + + const XmlElement * show = stanza->FirstNamed(TQN_SHOW); + if (show == NULL || show->FirstChild() == NULL) { + s.set_show(Status::SHOW_ONLINE); + } + else { + if (show->BodyText() == "away") { + s.set_show(Status::SHOW_AWAY); + } + else if (show->BodyText() == "xa") { + s.set_show(Status::SHOW_XA); + } + else if (show->BodyText() == "dnd") { + s.set_show(Status::SHOW_DND); + } + else if (show->BodyText() == "chat") { + s.set_show(Status::SHOW_CHAT); + } + else { + s.set_show(Status::SHOW_ONLINE); + } + } + + const XmlElement * caps = stanza->FirstNamed(TQN_CAPS_C); + if (caps != NULL) { + std::string node = caps->Attr(TQN_NODE); + std::string ver = caps->Attr(TQN_VER); + std::string exts = caps->Attr(TQN_EXT); + + s.set_know_capabilities(true); + + if (node == GOOGLE_CLIENT_NODE) { + s.set_is_google_client(true); + s.set_version(ver); + if (ListContainsToken(exts, "voice-v1")) { + s.set_phone_capability(true); + } + } + } + + const XmlElement* delay = stanza->FirstNamed(kQnDelayX); + if (delay != NULL) { + // Ideally we would parse this according to the Psuedo ISO-8601 rules + // that are laid out in JEP-0082: + // http://www.jabber.org/jeps/jep-0082.html + std::string stamp = delay->Attr(kQnStamp); + s.set_sent_time(stamp); + } + + SignalStatusUpdate(s); + } + + return STATE_START; +} + + +} + + |