<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>Crypto++: channels.cpp Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.3.7 --> <div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="globals.html">File Members</a></div> <h1>channels.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// channels.cpp - written and placed in the public domain by Wei Dai</span> 00002 00003 <span class="preprocessor">#include "pch.h"</span> 00004 00005 <span class="preprocessor">#ifndef CRYPTOPP_IMPORTS</span> 00006 <span class="preprocessor"></span> 00007 <span class="preprocessor">#include "channels.h"</span> 00008 00009 NAMESPACE_BEGIN(CryptoPP) 00010 USING_NAMESPACE(std) 00011 00012 #if 0 00013 <span class="keywordtype">void</span> MessageSwitch::AddDefaultRoute(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination, const std::string &channel) 00014 { 00015 m_defaultRoutes.push_back(Route(&destination, channel)); 00016 } 00017 00018 <span class="keywordtype">void</span> MessageSwitch::AddRoute(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> end, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination, <span class="keyword">const</span> std::string &channel) 00019 { 00020 RangeRoute route(begin, end, Route(&destination, channel)); 00021 RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route); 00022 m_routes.insert(it, route); 00023 } 00024 00025 <span class="comment">/*</span> 00026 <span class="comment">class MessageRouteIterator</span> 00027 <span class="comment">{</span> 00028 <span class="comment">public:</span> 00029 <span class="comment"> typedef MessageSwitch::RouteList::const_iterator RouteIterator;</span> 00030 <span class="comment"> typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator;</span> 00031 <span class="comment"></span> 00032 <span class="comment"> bool m_useDefault;</span> 00033 <span class="comment"> RouteIterator m_itRouteCurrent, m_itRouteEnd;</span> 00034 <span class="comment"> DefaultIterator m_itDefaultCurrent, m_itDefaultEnd;</span> 00035 <span class="comment"></span> 00036 <span class="comment"> MessageRouteIterator(MessageSwitch &ms, const std::string &channel)</span> 00037 <span class="comment"> : m_channel(channel)</span> 00038 <span class="comment"> {</span> 00039 <span class="comment"> pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel);</span> 00040 <span class="comment"> if (range.first == range.second)</span> 00041 <span class="comment"> {</span> 00042 <span class="comment"> m_useDefault = true;</span> 00043 <span class="comment"> m_itListCurrent = cs.m_defaultRoutes.begin();</span> 00044 <span class="comment"> m_itListEnd = cs.m_defaultRoutes.end();</span> 00045 <span class="comment"> }</span> 00046 <span class="comment"> else</span> 00047 <span class="comment"> {</span> 00048 <span class="comment"> m_useDefault = false;</span> 00049 <span class="comment"> m_itMapCurrent = range.first;</span> 00050 <span class="comment"> m_itMapEnd = range.second;</span> 00051 <span class="comment"> }</span> 00052 <span class="comment"> }</span> 00053 <span class="comment"></span> 00054 <span class="comment"> bool End() const</span> 00055 <span class="comment"> {</span> 00056 <span class="comment"> return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;</span> 00057 <span class="comment"> }</span> 00058 <span class="comment"></span> 00059 <span class="comment"> void Next()</span> 00060 <span class="comment"> {</span> 00061 <span class="comment"> if (m_useDefault)</span> 00062 <span class="comment"> ++m_itListCurrent;</span> 00063 <span class="comment"> else</span> 00064 <span class="comment"> ++m_itMapCurrent;</span> 00065 <span class="comment"> }</span> 00066 <span class="comment"></span> 00067 <span class="comment"> BufferedTransformation & Destination()</span> 00068 <span class="comment"> {</span> 00069 <span class="comment"> return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;</span> 00070 <span class="comment"> }</span> 00071 <span class="comment"></span> 00072 <span class="comment"> const std::string & Message()</span> 00073 <span class="comment"> {</span> 00074 <span class="comment"> if (m_useDefault)</span> 00075 <span class="comment"> return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;</span> 00076 <span class="comment"> else</span> 00077 <span class="comment"> return m_itMapCurrent->second.second;</span> 00078 <span class="comment"> }</span> 00079 <span class="comment">};</span> 00080 <span class="comment"></span> 00081 <span class="comment">void MessageSwitch::Put(byte inByte);</span> 00082 <span class="comment">void MessageSwitch::Put(const byte *inString, unsigned int length);</span> 00083 <span class="comment"></span> 00084 <span class="comment">void MessageSwitch::Flush(bool completeFlush, int propagation=-1);</span> 00085 <span class="comment">void MessageSwitch::MessageEnd(int propagation=-1);</span> 00086 <span class="comment">void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1);</span> 00087 <span class="comment">void MessageSwitch::MessageSeriesEnd(int propagation=-1);</span> 00088 <span class="comment">*/</span> 00089 <span class="preprocessor">#endif</span> 00090 <span class="preprocessor"></span> 00091 00092 <span class="comment">//</span> 00093 <span class="comment">// ChannelRouteIterator</span><span class="comment"></span> 00094 <span class="comment">//////////////////////////</span> 00095 <span class="comment"></span> 00096 <span class="keywordtype">void</span> ChannelRouteIterator::Reset(<span class="keyword">const</span> std::string &channel) 00097 { 00098 m_channel = channel; 00099 pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel); 00100 <span class="keywordflow">if</span> (range.first == range.second) 00101 { 00102 m_useDefault = <span class="keyword">true</span>; 00103 m_itListCurrent = m_cs.m_defaultRoutes.begin(); 00104 m_itListEnd = m_cs.m_defaultRoutes.end(); 00105 } 00106 <span class="keywordflow">else</span> 00107 { 00108 m_useDefault = <span class="keyword">false</span>; 00109 m_itMapCurrent = range.first; 00110 m_itMapEnd = range.second; 00111 } 00112 } 00113 00114 <span class="keywordtype">bool</span> ChannelRouteIterator::End()<span class="keyword"> const</span> 00115 <span class="keyword"></span>{ 00116 <span class="keywordflow">return</span> m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; 00117 } 00118 00119 <span class="keywordtype">void</span> ChannelRouteIterator::Next() 00120 { 00121 <span class="keywordflow">if</span> (m_useDefault) 00122 ++m_itListCurrent; 00123 <span class="keywordflow">else</span> 00124 ++m_itMapCurrent; 00125 } 00126 00127 <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> & ChannelRouteIterator::Destination() 00128 { 00129 <span class="keywordflow">return</span> m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; 00130 } 00131 00132 <span class="keyword">const</span> std::string & ChannelRouteIterator::Channel() 00133 { 00134 <span class="keywordflow">if</span> (m_useDefault) 00135 <span class="keywordflow">return</span> m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; 00136 <span class="keywordflow">else</span> 00137 <span class="keywordflow">return</span> m_itMapCurrent->second.second; 00138 } 00139 00140 00141 <span class="comment">//</span> 00142 <span class="comment">// ChannelSwitch</span><span class="comment"></span> 00143 <span class="comment">///////////////////</span> 00144 <span class="comment"></span> 00145 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelSwitch::ChannelPut2(<span class="keyword">const</span> std::string &channel, <span class="keyword">const</span> byte *begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> messageEnd, <span class="keywordtype">bool</span> blocking) 00146 { 00147 <span class="keywordflow">if</span> (m_blocked) 00148 { 00149 m_blocked = <span class="keyword">false</span>; 00150 <span class="keywordflow">goto</span> WasBlocked; 00151 } 00152 00153 m_it.Reset(channel); 00154 00155 <span class="keywordflow">while</span> (!m_it.End()) 00156 { 00157 WasBlocked: 00158 <span class="keywordflow">if</span> (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking)) 00159 { 00160 m_blocked = <span class="keyword">true</span>; 00161 <span class="keywordflow">return</span> 1; 00162 } 00163 00164 m_it.Next(); 00165 } 00166 00167 <span class="keywordflow">return</span> 0; 00168 } 00169 00170 <span class="keywordtype">void</span> ChannelSwitch::IsolatedInitialize(<span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &parameters<span class="comment">/* =g_nullNameValuePairs */</span>) 00171 { 00172 m_routeMap.clear(); 00173 m_defaultRoutes.clear(); 00174 m_blocked = <span class="keyword">false</span>; 00175 } 00176 00177 <span class="keywordtype">bool</span> ChannelSwitch::ChannelFlush(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> completeFlush, <span class="keywordtype">int</span> propagation, <span class="keywordtype">bool</span> blocking) 00178 { 00179 <span class="keywordflow">if</span> (m_blocked) 00180 { 00181 m_blocked = <span class="keyword">false</span>; 00182 <span class="keywordflow">goto</span> WasBlocked; 00183 } 00184 00185 m_it.Reset(channel); 00186 00187 <span class="keywordflow">while</span> (!m_it.End()) 00188 { 00189 WasBlocked: 00190 <span class="keywordflow">if</span> (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking)) 00191 { 00192 m_blocked = <span class="keyword">true</span>; 00193 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00194 } 00195 00196 m_it.Next(); 00197 } 00198 00199 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00200 } 00201 00202 <span class="keywordtype">bool</span> ChannelSwitch::ChannelMessageSeriesEnd(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">int</span> propagation, <span class="keywordtype">bool</span> blocking) 00203 { 00204 <span class="keywordflow">if</span> (m_blocked) 00205 { 00206 m_blocked = <span class="keyword">false</span>; 00207 <span class="keywordflow">goto</span> WasBlocked; 00208 } 00209 00210 m_it.Reset(channel); 00211 00212 <span class="keywordflow">while</span> (!m_it.End()) 00213 { 00214 WasBlocked: 00215 <span class="keywordflow">if</span> (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation)) 00216 { 00217 m_blocked = <span class="keyword">true</span>; 00218 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00219 } 00220 00221 m_it.Next(); 00222 } 00223 00224 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00225 } 00226 00227 byte * ChannelSwitch::ChannelCreatePutSpace(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &size) 00228 { 00229 m_it.Reset(channel); 00230 <span class="keywordflow">if</span> (!m_it.End()) 00231 { 00232 <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target = m_it.Destination(); 00233 <span class="keyword">const</span> std::string &channel = m_it.Channel(); 00234 m_it.Next(); 00235 <span class="keywordflow">if</span> (m_it.End()) <span class="comment">// there is only one target channel</span> 00236 <span class="keywordflow">return</span> target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_7">ChannelCreatePutSpace</a>(channel, size); 00237 } 00238 size = 0; 00239 <span class="keywordflow">return</span> NULL; 00240 } 00241 00242 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelSwitch::ChannelPutModifiable2(<span class="keyword">const</span> std::string &channel, byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> messageEnd, <span class="keywordtype">bool</span> blocking) 00243 { 00244 ChannelRouteIterator it(*<span class="keyword">this</span>); 00245 it.Reset(channel); 00246 00247 <span class="keywordflow">if</span> (!it.End()) 00248 { 00249 <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target = it.Destination(); 00250 <span class="keyword">const</span> std::string &targetChannel = it.Channel(); 00251 it.Next(); 00252 <span class="keywordflow">if</span> (it.End()) <span class="comment">// there is only one target channel</span> 00253 <span class="keywordflow">return</span> target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_9">ChannelPutModifiable2</a>(targetChannel, inString, length, messageEnd, blocking); 00254 } 00255 00256 <span class="keywordflow">return</span> ChannelPut2(channel, inString, length, messageEnd, blocking); 00257 } 00258 00259 <span class="keywordtype">void</span> ChannelSwitch::AddDefaultRoute(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination) 00260 { 00261 m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL))); 00262 } 00263 00264 <span class="keywordtype">void</span> ChannelSwitch::RemoveDefaultRoute(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination) 00265 { 00266 <span class="keywordflow">for</span> (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) 00267 <span class="keywordflow">if</span> (it->first == &destination && !it->second.get()) 00268 { 00269 m_defaultRoutes.erase(it); 00270 <span class="keywordflow">break</span>; 00271 } 00272 } 00273 00274 <span class="keywordtype">void</span> ChannelSwitch::AddDefaultRoute(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination, <span class="keyword">const</span> std::string &outChannel) 00275 { 00276 m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel)); 00277 } 00278 00279 <span class="keywordtype">void</span> ChannelSwitch::RemoveDefaultRoute(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination, <span class="keyword">const</span> std::string &outChannel) 00280 { 00281 <span class="keywordflow">for</span> (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) 00282 <span class="keywordflow">if</span> (it->first == &destination && (it->second.get() && *it->second == outChannel)) 00283 { 00284 m_defaultRoutes.erase(it); 00285 <span class="keywordflow">break</span>; 00286 } 00287 } 00288 00289 <span class="keywordtype">void</span> ChannelSwitch::AddRoute(<span class="keyword">const</span> std::string &inChannel, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination, <span class="keyword">const</span> std::string &outChannel) 00290 { 00291 m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel))); 00292 } 00293 00294 <span class="keywordtype">void</span> ChannelSwitch::RemoveRoute(<span class="keyword">const</span> std::string &inChannel, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &destination, <span class="keyword">const</span> std::string &outChannel) 00295 { 00296 <span class="keyword">typedef</span> ChannelSwitch::RouteMap::iterator MapIterator; 00297 pair<MapIterator, MapIterator> range = m_routeMap.equal_range(inChannel); 00298 00299 <span class="keywordflow">for</span> (MapIterator it = range.first; it != range.second; ++it) 00300 <span class="keywordflow">if</span> (it->second.first == &destination && it->second.second == outChannel) 00301 { 00302 m_routeMap.erase(it); 00303 <span class="keywordflow">break</span>; 00304 } 00305 } 00306 00307 NAMESPACE_END 00308 00309 <span class="preprocessor">#endif</span> </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:57 2004 for Crypto++ by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.7 </small></address> </body> </html>