Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:09

0001 // simple.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file simple.h

0004 /// \brief Classes providing basic library services.

0005 
0006 #ifndef CRYPTOPP_SIMPLE_H
0007 #define CRYPTOPP_SIMPLE_H
0008 
0009 #include "config.h"
0010 
0011 #if CRYPTOPP_MSC_VERSION
0012 # pragma warning(push)
0013 # pragma warning(disable: 4127 4189)
0014 #endif
0015 
0016 #include "cryptlib.h"
0017 #include "misc.h"
0018 
0019 NAMESPACE_BEGIN(CryptoPP)
0020 
0021 /// \brief Base class for identifying algorithm

0022 /// \tparam BASE base class from which to derive

0023 /// \tparam DERIVED class which to clone

0024 template <class DERIVED, class BASE>
0025 class CRYPTOPP_NO_VTABLE ClonableImpl : public BASE
0026 {
0027 public:
0028     /// \brief Create a copy of this object

0029     /// \return a copy of this object

0030     /// \details The caller is responsible for freeing the object.

0031     Clonable * Clone() const {return new DERIVED(*static_cast<const DERIVED *>(this));}
0032 };
0033 
0034 /// \brief Base class information

0035 /// \tparam BASE an Algorithm derived class

0036 /// \tparam ALGORITHM_INFO an Algorithm derived class

0037 /// \details AlgorithmImpl provides StaticAlgorithmName from the template parameter BASE

0038 template <class BASE, class ALGORITHM_INFO=BASE>
0039 class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE
0040 {
0041 public:
0042     /// \brief The algorithm name

0043     /// \return the algorithm name

0044     /// \details StaticAlgorithmName returns the algorithm's name as a static member function.

0045     ///  The name is taken from information provided by BASE.

0046     static std::string CRYPTOPP_API StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();}
0047     /// \brief The algorithm name

0048     /// \return the algorithm name

0049     /// \details AlgorithmName returns the algorithm's name as a member function.

0050     ///  The name is acquired by calling StaticAlgorithmName.

0051     std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();}
0052 };
0053 
0054 /// \brief Exception thrown when an invalid key length is encountered

0055 class CRYPTOPP_DLL InvalidKeyLength : public InvalidArgument
0056 {
0057 public:
0058     /// \brief Construct an InvalidKeyLength

0059     /// \param algorithm the Algorithm associated with the exception

0060     /// \param length the key size associated with the exception

0061     explicit InvalidKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid key length") {}
0062 };
0063 
0064 /// \brief Exception thrown when an invalid number of rounds is encountered

0065 class CRYPTOPP_DLL InvalidRounds : public InvalidArgument
0066 {
0067 public:
0068     /// \brief Construct an InvalidRounds

0069     /// \param algorithm the Algorithm associated with the exception

0070     /// \param rounds the number of rounds associated with the exception

0071     explicit InvalidRounds(const std::string &algorithm, unsigned int rounds) : InvalidArgument(algorithm + ": " + IntToString(rounds) + " is not a valid number of rounds") {}
0072 };
0073 
0074 /// \brief Exception thrown when an invalid block size is encountered

0075 class CRYPTOPP_DLL InvalidBlockSize : public InvalidArgument
0076 {
0077 public:
0078     /// \brief Construct an InvalidBlockSize

0079     /// \param algorithm the Algorithm associated with the exception

0080     /// \param length the block size associated with the exception

0081     explicit InvalidBlockSize(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid block size") {}
0082 };
0083 
0084 /// \brief Exception thrown when an invalid derived key length is encountered

0085 class CRYPTOPP_DLL InvalidDerivedKeyLength : public InvalidArgument
0086 {
0087 public:
0088     /// \brief Construct an InvalidDerivedKeyLength

0089     /// \param algorithm the Algorithm associated with the exception

0090     /// \param length the size associated with the exception

0091     explicit InvalidDerivedKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid derived key length") {}
0092 };
0093 
0094 /// \brief Exception thrown when an invalid personalization string length is encountered

0095 class CRYPTOPP_DLL InvalidPersonalizationLength : public InvalidArgument
0096 {
0097 public:
0098     /// \brief Construct an InvalidPersonalizationLength

0099     /// \param algorithm the Algorithm associated with the exception

0100     /// \param length the personalization size associated with the exception

0101     explicit InvalidPersonalizationLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid salt length") {}
0102 };
0103 
0104 /// \brief Exception thrown when an invalid salt length is encountered

0105 class CRYPTOPP_DLL InvalidSaltLength : public InvalidArgument
0106 {
0107 public:
0108     /// \brief Construct an InvalidSaltLength

0109     /// \param algorithm the Algorithm associated with the exception

0110     /// \param length the salt size associated with the exception

0111     explicit InvalidSaltLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid salt length") {}
0112 };
0113 
0114 // *****************************

0115 
0116 /// \brief Base class for bufferless filters

0117 /// \tparam T the class or type

0118 template <class T>
0119 class CRYPTOPP_NO_VTABLE Bufferless : public T
0120 {
0121 public:
0122     /// \brief Flushes data buffered by this object, without signal propagation

0123     /// \param hardFlush indicates whether all data should be flushed

0124     /// \param blocking specifies whether the object should block when processing input

0125     /// \note hardFlush must be used with care

0126     bool IsolatedFlush(bool hardFlush, bool blocking)
0127         {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); return false;}
0128 };
0129 
0130 /// \brief Base class for unflushable filters

0131 /// \tparam T the class or type

0132 template <class T>
0133 class CRYPTOPP_NO_VTABLE Unflushable : public T
0134 {
0135 public:
0136     /// \brief Flush buffered input and/or output, with signal propagation

0137     /// \param completeFlush is used to indicate whether all data should be flushed

0138     /// \param propagation the number of attached transformations the Flush()

0139     ///  signal should be passed

0140     /// \param blocking specifies whether the object should block when processing

0141     ///  input

0142     /// \details propagation count includes this object. Setting propagation to

0143     ///  <tt>1</tt> means this object only. Setting propagation to <tt>-1</tt>

0144     ///  means unlimited propagation.

0145     /// \note Hard flushes must be used with care. It means try to process and

0146     ///  output everything, even if there may not be enough data to complete the

0147     ///  action. For example, hard flushing a HexDecoder would cause an error if

0148     ///  you do it after inputing an odd number of hex encoded characters.

0149     /// \note For some types of filters, like  ZlibDecompressor, hard flushes can

0150     ///  only be done at "synchronization points". These synchronization points

0151     ///  are positions in the data stream that are created by hard flushes on the

0152     ///  corresponding reverse filters, in this example ZlibCompressor. This is

0153     ///  useful when zlib compressed data is moved across a network in packets

0154     ///  and compression state is preserved across packets, as in the SSH2 protocol.

0155     bool Flush(bool completeFlush, int propagation=-1, bool blocking=true)
0156         {return ChannelFlush(DEFAULT_CHANNEL, completeFlush, propagation, blocking);}
0157 
0158     /// \brief Flushes data buffered by this object, without signal propagation

0159     /// \param hardFlush indicates whether all data should be flushed

0160     /// \param blocking specifies whether the object should block when processing input

0161     /// \note hardFlush must be used with care

0162     bool IsolatedFlush(bool hardFlush, bool blocking)
0163         {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); CRYPTOPP_ASSERT(false); return false;}
0164 
0165     /// \brief Flush buffered input and/or output on a channel

0166     /// \param channel the channel to flush the data

0167     /// \param hardFlush is used to indicate whether all data should be flushed

0168     /// \param propagation the number of attached transformations the ChannelFlush()

0169     ///  signal should be passed

0170     /// \param blocking specifies whether the object should block when processing input

0171     /// \return true of the Flush was successful

0172     /// \details propagation count includes this object. Setting propagation to

0173     ///  <tt>1</tt> means this object only. Setting propagation to <tt>-1</tt> means

0174     ///  unlimited propagation.

0175     bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true)
0176     {
0177         if (hardFlush && !InputBufferIsEmpty())
0178             throw CannotFlush("Unflushable<T>: this object has buffered input that cannot be flushed");
0179         else
0180         {
0181             BufferedTransformation *attached = this->AttachedTransformation();
0182             return attached && propagation ? attached->ChannelFlush(channel, hardFlush, propagation-1, blocking) : false;
0183         }
0184     }
0185 
0186 protected:
0187     virtual bool InputBufferIsEmpty() const {return false;}
0188 };
0189 
0190 /// \brief Base class for input rejecting filters

0191 /// \tparam T the class or type

0192 /// \details T should be a BufferedTransformation derived class

0193 template <class T>
0194 class CRYPTOPP_NO_VTABLE InputRejecting : public T
0195 {
0196 public:
0197     struct InputRejected : public NotImplemented
0198         {InputRejected() : NotImplemented("BufferedTransformation: this object doesn't allow input") {}};
0199 
0200     /// \name INPUT

0201     //@{

0202 
0203     /// \brief Input a byte array for processing

0204     /// \param inString the byte array to process

0205     /// \param length the size of the string, in bytes

0206     /// \param messageEnd means how many filters to signal MessageEnd() to, including this one

0207     /// \param blocking specifies whether the object should block when processing input

0208     /// \throw InputRejected

0209     /// \return the number of bytes that remain to be processed (i.e., bytes not processed)

0210     /// \details Internally, the default implementation throws InputRejected.

0211     size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
0212         {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
0213     //@}

0214 
0215     /// \name SIGNALS

0216     //@{

0217 
0218     /// \brief Flushes data buffered by this object, without signal propagation

0219     /// \param hardFlush indicates whether all data should be flushed

0220     /// \param blocking specifies whether the object should block when processing input

0221     /// \note hardFlush must be used with care

0222     bool IsolatedFlush(bool hardFlush, bool blocking)
0223         {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); return false;}
0224 
0225     /// \brief Marks the end of a series of messages, without signal propagation

0226     /// \param blocking specifies whether the object should block when completing the processing on

0227     ///  the current series of messages

0228     /// \return true if the message was successful, false otherwise

0229     bool IsolatedMessageSeriesEnd(bool blocking)
0230         {CRYPTOPP_UNUSED(blocking); throw InputRejected();}
0231 
0232     /// \brief Input multiple bytes for processing on a channel.

0233     /// \param channel the channel to process the data.

0234     /// \param inString the byte buffer to process.

0235     /// \param length the size of the string, in bytes.

0236     /// \param messageEnd means how many filters to signal MessageEnd() to, including this one.

0237     /// \param blocking specifies whether the object should block when processing input.

0238     /// \return the number of bytes that remain to be processed (i.e., bytes not processed)

0239     size_t ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
0240         {CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
0241          CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
0242 
0243     /// \brief Marks the end of a series of messages on a channel

0244     /// \param channel the channel to signal the end of a series of messages

0245     /// \param messageEnd the number of attached transformations the ChannelMessageSeriesEnd() signal should be passed

0246     /// \param blocking specifies whether the object should block when processing input

0247     /// \return true if the message was successful, false otherwise

0248     /// \details Each object that receives the signal will perform its processing, decrement

0249     ///  propagation, and then pass the signal on to attached transformations if the value is not 0.

0250     /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this

0251     ///  object only. Setting propagation to <tt>-1</tt> means unlimited propagation.

0252     /// \note There should be a MessageEnd() immediately before MessageSeriesEnd().

0253     bool ChannelMessageSeriesEnd(const std::string& channel, int messageEnd, bool blocking)
0254         {CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); throw InputRejected();}
0255     //@}

0256 };
0257 
0258 /// \brief Interface for custom flush signals propagation

0259 /// \tparam T BufferedTransformation derived class

0260 template <class T>
0261 class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T
0262 {
0263 public:
0264     /// \name SIGNALS

0265     //@{

0266 
0267     /// \brief Flush buffered input and/or output, with signal propagation

0268     /// \param hardFlush is used to indicate whether all data should be flushed

0269     /// \param propagation the number of attached transformations the  Flush() signal should be passed

0270     /// \param blocking specifies whether the object should block when processing input

0271     /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this

0272     ///  object only. Setting propagation to <tt>-1</tt> means unlimited propagation.

0273     /// \note Hard flushes must be used with care. It means try to process and output everything, even if

0274     ///  there may not be enough data to complete the action. For example, hard flushing a HexDecoder

0275     ///  would cause an error if you do it after inputing an odd number of hex encoded characters.

0276     /// \note For some types of filters, like  ZlibDecompressor, hard flushes can only

0277     ///  be done at "synchronization points". These synchronization points are positions in the data

0278     ///  stream that are created by hard flushes on the corresponding reverse filters, in this

0279     ///  example ZlibCompressor. This is useful when zlib compressed data is moved across a

0280     ///  network in packets and compression state is preserved across packets, as in the SSH2 protocol.

0281     virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0;
0282 
0283     //@}

0284 
0285 private:
0286     bool IsolatedFlush(bool hardFlush, bool blocking)
0287         {CRYPTOPP_UNUSED(hardFlush); CRYPTOPP_UNUSED(blocking); CRYPTOPP_ASSERT(false); return false;}
0288 };
0289 
0290 /// \brief Interface for custom flush signals

0291 /// \tparam T BufferedTransformation derived class

0292 template <class T>
0293 class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation<T>
0294 {
0295 public:
0296     /// \brief Initialize or reinitialize this object, with signal propagation

0297     /// \param parameters a set of NameValuePairs to initialize or reinitialize this object

0298     /// \param propagation the number of attached transformations the Initialize() signal should be passed

0299     /// \details Initialize() is used to initialize or reinitialize an object using a variable number of

0300     ///  arbitrarily typed arguments. The function avoids the need for multiple constructors providing

0301     ///  all possible combintations of configurable parameters.

0302     /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this

0303     ///  object only. Setting propagation to <tt>-1</tt> means unlimited propagation.

0304     virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1) =0;
0305 
0306 private:
0307     void IsolatedInitialize(const NameValuePairs &parameters)
0308         {CRYPTOPP_UNUSED(parameters); CRYPTOPP_ASSERT(false);}
0309 };
0310 
0311 /// \brief Multiple channels support for custom signal processing

0312 /// \tparam T the class or type

0313 /// \details T should be a BufferedTransformation derived class

0314 template <class T>
0315 class CRYPTOPP_NO_VTABLE Multichannel : public CustomFlushPropagation<T>
0316 {
0317 public:
0318     bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
0319         {return this->ChannelFlush(DEFAULT_CHANNEL, hardFlush, propagation, blocking);}
0320 
0321     /// \brief Marks the end of a series of messages, with signal propagation

0322     /// \param propagation the number of attached transformations the  MessageSeriesEnd() signal should be passed

0323     /// \param blocking specifies whether the object should block when processing input

0324     /// \details Each object that receives the signal will perform its processing, decrement

0325     ///  propagation, and then pass the signal on to attached transformations if the value is not 0.

0326     /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this

0327     ///  object only. Setting propagation to <tt>-1</tt> means unlimited propagation.

0328     /// \note There should be a MessageEnd() immediately before MessageSeriesEnd().

0329     bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
0330         {return this->ChannelMessageSeriesEnd(DEFAULT_CHANNEL, propagation, blocking);}
0331 
0332     /// \brief Request space which can be written into by the caller

0333     /// \param size the requested size of the buffer

0334     /// \details The purpose of this method is to help avoid extra memory allocations.

0335     /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made,

0336     ///  size is the requested size of the buffer. When the call returns,  size is the size of

0337     ///  the array returned to the caller.

0338     /// \details The base class implementation sets  size to 0 and returns  NULL.

0339     /// \note Some objects, like ArraySink, cannot create a space because its fixed. In the case of

0340     ///  an ArraySink, the pointer to the array is returned and the  size is remaining size.

0341     byte * CreatePutSpace(size_t &size)
0342         {return this->ChannelCreatePutSpace(DEFAULT_CHANNEL, size);}
0343 
0344     /// \brief Input multiple bytes for processing

0345     /// \param inString the byte buffer to process

0346     /// \param length the size of the string, in bytes

0347     /// \param messageEnd means how many filters to signal MessageEnd() to, including this one

0348     /// \param blocking specifies whether the object should block when processing input

0349     /// \return the number of bytes that remain to be processed (i.e., bytes not processed)

0350     /// \details Derived classes must implement Put2().

0351     size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
0352         {return this->ChannelPut2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);}
0353 
0354     /// \brief Input multiple bytes that may be modified by callee.

0355     /// \param inString the byte buffer to process.

0356     /// \param length the size of the string, in bytes.

0357     /// \param messageEnd means how many filters to signal MessageEnd() to, including this one.

0358     /// \param blocking specifies whether the object should block when processing input.

0359     /// \return the number of bytes that remain to be processed (i.e., bytes not processed)

0360     /// \details Internally, PutModifiable2() calls Put2().

0361     size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
0362         {return this->ChannelPutModifiable2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);}
0363 
0364     //  void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1)

0365     //      {PropagateMessageSeriesEnd(propagation, channel);}

0366 
0367     /// \brief Request space which can be written into by the caller

0368     /// \param channel the channel to process the data

0369     /// \param size the requested size of the buffer

0370     /// \return a pointer to a memory block with length size

0371     /// \details The purpose of this method is to help avoid extra memory allocations.

0372     /// \details size is an \a IN and \a OUT parameter and used as a hint. When the call is made,

0373     ///  size is the requested size of the buffer. When the call returns, size is the size of

0374     ///  the array returned to the caller.

0375     /// \details The base class implementation sets size to 0 and returns NULL.

0376     /// \note Some objects, like ArraySink(), cannot create a space because its fixed. In the case of

0377     ///  an ArraySink(), the pointer to the array is returned and the size is remaining size.

0378     byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
0379         {CRYPTOPP_UNUSED(channel); size = 0; return NULLPTR;}
0380 
0381     /// \brief Input multiple bytes that may be modified by callee on a channel

0382     /// \param channel the channel to process the data.

0383     /// \param inString the byte buffer to process

0384     /// \param length the size of the string, in bytes

0385     /// \return true if all bytes were processed, false otherwise.

0386     bool ChannelPutModifiable(const std::string &channel, byte *inString, size_t length)
0387         {this->ChannelPut(channel, inString, length); return false;}
0388 
0389     /// \brief Input multiple bytes for processing on a channel.

0390     /// \param channel the channel to process the data.

0391     /// \param begin the byte buffer to process.

0392     /// \param length the size of the string, in bytes.

0393     /// \param messageEnd means how many filters to signal MessageEnd() to, including this one.

0394     /// \param blocking specifies whether the object should block when processing input.

0395     /// \return the number of bytes that remain to be processed (i.e., bytes not processed)

0396     virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) =0;
0397 
0398     /// \brief Input multiple bytes that may be modified by callee on a channel

0399     /// \param channel the channel to process the data

0400     /// \param begin the byte buffer to process

0401     /// \param length the size of the string, in bytes

0402     /// \param messageEnd means how many filters to signal MessageEnd() to, including this one

0403     /// \param blocking specifies whether the object should block when processing input

0404     /// \return the number of bytes that remain to be processed (i.e., bytes not processed)

0405     size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
0406         {return ChannelPut2(channel, begin, length, messageEnd, blocking);}
0407 
0408     /// \brief Flush buffered input and/or output on a channel

0409     /// \param channel the channel to flush the data

0410     /// \param hardFlush is used to indicate whether all data should be flushed

0411     /// \param propagation the number of attached transformations the ChannelFlush() signal should be passed

0412     /// \param blocking specifies whether the object should block when processing input

0413     /// \return true of the Flush was successful

0414     /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this

0415     ///  object only. Setting propagation to <tt>-1</tt> means unlimited propagation.

0416     virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) =0;
0417 };
0418 
0419 /// \brief Provides auto signaling support

0420 /// \tparam T BufferedTransformation derived class

0421 template <class T>
0422 class CRYPTOPP_NO_VTABLE AutoSignaling : public T
0423 {
0424 public:
0425     /// \brief Construct an AutoSignaling

0426     /// \param propagation the propagation count

0427     AutoSignaling(int propagation=-1) : m_autoSignalPropagation(propagation) {}
0428 
0429     /// \brief Set propagation of automatically generated and transferred signals

0430     /// \param propagation then new value

0431     /// \details Setting propagation to <tt>0</tt> means do not automatically generate signals. Setting

0432     ///  propagation to <tt>-1</tt> means unlimited propagation.

0433     void SetAutoSignalPropagation(int propagation)
0434         {m_autoSignalPropagation = propagation;}
0435 
0436     /// \brief Retrieve automatic signal propagation value

0437     /// \return the number of attached transformations the signal is propagated to. 0 indicates

0438     ///  the signal is only witnessed by this object

0439     int GetAutoSignalPropagation() const
0440         {return m_autoSignalPropagation;}
0441 
0442 private:
0443     int m_autoSignalPropagation;
0444 };
0445 
0446 /// \brief Acts as a Source for pre-existing, static data

0447 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Store : public AutoSignaling<InputRejecting<BufferedTransformation> >
0448 {
0449 public:
0450     /// \brief Construct a Store

0451     Store() : m_messageEnd(false) {}
0452 
0453     void IsolatedInitialize(const NameValuePairs &parameters)
0454     {
0455         m_messageEnd = false;
0456         StoreInitialize(parameters);
0457     }
0458 
0459     unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;}
0460     bool GetNextMessage();
0461     unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const;
0462 
0463 protected:
0464     virtual void StoreInitialize(const NameValuePairs &parameters) =0;
0465 
0466     bool m_messageEnd;
0467 };
0468 
0469 /// \brief Implementation of BufferedTransformation's attachment interface

0470 /// \details Sink is a cornerstone of the Pipeline trinity. Data flows from

0471 ///  Sources, through Filters, and then terminates in Sinks. The difference

0472 ///  between a Source and Filter is a Source \a pumps data, while a Filter does

0473 ///  not. The difference between a Filter and a Sink is a Filter allows an

0474 ///  attached transformation, while a Sink does not.

0475 /// \details A Sink does not produce any retrievable output.

0476 /// \details See the discussion of BufferedTransformation in cryptlib.h for

0477 ///  more details.

0478 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Sink : public BufferedTransformation
0479 {
0480 public:
0481     size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
0482         {CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(transferBytes); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking); transferBytes = 0; return 0;}
0483     size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
0484         {CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(end); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking); return 0;}
0485 };
0486 
0487 /// \brief Acts as an input discarding Filter or Sink

0488 /// \details The BitBucket discards all input and returns 0 to the caller

0489 ///  to indicate all data was processed.

0490 class CRYPTOPP_DLL BitBucket : public Bufferless<Sink>
0491 {
0492 public:
0493     std::string AlgorithmName() const {return "BitBucket";}
0494     void IsolatedInitialize(const NameValuePairs &params)
0495         {CRYPTOPP_UNUSED(params);}
0496     size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
0497         {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); return 0;}
0498 };
0499 
0500 NAMESPACE_END
0501 
0502 #if CRYPTOPP_MSC_VERSION
0503 # pragma warning(pop)
0504 #endif
0505 
0506 #endif