⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmpp.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* * xmpp.cxx * * Extensible Messaging and Presence Protocol (XMPP) Core * * Portable Windows Library * * Copyright (c) 2004 Reitek S.p.A. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Post Increment * * Contributor(s): ______________________________________. * * $Log: xmpp.cxx,v $ * Revision 1.5  2004/05/09 07:23:50  rjongbloed * More work on XMPP, thanks Federico Pinna and Reitek S.p.A. * * Revision 1.4  2004/04/27 06:19:12  rjongbloed * Fixed GCC 3.4 warnings and improved crash avoidance with NULL pointers. * * Revision 1.3  2004/04/26 04:17:19  rjongbloed * Fixed GNU warnings * * Revision 1.2  2004/04/26 01:51:58  rjongbloed * More implementation of XMPP, thanks a lot to Federico Pinna & Reitek S.p.A. * * Revision 1.1  2004/04/22 12:31:00  rjongbloed * Added PNotifier extensions and XMPP (Jabber) support, *   thanks to Federico Pinna and Reitek S.p.A. * * */#ifdef __GNUC__#pragma implementation "xmpp.h"#endif#include <ptlib.h>#include <ptclib/xmpp.h>#if P_EXPAT///////////////////////////////////////////////////////const PString XMPP::Language("xml:lang");const PString XMPP::Namespace("xmlns");const PString XMPP::MessageStanza("message");const PString XMPP::PresenceStanza("presence");const PString XMPP::IQStanza("iq");const PString XMPP::IQQuery("query");///////////////////////////////////////////////////////XMPP::JID::JID(const char * jid){  ParseJID(jid);}XMPP::JID::JID(const PString& jid){  ParseJID(jid);}XMPP::JID::JID(const PString& user, const PString& server, const PString& resource)  : m_User(user), m_Server(server), m_Resource(resource), m_IsDirty(TRUE){  BuildJID();}PObject::Comparison XMPP::JID::Compare(const PObject & obj) const{  if (m_IsDirty)    BuildJID();  if (PIsDescendant(&obj, XMPP::JID))    return m_JID.Compare((const PString&)((const XMPP::JID&)obj));  else if (PIsDescendant(&obj, PString))    return m_JID.Compare((const PString&)obj);  PAssertAlways(PInvalidCast);  return PObject::LessThan;}XMPP::JID& XMPP::JID::operator=(const PString & jid){  ParseJID(jid);  return *this;}XMPP::JID::operator const PString&() const{  if (m_IsDirty)    BuildJID();  return m_JID;}void XMPP::JID::SetUser(const PString& user){  m_IsDirty = TRUE;  m_User = user;}void XMPP::JID::SetServer(const PString& server){  m_IsDirty = TRUE;  m_Server = server;}void XMPP::JID::SetResource(const PString& resource){  m_IsDirty = TRUE;  m_Resource = resource;}void XMPP::JID::PrintOn(ostream & strm) const{  strm << m_JID;}void XMPP::JID::ParseJID(const PString& jid){  m_User[0] = m_Server[0] = m_Resource[0] = 0;  PINDEX i = jid.Find('@');  if (i == (jid.GetLength() - 1))    return;  else if (i == P_MAX_INDEX)    SetServer(jid);  else {    SetUser(jid.Left(i));    SetServer(jid.Mid(i + 1));  }  i = m_Server.Find('/');  if (i != P_MAX_INDEX && i != 0) {    SetResource(m_Server.Mid(i + 1));    SetServer(m_Server.Left(i));  }  BuildJID();}void XMPP::JID::BuildJID() const{  if (m_User.IsEmpty())    m_JID = m_Server;  else    m_JID = m_User + "@" + m_Server;  if (!m_Resource.IsEmpty())    m_JID += "/" + m_Resource;  m_IsDirty = FALSE;}///////////////////////////////////////////////////////PObject::Comparison XMPP::BareJID::Compare(const PObject & obj) const{  if (m_IsDirty)    BuildJID();  XMPP::BareJID that;  if (PIsDescendant(&obj, XMPP::JID))    that = (const PString&)((const XMPP::JID&)obj);  else if (PIsDescendant(&obj, PString))    that = (const PString&)obj;  else {    PAssertAlways(PInvalidCast);    return PObject::LessThan;  }  return m_JID.Compare(that.m_JID);}XMPP::BareJID& XMPP::BareJID::operator=(const PString & jid){  ParseJID(jid);  return *this;}///////////////////////////////////////////////////////XMPP::Stream::Stream(XMPP::Transport * transport)  : m_Parser(new PXMLStreamParser){  if (transport)    Open(transport);}XMPP::Stream::~Stream(){  delete m_Parser;  Close();}BOOL XMPP::Stream::Close(){  if (IsOpen()) {    OnClose();    return PIndirectChannel::Close();  }  return FALSE;}BOOL XMPP::Stream::Write(const void * buf, PINDEX len){  PTRACE(5, "XMPP\tSND: " << (const char *)buf);  return PIndirectChannel::Write(buf, len);}BOOL XMPP::Stream::Write(const PString& data){  return Write((const char *)data, data.GetLength());}BOOL XMPP::Stream::Write(const PXML& pdu){  PXMLElement * root = pdu.GetRootElement();  if (root == NULL)    return FALSE;  PStringStream os;  root->Output(os, pdu, 0);  return Write(os.GetPointer(), os.GetLength());}PXML * XMPP::Stream::Read(){  return m_Parser->Read(this);}void XMPP::Stream::Reset(){  delete m_Parser;  m_Parser = new PXMLStreamParser;}///////////////////////////////////////////////////////XMPP::BaseStreamHandler::BaseStreamHandler()  : PThread(0x1000, PThread::NoAutoDeleteThread),    m_Stream(NULL),    m_AutoReconnect(TRUE),    m_ReconnectTimeout(1000){}XMPP::BaseStreamHandler::~BaseStreamHandler(){  Stop();}BOOL XMPP::BaseStreamHandler::Start(XMPP::Transport * transport){  if (m_Stream != NULL)    Stop();  m_Stream = new XMPP::Stream();  m_Stream->OpenHandlers().Add(new PCREATE_NOTIFIER(OnOpen));  m_Stream->CloseHandlers().Add(new PCREATE_NOTIFIER(OnClose));  if (!transport->IsOpen() && !transport->Open())    return FALSE;  if (m_Stream->Open(transport))  {    if (IsSuspended())      Resume();    else      Restart();    return TRUE;  }  return FALSE;}BOOL XMPP::BaseStreamHandler::Stop(const PString& _error){  if (m_Stream == NULL)    return FALSE;  if (!_error.IsEmpty())  {    PString error = "<stream:error><";    error += _error;    error += " xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error>";    m_Stream->Write((const char *)error, error.GetLength());  }  m_Stream->Close();  if (PThread::Current() != this)    WaitForTermination(10000);  delete m_Stream;  m_Stream = NULL;  return FALSE;}void XMPP::BaseStreamHandler::OnOpen(XMPP::Stream&, INT){}void XMPP::BaseStreamHandler::OnClose(XMPP::Stream&, INT){}void XMPP::BaseStreamHandler::SetAutoReconnect(BOOL b, long t){  m_AutoReconnect = b;  m_ReconnectTimeout = t;}BOOL XMPP::BaseStreamHandler::Write(const void * buf, PINDEX len){  if (m_Stream == NULL)    return FALSE;  return m_Stream->Write(buf, len);}BOOL XMPP::BaseStreamHandler::Write(const PString& data){  if (m_Stream == NULL)    return FALSE;  return m_Stream->Write(data);}BOOL XMPP::BaseStreamHandler::Write(const PXML& pdu){  if (m_Stream == NULL)    return FALSE;  return m_Stream->Write(pdu);}void XMPP::BaseStreamHandler::OnElement(PXML& pdu){  m_ElementHandlers.Fire(pdu);}void XMPP::BaseStreamHandler::Main(){  PXML * pdu;  for (;;)  {    if (!m_Stream || !m_Stream->IsOpen())      break;    pdu = m_Stream->Read();    if (pdu != NULL)    {      if (PTrace::CanTrace(5)) {        ostream& os = PTrace::Begin(5, __FILE__, __LINE__);        os << "XMPP\tRCV: ";        pdu->GetRootElement()->Output(os, *pdu, 0);        os << PTrace::End;      }      OnElement(*pdu);    }    else if (m_Stream->GetErrorCode() != PChannel::Timeout)      break;    delete pdu;  }}///////////////////////////////////////////////////////const PString XMPP::Stanza::ID("id");const PString XMPP::Stanza::From("from");const PString XMPP::Stanza::To("to");void XMPP::Stanza::SetID(const PString& id){   if (!id.IsEmpty())    PAssertNULL(rootElement)->SetAttribute(XMPP::Stanza::ID, id);}void XMPP::Stanza::SetFrom(const PString& from){  if (!from.IsEmpty())    PAssertNULL(rootElement)->SetAttribute(XMPP::Stanza::From, from);}void XMPP::Stanza::SetTo(const PString& to){   if (!to.IsEmpty())    PAssertNULL(rootElement)->SetAttribute(XMPP::Stanza::To, to);}PString XMPP::Stanza::GetID() const{ return PAssertNULL(rootElement)->GetAttribute(XMPP::Stanza::ID); }PString XMPP::Stanza::GetFrom() const{ return PAssertNULL(rootElement)->GetAttribute(XMPP::Stanza::From); }PString XMPP::Stanza::GetTo() const{ return PAssertNULL(rootElement)->GetAttribute(XMPP::Stanza::To); }PXMLElement * XMPP::Stanza::GetElement(const PString& name, PINDEX i){  if (PAssertNULL(rootElement) == 0)    return 0;  return rootElement->GetElement(name, i);}void XMPP::Stanza::AddElement(PXMLElement * elem){  if (elem == 0)    return;  if (PAssertNULL(rootElement) == 0)    return;  elem->SetParent(rootElement);  rootElement->AddChild(elem);}PString XMPP::Stanza::GenerateID(){  static PAtomicInteger s_id;  return PString(PString::Printf, "pdu_%d", (int)++s_id);}///////////////////////////////////////////////////////const PString XMPP::Message::Type("type");const PString XMPP::Message::Subject("subject");const PString XMPP::Message::Body("body");const PString XMPP::Message::Thread("thread");XMPP::Message::Message(){  SetRootElement(new PXMLElement(NULL, XMPP::MessageStanza));  PWaitAndSignal m(rootMutex);  rootElement->SetAttribute(XMPP::Message::Type, "normal");  SetID(XMPP::Stanza::GenerateID());}XMPP::Message::Message(PXML& pdu){  if (XMPP::Message::IsValid(&pdu)) {    PWaitAndSignal m(pdu.GetMutex());    PXMLElement * elem = pdu.GetRootElement();    if (elem != NULL)      SetRootElement((PXMLElement *)elem->Clone(0));  }}XMPP::Message::Message(PXML * pdu){  if (XMPP::Message::IsValid(pdu)) {    PWaitAndSignal m(PAssertNULL(pdu)->GetMutex());    PXMLElement * elem = pdu->GetRootElement();    if (elem != NULL)      SetRootElement((PXMLElement *)elem->Clone(0));  }}BOOL XMPP::Message::IsValid() const{  return XMPP::Message::IsValid(this);}BOOL XMPP::Message::IsValid(const PXML * pdu){  PXMLElement * elem = PAssertNULL(pdu)->GetRootElement();  return elem != NULL && elem->GetName() == XMPP::MessageStanza;}XMPP::Message::MessageType XMPP::Message::GetType(PString * typeName) const{  PString t = PAssertNULL(rootElement)->GetAttribute(XMPP::Message::Type);  if (typeName != NULL)    *typeName = t;  if (t *= "normal")    return XMPP::Message::Normal;  else if (t *= "chat")    return XMPP::Message::Chat;  else if (t *= "error")    return XMPP::Message::Error;  else if (t *= "groupchat")    return XMPP::Message::GroupChat;  else if (t *= "headline")    return XMPP::Message::HeadLine;  else    return XMPP::Message::Unknown;}PString XMPP::Message::GetLanguage() const{  return PAssertNULL(rootElement)->GetAttribute(XMPP::Language);}PXMLElement * XMPP::Message::GetSubjectElement(const PString& lang){  if (PAssertNULL(rootElement) == NULL)    return NULL;  PXMLElement * dfltSubj = NULL;  PINDEX i = 0;  PXMLElement * subj;  PString l;  while ((subj = rootElement->GetElement(XMPP::Message::Subject, i++)) != NULL) {    l = subj->GetAttribute(XMPP::Language);    if (l == lang)      return subj;    else if (l.IsEmpty() && dfltSubj == NULL)      dfltSubj = subj;  }  return dfltSubj;}PString XMPP::Message::GetSubject(const PString& lang){  PXMLElement * elem = GetSubjectElement(lang);  return elem != NULL ? elem->GetData() : PString::Empty();}PXMLElement * XMPP::Message::GetBodyElement(const PString& lang){  if (PAssertNULL(rootElement) == NULL)    return NULL;  PXMLElement * dfltBody = NULL;  PINDEX i = 0;  PXMLElement * body;  PString l;  while ((body = rootElement->GetElement(XMPP::Message::Body, i++)) != NULL) {    l = body->GetAttribute(XMPP::Language);    if (l == lang)      return body;    else if (l.IsEmpty() && dfltBody == NULL)      dfltBody = body;  }  return dfltBody;}PString XMPP::Message::GetBody(const PString& lang){  PXMLElement * elem = GetBodyElement(lang);  return elem != NULL ? elem->GetData() : PString::Empty();}PString XMPP::Message::GetThread(){  PXMLElement * elem = PAssertNULL(rootElement)->GetElement(XMPP::Message::Thread);  return elem != NULL ? elem->GetData() : PString::Empty();}void XMPP::Message::SetType(MessageType type){  switch (type) {  case XMPP::Message::Normal:    SetType("normal");    break;  case XMPP::Message::Chat:    SetType("chat");    break;  case XMPP::Message::Error:    SetType("error");    break;  case XMPP::Message::GroupChat:    SetType("groupchat");    break;  case XMPP::Message::HeadLine:    SetType("headline");    break;  default :    break;  }}void XMPP::Message::SetType(const PString& type){  PAssertNULL(rootElement)->SetAttribute(XMPP::Message::Type, type);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -