<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>connection.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.17 -->
<center>
<a class="qindex" href="main.html">Main Page</a> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="classes.html">Alphabetical List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>connection.cpp</h1><a href="connection_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 
00009 <span class="preprocessor">#include "<a class="code" href="sysconfig_8h.html">sysconfig.h</a>"</span>
00010 <span class="preprocessor">#include "<a class="code" href="connection_8h.html">connection.h</a>"</span>
00011 
00012 
00017 <span class="comment">//##ModelId=3ED44BF10253</span>
<a name="l00018"></a><a class="code" href="classConnection.html#a0">00018</a> <a class="code" href="classConnection.html#a0">Connection::Connection</a>(SOCKET sock)
00019         : mSock(sock), mpPendingInput(NULL), mpPendingOutput(NULL),
00020 mDisconnectable(false) {}
00021 
00025 <span class="comment">//##ModelId=3ED44BF10255</span>
<a name="l00026"></a><a class="code" href="classConnection.html#a1">00026</a> <a class="code" href="classConnection.html#a1">Connection::~Connection</a>() {
00027     <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n4">mpPendingOutput</a>;
00028     <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n5">mpPendingInput</a>;
00029 }
00030 
00034 <span class="comment">//##ModelId=3ED44BF1025E</span>
<a name="l00035"></a><a class="code" href="classConnection.html#a2">00035</a> <a class="code" href="classConnection.html#a0">Connection::Connection</a>(<span class="keyword">const</span> <a class="code" href="classConnection.html">Connection</a>&amp; r_conn)
00036         : mDisconnectable(r_conn.mDisconnectable), mSock(r_conn.mSock),
00037 mpPendingInput(NULL), mpPendingOutput(NULL) {
00038     <a class="code" href="classConnection.html#n2">mInBuffer</a> = r_conn.mInBuffer;
00039     <a class="code" href="classConnection.html#n3">mOutBuffer</a> = r_conn.mOutBuffer;
00040     <span class="keywordflow">if</span> (r_conn.mpPendingInput) {
00041         <a class="code" href="classConnection.html#n5">mpPendingInput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.mpPendingInput) + 1];
00042         strcpy(<a class="code" href="classConnection.html#n5">mpPendingInput</a>, r_conn.mpPendingInput);
00043     }
00044     <span class="keywordflow">if</span> (r_conn.mpPendingOutput) {
00045         <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.mpPendingOutput) + 1];
00046         strcpy(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>, r_conn.mpPendingOutput);
00047     }
00048 }
00049 
00053 <span class="comment">//##ModelId=3ED44BF10288</span>
<a name="l00054"></a><a class="code" href="classConnection.html#b0">00054</a> <a class="code" href="classConnection.html">Connection</a> &amp; <a class="code" href="classConnection.html#b0">Connection::operator=</a>(<span class="keyword">const</span> <a class="code" href="classConnection.html">Connection</a>&amp; r_conn) {
00055     <span class="keywordflow">if</span> (<span class="keyword">this</span> == &amp;r_conn)
00056         <span class="keywordflow">return</span> * <span class="keyword">this</span>;
00057     <a class="code" href="classConnection.html#n2">mInBuffer</a> = r_conn.<a class="code" href="classConnection.html#n2">mInBuffer</a>;
00058     <a class="code" href="classConnection.html#n3">mOutBuffer</a> = r_conn.<a class="code" href="classConnection.html#n3">mOutBuffer</a>;
00059     <span class="keywordflow">if</span> (r_conn.<a class="code" href="classConnection.html#n5">mpPendingInput</a>) {
00060         <a class="code" href="classConnection.html#n5">mpPendingInput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.<a class="code" href="classConnection.html#n5">mpPendingInput</a>) + 1];
00061         strcpy(<a class="code" href="classConnection.html#n5">mpPendingInput</a>, r_conn.<a class="code" href="classConnection.html#n5">mpPendingInput</a>);
00062     }
00063     <span class="keywordflow">if</span> (r_conn.<a class="code" href="classConnection.html#n4">mpPendingOutput</a>) {
00064         <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.<a class="code" href="classConnection.html#n4">mpPendingOutput</a>) + 1];
00065         strcpy(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>, r_conn.<a class="code" href="classConnection.html#n4">mpPendingOutput</a>);
00066     }
00067     <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00068 }
00069 
00086 <span class="comment">//##ModelId=3ED44BF10260</span>
<a name="l00087"></a><a class="code" href="classConnection.html#a3">00087</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a3">Connection::HandleInput</a>() {
00088     string strin;
00089     <span class="keywordtype">char</span> inbuf[4096];
00090     <span class="comment">// If there was input leftover from the last call to HandleInput</span>
00091     <span class="comment">// prepend it to the input string and clear it.</span>
00092     <span class="keywordflow">if</span> (mpPendingInput) {
00093         strin.append(<a class="code" href="classConnection.html#n5">mpPendingInput</a>);
00094         <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n5">mpPendingInput</a>;
00095         <a class="code" href="classConnection.html#n5">mpPendingInput</a> = NULL;
00096     }
00097     <span class="comment">// Loop to gather all socket input in 4K chunks.</span>
00098     <span class="keywordflow">while</span> (true) {
00099         <span class="keywordtype">int</span> nbytes = recv (<a class="code" href="classConnection.html#n0">mSock</a>, inbuf, 4096, 0);
00100         <span class="keywordflow">if</span> (nbytes == 0) {
00101             <span class="comment">// Connection is scheduled for disconnection, and we'll exit</span>
00102             <a class="code" href="classConnection.html#n1">mDisconnectable</a> = <span class="keyword">true</span>;
00103             <span class="keywordflow">return</span> ;
00104         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nbytes == SOCKET_ERROR) {
00105             <span class="keywordtype">int</span> err = WSAGetLastError ();
00106             <span class="keywordflow">if</span> (err == WSAEWOULDBLOCK) {
00107                 <span class="comment">// Indicates no more input can be squeezed from this socket.</span>
00108                 <span class="comment">// Let's bust this loop</span>
00109                 <span class="keywordflow">break</span>;
00110             } <span class="keywordflow">else</span> {
00111                 <span class="comment">// We have a serious error</span>
00112                 <span class="comment">// Connection is scheduled for disconnection, and we'll exit</span>
00113                 cout &lt;&lt; <span class="stringliteral">"Error-Connection(recv):"</span> &lt;&lt; err &lt;&lt; <span class="stringliteral">" on "</span> &lt;&lt; <a class="code" href="classConnection.html#n0">mSock</a> &lt;&lt; endl;
00114                 <a class="code" href="classConnection.html#n1">mDisconnectable</a> = <span class="keyword">true</span>;
00115                 <span class="keywordflow">return</span> ;
00116             }
00117         }
00118         <span class="comment">// Append everything read to our string.</span>
00119         inbuf[nbytes] = <span class="charliteral">'\0'</span>;
00120         strin.append(inbuf);
00121     }
00122     <span class="comment">// Loop to parse all input into lines for our buffer</span>
00123     <span class="keywordflow">while</span> (true) {
00124         <span class="keywordtype">int</span> pos = strin.find(<span class="stringliteral">"\r\n"</span>);
00125         <span class="keywordflow">if</span> (pos != (int)strin.npos) {
00126             <span class="comment">// A line was found; save it to buffer and remove from input string</span>
00127             <a class="code" href="classConnection.html#n2">mInBuffer</a>.push_back(strin.substr(0, pos));
00128             strin.erase(0, pos + 2);
00129         } <span class="keywordflow">else</span> {
00130             <span class="comment">// No       more complete lines found</span>
00131             <span class="keywordflow">if</span> (!strin.empty()) {
00132                 <span class="comment">// Save leftovers into pending input array</span>
00133                 <a class="code" href="classConnection.html#n5">mpPendingInput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strin.size() + 1];
00134                 strcpy(<a class="code" href="classConnection.html#n5">mpPendingInput</a>, strin.c_str());
00135             }
00136             <span class="keywordflow">break</span>;
00137         }
00138     }
00139 }
00140 
00153 <span class="comment">//##ModelId=3ED44BF10268</span>
<a name="l00154"></a><a class="code" href="classConnection.html#a4">00154</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a4">Connection::HandleOutput</a>() {
00155     string strout;
00156     <span class="comment">// If there is output left to be sent from last time append</span>
00157     <span class="comment">// it to our output string</span>
00158     <span class="keywordflow">if</span> (mpPendingOutput) {
00159         strout.append(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>);
00160         <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n4">mpPendingOutput</a>;
00161         <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = NULL;
00162     }
00163     <span class="comment">// If there is any output waiting in line buffer append the first line</span>
00164     <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n3">mOutBuffer</a>.empty()) {
00165         strout.append(<a class="code" href="classConnection.html#n3">mOutBuffer</a>.front());
00166         <a class="code" href="classConnection.html#n3">mOutBuffer</a>.pop_front();
00167     }
00168     <span class="comment">// Loop until our output string is empty</span>
00169     <span class="keywordflow">while</span> (!strout.empty()) {
00170         <span class="keyword">const</span> <span class="keywordtype">char</span> * pstr = strout.c_str();
00171         <span class="keywordflow">while</span> (pstr) {  <span class="comment">// Loop until we have written this string</span>
00172             <span class="keywordtype">int</span> nbytes = send (<a class="code" href="classConnection.html#n0">mSock</a>, pstr, strlen(pstr), 0);
00173             <span class="keywordflow">if</span> (nbytes == SOCKET_ERROR) {
00174                 <span class="keywordtype">int</span> err = WSAGetLastError ();
00175                 <span class="keywordflow">if</span> (err == WSAEWOULDBLOCK) {
00176                     <span class="comment">// socket will block - save unwritten output in pending array</span>
00177                     <span class="comment">// and leave</span>
00178                     <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(pstr) + 1];
00179                     strcpy(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>, pstr);
00180                     <span class="keywordflow">return</span> ;
00181                 }
00182                 <span class="comment">// severe error set socket as disconnectable and leave</span>
00183                 cout &lt;&lt; <span class="stringliteral">"Error-Connection(recv):"</span> &lt;&lt; err &lt;&lt; <span class="stringliteral">" on "</span> &lt;&lt; <a class="code" href="classConnection.html#n0">mSock</a> &lt;&lt; endl;
00184                 <a class="code" href="classConnection.html#n1">mDisconnectable</a> = <span class="keyword">true</span>;
00185                 <span class="keywordflow">return</span> ;
00186             } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nbytes &lt; (int)strlen(pstr)) {
00187                 pstr += nbytes;
00188             } <span class="keywordflow">else</span> {
00189                 pstr = NULL;
00190             }
00191         }
00192         strout.erase();
00193         <span class="comment">// fetch next line in buffer if not empty</span>
00194         <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n3">mOutBuffer</a>.empty()) {
00195             strout.append(<a class="code" href="classConnection.html#n3">mOutBuffer</a>.front());
00196             <a class="code" href="classConnection.html#n3">mOutBuffer</a>.pop_front();
00197         }
00198     }
00199 }
00200 
00204 <span class="comment">//##ModelId=3ED44BF10272</span>
<a name="l00205"></a><a class="code" href="classConnection.html#a6">00205</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a6">Connection::Disconnect</a>() {
00206     <span class="keywordtype">char</span> inbuf[4096];
00207     <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
00208     shutdown(<a class="code" href="classConnection.html#n0">mSock</a>, SD_SEND);
00209     <span class="keywordflow">while</span> (!done) {
00210         <span class="keywordtype">int</span> nbytes = recv (<a class="code" href="classConnection.html#n0">mSock</a>, inbuf, 4096, 0);
00211         <span class="keywordflow">if</span> (!nbytes || nbytes == SOCKET_ERROR)
00212             done = <span class="keyword">true</span>;
00213     }
00214     closesocket(<a class="code" href="classConnection.html#n0">mSock</a>);
00215 }
00216 
00222 <span class="comment">//##ModelId=3ED44BF10274</span>
<a name="l00223"></a><a class="code" href="classConnection.html#a7">00223</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a7">Connection::SendMsg</a>(<span class="keyword">const</span> string&amp; r_msg) {
00224     <a class="code" href="classConnection.html#n3">mOutBuffer</a>.push_back(r_msg);
00225 }
00226 
00232 <span class="comment">//##ModelId=3ED44BF1027D</span>
<a name="l00233"></a><a class="code" href="classConnection.html#a8">00233</a> string* <a class="code" href="classConnection.html#a8">Connection::ReadMsg</a>() {
00234     <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n2">mInBuffer</a>.empty()) {
00235         string msg = <a class="code" href="classConnection.html#n2">mInBuffer</a>.front();
00236         <a class="code" href="classConnection.html#n2">mInBuffer</a>.pop_front();
00237         <span class="keywordflow">return</span> <span class="keyword">new</span> string(msg);
00238     }
00239     <span class="keywordflow">return</span> NULL;
00240 }
00241 
00250 <span class="comment">//##ModelId=3ED44BF1026A</span>
<a name="l00251"></a><a class="code" href="classConnection.html#a5">00251</a> <span class="keywordtype">bool</span> <a class="code" href="classConnection.html#a5">Connection::CanBeDisconnected</a>() {
00252     <span class="keywordflow">return</span> <a class="code" href="classConnection.html#n1">mDisconnectable</a>;
00253 }
00254 
00260 <span class="comment">//##ModelId=3ED44BF10286</span>
<a name="l00261"></a><a class="code" href="classConnection.html#a9">00261</a> SOCKET <a class="code" href="classConnection.html#a9">Connection::GetSocket</a>() {
00262     <span class="keywordflow">return</span> <a class="code" href="classConnection.html#n0">mSock</a>;
00263 }
</pre></div><hr><address style="align: right;"><small>Generated on Mon Mar 29 22:38:41 2004 for Paradigm by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.17 </small></address>
</body>
</html>