contact.cpp

00001 // -*- C++ -*- 00002 /* 00003 $Id: contact_8cpp-source.html,v 1.1 2004/10/05 21:12:01 mentat Exp $ 00004 00005 GNU Messenger - The secure instant messenger 00006 Copyright (C) 1999-2002 Henrik Abelsson <henrik@abelsson.com> 00007 parts Copyright (C) 2002-2004 Jesse Lovelace <jesse at aslogicsys dot com> 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 #include <string> 00025 #include <list> 00026 00027 #include "gm/debug.h" 00028 #include "gm/xmlnode.h" 00029 #include "gm/contact.h" 00030 00031 namespace GNUMessenger { 00032 00033 using namespace std; 00034 00035 Contact::Contact(const Contact& other): 00036 XMLNode(other) 00037 { 00038 m_session = other.m_session; 00039 } 00040 00041 Contact::Contact() 00042 { 00043 XMLNode::setName("contact"); 00044 } 00045 00046 00047 Contact::Contact(const XMLNode &config): 00048 XMLNode(config) 00049 { 00050 00051 } 00052 00053 string Contact::getServerId( const string& proto ) const 00054 { 00055 00056 try { 00057 if (child("protocols").hasChild(proto)) 00058 return child("protocols").child(proto).property("login"); 00059 } catch (XMLNode::InvalidChild &e) { 00060 LOG_DEBUG("No protocols group"); 00061 } 00062 00063 return ""; 00064 } 00065 00066 void Contact::setStatus(const string& proto, Status state) 00067 { 00068 if (child("protocols").hasChild(proto)) { 00069 child("protocols").child(proto).setProperty("status",state); 00070 } else { 00071 LOG_THROW("Contact::setStatus: invalid protocol", XMLNode::InvalidChild); 00072 } 00073 00074 } 00075 00076 Contact::Status Contact::getStatus(const string& proto) const 00077 { 00078 if (child("protocols").hasChild(proto)) { 00079 int status = child("protocols").child(proto).intProperty("status"); 00080 return Status(status); 00081 } else { 00082 LOG_THROW("Contact::getStatus: invalid protocol", XMLNode::InvalidChild); 00083 } 00084 00085 return Error; 00086 } 00087 00088 Contact::Status Contact::getOverallStatus() const 00089 { 00090 if (!hasChild("protocols")) 00091 return Error; 00092 00093 Status bestSoFar = Offline; 00094 00095 vector<XMLNode> xml = child("protocols").const_children(); 00096 for (unsigned int i = 0; i < xml.size(); i++) { 00097 Status temp = (Status)xml[i].intProperty("status"); 00098 00099 if (temp == Online) 00100 return Online; 00101 else 00102 if (temp > bestSoFar) 00103 return temp; 00104 } 00105 00106 return Error; 00107 } 00108 00109 00110 void Contact::setServerId(const string& proto, const string& id) 00111 { 00112 if (proto.length() == 0){ 00113 LOG_ERROR("PROTO LENGTH ZERO!"); 00114 return; 00115 } 00116 00117 LOG_DEBUG("Contact::setServerId: " << proto << " " << id); 00118 // set the server Id for a specified protocol 00119 if (!child("protocols").hasChild(proto)) 00120 child("protocols").addChild(proto); 00121 00122 child("protocols").child(proto).setProperty("login", id); 00123 } 00124 00125 00126 #if 0 00127 bool Contact::activateProtocol() // approx worse case, this function only, 2*O(N) 00128 { 00129 vector<XMLNode> nets = m_session.children(); 00130 string current; // best protocol found to date 00131 string alreadyActive; // the currently active protocol, if one exists 00132 unsigned int index; // the index of the 'good' protocol 00133 unsigned int i; // loop variable 00134 00135 // first we want to find the active protocol if one exists, 00136 // and set it to not active 00137 for (i = 0; i < nets.size(); i++) 00138 if (nets[i].property("active") == "true") 00139 { 00140 alreadyActive = nets[i].name(); 00141 nets[i].setProperty("active", "false"); 00142 } 00143 00144 // now search for another active network 00145 for (i = 0; i < nets.size(); i++) 00146 if ((nets[i].intProperty("status") == Online) && (nets[i].name() != alreadyActive)) 00147 { // if we find a protocol online that is not the already active one, go with it 00148 current = nets[i].name(); 00149 index = i; // keep record of index so we dont have to search again 00150 break; // hmm, i know people dont like breaks, but this clearly 00151 // exits the loop when a 'good' contact is found 00152 } 00153 else 00154 if ((nets[i].intProperty("status") != Offline) && 00155 (current == "")) // otherwise, assign one that isn't offline and loop 00156 { 00157 current = nets[i].name(); 00158 index = i; 00159 } 00160 #if 0 // on second thought, lets not add another O(N) function 00161 // now lets set all the other nets to not active 00162 // so as to not confuse the program 00163 for (i = 0; i < nets.size(); i++) 00164 { 00165 nets[i].setProperty("active", "false"); 00166 } 00167 #endif 00168 if (current == "") // if no protocol is found, return false 00169 { 00170 debug() << "No suitable protocol found in activateProtocol()\n"; 00171 return false; 00172 } 00173 else 00174 { 00175 debug() << "Protocol activated: " << nets[i].name() << endl; 00176 nets[index].setProperty("active", "true"); 00177 return true; 00178 } 00179 } 00180 #endif 00181 00182 void Contact::addProtocol(const string& proto) 00183 { 00184 if (child("protocols").hasChild(proto)) 00185 return; 00186 00187 child("protocols").addChild(proto); 00188 } 00189 00190 bool Contact::isOK() const { 00191 if (property("destroyed") == "true") 00192 return false; 00193 return true; 00194 } 00195 00196 void Contact::Destroy() { 00197 setProperty("destroyed", "true"); 00198 } 00199 00200 bool Contact::hasProtocol(const string& str) const 00201 { 00202 if (!hasChild("protocols")) 00203 return false; 00204 00205 if (child("protocols").hasChild(str)) 00206 return true; 00207 00208 return false; 00209 } 00210 00211 string Contact::getProtocol() const 00212 { 00213 if (!hasChild("protocols")) 00214 return ""; 00215 00216 vector<XMLNode> xml = child("protocols").const_children(); 00217 00218 // try first searching for online protocol 00219 for (unsigned int i = 0; i < xml.size(); i++) { 00220 if (xml[i].intProperty("status") == Online) 00221 return xml[i].name(); 00222 } 00223 00224 // then search for any non-offline protocol 00225 for (unsigned int i = 0; i < xml.size(); i++) { 00226 if (xml[i].intProperty("status") != Offline) 00227 return xml[i].name(); 00228 } 00229 00230 return ""; 00231 00232 } 00233 00234 Contact& Contact::operator=(const Contact &other) 00235 { 00236 other.m_xmlData->ref(); 00237 00238 if (m_xmlData && m_xmlData->deref()) { 00239 delete m_xmlData; 00240 m_xmlData=0; 00241 } 00242 00243 m_xmlData=other.m_xmlData; 00244 00245 m_session = other.m_session; 00246 00247 return *this; 00248 } 00249 00250 bool operator < (const Contact& lhs, const Contact& rhs) 00251 { 00252 return (lhs.name() < rhs.name()); 00253 //return (c1.getName() < c2.getName()); 00254 } 00255 00256 bool operator==(const Contact& lhs, const Contact& rhs) 00257 { 00258 return (lhs.m_xmlData == rhs.m_xmlData); 00259 } 00260 00261 bool operator!=(const Contact& lhs, const Contact& rhs) 00262 { 00263 return !(lhs==rhs); 00264 } 00265 00266 } 00267

Generated on Tue Oct 5 14:41:47 2004 for GNU Messenger by doxygen 1.3.8