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