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

# network.h

    00001 #ifndef CRYPTOPP_NETWORK_H
    00002 #define CRYPTOPP_NETWORK_H
    00003
    00004 #include "filters.h"
    00005 #include "hrtimer.h"
    00006
    00007 NAMESPACE_BEGIN(CryptoPP)
    00008
    00009 //! a Source class that can pump from a device for a specified amount of time.
    00010 class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source>
    00011 {
    00012 public:
    00013         NonblockingSource(BufferedTransformation *attachment)
    00014                 : m_messageEndSent(false) {Detach(attachment);}
    00015
    00016         //!     \name NONBLOCKING SOURCE
    00017         //@{
    00018
    00019         //! pump up to maxSize bytes using at most maxTime milliseconds
    00020         /*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */
    00021         virtual unsigned int GeneralPump2(unsigned long &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n') =0;
    00022
    00023         unsigned long GeneralPump(unsigned long maxSize=ULONG_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n')
    00024         {
    00025                 GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter);
    00026                 return maxSize;
    00027         }
    00028         unsigned long TimedPump(unsigned long maxTime)
    00029                 {return GeneralPump(ULONG_MAX, maxTime);}
    00030         unsigned long PumpLine(byte delimiter='\n', unsigned long maxSize=1024)
    00031                 {return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);}
    00032
    00033         unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
    00034                 {return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);}
    00035         unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true);
    00036         //@}
    00037
    00038 private:
    00039         bool m_messageEndSent;
    00040 };
    00041
    00042 //! Network Receiver
    00043 class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable
    00044 {
    00045 public:
    00046         virtual bool MustWaitToReceive() {return false;}
    00047         virtual bool MustWaitForResult() {return false;}
    00048         //! receive data from network source, returns whether result is immediately available
    00049         virtual bool Receive(byte* buf, unsigned int bufLen) =0;
    00050         virtual unsigned int GetReceiveResult() =0;
    00051         virtual bool EofReceived() const =0;
    00052 };
    00053
    00054 class CRYPTOPP_NO_VTABLE NonblockingSinkInfo
    00055 {
    00056 public:
    00057         virtual ~NonblockingSinkInfo() {}
    00058         virtual unsigned int GetMaxBufferSize() const =0;
    00059         virtual unsigned int GetCurrentBufferSize() const =0;
    00060         //! compute the current speed of this sink in bytes per second
    00061         virtual float ComputeCurrentSpeed() =0;
    00062         //! get the maximum observed speed of this sink in bytes per second
    00063         virtual float GetMaxObservedSpeed() const =0;
    00064 };
    00065
    00066 //! a Sink class that queues input and can flush to a device for a specified amount of time.
    00067 class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo
    00068 {
    00069 public:
    00070         bool IsolatedFlush(bool hardFlush, bool blocking);
    00071
    00072         //! flush to device for no more than maxTime milliseconds
    00073         /*! This function will repeatedly attempt to flush data to some device, until
    00074                 the queue is empty, or a total of maxTime milliseconds have elapsed.
    00075                 If maxTime == 0, at least one attempt will be made to flush some data, but
    00076                 it is likely that not all queued data will be flushed, even if the device
    00077                 is ready to receive more data without waiting. If you want to flush as much data
    00078                 as possible without waiting for the device, call this function in a loop.
    00079                 For example: while (sink.TimedFlush(0) > 0) {}
    00080                 \return number of bytes flushed
    00081         */
    00082         virtual unsigned int TimedFlush(unsigned long maxTime, unsigned int targetSize = 0) =0;
    00083
    00084         virtual void SetMaxBufferSize(unsigned int maxBufferSize) =0;
    00085         //! set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize()
    00086         virtual void SetAutoFlushBound(unsigned int bound) =0;
    00087 };
    00088
    00089 //! Network Sender
    00090 class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable
    00091 {
    00092 public:
    00093         virtual bool MustWaitToSend() {return false;}
    00094         virtual bool MustWaitForResult() {return false;}
    00095         virtual void Send(const byte* buf, unsigned int bufLen) =0;
    00096         virtual unsigned int GetSendResult() =0;
    00097         virtual void SendEof() =0;
    00098 };
    00099
    00100 #ifdef HIGHRES_TIMER_AVAILABLE
    00101
    00102 //! Network Source
    00103 class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource
    00104 {
    00105 public:
    00106         NetworkSource(BufferedTransformation *attachment);
    00107
    00108         unsigned int GetMaxWaitObjectCount() const
    00109                 {return GetReceiver().GetMaxWaitObjectCount() + AttachedTransformation()->GetMaxWaitObjectCount();}
    00110         void GetWaitObjects(WaitObjectContainer &container);
    00111
    00112         unsigned int GeneralPump2(unsigned long &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n');
    00113         bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();}
    00114
    00115 protected:
    00116         virtual NetworkReceiver & AccessReceiver() =0;
    00117         const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();}
    00118
    00119 private:
    00120         SecByteBlock m_buf;
    00121         unsigned int m_putSize, m_dataBegin, m_dataEnd;
    00122         bool m_waitingForResult, m_outputBlocked;
    00123 };
    00124
    00125 //! Network Sink
    00126 class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink
    00127 {
    00128 public:
    00129         NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound);
    00130
    00131         unsigned int GetMaxWaitObjectCount() const
    00132                 {return GetSender().GetMaxWaitObjectCount();}
    00133         void GetWaitObjects(WaitObjectContainer &container)
    00134                 {if (m_wasBlocked || !m_buffer.IsEmpty()) AccessSender().GetWaitObjects(container);}
    00135
    00136         unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
    00137
    00138         unsigned int TimedFlush(unsigned long maxTime, unsigned int targetSize = 0);
    00139
    00140         void SetMaxBufferSize(unsigned int maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(STDMIN(16U*1024U+256, maxBufferSize));}
    00141         void SetAutoFlushBound(unsigned int bound) {m_autoFlushBound = bound;}
    00142
    00143         unsigned int GetMaxBufferSize() const {return m_maxBufferSize;}
    00144         unsigned int GetCurrentBufferSize() const {return m_buffer.CurrentSize();}
    00145
    00146         void ClearBuffer() {m_buffer.Clear();}
    00147
    00148         //! compute the current speed of this sink in bytes per second
    00149         float ComputeCurrentSpeed();
    00150         //! get the maximum observed speed of this sink in bytes per second
    00151         float GetMaxObservedSpeed() const {return m_maxObservedSpeed;}
    00152
    00153 protected:
    00154         virtual NetworkSender & AccessSender() =0;
    00155         const NetworkSender & GetSender() const {return const_cast<NetworkSink *>(this)->AccessSender();}
    00156
    00157 private:
    00158         unsigned int m_maxBufferSize, m_autoFlushBound;
    00159         bool m_needSendResult, m_wasBlocked;
    00160         ByteQueue m_buffer;
    00161         unsigned int m_skipBytes;
    00162         Timer m_speedTimer;
    00163         float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed;
    00164 };
    00165
    00166 #endif  // #ifdef HIGHRES_TIMER_AVAILABLE
    00167
    00168 NAMESPACE_END
    00169
    00170 #endif