Main Page   Namespace List   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

connection.cpp

Go to the documentation of this file.
00001 
00008 #include "sysconfig.h"
00009 #include "connection.h"
00010 #include "socket.h"
00011 #include "server.h"
00012 #include "log.h"
00013 
00018 Connection::Connection(SOCKET sock, Server* server)
00019   : mServer(server), mDisconnectable(false) {
00020   mSock = new Socket(sock);
00021 }
00022 
00026 Connection::~Connection() {
00027   delete mSock;
00028 }
00029 
00033 Connection::Connection(const Connection& r_conn)
00034   : mServer(r_conn.mServer), mDisconnectable(r_conn.mDisconnectable),
00035     mInBuffer(r_conn.mInBuffer), mOutBuffer(r_conn.mOutBuffer),
00036     mPendingInput(r_conn.mPendingInput) {
00037   mSock = new Socket(*r_conn.mSock);
00038 }
00039 
00043 Connection & Connection::operator=(const Connection& r_conn) {
00044   if (this == &r_conn)
00045     return *this;
00046   mServer = r_conn.mServer;
00047   mInBuffer = r_conn.mInBuffer;
00048   mOutBuffer = r_conn.mOutBuffer;
00049   mPendingInput = r_conn.mPendingInput;
00050   delete mSock;
00051   mSock = new Socket(*r_conn.mSock);
00052   return *this;
00053 }
00054 
00059 bool Connection::operator==(const Connection& r_conn) const {
00060   return (GetSocket() == r_conn.GetSocket());
00061 }
00062 
00073 void Connection::HandleInput() {
00074   // Loop to gather all socket input.
00075   while(true) {
00076     char c;
00077     try {
00078       c = mSock->Read();
00079     }
00080     catch (BlockingException &ex) {
00081       // Indicates no more input can be squeezed from this socket.
00082       // Let's bust this loop
00083       mServer->ServerLog().Write("INFO-Connection(recv): Blocking %d on %d",
00084         ex.mErrCode, GetSocket());
00085       break;
00086     }
00087     catch (ShutdownException &ex) {
00088       mDisconnectable = true;
00089       // Connection is scheduled for disconnection, and we'll exit
00090       mServer->ServerLog().Write("WARNING-Connection(recv): Shutdown %d on %d",
00091         ex.mErrCode, GetSocket());
00092       return;
00093     }
00094     catch (IOErrorException &ex) {
00095       // We have a serious error
00096       // Connection is scheduled for disconnection, and we'll exit
00097       mServer->ServerLog().Write("ERROR-Connection(recv): IOError %d on %d",
00098         ex.mErrCode, GetSocket());
00099       mDisconnectable = true;
00100       return;
00101     }
00102     // Append everything read to our string.
00103     mPendingInput += c;
00104     // Let's yield every 4K of input
00105     if (mPendingInput.size() > 4096)
00106       break;
00107   } // while
00108 
00109   // Loop to parse all the input into lines for our buffer
00110   while(true) {
00111     int pos = mPendingInput.find("\r\n");
00112     if (pos != (int)mPendingInput.npos) {
00113       // A line was found; save it to buffer and remove from input string
00114       mInBuffer.push_back(mPendingInput.substr(0,pos));
00115       mPendingInput.erase(0,pos + 2);
00116     } else {
00117       // No     more complete lines found
00118       break;
00119     }
00120   }
00121 }
00122 
00135 void Connection::HandleOutput() {
00136   // If there is any output waiting in line buffer write it out
00137   while (!mOutBuffer.empty()) {
00138     try {
00139       mSock->Write(mOutBuffer.front());
00140       mOutBuffer.pop_front();
00141       mSock->Flush();
00142     }
00143     catch (BlockingException &ex) {
00144       // :bug: we don't save where we last were in the output.
00145       mServer->ServerLog().Write("INFO-Connection(send): Blocking %d on %d",
00146         ex.mErrCode, GetSocket());
00147       return;
00148     }
00149     catch (IOErrorException &ex) {
00150       // severe error set socket as disconnectable and leave
00151       mServer->ServerLog().Write("ERROR-Connection(send): IOError %d on %d",
00152         ex.mErrCode, GetSocket());
00153       mDisconnectable = true;
00154       return;
00155     }
00156   } // while
00157 }
00158 
00162 void Connection::Disconnect() {
00163   mServer->ServerLog().Write(
00164     "INFO-Connection(disconnect): Connection %d disconnected", GetSocket());
00165   mSock->Close();
00166 }
00167 
00173 void Connection::SendMsg(const string& r_msg) {
00174   mOutBuffer.push_back(r_msg);
00175 }
00176 
00185 string* Connection::ReadMsg() {
00186   if (!mInBuffer.empty()) {
00187           string * msg = new string(mInBuffer.front());
00188           mInBuffer.pop_front();
00189           return msg;
00190   }
00191   return NULL;
00192 }
00193 
00202 bool Connection::CanBeDisconnected() {
00203   return mDisconnectable;
00204 }
00205 
00211 SOCKET Connection::GetSocket() const {
00212   return mSock->GetSocket();
00213 }
00214 
00221 bool Connection::HasOutput() {
00222   return !mOutBuffer.empty();
00223 }
00224 

Generated on Mon Mar 29 23:12:52 2004 for Paradigm by doxygen1.2.17