diff options
author | weidai <weidai11@users.noreply.github.com> | 2006-04-06 21:20:25 +0000 |
---|---|---|
committer | weidai <weidai11@users.noreply.github.com> | 2006-04-06 21:20:25 +0000 |
commit | 6aacd0a0de141d218710374018412cca1893ad9d (patch) | |
tree | 34dba126863f587607debfecab883867f5f2d3dd /network.h | |
parent | 254b0f0d4d307221e0328b8f4e892a9bc0d93765 (diff) | |
download | cryptopp-git-6aacd0a0de141d218710374018412cca1893ad9d.tar.gz |
merge in changes by denis bider and fix compile on gcc 3.4.4 and MSVC 6
Diffstat (limited to 'network.h')
-rw-r--r-- | network.h | 99 |
1 files changed, 81 insertions, 18 deletions
@@ -4,21 +4,62 @@ #include "filters.h" #include "hrtimer.h" +#include <deque> + NAMESPACE_BEGIN(CryptoPP) +class LimitedBandwidth +{ +public: + LimitedBandwidth(lword maxBytesPerSecond = 0) + : m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS) + , m_nextTransceiveTime(0) + { m_timer.StartTimer(); } + + lword GetMaxBytesPerSecond() const + { return m_maxBytesPerSecond; } + + void SetMaxBytesPerSecond(lword v) + { m_maxBytesPerSecond = v; } + + lword ComputeCurrentTransceiveLimit(); + + double TimeToNextTransceive(); + + void NoteTransceive(lword size); + +public: + /*! GetWaitObjects() must be called despite the 0 return from GetMaxWaitObjectCount(); + the 0 is because the ScheduleEvent() method is used instead of adding a wait object */ + unsigned int GetMaxWaitObjectCount() const { return 0; } + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + +private: + lword m_maxBytesPerSecond; + + typedef std::deque<std::pair<double, lword> > OpQueue; + OpQueue m_ops; + + Timer m_timer; + double m_nextTransceiveTime; + + void ComputeNextTransceiveTime(); + double GetCurTimeAndCleanUp(); +}; + //! a Source class that can pump from a device for a specified amount of time. -class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source> +class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source>, public LimitedBandwidth { public: NonblockingSource(BufferedTransformation *attachment) - : m_messageEndSent(false) {Detach(attachment);} + : m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);} //! \name NONBLOCKING SOURCE //@{ //! pump up to maxSize bytes using at most maxTime milliseconds /*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */ - virtual size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n') =0; + size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n'); lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n') { @@ -35,8 +76,14 @@ public: size_t PumpMessages2(unsigned int &messageCount, bool blocking=true); //@} +protected: + virtual size_t DoPump(lword &byteCount, bool blockingOutput, + unsigned long maxTime, bool checkDelimiter, byte delimiter) =0; + + bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } + private: - bool m_messageEndSent; + bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit; }; //! Network Receiver @@ -57,6 +104,7 @@ public: virtual ~NonblockingSinkInfo() {} virtual size_t GetMaxBufferSize() const =0; virtual size_t GetCurrentBufferSize() const =0; + virtual bool EofPending() const =0; //! compute the current speed of this sink in bytes per second virtual float ComputeCurrentSpeed() =0; //! get the maximum observed speed of this sink in bytes per second @@ -64,9 +112,11 @@ public: }; //! a Sink class that queues input and can flush to a device for a specified amount of time. -class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo +class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth { public: + NonblockingSink() : m_blockedBySpeedLimit(false) {} + bool IsolatedFlush(bool hardFlush, bool blocking); //! flush to device for no more than maxTime milliseconds @@ -79,11 +129,19 @@ public: For example: while (sink.TimedFlush(0) > 0) {} \return number of bytes flushed */ - virtual lword TimedFlush(unsigned long maxTime, size_t targetSize=0) =0; + lword TimedFlush(unsigned long maxTime, size_t targetSize = 0); virtual void SetMaxBufferSize(size_t maxBufferSize) =0; //! set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize() virtual void SetAutoFlushBound(size_t bound) =0; + +protected: + virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0; + + bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } + +private: + bool m_blockedBySpeedLimit; }; //! Network Sender @@ -94,7 +152,9 @@ public: virtual bool MustWaitForResult() {return false;} virtual void Send(const byte* buf, size_t bufLen) =0; virtual unsigned int GetSendResult() =0; + virtual bool MustWaitForEof() {return false;} virtual void SendEof() =0; + virtual bool EofSent() {return false;} // implement if MustWaitForEof() == true }; #ifdef HIGHRES_TIMER_AVAILABLE @@ -105,14 +165,14 @@ class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource public: NetworkSource(BufferedTransformation *attachment); - unsigned int GetMaxWaitObjectCount() const - {return GetReceiver().GetMaxWaitObjectCount() + AttachedTransformation()->GetMaxWaitObjectCount();} - void GetWaitObjects(WaitObjectContainer &container); + unsigned int GetMaxWaitObjectCount() const; + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n'); bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();} protected: + size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter); + virtual NetworkReceiver & AccessReceiver() =0; const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();} @@ -128,35 +188,38 @@ class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink public: NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound); - unsigned int GetMaxWaitObjectCount() const - {return GetSender().GetMaxWaitObjectCount();} - void GetWaitObjects(WaitObjectContainer &container) - {if (m_wasBlocked || !m_buffer.IsEmpty()) AccessSender().GetWaitObjects(container);} + unsigned int GetMaxWaitObjectCount() const; + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); - lword TimedFlush(unsigned long maxTime, size_t targetSize = 0); - void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));} void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;} size_t GetMaxBufferSize() const {return m_maxBufferSize;} size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();} - void ClearBuffer() {m_buffer.Clear();} + void ClearBuffer() { m_buffer.Clear(); } + + bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; } //! compute the current speed of this sink in bytes per second float ComputeCurrentSpeed(); //! get the maximum observed speed of this sink in bytes per second - float GetMaxObservedSpeed() const {return m_maxObservedSpeed;} + float GetMaxObservedSpeed() const; protected: + lword DoFlush(unsigned long maxTime, size_t targetSize); + virtual NetworkSender & AccessSender() =0; const NetworkSender & GetSender() const {return const_cast<NetworkSink *>(this)->AccessSender();} private: + enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE }; + size_t m_maxBufferSize, m_autoFlushBound; bool m_needSendResult, m_wasBlocked; + EofState m_eofState; ByteQueue m_buffer; size_t m_skipBytes; Timer m_speedTimer; |