Line | Count | Source (jump to first uncovered line) |
1 | | // mqueue.h - originally written and placed in the public domain by Wei Dai |
2 | | |
3 | | /// \file |
4 | | /// \brief Classes for an unlimited queue to store messages |
5 | | |
6 | | #ifndef CRYPTOPP_MQUEUE_H |
7 | | #define CRYPTOPP_MQUEUE_H |
8 | | |
9 | | #include "cryptlib.h" |
10 | | #include "queue.h" |
11 | | #include "filters.h" |
12 | | #include "misc.h" |
13 | | |
14 | | #include <deque> |
15 | | |
16 | | NAMESPACE_BEGIN(CryptoPP) |
17 | | |
18 | | /// \brief Data structure used to store messages |
19 | | /// \details The queue is implemented with a ByteQueue. |
20 | | /// \sa <A HREF="https://www.cryptopp.com/wiki/MessageQueue">MessageQueue</A> |
21 | | /// on the Crypto++ wiki. |
22 | | /// \since Crypto++ 2.0 |
23 | | class CRYPTOPP_DLL MessageQueue : public AutoSignaling<BufferedTransformation> |
24 | | { |
25 | | public: |
26 | 136k | virtual ~MessageQueue() {} |
27 | | |
28 | | /// \brief Construct a MessageQueue |
29 | | /// \param nodeSize the initial node size |
30 | | MessageQueue(unsigned int nodeSize=256); |
31 | | |
32 | | // BufferedTransformation |
33 | | void IsolatedInitialize(const NameValuePairs ¶meters) |
34 | 0 | {m_queue.IsolatedInitialize(parameters); m_lengths.assign(1, 0U); m_messageCounts.assign(1, 0U);} |
35 | | size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) |
36 | 5.04M | { |
37 | 5.04M | CRYPTOPP_UNUSED(blocking); |
38 | 5.04M | m_queue.Put(begin, length); |
39 | 5.04M | m_lengths.back() += length; |
40 | 5.04M | if (messageEnd) |
41 | 136k | { |
42 | 136k | m_lengths.push_back(0); |
43 | 136k | m_messageCounts.back()++; |
44 | 136k | } |
45 | 5.04M | return 0; |
46 | 5.04M | } |
47 | | bool IsolatedFlush(bool hardFlush, bool blocking) |
48 | 0 | {CRYPTOPP_UNUSED(hardFlush), CRYPTOPP_UNUSED(blocking); return false;} |
49 | | bool IsolatedMessageSeriesEnd(bool blocking) |
50 | 0 | {CRYPTOPP_UNUSED(blocking); m_messageCounts.push_back(0); return false;} |
51 | | |
52 | | lword MaxRetrievable() const |
53 | 6.04M | {return m_lengths.front();} |
54 | | bool AnyRetrievable() const |
55 | 0 | {return m_lengths.front() > 0;} |
56 | | |
57 | | size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); |
58 | | size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; |
59 | | |
60 | | lword TotalBytesRetrievable() const |
61 | 0 | {return m_queue.MaxRetrievable();} |
62 | | unsigned int NumberOfMessages() const |
63 | 0 | {return (unsigned int)m_lengths.size()-1;} |
64 | | bool GetNextMessage(); |
65 | | |
66 | | unsigned int NumberOfMessagesInThisSeries() const |
67 | 0 | {return m_messageCounts[0];} |
68 | | unsigned int NumberOfMessageSeries() const |
69 | 0 | {return (unsigned int)m_messageCounts.size()-1;} |
70 | | |
71 | | /// \brief Copy messages from this object to another BufferedTransformation. |
72 | | /// \param target the destination BufferedTransformation |
73 | | /// \param count the number of messages to copy |
74 | | /// \param channel the channel on which the transfer should occur |
75 | | /// \return the number of messages that remain in the copy (i.e., messages not copied) |
76 | | unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; |
77 | | |
78 | | /// \brief Peek data in the queue |
79 | | /// \param contiguousSize the size of the data |
80 | | /// \details Spy() peeks at data at the head of the queue. Spy() does |
81 | | /// not remove data from the queue. |
82 | | /// \details The data's size is returned in <tt>contiguousSize</tt>. |
83 | | /// Spy() returns the size of the first message in the list. |
84 | | const byte * Spy(size_t &contiguousSize) const; |
85 | | |
86 | | /// \brief Swap contents with another MessageQueue |
87 | | /// \param rhs the other MessageQueue |
88 | | void swap(MessageQueue &rhs); |
89 | | |
90 | | private: |
91 | | ByteQueue m_queue; |
92 | | std::deque<lword> m_lengths; |
93 | | std::deque<unsigned int> m_messageCounts; |
94 | | }; |
95 | | |
96 | | /// \brief Filter that checks messages on two channels for equality |
97 | | class CRYPTOPP_DLL EqualityComparisonFilter : public Unflushable<Multichannel<Filter> > |
98 | | { |
99 | | public: |
100 | | /// \brief Different messages were detected |
101 | | struct MismatchDetected : public Exception |
102 | | { |
103 | | /// \brief Construct a MismatchDetected exception |
104 | 0 | MismatchDetected() : Exception(DATA_INTEGRITY_CHECK_FAILED, "EqualityComparisonFilter: did not receive the same data on two channels") {} |
105 | | }; |
106 | | |
107 | | /// \brief Construct an EqualityComparisonFilter |
108 | | /// \param attachment an attached transformation |
109 | | /// \param throwIfNotEqual flag indicating whether the objects throws |
110 | | /// \param firstChannel string naming the first channel |
111 | | /// \param secondChannel string naming the second channel |
112 | | /// \throw MismatchDetected if throwIfNotEqual is true and not equal |
113 | | /// \details If throwIfNotEqual is false, this filter will output a '\\0' |
114 | | /// byte when it detects a mismatch, '\\1' otherwise. |
115 | | EqualityComparisonFilter(BufferedTransformation *attachment=NULLPTR, bool throwIfNotEqual=true, const std::string &firstChannel="0", const std::string &secondChannel="1") |
116 | | : m_throwIfNotEqual(throwIfNotEqual), m_mismatchDetected(false) |
117 | | , m_firstChannel(firstChannel), m_secondChannel(secondChannel) |
118 | 0 | {Detach(attachment);} |
119 | | |
120 | | // BufferedTransformation |
121 | | size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); |
122 | | bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); |
123 | | |
124 | | protected: |
125 | | unsigned int MapChannel(const std::string &channel) const; |
126 | | bool HandleMismatchDetected(bool blocking); |
127 | | |
128 | | private: |
129 | | bool m_throwIfNotEqual, m_mismatchDetected; |
130 | | std::string m_firstChannel, m_secondChannel; |
131 | | MessageQueue m_q[2]; |
132 | | }; |
133 | | |
134 | | NAMESPACE_END |
135 | | |
136 | | #ifndef __BORLANDC__ |
137 | | NAMESPACE_BEGIN(std) |
138 | | template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) |
139 | 0 | { |
140 | 0 | a.swap(b); |
141 | 0 | } |
142 | | NAMESPACE_END |
143 | | #endif |
144 | | |
145 | | #endif |