?? filters.cpp
字號:
// filters.cpp - written and placed in the public domain by Wei Dai#include "pch.h"#include "filters.h"#include "mqueue.h"#include "fltrimpl.h"#include "argnames.h"#include <memory>#include <functional>NAMESPACE_BEGIN(CryptoPP)Filter::Filter(BufferedTransformation *attachment) : m_attachment(attachment), m_continueAt(0){}BufferedTransformation * Filter::NewDefaultAttachment() const{ return new MessageQueue;}BufferedTransformation * Filter::AttachedTransformation(){ if (m_attachment.get() == NULL) m_attachment.reset(NewDefaultAttachment()); return m_attachment.get();}const BufferedTransformation *Filter::AttachedTransformation() const{ if (m_attachment.get() == NULL) const_cast<Filter *>(this)->m_attachment.reset(NewDefaultAttachment()); return m_attachment.get();}void Filter::Detach(BufferedTransformation *newOut){ m_attachment.reset(newOut); NotifyAttachmentChange();}void Filter::Insert(Filter *filter){ filter->m_attachment.reset(m_attachment.release()); m_attachment.reset(filter); NotifyAttachmentChange();}unsigned int Filter::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const{ return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);}unsigned int Filter::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking){ return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);}void Filter::Initialize(const NameValuePairs ¶meters, int propagation){ m_continueAt = 0; IsolatedInitialize(parameters); PropagateInitialize(parameters, propagation);}bool Filter::Flush(bool hardFlush, int propagation, bool blocking){ switch (m_continueAt) { case 0: if (IsolatedFlush(hardFlush, blocking)) return true; case 1: if (OutputFlush(1, hardFlush, propagation, blocking)) return true; } return false;}bool Filter::MessageSeriesEnd(int propagation, bool blocking){ switch (m_continueAt) { case 0: if (IsolatedMessageSeriesEnd(blocking)) return true; case 1: if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking)) return true; } return false;}void Filter::PropagateInitialize(const NameValuePairs ¶meters, int propagation, const std::string &channel){ if (propagation) AttachedTransformation()->ChannelInitialize(channel, parameters, propagation-1);}unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel){ if (messageEnd) messageEnd--; unsigned int result = AttachedTransformation()->Put2(inString, length, messageEnd, blocking); m_continueAt = result ? outputSite : 0; return result;}bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel){ if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking)) { m_continueAt = outputSite; return true; } m_continueAt = 0; return false;}bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel){ if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking)) { m_continueAt = outputSite; return true; } m_continueAt = 0; return false;}// *************************************************************unsigned int MeterFilter::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking){ if (m_transparent) { FILTER_BEGIN; m_currentMessageBytes += length; m_totalBytes += length; if (messageEnd) { m_currentMessageBytes = 0; m_currentSeriesMessages++; m_totalMessages++; } FILTER_OUTPUT(1, begin, length, messageEnd); FILTER_END_NO_MESSAGE_END; } return 0;}bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking){ m_currentMessageBytes = 0; m_currentSeriesMessages = 0; m_totalMessageSeries++; return false;}// *************************************************************void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int maxBlocks){ m_buffer.New(blockSize * maxBlocks); m_blockSize = blockSize; m_maxBlocks = maxBlocks; m_size = 0; m_begin = m_buffer;}byte *FilterWithBufferedInput::BlockQueue::GetBlock(){ if (m_size >= m_blockSize) { byte *ptr = m_begin; if ((m_begin+=m_blockSize) == m_buffer.end()) m_begin = m_buffer; m_size -= m_blockSize; return ptr; } else return NULL;}byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBytes){ numberOfBytes = STDMIN(numberOfBytes, STDMIN((unsigned int)(m_buffer.end()-m_begin), m_size)); byte *ptr = m_begin; m_begin += numberOfBytes; m_size -= numberOfBytes; if (m_size == 0 || m_begin == m_buffer.end()) m_begin = m_buffer; return ptr;}unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString){ unsigned int size = m_size; unsigned int numberOfBytes = m_maxBlocks*m_blockSize; const byte *ptr = GetContigousBlocks(numberOfBytes); memcpy(outString, ptr, numberOfBytes); memcpy(outString+numberOfBytes, m_begin, m_size); m_size = 0; return size;}void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length){ assert(m_size + length <= m_buffer.size()); byte *end = (m_size < (unsigned int)(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size(); unsigned int len = STDMIN(length, (unsigned int)(m_buffer.end()-end)); memcpy(end, inString, len); if (len < length) memcpy(m_buffer, inString+len, length-len); m_size += length;}FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment) : Filter(attachment){}FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment) : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize) , m_firstInputDone(false){ if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0) throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); m_queue.ResetQueue(1, m_firstSize);}void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs ¶meters){ InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize); if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0) throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); m_queue.ResetQueue(1, m_firstSize); m_firstInputDone = false;}bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking){ if (!blocking) throw BlockingInputOnly("FilterWithBufferedInput"); if (hardFlush) ForceNextPut(); FlushDerived(); return false;}unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigned int length, int messageEnd, bool blocking, bool modifiable){ if (!blocking) throw BlockingInputOnly("FilterWithBufferedInput"); if (length != 0) { unsigned int newLength = m_queue.CurrentSize() + length; if (!m_firstInputDone && newLength >= m_firstSize) { unsigned int len = m_firstSize - m_queue.CurrentSize(); m_queue.Put(inString, len); FirstPut(m_queue.GetContigousBlocks(m_firstSize)); assert(m_queue.CurrentSize() == 0); m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); inString += len; newLength -= m_firstSize; m_firstInputDone = true; } if (m_firstInputDone) { if (m_blockSize == 1) { while (newLength > m_lastSize && m_queue.CurrentSize() > 0) { unsigned int len = newLength - m_lastSize; byte *ptr = m_queue.GetContigousBlocks(len); NextPutModifiable(ptr, len); newLength -= len; } if (newLength > m_lastSize) { unsigned int len = newLength - m_lastSize; NextPutMaybeModifiable(inString, len, modifiable); inString += len; newLength -= len; } } else { while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) { NextPutModifiable(m_queue.GetBlock(), m_blockSize); newLength -= m_blockSize; } if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) { assert(m_queue.CurrentSize() < m_blockSize); unsigned int len = m_blockSize - m_queue.CurrentSize(); m_queue.Put(inString, len); inString += len; NextPutModifiable(m_queue.GetBlock(), m_blockSize); newLength -= m_blockSize; } if (newLength >= m_blockSize + m_lastSize) { unsigned int len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); NextPutMaybeModifiable(inString, len, modifiable); inString += len; newLength -= len; } } } m_queue.Put(inString, newLength - m_queue.CurrentSize()); } if (messageEnd) { if (!m_firstInputDone && m_firstSize==0) FirstPut(NULL); SecByteBlock temp(m_queue.CurrentSize()); m_queue.GetAll(temp); LastPut(temp, temp.size()); m_firstInputDone = false; m_queue.ResetQueue(1, m_firstSize); Output(1, NULL, 0, messageEnd, blocking); } return 0;}void FilterWithBufferedInput::ForceNextPut(){ if (!m_firstInputDone) return; if (m_blockSize > 1) { while (m_queue.CurrentSize() >= m_blockSize) NextPutModifiable(m_queue.GetBlock(), m_blockSize); } else { unsigned int len; while ((len = m_queue.CurrentSize()) > 0) NextPutModifiable(m_queue.GetContigousBlocks(len), len); }}void FilterWithBufferedInput::NextPutMultiple(const byte *inString, unsigned int length){ assert(m_blockSize > 1); // m_blockSize = 1 should always override this function while (length > 0) { assert(length >= m_blockSize); NextPutSingle(inString); inString += m_blockSize; length -= m_blockSize; }}// *************************************************************void Redirector::ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters, int propagation){ if (channel.empty()) { m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL); m_passSignal = parameters.GetValueWithDefault("PassSignal", true); } if (m_target && m_passSignal) m_target->ChannelInitialize(channel, parameters, propagation);}// *************************************************************ProxyFilter::ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment) : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter){ if (m_filter.get()) m_filter->Attach(new OutputProxy(*this, false));}bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking){ return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;}void ProxyFilter::SetFilter(Filter *filter){ m_filter.reset(filter); if (filter) { OutputProxy *proxy; std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false)); m_filter->TransferAllTo(*proxy); m_filter->Attach(temp.release()); }}void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len) { if (m_filter.get()) m_filter->Put(s, len);}// *************************************************************unsigned int ArraySink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking){ memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); m_total += length; return 0;}byte * ArraySink::CreatePutSpace(unsigned int &size){ size = m_size - m_total; return m_buf + m_total;}void ArraySink::IsolatedInitialize(const NameValuePairs ¶meters){ ByteArrayParameter array; if (!parameters.GetValue(Name::OutputBuffer(), array)) throw InvalidArgument("ArraySink: missing OutputBuffer argument"); m_buf = array.begin(); m_size = array.size(); m_total = 0;}unsigned int ArrayXorSink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -