<!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++: queue.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>queue.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// queue.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 "queue.h"</span> 00008 <span class="preprocessor">#include "filters.h"</span> 00009 00010 NAMESPACE_BEGIN(CryptoPP) 00011 00012 static const <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> s_maxAutoNodeSize = 16*1024; 00013 00014 <span class="comment">// this class for use by ByteQueue only</span> 00015 class ByteQueueNode 00016 { 00017 <span class="keyword">public</span>: 00018 ByteQueueNode(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxSize) 00019 : buf(maxSize) 00020 { 00021 m_head = m_tail = 0; 00022 next = 0; 00023 } 00024 00025 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> buf.size();} 00026 00027 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CurrentSize()<span class="keyword"> const</span> 00028 <span class="keyword"> </span>{ 00029 <span class="keywordflow">return</span> m_tail-m_head; 00030 } 00031 00032 <span class="keyword">inline</span> <span class="keywordtype">bool</span> UsedUp()<span class="keyword"> const</span> 00033 <span class="keyword"> </span>{ 00034 <span class="keywordflow">return</span> (m_head==MaxSize()); 00035 } 00036 00037 <span class="keyword">inline</span> <span class="keywordtype">void</span> Clear() 00038 { 00039 m_head = m_tail = 0; 00040 } 00041 00042 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Put(<span class="keyword">const</span> byte *begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00043 { 00044 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> l = STDMIN(length, MaxSize()-m_tail); 00045 <span class="keywordflow">if</span> (buf+m_tail != begin) 00046 memcpy(buf+m_tail, begin, l); 00047 m_tail += l; 00048 <span class="keywordflow">return</span> l; 00049 } 00050 00051 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Peek(byte &outByte)<span class="keyword"> const</span> 00052 <span class="keyword"> </span>{ 00053 <span class="keywordflow">if</span> (m_tail==m_head) 00054 <span class="keywordflow">return</span> 0; 00055 00056 outByte=buf[m_head]; 00057 <span class="keywordflow">return</span> 1; 00058 } 00059 00060 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Peek(byte *target, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> copyMax)<span class="keyword"> const</span> 00061 <span class="keyword"> </span>{ 00062 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = STDMIN(copyMax, m_tail-m_head); 00063 memcpy(target, buf+m_head, len); 00064 <span class="keywordflow">return</span> len; 00065 } 00066 00067 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CopyTo(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keyword">const</span> std::string &channel=BufferedTransformation::NULL_CHANNEL)<span class="keyword"> const</span> 00068 <span class="keyword"> </span>{ 00069 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = m_tail-m_head; 00070 target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_0">ChannelPut</a>(channel, buf+m_head, len); 00071 <span class="keywordflow">return</span> len; 00072 } 00073 00074 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CopyTo(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> copyMax, <span class="keyword">const</span> std::string &channel=BufferedTransformation::NULL_CHANNEL)<span class="keyword"> const</span> 00075 <span class="keyword"> </span>{ 00076 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = STDMIN(copyMax, m_tail-m_head); 00077 target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_0">ChannelPut</a>(channel, buf+m_head, len); 00078 <span class="keywordflow">return</span> len; 00079 } 00080 00081 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Get(byte &outByte) 00082 { 00083 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = Peek(outByte); 00084 m_head += len; 00085 <span class="keywordflow">return</span> len; 00086 } 00087 00088 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Get(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getMax) 00089 { 00090 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = Peek(outString, getMax); 00091 m_head += len; 00092 <span class="keywordflow">return</span> len; 00093 } 00094 00095 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TransferTo(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keyword">const</span> std::string &channel=BufferedTransformation::NULL_CHANNEL) 00096 { 00097 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = m_tail-m_head; 00098 target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_2">ChannelPutModifiable</a>(channel, buf+m_head, len); 00099 m_head = m_tail; 00100 <span class="keywordflow">return</span> len; 00101 } 00102 00103 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TransferTo(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> transferMax, <span class="keyword">const</span> std::string &channel=BufferedTransformation::NULL_CHANNEL) 00104 { 00105 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = STDMIN(transferMax, m_tail-m_head); 00106 target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_2">ChannelPutModifiable</a>(channel, buf+m_head, len); 00107 m_head += len; 00108 <span class="keywordflow">return</span> len; 00109 } 00110 00111 <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Skip(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> skipMax) 00112 { 00113 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = STDMIN(skipMax, m_tail-m_head); 00114 m_head += len; 00115 <span class="keywordflow">return</span> len; 00116 } 00117 00118 <span class="keyword">inline</span> byte operator[](<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i)<span class="keyword"> const</span> 00119 <span class="keyword"> </span>{ 00120 <span class="keywordflow">return</span> buf[m_head+i]; 00121 } 00122 00123 ByteQueueNode *next; 00124 00125 <a class="code" href="class_sec_block.html">SecByteBlock</a> buf; 00126 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> m_head, m_tail; 00127 }; 00128 00129 <span class="comment">// ********************************************************</span> 00130 00131 ByteQueue::ByteQueue(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nodeSize) 00132 : m_lazyLength(0) 00133 { 00134 SetNodeSize(nodeSize); 00135 m_head = m_tail = <span class="keyword">new</span> ByteQueueNode(m_nodeSize); 00136 } 00137 00138 <span class="keywordtype">void</span> ByteQueue::SetNodeSize(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nodeSize) 00139 { 00140 m_autoNodeSize = !nodeSize; 00141 m_nodeSize = m_autoNodeSize ? 256 : nodeSize; 00142 } 00143 00144 ByteQueue::ByteQueue(<span class="keyword">const</span> <a class="code" href="class_byte_queue.html">ByteQueue</a> &copy) 00145 { 00146 CopyFrom(copy); 00147 } 00148 00149 <span class="keywordtype">void</span> ByteQueue::CopyFrom(<span class="keyword">const</span> <a class="code" href="class_byte_queue.html">ByteQueue</a> &copy) 00150 { 00151 m_lazyLength = 0; 00152 m_autoNodeSize = copy.<a class="code" href="class_byte_queue.html#_byte_queuer0">m_autoNodeSize</a>; 00153 m_nodeSize = copy.<a class="code" href="class_byte_queue.html#_byte_queuer1">m_nodeSize</a>; 00154 m_head = m_tail = <span class="keyword">new</span> ByteQueueNode(*copy.<a class="code" href="class_byte_queue.html#_byte_queuer2">m_head</a>); 00155 00156 <span class="keywordflow">for</span> (ByteQueueNode *current=copy.<a class="code" href="class_byte_queue.html#_byte_queuer2">m_head</a>->next; current; current=current->next) 00157 { 00158 m_tail->next = <span class="keyword">new</span> ByteQueueNode(*current); 00159 m_tail = m_tail->next; 00160 } 00161 00162 m_tail->next = NULL; 00163 00164 Put(copy.<a class="code" href="class_byte_queue.html#_byte_queuer4">m_lazyString</a>, copy.<a class="code" href="class_byte_queue.html#_byte_queuer5">m_lazyLength</a>); 00165 } 00166 00167 ByteQueue::~ByteQueue() 00168 { 00169 Destroy(); 00170 } 00171 00172 <span class="keywordtype">void</span> ByteQueue::Destroy() 00173 { 00174 <span class="keywordflow">for</span> (ByteQueueNode *next, *current=m_head; current; current=next) 00175 { 00176 next=current->next; 00177 <span class="keyword">delete</span> current; 00178 } 00179 } 00180 00181 <span class="keywordtype">void</span> ByteQueue::IsolatedInitialize(<span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &parameters) 00182 { 00183 m_nodeSize = parameters.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha43">GetIntValueWithDefault</a>(<span class="stringliteral">"NodeSize"</span>, 256); 00184 Clear(); 00185 } 00186 00187 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> ByteQueue::CurrentSize()<span class="keyword"> const</span> 00188 <span class="keyword"></span>{ 00189 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> size=0; 00190 00191 <span class="keywordflow">for</span> (ByteQueueNode *current=m_head; current; current=current->next) 00192 size += current->CurrentSize(); 00193 00194 <span class="keywordflow">return</span> size + m_lazyLength; 00195 } 00196 00197 <span class="keywordtype">bool</span> ByteQueue::IsEmpty()<span class="keyword"> const</span> 00198 <span class="keyword"></span>{ 00199 <span class="keywordflow">return</span> m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0; 00200 } 00201 00202 <span class="keywordtype">void</span> ByteQueue::Clear() 00203 { 00204 <span class="keywordflow">for</span> (ByteQueueNode *next, *current=m_head->next; current; current=next) 00205 { 00206 next=current->next; 00207 <span class="keyword">delete</span> current; 00208 } 00209 00210 m_tail = m_head; 00211 m_head->Clear(); 00212 m_head->next = NULL; 00213 m_lazyLength = 0; 00214 } 00215 <a name="l00216"></a><a class="code" href="class_byte_queue.html#_d_e_r_set_encodera7">00216</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_byte_queue.html#_d_e_r_set_encodera7">ByteQueue::Put2</a>(<span class="keyword">const</span> 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) 00217 { 00218 <span class="keywordflow">if</span> (m_lazyLength > 0) 00219 FinalizeLazyPut(); 00220 00221 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len; 00222 <span class="keywordflow">while</span> ((len=m_tail->Put(inString, length)) < length) 00223 { 00224 inString += len; 00225 length -= len; 00226 <span class="keywordflow">if</span> (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize) 00227 <span class="keywordflow">do</span> 00228 { 00229 m_nodeSize *= 2; 00230 } 00231 <span class="keywordflow">while</span> (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize); 00232 m_tail->next = <span class="keyword">new</span> ByteQueueNode(STDMAX(m_nodeSize, length)); 00233 m_tail = m_tail->next; 00234 } 00235 00236 <span class="keywordflow">return</span> 0; 00237 } 00238 00239 <span class="keywordtype">void</span> ByteQueue::CleanupUsedNodes() 00240 { 00241 <span class="keywordflow">while</span> (m_head != m_tail && m_head->UsedUp()) 00242 { 00243 ByteQueueNode *temp=m_head; 00244 m_head=m_head->next; 00245 <span class="keyword">delete</span> temp; 00246 } 00247 00248 <span class="keywordflow">if</span> (m_head->CurrentSize() == 0) 00249 m_head->Clear(); 00250 } 00251 00252 <span class="keywordtype">void</span> ByteQueue::LazyPut(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) 00253 { 00254 <span class="keywordflow">if</span> (m_lazyLength > 0) 00255 FinalizeLazyPut(); 00256 00257 <span class="keywordflow">if</span> (inString == m_tail->buf+m_tail->m_tail) 00258 Put(inString, size); 00259 <span class="keywordflow">else</span> 00260 { 00261 m_lazyString = const_cast<byte *>(inString); 00262 m_lazyLength = size; 00263 m_lazyStringModifiable = <span class="keyword">false</span>; 00264 } 00265 } 00266 00267 <span class="keywordtype">void</span> ByteQueue::LazyPutModifiable(byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) 00268 { 00269 <span class="keywordflow">if</span> (m_lazyLength > 0) 00270 FinalizeLazyPut(); 00271 m_lazyString = inString; 00272 m_lazyLength = size; 00273 m_lazyStringModifiable = <span class="keyword">true</span>; 00274 } 00275 00276 <span class="keywordtype">void</span> ByteQueue::UndoLazyPut(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) 00277 { 00278 <span class="keywordflow">if</span> (m_lazyLength < size) 00279 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"ByteQueue: size specified for UndoLazyPut is too large"</span>); 00280 00281 m_lazyLength -= size; 00282 } 00283 00284 <span class="keywordtype">void</span> ByteQueue::FinalizeLazyPut() 00285 { 00286 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = m_lazyLength; 00287 m_lazyLength = 0; 00288 <span class="keywordflow">if</span> (len) 00289 Put(m_lazyString, len); 00290 } 00291 <a name="l00292"></a><a class="code" href="class_byte_queue.html#_d_e_r_set_encodera8">00292</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_byte_queue.html#_d_e_r_set_encodera8">ByteQueue::Get</a>(byte &outByte) 00293 { 00294 <span class="keywordflow">if</span> (m_head->Get(outByte)) 00295 { 00296 <span class="keywordflow">if</span> (m_head->UsedUp()) 00297 CleanupUsedNodes(); 00298 <span class="keywordflow">return</span> 1; 00299 } 00300 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (m_lazyLength > 0) 00301 { 00302 outByte = *m_lazyString++; 00303 m_lazyLength--; 00304 <span class="keywordflow">return</span> 1; 00305 } 00306 <span class="keywordflow">else</span> 00307 <span class="keywordflow">return</span> 0; 00308 } 00309 <a name="l00310"></a><a class="code" href="class_byte_queue.html#_d_e_r_set_encodera9">00310</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_byte_queue.html#_d_e_r_set_encodera8">ByteQueue::Get</a>(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getMax) 00311 { 00312 <a class="code" href="class_array_sink.html">ArraySink</a> sink(outString, getMax); 00313 <span class="keywordflow">return</span> TransferTo(sink, getMax); 00314 } 00315 <a name="l00316"></a><a class="code" href="class_byte_queue.html#_d_e_r_set_encodera10">00316</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_byte_queue.html#_d_e_r_set_encodera10">ByteQueue::Peek</a>(byte &outByte)<span class="keyword"> const</span> 00317 <span class="keyword"></span>{ 00318 <span class="keywordflow">if</span> (m_head->Peek(outByte)) 00319 <span class="keywordflow">return</span> 1; 00320 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (m_lazyLength > 0) 00321 { 00322 outByte = *m_lazyString; 00323 <span class="keywordflow">return</span> 1; 00324 } 00325 <span class="keywordflow">else</span> 00326 <span class="keywordflow">return</span> 0; 00327 } 00328 <a name="l00329"></a><a class="code" href="class_byte_queue.html#_d_e_r_set_encodera11">00329</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_byte_queue.html#_d_e_r_set_encodera10">ByteQueue::Peek</a>(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> peekMax)<span class="keyword"> const</span> 00330 <span class="keyword"></span>{ 00331 <a class="code" href="class_array_sink.html">ArraySink</a> sink(outString, peekMax); 00332 <span class="keywordflow">return</span> CopyTo(sink, peekMax); 00333 } 00334 00335 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::TransferTo2(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &transferBytes, <span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> blocking) 00336 { 00337 <span class="keywordflow">if</span> (blocking) 00338 { 00339 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> bytesLeft = transferBytes; 00340 <span class="keywordflow">for</span> (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next) 00341 bytesLeft -= current->TransferTo(target, bytesLeft, channel); 00342 CleanupUsedNodes(); 00343 00344 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)STDMIN(bytesLeft, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)m_lazyLength); 00345 <span class="keywordflow">if</span> (len) 00346 { 00347 <span class="keywordflow">if</span> (m_lazyStringModifiable) 00348 target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_2">ChannelPutModifiable</a>(channel, m_lazyString, len); 00349 <span class="keywordflow">else</span> 00350 target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_0">ChannelPut</a>(channel, m_lazyString, len); 00351 m_lazyString += len; 00352 m_lazyLength -= len; 00353 bytesLeft -= len; 00354 } 00355 transferBytes -= bytesLeft; 00356 <span class="keywordflow">return</span> 0; 00357 } 00358 <span class="keywordflow">else</span> 00359 { 00360 Walker walker(*<span class="keyword">this</span>); 00361 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); 00362 <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_11">Skip</a>(transferBytes); 00363 <span class="keywordflow">return</span> blockedBytes; 00364 } 00365 } 00366 00367 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::CopyRangeTo2(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> end, <span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> blocking)<span class="keyword"> const</span> 00368 <span class="keyword"></span>{ 00369 Walker walker(*<span class="keyword">this</span>); 00370 walker.Skip(begin); 00371 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> transferBytes = end-begin; 00372 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); 00373 begin += transferBytes; 00374 <span class="keywordflow">return</span> blockedBytes; 00375 } 00376 00377 <span class="keywordtype">void</span> ByteQueue::Unget(byte inByte) 00378 { 00379 Unget(&inByte, 1); 00380 } 00381 00382 <span class="keywordtype">void</span> ByteQueue::Unget(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00383 { 00384 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = STDMIN(length, m_head->m_head); 00385 length -= len; 00386 m_head->m_head -= len; 00387 memcpy(m_head->buf + m_head->m_head, inString + length, len); 00388 00389 <span class="keywordflow">if</span> (length > 0) 00390 { 00391 ByteQueueNode *newHead = <span class="keyword">new</span> ByteQueueNode(length); 00392 newHead->next = m_head; 00393 m_head = newHead; 00394 m_head->Put(inString, length); 00395 } 00396 } 00397 00398 <span class="keyword">const</span> byte * ByteQueue::Spy(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &contiguousSize)<span class="keyword"> const</span> 00399 <span class="keyword"></span>{ 00400 contiguousSize = m_head->m_tail - m_head->m_head; 00401 <span class="keywordflow">if</span> (contiguousSize == 0 && m_lazyLength > 0) 00402 { 00403 contiguousSize = m_lazyLength; 00404 <span class="keywordflow">return</span> m_lazyString; 00405 } 00406 <span class="keywordflow">else</span> 00407 <span class="keywordflow">return</span> m_head->buf + m_head->m_head; 00408 } 00409 <a name="l00410"></a><a class="code" href="class_byte_queue.html#_d_e_r_set_encodera6">00410</a> byte * <a class="code" href="class_byte_queue.html#_d_e_r_set_encodera6">ByteQueue::CreatePutSpace</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &size) 00411 { 00412 <span class="keywordflow">if</span> (m_lazyLength > 0) 00413 FinalizeLazyPut(); 00414 00415 <span class="keywordflow">if</span> (m_tail->m_tail == m_tail->MaxSize()) 00416 { 00417 m_tail->next = <span class="keyword">new</span> ByteQueueNode(STDMAX(m_nodeSize, size)); 00418 m_tail = m_tail->next; 00419 } 00420 00421 size = m_tail->MaxSize() - m_tail->m_tail; 00422 <span class="keywordflow">return</span> m_tail->buf + m_tail->m_tail; 00423 } 00424 00425 <a class="code" href="class_byte_queue.html">ByteQueue</a> & ByteQueue::operator=(<span class="keyword">const</span> <a class="code" href="class_byte_queue.html">ByteQueue</a> &rhs) 00426 { 00427 Destroy(); 00428 CopyFrom(rhs); 00429 <span class="keywordflow">return</span> *<span class="keyword">this</span>; 00430 } 00431 00432 <span class="keywordtype">bool</span> ByteQueue::operator==(<span class="keyword">const</span> <a class="code" href="class_byte_queue.html">ByteQueue</a> &rhs)<span class="keyword"> const</span> 00433 <span class="keyword"></span>{ 00434 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> currentSize = CurrentSize(); 00435 00436 <span class="keywordflow">if</span> (currentSize != rhs.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera15">CurrentSize</a>()) 00437 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00438 00439 Walker walker1(*<span class="keyword">this</span>), walker2(rhs); 00440 byte b1, b2; 00441 00442 <span class="keywordflow">while</span> (walker1.Get(b1) && walker2.Get(b2)) 00443 <span class="keywordflow">if</span> (b1 != b2) 00444 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00445 00446 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00447 } 00448 00449 byte ByteQueue::operator[](<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> i)<span class="keyword"> const</span> 00450 <span class="keyword"></span>{ 00451 <span class="keywordflow">for</span> (ByteQueueNode *current=m_head; current; current=current->next) 00452 { 00453 <span class="keywordflow">if</span> (i < current->CurrentSize()) 00454 <span class="keywordflow">return</span> (*current)[i]; 00455 00456 i -= current->CurrentSize(); 00457 } 00458 00459 assert(i < m_lazyLength); 00460 <span class="keywordflow">return</span> m_lazyString[i]; 00461 } 00462 00463 <span class="keywordtype">void</span> ByteQueue::swap(<a class="code" href="class_byte_queue.html">ByteQueue</a> &rhs) 00464 { 00465 std::swap(m_autoNodeSize, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer0">m_autoNodeSize</a>); 00466 std::swap(m_nodeSize, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer1">m_nodeSize</a>); 00467 std::swap(m_head, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer2">m_head</a>); 00468 std::swap(m_tail, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer3">m_tail</a>); 00469 std::swap(m_lazyString, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer4">m_lazyString</a>); 00470 std::swap(m_lazyLength, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer5">m_lazyLength</a>); 00471 std::swap(m_lazyStringModifiable, rhs.<a class="code" href="class_byte_queue.html#_byte_queuer6">m_lazyStringModifiable</a>); 00472 } 00473 00474 <span class="comment">// ********************************************************</span> 00475 00476 <span class="keywordtype">void</span> ByteQueue::Walker::IsolatedInitialize(<span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &parameters) 00477 { 00478 m_node = m_queue.m_head; 00479 m_position = 0; 00480 m_offset = 0; 00481 m_lazyString = m_queue.m_lazyString; 00482 m_lazyLength = m_queue.m_lazyLength; 00483 } 00484 00485 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::Walker::Get(byte &outByte) 00486 { 00487 <a class="code" href="class_array_sink.html">ArraySink</a> sink(&outByte, 1); 00488 <span class="keywordflow">return</span> <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(sink, 1); 00489 } 00490 00491 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::Walker::Get(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getMax) 00492 { 00493 <a class="code" href="class_array_sink.html">ArraySink</a> sink(outString, getMax); 00494 <span class="keywordflow">return</span> <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(sink, getMax); 00495 } 00496 00497 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::Walker::Peek(byte &outByte)<span class="keyword"> const</span> 00498 <span class="keyword"></span>{ 00499 <a class="code" href="class_array_sink.html">ArraySink</a> sink(&outByte, 1); 00500 <span class="keywordflow">return</span> <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_12">CopyTo</a>(sink, 1); 00501 } 00502 00503 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::Walker::Peek(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> peekMax)<span class="keyword"> const</span> 00504 <span class="keyword"></span>{ 00505 <a class="code" href="class_array_sink.html">ArraySink</a> sink(outString, peekMax); 00506 <span class="keywordflow">return</span> <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_12">CopyTo</a>(sink, peekMax); 00507 } 00508 00509 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::Walker::TransferTo2(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &transferBytes, <span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> blocking) 00510 { 00511 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> bytesLeft = transferBytes; 00512 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockedBytes = 0; 00513 00514 <span class="keywordflow">while</span> (m_node) 00515 { 00516 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = STDMIN(bytesLeft, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)m_node->CurrentSize()-m_offset); 00517 blockedBytes = target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_8">ChannelPut2</a>(channel, m_node->buf+m_node->m_head+m_offset, len, 0, blocking); 00518 00519 <span class="keywordflow">if</span> (blockedBytes) 00520 <span class="keywordflow">goto</span> done; 00521 00522 m_position += len; 00523 bytesLeft -= len; 00524 00525 <span class="keywordflow">if</span> (!bytesLeft) 00526 { 00527 m_offset += len; 00528 <span class="keywordflow">goto</span> done; 00529 } 00530 00531 m_node = m_node->next; 00532 m_offset = 0; 00533 } 00534 00535 <span class="keywordflow">if</span> (bytesLeft && m_lazyLength) 00536 { 00537 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)STDMIN(bytesLeft, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)m_lazyLength); 00538 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockedBytes = target.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz13_8">ChannelPut2</a>(channel, m_lazyString, len, 0, blocking); 00539 <span class="keywordflow">if</span> (blockedBytes) 00540 <span class="keywordflow">goto</span> done; 00541 00542 m_lazyString += len; 00543 m_lazyLength -= len; 00544 bytesLeft -= len; 00545 } 00546 00547 done: 00548 transferBytes -= bytesLeft; 00549 <span class="keywordflow">return</span> blockedBytes; 00550 } 00551 00552 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ByteQueue::Walker::CopyRangeTo2(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> end, <span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> blocking)<span class="keyword"> const</span> 00553 <span class="keyword"></span>{ 00554 Walker walker(*<span class="keyword">this</span>); 00555 walker.Skip(begin); 00556 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> transferBytes = end-begin; 00557 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); 00558 begin += transferBytes; 00559 <span class="keywordflow">return</span> blockedBytes; 00560 } 00561 00562 NAMESPACE_END 00563 00564 <span class="preprocessor">#endif</span> </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:58 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>