<!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> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> <a class="qindex" href="pages.html">Related Pages</a> </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>& 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> & <a class="code" href="classConnection.html#b0">Connection::operator=</a>(<span class="keyword">const</span> <a class="code" href="classConnection.html">Connection</a>& r_conn) {
00055 <span class="keywordflow">if</span> (<span class="keyword">this</span> == &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 << <span class="stringliteral">"Error-Connection(recv):"</span> << err << <span class="stringliteral">" on "</span> << <a class="code" href="classConnection.html#n0">mSock</a> << 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 << <span class="stringliteral">"Error-Connection(recv):"</span> << err << <span class="stringliteral">" on "</span> << <a class="code" href="classConnection.html#n0">mSock</a> << 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 < (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& 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>