00001 #ifndef CRYPTOPP_FILTERS_H
00002 #define CRYPTOPP_FILTERS_H
00003
00004 #include "simple.h"
00005 #include "secblock.h"
00006 #include "misc.h"
00007 #include "smartptr.h"
00008 #include "queue.h"
00009 #include "algparam.h"
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013
00014 class Filter : public BufferedTransformation, public NotCopyable
00015 {
00016 public:
00017 Filter(BufferedTransformation *attachment);
00018
00019 bool Attachable() {return true;}
00020 BufferedTransformation *AttachedTransformation();
00021 const BufferedTransformation *AttachedTransformation() const;
00022 void Detach(BufferedTransformation *newAttachment = NULL);
00023
00024 unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00025 unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
00026
00027 void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1);
00028 bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
00029 bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
00030
00031 protected:
00032 virtual void NotifyAttachmentChange() {}
00033 virtual BufferedTransformation * NewDefaultAttachment() const;
00034 void Insert(Filter *nextFilter);
00035
00036 virtual bool ShouldPropagateMessageEnd() const {return true;}
00037 virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
00038
00039 void PropagateInitialize(const NameValuePairs ¶meters, int propagation, const std::string &channel=NULL_CHANNEL);
00040
00041 unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
00042 bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
00043 bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
00044 bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
00045
00046 private:
00047 member_ptr<BufferedTransformation> m_attachment;
00048
00049 protected:
00050 unsigned int m_inputPosition;
00051 int m_continueAt;
00052 };
00053
00054 struct FilterPutSpaceHelper
00055 {
00056
00057 byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int desiredSize, unsigned int &bufferSize)
00058 {
00059 assert(desiredSize >= minSize && bufferSize >= minSize);
00060 if (m_tempSpace.size() < minSize)
00061 {
00062 byte *result = target.ChannelCreatePutSpace(channel, desiredSize);
00063 if (desiredSize >= minSize)
00064 {
00065 bufferSize = desiredSize;
00066 return result;
00067 }
00068 m_tempSpace.New(bufferSize);
00069 }
00070
00071 bufferSize = m_tempSpace.size();
00072 return m_tempSpace.begin();
00073 }
00074 byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize)
00075 {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
00076 byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int bufferSize)
00077 {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
00078 SecByteBlock m_tempSpace;
00079 };
00080
00081
00082 class MeterFilter : public Bufferless<Filter>
00083 {
00084 public:
00085 MeterFilter(BufferedTransformation *attachment=NULL, bool transparent=true)
00086 : Bufferless<Filter>(attachment), m_transparent(transparent) {ResetMeter();}
00087
00088 void SetTransparent(bool transparent) {m_transparent = transparent;}
00089 void ResetMeter() {m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;}
00090
00091 unsigned long GetCurrentMessageBytes() const {return m_currentMessageBytes;}
00092 unsigned long GetTotalBytes() {return m_totalBytes;}
00093 unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;}
00094 unsigned int GetTotalMessages() {return m_totalMessages;}
00095 unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;}
00096
00097 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00098 bool IsolatedMessageSeriesEnd(bool blocking);
00099
00100 private:
00101 bool ShouldPropagateMessageEnd() const {return m_transparent;}
00102 bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;}
00103
00104 bool m_transparent;
00105 unsigned long m_currentMessageBytes, m_totalBytes;
00106 unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries;
00107 };
00108
00109
00110 class TransparentFilter : public MeterFilter
00111 {
00112 public:
00113 TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {}
00114 };
00115
00116
00117 class OpaqueFilter : public MeterFilter
00118 {
00119 public:
00120 OpaqueFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, false) {}
00121 };
00122
00123
00124
00125
00126
00127
00128 class FilterWithBufferedInput : public Filter
00129 {
00130 public:
00131 FilterWithBufferedInput(BufferedTransformation *attachment);
00132
00133 FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment);
00134
00135 void IsolatedInitialize(const NameValuePairs ¶meters);
00136 unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00137 {
00138 return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
00139 }
00140 unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking)
00141 {
00142 return PutMaybeModifiable(inString, length, messageEnd, blocking, true);
00143 }
00144
00145 bool IsolatedFlush(bool hardFlush, bool blocking);
00146
00147
00148
00149
00150 void ForceNextPut();
00151
00152 protected:
00153 bool DidFirstPut() {return m_firstInputDone;}
00154
00155 virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
00156 {InitializeDerived(parameters);}
00157 virtual void InitializeDerived(const NameValuePairs ¶meters) {}
00158
00159
00160 virtual void FirstPut(const byte *inString) =0;
00161
00162 virtual void NextPutSingle(const byte *inString) {assert(false);}
00163
00164
00165 virtual void NextPutMultiple(const byte *inString, unsigned int length);
00166
00167 virtual void NextPutModifiable(byte *inString, unsigned int length)
00168 {NextPutMultiple(inString, length);}
00169
00170
00171
00172
00173 virtual void LastPut(const byte *inString, unsigned int length) =0;
00174 virtual void FlushDerived() {}
00175
00176 private:
00177 unsigned int PutMaybeModifiable(byte *begin, unsigned int length, int messageEnd, bool blocking, bool modifiable);
00178 void NextPutMaybeModifiable(byte *inString, unsigned int length, bool modifiable)
00179 {
00180 if (modifiable) NextPutModifiable(inString, length);
00181 else NextPutMultiple(inString, length);
00182 }
00183
00184
00185
00186 virtual int NextPut(const byte *inString, unsigned int length) {assert(false); return 0;}
00187
00188 class BlockQueue
00189 {
00190 public:
00191 void ResetQueue(unsigned int blockSize, unsigned int maxBlocks);
00192 byte *GetBlock();
00193 byte *GetContigousBlocks(unsigned int &numberOfBytes);
00194 unsigned int GetAll(byte *outString);
00195 void Put(const byte *inString, unsigned int length);
00196 unsigned int CurrentSize() const {return m_size;}
00197 unsigned int MaxSize() const {return m_buffer.size();}
00198
00199 private:
00200 SecByteBlock m_buffer;
00201 unsigned int m_blockSize, m_maxBlocks, m_size;
00202 byte *m_begin;
00203 };
00204
00205 unsigned int m_firstSize, m_blockSize, m_lastSize;
00206 bool m_firstInputDone;
00207 BlockQueue m_queue;
00208 };
00209
00210
00211 class FilterWithInputQueue : public Filter
00212 {
00213 public:
00214 FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {}
00215 unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00216 {
00217 if (!blocking)
00218 throw BlockingInputOnly("FilterWithInputQueue");
00219
00220 m_inQueue.Put(inString, length);
00221 if (messageEnd)
00222 {
00223 IsolatedMessageEnd(blocking);
00224 Output(0, NULL, 0, messageEnd, blocking);
00225 }
00226 return 0;
00227 }
00228
00229 protected:
00230 virtual bool IsolatedMessageEnd(bool blocking) =0;
00231 void IsolatedInitialize(const NameValuePairs ¶meters) {m_inQueue.Clear();}
00232
00233 ByteQueue m_inQueue;
00234 };
00235
00236
00237 class StreamTransformationFilter : public FilterWithBufferedInput, private FilterPutSpaceHelper
00238 {
00239 public:
00240 enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
00241
00242
00243 StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING);
00244
00245 void FirstPut(const byte *inString);
00246 void NextPutMultiple(const byte *inString, unsigned int length);
00247 void NextPutModifiable(byte *inString, unsigned int length);
00248 void LastPut(const byte *inString, unsigned int length);
00249
00250
00251 protected:
00252 static unsigned int LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding);
00253
00254 StreamTransformation &m_cipher;
00255 BlockPaddingScheme m_padding;
00256 unsigned int m_optimalBufferSize;
00257 };
00258
00259 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00260 typedef StreamTransformationFilter StreamCipherFilter;
00261 #endif
00262
00263
00264 class HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
00265 {
00266 public:
00267 HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false)
00268 : Bufferless<Filter>(attachment), m_hashModule(hm), m_putMessage(putMessage) {}
00269
00270 void IsolatedInitialize(const NameValuePairs ¶meters);
00271 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00272
00273 byte * CreatePutSpace(unsigned int &size) {return m_hashModule.CreateUpdateSpace(size);}
00274
00275 private:
00276 HashTransformation &m_hashModule;
00277 bool m_putMessage;
00278 byte *m_space;
00279 };
00280
00281
00282 class HashVerificationFilter : public FilterWithBufferedInput
00283 {
00284 public:
00285 class HashVerificationFailed : public Exception
00286 {
00287 public:
00288 HashVerificationFailed()
00289 : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not valid") {}
00290 };
00291
00292 enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT};
00293 HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
00294
00295 bool GetLastResult() const {return m_verified;}
00296
00297 protected:
00298 void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
00299 void FirstPut(const byte *inString);
00300 void NextPutMultiple(const byte *inString, unsigned int length);
00301 void LastPut(const byte *inString, unsigned int length);
00302
00303 private:
00304 static inline unsigned int FirstSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? hm.DigestSize() : 0;}
00305 static inline unsigned int LastSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? 0 : hm.DigestSize();}
00306
00307 HashTransformation &m_hashModule;
00308 word32 m_flags;
00309 SecByteBlock m_expectedHash;
00310 bool m_verified;
00311 };
00312
00313 typedef HashVerificationFilter HashVerifier;
00314
00315
00316 class SignerFilter : public Unflushable<Filter>
00317 {
00318 public:
00319 SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false)
00320 : Unflushable<Filter>(attachment), m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator()), m_putMessage(putMessage) {}
00321
00322 void IsolatedInitialize(const NameValuePairs ¶meters);
00323 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00324
00325 private:
00326 RandomNumberGenerator &m_rng;
00327 const PK_Signer &m_signer;
00328 member_ptr<PK_MessageAccumulator> m_messageAccumulator;
00329 bool m_putMessage;
00330 SecByteBlock m_buf;
00331 };
00332
00333
00334 class SignatureVerificationFilter : public FilterWithBufferedInput
00335 {
00336 public:
00337 class SignatureVerificationFailed : public Exception
00338 {
00339 public:
00340 SignatureVerificationFailed()
00341 : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
00342 };
00343
00344 enum Flags {SIGNATURE_AT_BEGIN=1, PUT_MESSAGE=2, PUT_SIGNATURE=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT};
00345 SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
00346
00347 bool GetLastResult() const {return m_verified;}
00348
00349 protected:
00350 void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
00351 void FirstPut(const byte *inString);
00352 void NextPutMultiple(const byte *inString, unsigned int length);
00353 void LastPut(const byte *inString, unsigned int length);
00354
00355 private:
00356 const PK_Verifier &m_verifier;
00357 member_ptr<PK_MessageAccumulator> m_messageAccumulator;
00358 word32 m_flags;
00359 SecByteBlock m_signature;
00360 bool m_verified;
00361 };
00362
00363 typedef SignatureVerificationFilter VerifierFilter;
00364
00365
00366 class Redirector : public CustomSignalPropagation<Sink>
00367 {
00368 public:
00369 Redirector() : m_target(NULL), m_passSignal(true) {}
00370 Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {}
00371
00372 void Redirect(BufferedTransformation &target) {m_target = ⌖}
00373 void StopRedirection() {m_target = NULL;}
00374 bool GetPassSignal() const {return m_passSignal;}
00375 void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
00376
00377 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
00378 {return m_target ? m_target->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
00379 void Initialize(const NameValuePairs ¶meters, int propagation)
00380 {ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
00381 bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
00382 {return m_target && m_passSignal ? m_target->Flush(hardFlush, propagation, blocking) : false;}
00383 bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
00384 {return m_target && m_passSignal ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
00385
00386 void ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1);
00387 unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
00388 {return m_target ? m_target->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
00389 unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
00390 {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
00391 bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
00392 {return m_target && m_passSignal ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
00393 bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00394 {return m_target && m_passSignal ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
00395
00396 private:
00397 BufferedTransformation *m_target;
00398 bool m_passSignal;
00399 };
00400
00401
00402 class OutputProxy : public CustomSignalPropagation<Sink>
00403 {
00404 public:
00405 OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
00406
00407 bool GetPassSignal() const {return m_passSignal;}
00408 void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
00409
00410 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
00411 {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
00412 unsigned int PutModifiable2(byte *begin, unsigned int length, int messageEnd, bool blocking)
00413 {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
00414 void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1)
00415 {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
00416 bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
00417 {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
00418 bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
00419 {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
00420
00421 unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
00422 {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
00423 unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
00424 {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
00425 void ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters, int propagation=-1)
00426 {if (m_passSignal) m_owner.AttachedTransformation()->ChannelInitialize(channel, parameters, propagation);}
00427 bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
00428 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
00429 bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00430 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
00431
00432 private:
00433 BufferedTransformation &m_owner;
00434 bool m_passSignal;
00435 };
00436
00437
00438 class ProxyFilter : public FilterWithBufferedInput
00439 {
00440 public:
00441 ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment);
00442
00443 bool IsolatedFlush(bool hardFlush, bool blocking);
00444
00445 void SetFilter(Filter *filter);
00446 void NextPutMultiple(const byte *s, unsigned int len);
00447
00448 protected:
00449 member_ptr<BufferedTransformation> m_filter;
00450 };
00451
00452
00453 class SimpleProxyFilter : public ProxyFilter
00454 {
00455 public:
00456 SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
00457 : ProxyFilter(filter, 0, 0, attachment) {}
00458
00459 void FirstPut(const byte *) {}
00460 void LastPut(const byte *, unsigned int) {m_filter->MessageEnd();}
00461 };
00462
00463
00464
00465 class PK_EncryptorFilter : public SimpleProxyFilter
00466 {
00467 public:
00468 PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULL)
00469 : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {}
00470 };
00471
00472
00473
00474 class PK_DecryptorFilter : public SimpleProxyFilter
00475 {
00476 public:
00477 PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL)
00478 : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {}
00479 };
00480
00481
00482 template <class T>
00483 class StringSinkTemplate : public Bufferless<Sink>
00484 {
00485 public:
00486
00487 typedef typename T::traits_type::char_type char_type;
00488
00489 StringSinkTemplate(T &output)
00490 : m_output(&output) {assert(sizeof(output[0])==1);}
00491
00492 void IsolatedInitialize(const NameValuePairs ¶meters)
00493 {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
00494
00495 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
00496 {
00497 if (length > 0)
00498 {
00499 typename T::size_type size = m_output->size();
00500 if (length < size && size + length > m_output->capacity())
00501 m_output->reserve(2*size);
00502 m_output->append((const char_type *)begin, (const char_type *)begin+length);
00503 }
00504 return 0;
00505 }
00506
00507 private:
00508 T *m_output;
00509 };
00510
00511
00512 typedef StringSinkTemplate<std::string> StringSink;
00513
00514
00515 class ArraySink : public Bufferless<Sink>
00516 {
00517 public:
00518 ArraySink(const NameValuePairs ¶meters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
00519 ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
00520
00521 unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
00522 unsigned long TotalPutLength() {return m_total;}
00523
00524 void IsolatedInitialize(const NameValuePairs ¶meters);
00525 byte * CreatePutSpace(unsigned int &size);
00526 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00527
00528 protected:
00529 byte *m_buf;
00530 unsigned int m_size;
00531 unsigned long m_total;
00532 };
00533
00534
00535 class ArrayXorSink : public ArraySink
00536 {
00537 public:
00538 ArrayXorSink(byte *buf, unsigned int size)
00539 : ArraySink(buf, size) {}
00540
00541 unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00542 byte * CreatePutSpace(unsigned int &size) {return BufferedTransformation::CreatePutSpace(size);}
00543 };
00544
00545
00546 class StringStore : public Store
00547 {
00548 public:
00549 StringStore(const char *string = NULL)
00550 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00551 StringStore(const byte *string, unsigned int length)
00552 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00553 template <class T> StringStore(const T &string)
00554 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00555
00556 unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00557 unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
00558
00559 private:
00560 void StoreInitialize(const NameValuePairs ¶meters);
00561
00562 const byte *m_store;
00563 unsigned int m_length, m_count;
00564 };
00565
00566
00567 class RandomNumberStore : public Store
00568 {
00569 public:
00570 RandomNumberStore(RandomNumberGenerator &rng, unsigned long length)
00571 : m_rng(rng), m_length(length), m_count(0) {}
00572
00573 bool AnyRetrievable() const {return MaxRetrievable() != 0;}
00574 unsigned long MaxRetrievable() const {return m_length-m_count;}
00575
00576 unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00577 unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const
00578 {
00579 throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
00580 }
00581
00582 private:
00583 void StoreInitialize(const NameValuePairs ¶meters) {m_count = 0;}
00584
00585 RandomNumberGenerator &m_rng;
00586 const unsigned long m_length;
00587 unsigned long m_count;
00588 };
00589
00590
00591 class NullStore : public Store
00592 {
00593 public:
00594 NullStore(unsigned long size = ULONG_MAX) : m_size(size) {}
00595 void StoreInitialize(const NameValuePairs ¶meters) {}
00596 unsigned long MaxRetrievable() const {return m_size;}
00597 unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00598 unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
00599
00600 private:
00601 unsigned long m_size;
00602 };
00603
00604
00605 class Source : public InputRejecting<Filter>
00606 {
00607 public:
00608 Source(BufferedTransformation *attachment)
00609 : InputRejecting<Filter>(attachment) {}
00610
00611 unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
00612 {Pump2(pumpMax); return pumpMax;}
00613 unsigned int PumpMessages(unsigned int count=UINT_MAX)
00614 {PumpMessages2(count); return count;}
00615 void PumpAll()
00616 {PumpAll2();}
00617 virtual unsigned int Pump2(unsigned long &byteCount, bool blocking=true) =0;
00618 virtual unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
00619 virtual unsigned int PumpAll2(bool blocking=true);
00620 virtual bool SourceExhausted() const =0;
00621
00622 protected:
00623 void SourceInitialize(bool pumpAll, const NameValuePairs ¶meters)
00624 {
00625 IsolatedInitialize(parameters);
00626 if (pumpAll)
00627 PumpAll();
00628 }
00629 };
00630
00631
00632 template <class T>
00633 class SourceTemplate : public Source
00634 {
00635 public:
00636 SourceTemplate<T>(BufferedTransformation *attachment)
00637 : Source(attachment) {}
00638 SourceTemplate<T>(BufferedTransformation *attachment, T store)
00639 : Source(attachment), m_store(store) {}
00640 void IsolatedInitialize(const NameValuePairs ¶meters)
00641 {m_store.IsolatedInitialize(parameters);}
00642 unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
00643 {return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);}
00644 unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true)
00645 {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);}
00646 unsigned int PumpAll2(bool blocking=true)
00647 {return m_store.TransferAllTo2(*AttachedTransformation(), NULL_CHANNEL, blocking);}
00648 bool SourceExhausted() const
00649 {return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
00650 void SetAutoSignalPropagation(int propagation)
00651 {m_store.SetAutoSignalPropagation(propagation);}
00652 int GetAutoSignalPropagation() const
00653 {return m_store.GetAutoSignalPropagation();}
00654
00655 protected:
00656 T m_store;
00657 };
00658
00659
00660 class StringSource : public SourceTemplate<StringStore>
00661 {
00662 public:
00663 StringSource(BufferedTransformation *attachment = NULL)
00664 : SourceTemplate<StringStore>(attachment) {}
00665 StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
00666 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00667 StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
00668 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00669
00670 #ifdef __MWERKS__ // CW60 workaround
00671 StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
00672 #else
00673 template <class T> StringSource(const T &string, bool pumpAll, BufferedTransformation *attachment = NULL)
00674 #endif
00675 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00676 };
00677
00678
00679 class RandomNumberSource : public SourceTemplate<RandomNumberStore>
00680 {
00681 public:
00682 RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
00683 : SourceTemplate<RandomNumberStore>(attachment, RandomNumberStore(rng, length)) {if (pumpAll) PumpAll();}
00684 };
00685
00686 NAMESPACE_END
00687
00688 #endif