reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
Pidf.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
8#include "rutil/XMLCursor.hxx"
9#include "rutil/Logger.hxx"
10#include "rutil/Inserter.hxx"
12
13using namespace resip;
14using namespace std;
15
16#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
17
18bool
20{
21 static ContentsFactory<Pidf> factory;
22 (void)factory;
23 return true;
24}
25
26const Pidf Pidf::Empty;
27
29 : Contents(getStaticType()),
30 mNote()
31{
32}
33
34Pidf::Pidf(const Data& txt)
35 : Contents(getStaticType()),
36 mNote(txt)
37{
38}
39
40Pidf::Pidf(const Mime& contentType)
41 : Contents(getStaticType()),
42 mNote()
43{
44}
45
46Pidf::Pidf(const HeaderFieldValue& hfv, const Mime& contentsType)
47 : Contents(hfv, contentsType),
48 mNote()
49{
50}
51
52Pidf::Pidf(const Data& txt, const Mime& contentType)
53 : Contents(contentType),
54 mNote(txt)
55{
56}
57
58Pidf&
60{
61 if (this != &rhs)
62 {
64 mNote = rhs.mNote;
65 mEntity = rhs.mEntity;
66 mTuples = rhs.mTuples;
67 }
68 return *this;
69}
70
71Pidf::Pidf(const Pidf& rhs)
72 : Contents(rhs),
73 mNote(rhs.mNote),
74 mEntity(rhs.mEntity),
75 mTuples(rhs.mTuples)
76{
77}
78
79Pidf::Pidf(const Uri& entity)
80 : Contents(getStaticType()),
81 mEntity(entity)
82{
83}
84
86{
87}
88
89void
90Pidf::setEntity(const Uri& entity)
91{
93 mEntity = entity;
94}
95
96const Uri&
98{
100 return mEntity;
101};
102
103std::vector<Pidf::Tuple>&
105{
106 checkParsed();
107 return mTuples;
108}
109
110const std::vector<Pidf::Tuple>&
112{
113 checkParsed();
114 return mTuples;
115}
116
117int
119{
120 checkParsed();
121 return (int)mTuples.size();
122}
123
124Contents*
126{
127 return new Pidf(*this);
128}
129
130const Mime&
132{
133 static Mime type("application","pidf+xml");
134 return type;
135}
136
138Pidf::encodeParsed(EncodeStream& str) const
139{
140 str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << Symbols::CRLF;
141 str << "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"" << Symbols::CRLF;
142 str << " entity=\"" << mEntity << "\">" << Symbols::CRLF;
143 for (vector<Tuple>::const_iterator i = mTuples.begin(); i != mTuples.end(); ++i)
144 {
145 Data status( (char*)( (i->status) ? "open" : "closed" ) );
146 str << " <tuple id=\"" << i->id << "\" ";
147
148 XMLCursor::encode(str, i->attributes);
149 str << ">" << Symbols::CRLF;
150 str << " <status><basic>" << status << "</basic></status>" << Symbols::CRLF;
151 if ( !i->contact.empty() )
152 {
153 str << " <contact priority=\"" << i->contactPriority << "\">" << i->contact << "</contact>" << Symbols::CRLF;
154 }
155 if ( !i->timeStamp.empty() )
156 {
157 str << " <timestamp>" << i->timeStamp << "</timestamp>" << Symbols::CRLF;
158 }
159 if ( !i->note.empty() )
160 {
161 str << " <note>" << i->note << "</note>" << Symbols::CRLF;
162 }
163 str << " </tuple>" << Symbols::CRLF;
164 }
165 str << "</presence>" << Symbols::CRLF;
166
167 return str;
168}
169
170void
172{
173 DebugLog(<< "Pidf::parse(" << Data(pb.start(), int(pb.end()-pb.start())) << ") ");
174
175 std::string pidf_namespace;
176
177 XMLCursor xml(pb);
178
181 std::find_if(attr.begin(), attr.end(), XMLCursor::AttributeValueEqual("urn:ietf:params:xml:ns:pidf"));
182
183 if ( it != attr.end() )
184 {
185
186 std::string key(it->first.data(), it->first.size());
187
188 size_t pos = key.find(':');
189
190 if ( pos != string::npos)
191 {
192 pidf_namespace.assign(key, pos+1, key.size()-pos-1);
193 pidf_namespace.append(1, ':');
194 }
195 }
196
197 const std::string presence = pidf_namespace + "presence";
198
199 if (xml.getTag() == presence.c_str())
200 {
202 if (i != xml.getAttributes().end())
203 {
204 mEntity = Uri(i->second);
205 }
206 else
207 {
208 DebugLog(<< "no entity!");
209 }
210
211 if (xml.firstChild())
212 {
213 do
214 {
215 const std::string tuple = pidf_namespace + "tuple";
216 if (xml.getTag() == tuple.c_str())
217 {
218 Tuple t;
219 t.attributes = xml.getAttributes();
221 if (i != xml.getAttributes().end())
222 {
223 t.id = i->second;
224 t.attributes.erase("id");
225 }
226
227 // look for status, contacts, notes -- take last of each for now
228 if (xml.firstChild())
229 {
230 do
231 {
232 const std::string status = pidf_namespace + "status";
233 const std::string contact = pidf_namespace + "contact";
234 const std::string note = pidf_namespace + "note";
235 const std::string timestamp = pidf_namespace + "timestamp";
236 if (xml.getTag() == status.c_str())
237 {
238 // look for basic
239 if (xml.firstChild())
240 {
241 do
242 {
243 std::string basic = pidf_namespace + "basic";
244 if (xml.getTag() == basic.c_str())
245 {
246 if (xml.firstChild())
247 {
248 t.status = (xml.getValue() == "open");
249 xml.parent();
250 }
251 }
252 } while (xml.nextSibling());
253 xml.parent();
254 }
255 }
256 else if (xml.getTag() == contact.c_str())
257 {
259 if (i != xml.getAttributes().end())
260 {
261 t.contactPriority.setValue(i->second);
262 }
263 if (xml.firstChild())
264 {
265 t.contact = xml.getValue();
266 xml.parent();
267 }
268 }
269 else if (xml.getTag() == note.c_str())
270 {
271 if (xml.firstChild())
272 {
273 t.note = xml.getValue();
274 xml.parent();
275 }
276 }
277 else if (xml.getTag() == timestamp.c_str())
278 {
279 if (xml.firstChild())
280 {
281 t.timeStamp = xml.getValue();
282 xml.parent();
283 }
284 }
285 } while (xml.nextSibling());
286 xml.parent();
287 }
288
289 mTuples.push_back(t);
290 }
291 } while (xml.nextSibling());
292 xml.parent();
293 }
294 }
295 else
296 {
297 DebugLog(<< "no presence tag!");
298 }
299}
300
301void
303{
304 checkParsed();
305 if (mTuples.empty())
306 {
307 Tuple t;
308 mTuples.push_back(t);
309 }
310 mTuples[0].id = id;
311}
312
313void
314Pidf::setSimpleStatus( bool online, const Data& note, const Data& contact )
315{
316 checkParsed();
317 if (mTuples.empty())
318 {
319 Tuple t;
320 mTuples.push_back(t);
321 }
322
323 mTuples[0].status = online;
324 mTuples[0].contact = contact;
325 mTuples[0].contactPriority = 1000; // 1.0
326 mTuples[0].note = note;
327 mTuples[0].timeStamp = Data::Empty;
328}
329
330bool
332{
333 checkParsed();
334
335 if (!mTuples.empty())
336 {
337 if (note)
338 {
339 *note = mTuples[0].note;
340 }
341
342 return mTuples[0].status;
343 }
344 return false;
345}
346
347void
348Pidf::merge(const Pidf& other)
349{
350 vector<Tuple>& tuples = getTuples();
351 tuples.reserve(tuples.size() + other.getTuples().size());
352
353 setEntity(other.mEntity);
354
355 for (vector<Tuple>::const_iterator i = other.getTuples().begin();
356 i != other.getTuples().end(); ++i)
357 {
358 bool found = false;
359 for (vector<Tuple>::iterator j = getTuples().begin();
360 j != getTuples().end(); ++j)
361 {
362 // TODO - only merge over if timestamp is greater
363 if (i->id == j->id)
364 {
365 found = true;
366 *j = *i;
367 break;
368 }
369 }
370 if (!found)
371 {
372 tuples.push_back(*i);
373 }
374 }
375}
376
378resip::operator<<(EncodeStream& strm, const Pidf::Tuple& tuple)
379{
380 strm << "Tuple ["
381 << " status=" << tuple.status
382 << " id=" << tuple.id
383 << " contact=" << tuple.contact
384 << " attributes=" << Inserter(tuple.attributes);
385 return strm;
386}
387
388/* ====================================================================
389 * The Vovida Software License, Version 1.0
390 *
391 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
392 *
393 * Redistribution and use in source and binary forms, with or without
394 * modification, are permitted provided that the following conditions
395 * are met:
396 *
397 * 1. Redistributions of source code must retain the above copyright
398 * notice, this list of conditions and the following disclaimer.
399 *
400 * 2. Redistributions in binary form must reproduce the above copyright
401 * notice, this list of conditions and the following disclaimer in
402 * the documentation and/or other materials provided with the
403 * distribution.
404 *
405 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
406 * and "Vovida Open Communication Application Library (VOCAL)" must
407 * not be used to endorse or promote products derived from this
408 * software without prior written permission. For written
409 * permission, please contact vocal@vovida.org.
410 *
411 * 4. Products derived from this software may not be called "VOCAL", nor
412 * may "VOCAL" appear in their name, without prior written
413 * permission of Vovida Networks, Inc.
414 *
415 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
416 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
417 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
418 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
419 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
420 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
421 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
422 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
423 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
424 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
425 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
426 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
427 * DAMAGE.
428 *
429 * ====================================================================
430 *
431 * This software consists of voluntary contributions made by Vovida
432 * Networks, Inc. and many individuals on behalf of Vovida Networks,
433 * Inc. For more information on Vovida Networks, Inc., please see
434 * <http://www.vovida.org/>.
435 *
436 */
#define DebugLog(args_)
Definition Logger.hxx:128
Base class for all SIP body types.
Definition Contents.hxx:51
Contents & operator=(const Contents &rhs)
Assignment operator.
Definition Contents.cxx:71
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
static const Data Empty
Constant that represents a zero-length data.
Definition Data.hxx:882
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
void checkParsed() const
iterator find(const Key &key)
iterator erase(const_iterator pos)
Represents the "media-type" element in the RFC 3261 grammar.
Definition Mime.hxx:20
Provides string-parsing functionality with protection from buffer overflow.
Pointer start() const
Pointer end() const
Deprecated.
Definition Pidf.hxx:62
LinkedHashMap< Data, Data, KeyedDataHash > attributes
Definition Pidf.hxx:71
QValue contactPriority
Definition Pidf.hxx:67
Deprecated.
Definition Pidf.hxx:24
bool getSimpleStatus(Data *note=NULL) const
Definition Pidf.cxx:331
Pidf & operator=(const Pidf &rhs)
Definition Pidf.cxx:59
int getNumTuples() const
Definition Pidf.cxx:118
virtual void parse(ParseBuffer &pb)
Definition Pidf.cxx:171
static const Pidf Empty
Definition Pidf.hxx:26
static bool init()
Definition Pidf.cxx:19
virtual Contents * clone() const
duplicate an Pidf object
Definition Pidf.cxx:125
void merge(const Pidf &other)
Definition Pidf.cxx:348
void setSimpleId(const Data &id)
Definition Pidf.cxx:302
static const Mime & getStaticType()
Definition Pidf.cxx:131
std::vector< Tuple > & getTuples()
Definition Pidf.cxx:104
void setEntity(const Uri &entity)
Definition Pidf.cxx:90
virtual EncodeStream & encodeParsed(EncodeStream &str) const
Definition Pidf.cxx:138
const Uri & getEntity() const
Definition Pidf.cxx:97
void setSimpleStatus(bool online, const Data &note=Data::Empty, const Data &contact=Data::Empty)
Definition Pidf.cxx:314
virtual ~Pidf()
Definition Pidf.cxx:85
void setValue(int val)
Definition QValue.hxx:73
static const char * CRLF
Definition Symbols.hxx:21
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
const Data & getValue() const
const Data & getTag() const
const AttributeMap & getAttributes() const
static EncodeStream & encode(EncodeStream &strm, const AttributeMap &attrs)
dcm! – add UnusedChecking(_enum) below;
InserterClass< T > Inserter(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
Definition Inserter.hxx:312
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
#define EncodeStream