Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# network.cpp

    00001 // network.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004 #include "network.h"
    00005
    00006 NAMESPACE_BEGIN(CryptoPP)
    00007
    00008 unsigned int NonblockingSource::PumpMessages2(unsigned int &messageCount, bool blocking)
    00009 {
    00010         if (messageCount == 0)
    00011                 return 0;
    00012
    00013         unsigned long byteCount = ULONG_MAX;
    00014         messageCount = 0;
    00015         RETURN_IF_NONZERO(Pump2(byteCount, blocking));
    00016         if (!m_messageEndSent && SourceExhausted())
    00017         {
    00018                 RETURN_IF_NONZERO(AttachedTransformation()->Put2(NULL, 0, GetAutoSignalPropagation(), true));
    00019                 m_messageEndSent = true;
    00020                 messageCount = 1;
    00021         }
    00022         return 0;
    00023 }
    00024
    00025 bool NonblockingSink::IsolatedFlush(bool hardFlush, bool blocking)
    00026 {
    00027         TimedFlush(blocking ? INFINITE_TIME : 0);
    00028         return hardFlush && !!GetCurrentBufferSize();
    00029 }
    00030
    00031 // *************************************************************
    00032
    00033 #ifdef HIGHRES_TIMER_AVAILABLE
    00034
    00035 NetworkSource::NetworkSource(BufferedTransformation *attachment)
    00036         : NonblockingSource(attachment), m_buf(1024*4), m_bufSize(0), m_state(NORMAL)
    00037 {
    00038 }
    00039
    00040 unsigned int NetworkSource::GeneralPump2(unsigned long &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter)
    00041 {
    00042         NetworkReceiver &receiver = AccessReceiver();
    00043
    00044         unsigned long maxSize = byteCount;
    00045         byteCount = 0;
    00046         bool forever = maxTime == INFINITE_TIME;
    00047         Timer timer(Timer::MILLISECONDS, forever);
    00048         unsigned long timeout;
    00049         BufferedTransformation *t = AttachedTransformation();
    00050
    00051         if (m_state == OUTPUT_BLOCKED)
    00052                 goto DoOutput;
    00053
    00054         while (true)
    00055         {
    00056                 if (m_state == WAITING_FOR_RESULT)
    00057                 {
    00058                         if (receiver.MustWaitForResult())
    00059                         {
    00060                                 timeout = SaturatingSubtract(maxTime, timer.ElapsedTime());
    00061                                 if (!receiver.Wait(timeout))
    00062                                         break;
    00063                         }
    00064
    00065                         unsigned int recvResult = receiver.GetReceiveResult();
    00066 //                      assert(recvResult > 0 || receiver.EofReceived());
    00067                         m_bufSize += recvResult;
    00068                         m_state = NORMAL;
    00069                 }
    00070
    00071                 if (m_bufSize == 0)
    00072                 {
    00073                         if (receiver.EofReceived())
    00074                                 break;
    00075                 }
    00076                 else
    00077                 {
    00078                         m_putSize = STDMIN((unsigned long)m_bufSize, maxSize - byteCount);
    00079                         if (checkDelimiter)
    00080                                 m_putSize = std::find(m_buf.begin(), m_buf+m_putSize, delimiter) - m_buf;
    00081
    00082 DoOutput:
    00083                         unsigned int result = t->PutModifiable2(m_buf, m_putSize, 0, forever || blockingOutput);
    00084                         if (result)
    00085                         {
    00086                                 timeout = SaturatingSubtract(maxTime, timer.ElapsedTime());
    00087                                 if (t->Wait(timeout))
    00088                                         goto DoOutput;
    00089                                 else
    00090                                 {
    00091                                         m_state = OUTPUT_BLOCKED;
    00092                                         return result;
    00093                                 }
    00094                         }
    00095                         m_state = NORMAL;
    00096
    00097                         byteCount += m_putSize;
    00098                         m_bufSize -= m_putSize;
    00099                         if (m_bufSize > 0)
    00100                         {
    00101                                 memmove(m_buf, m_buf+m_putSize, m_bufSize);
    00102                                 if (checkDelimiter && m_buf[0] == delimiter)
    00103                                         break;
    00104                         }
    00105                 }
    00106
    00107                 if (byteCount == maxSize)
    00108                         break;
    00109
    00110                 unsigned long elapsed = timer.ElapsedTime();
    00111                 if (elapsed > maxTime)
    00112                         break;  // once time limit is reached, return even if there is more data waiting
    00113
    00114                 if (receiver.MustWaitToReceive())
    00115                 {
    00116                         if (!receiver.Wait(maxTime - elapsed))
    00117                                 break;
    00118                 }
    00119
    00120                 receiver.Receive(m_buf+m_bufSize, m_buf.size()-m_bufSize);
    00121                 m_state = WAITING_FOR_RESULT;
    00122         }
    00123
    00124         return 0;
    00125 }
    00126
    00127 // *************************************************************
    00128
    00129 unsigned int NetworkSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
    00130 {
    00131         if (m_blockedBytes)
    00132         {
    00133                 assert(length >= m_blockedBytes);
    00134                 inString += length - m_blockedBytes;
    00135                 length = m_blockedBytes;
    00136         }
    00137         m_buffer.LazyPut(inString, length);
    00138
    00139         unsigned int targetSize = messageEnd ? 0 : m_maxBufferSize;
    00140         TimedFlush(blocking ? INFINITE_TIME : 0, m_autoFlush ? 0 : targetSize);
    00141
    00142         if (m_buffer.CurrentSize() > targetSize)
    00143         {
    00144                 assert(!blocking);
    00145                 m_blockedBytes = STDMIN(m_buffer.CurrentSize() - targetSize, (unsigned long)length);
    00146                 m_buffer.UndoLazyPut(m_blockedBytes);
    00147                 m_buffer.FinalizeLazyPut();
    00148                 return STDMAX(m_blockedBytes, 1U);
    00149         }
    00150         m_blockedBytes = 0;
    00151
    00152         if (messageEnd)
    00153                 AccessSender().SendEof();
    00154         return 0;
    00155 }
    00156
    00157 unsigned int NetworkSink::TimedFlush(unsigned long maxTime, unsigned int targetSize)
    00158 {
    00159         if (m_buffer.IsEmpty())
    00160                 return 0;
    00161
    00162         NetworkSender &sender = AccessSender();
    00163
    00164         bool forever = maxTime == INFINITE_TIME;
    00165         Timer timer(Timer::MILLISECONDS, forever);
    00166         unsigned long timeout;
    00167         unsigned int totalFlushSize = 0;
    00168
    00169         while (true)
    00170         {
    00171                 if (m_needSendResult)
    00172                 {
    00173                         if (sender.MustWaitForResult())
    00174                         {
    00175                                 timeout = SaturatingSubtract(maxTime, timer.ElapsedTime());
    00176                                 if (!sender.Wait(timeout))
    00177                                         break;
    00178                         }
    00179
    00180                         unsigned int sendResult = sender.GetSendResult();
    00181                         m_buffer.Skip(sendResult);
    00182                         totalFlushSize += sendResult;
    00183                         m_needSendResult = false;
    00184
    00185                         if (m_buffer.CurrentSize() <= targetSize)
    00186                                 break;
    00187                 }
    00188
    00189                 unsigned long elapsed = timer.ElapsedTime();
    00190                 if (elapsed > maxTime)
    00191                         break;  // once time limit is reached, return even if there is more data waiting
    00192
    00193                 if (sender.MustWaitToSend())
    00194                 {
    00195                         if (!sender.Wait(maxTime - elapsed))
    00196                                 break;
    00197                 }
    00198
    00199                 unsigned int contiguousSize = 0;
    00200                 const byte *block = m_buffer.Spy(contiguousSize);
    00201
    00202                 sender.Send(block, contiguousSize);
    00203                 m_needSendResult = true;
    00204         }
    00205
    00206         return totalFlushSize;
    00207 }
    00208
    00209 #endif  // #ifdef HIGHRES_TIMER_AVAILABLE
    00210
    00211 NAMESPACE_END