OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/libjingle/xmpp/presencereceivetask.h" | |
12 | |
13 #include "webrtc/libjingle/xmpp/constants.h" | |
14 #include "webrtc/base/stringencode.h" | |
15 | |
16 namespace buzz { | |
17 | |
18 static bool IsUtf8FirstByte(int c) { | |
19 return (((c)&0x80)==0) || // is single byte | |
20 ((unsigned char)((c)-0xc0)<0x3e); // or is lead byte | |
21 } | |
22 | |
23 PresenceReceiveTask::PresenceReceiveTask(XmppTaskParentInterface* parent) | |
24 : XmppTask(parent, XmppEngine::HL_TYPE) { | |
25 } | |
26 | |
27 PresenceReceiveTask::~PresenceReceiveTask() { | |
28 Stop(); | |
29 } | |
30 | |
31 int PresenceReceiveTask::ProcessStart() { | |
32 const XmlElement * stanza = NextStanza(); | |
33 if (stanza == NULL) { | |
34 return STATE_BLOCKED; | |
35 } | |
36 | |
37 Jid from(stanza->Attr(QN_FROM)); | |
38 HandlePresence(from, stanza); | |
39 | |
40 return STATE_START; | |
41 } | |
42 | |
43 bool PresenceReceiveTask::HandleStanza(const XmlElement * stanza) { | |
44 // Verify that this is a presence stanze | |
45 if (stanza->Name() != QN_PRESENCE) { | |
46 return false; // not sure if this ever happens. | |
47 } | |
48 | |
49 // Queue it up | |
50 QueueStanza(stanza); | |
51 | |
52 return true; | |
53 } | |
54 | |
55 void PresenceReceiveTask::HandlePresence(const Jid& from, | |
56 const XmlElement* stanza) { | |
57 if (stanza->Attr(QN_TYPE) == STR_ERROR) { | |
58 return; | |
59 } | |
60 | |
61 PresenceStatus status; | |
62 DecodeStatus(from, stanza, &status); | |
63 PresenceUpdate(status); | |
64 } | |
65 | |
66 void PresenceReceiveTask::DecodeStatus(const Jid& from, | |
67 const XmlElement* stanza, | |
68 PresenceStatus* presence_status) { | |
69 presence_status->set_jid(from); | |
70 if (stanza->Attr(QN_TYPE) == STR_UNAVAILABLE) { | |
71 presence_status->set_available(false); | |
72 } else { | |
73 presence_status->set_available(true); | |
74 const XmlElement * status_elem = stanza->FirstNamed(QN_STATUS); | |
75 if (status_elem != NULL) { | |
76 presence_status->set_status(status_elem->BodyText()); | |
77 | |
78 // Truncate status messages longer than 300 bytes | |
79 if (presence_status->status().length() > 300) { | |
80 size_t len = 300; | |
81 | |
82 // Be careful not to split legal utf-8 chars in half | |
83 while (!IsUtf8FirstByte(presence_status->status()[len]) && len > 0) { | |
84 len -= 1; | |
85 } | |
86 std::string truncated(presence_status->status(), 0, len); | |
87 presence_status->set_status(truncated); | |
88 } | |
89 } | |
90 | |
91 const XmlElement * priority = stanza->FirstNamed(QN_PRIORITY); | |
92 if (priority != NULL) { | |
93 int pri; | |
94 if (rtc::FromString(priority->BodyText(), &pri)) { | |
95 presence_status->set_priority(pri); | |
96 } | |
97 } | |
98 | |
99 const XmlElement * show = stanza->FirstNamed(QN_SHOW); | |
100 if (show == NULL || show->FirstChild() == NULL) { | |
101 presence_status->set_show(PresenceStatus::SHOW_ONLINE); | |
102 } else if (show->BodyText() == "away") { | |
103 presence_status->set_show(PresenceStatus::SHOW_AWAY); | |
104 } else if (show->BodyText() == "xa") { | |
105 presence_status->set_show(PresenceStatus::SHOW_XA); | |
106 } else if (show->BodyText() == "dnd") { | |
107 presence_status->set_show(PresenceStatus::SHOW_DND); | |
108 } else if (show->BodyText() == "chat") { | |
109 presence_status->set_show(PresenceStatus::SHOW_CHAT); | |
110 } else { | |
111 presence_status->set_show(PresenceStatus::SHOW_ONLINE); | |
112 } | |
113 | |
114 const XmlElement * caps = stanza->FirstNamed(QN_CAPS_C); | |
115 if (caps != NULL) { | |
116 std::string node = caps->Attr(QN_NODE); | |
117 std::string ver = caps->Attr(QN_VER); | |
118 std::string exts = caps->Attr(QN_EXT); | |
119 | |
120 presence_status->set_know_capabilities(true); | |
121 presence_status->set_caps_node(node); | |
122 presence_status->set_version(ver); | |
123 } | |
124 | |
125 const XmlElement* delay = stanza->FirstNamed(kQnDelayX); | |
126 if (delay != NULL) { | |
127 // Ideally we would parse this according to the Psuedo ISO-8601 rules | |
128 // that are laid out in JEP-0082: | |
129 // http://www.jabber.org/jeps/jep-0082.html | |
130 std::string stamp = delay->Attr(kQnStamp); | |
131 presence_status->set_sent_time(stamp); | |
132 } | |
133 | |
134 const XmlElement* nick = stanza->FirstNamed(QN_NICKNAME); | |
135 if (nick) { | |
136 presence_status->set_nick(nick->BodyText()); | |
137 } | |
138 } | |
139 } | |
140 | |
141 } // namespace buzz | |
OLD | NEW |