Crypto++ 7.0 Free C++ class library of cryptographic schemes

mqueue.cpp
1 // mqueue.cpp - originally written and placed in the public domain by Wei Dai
2
3 #include "pch.h"
4
5 #ifndef CRYPTOPP_IMPORTS
6
7 #include "mqueue.h"
8
9 NAMESPACE_BEGIN(CryptoPP)
10
11 MessageQueue::MessageQueue(unsigned int nodeSize)
12 : m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U)
13 {
14 }
15
16 size_t MessageQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
17 {
18 if (begin >= MaxRetrievable())
19 return 0;
20
21 return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking);
22 }
23
24 size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
25 {
26 transferBytes = STDMIN(MaxRetrievable(), transferBytes);
27 size_t blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking);
28 m_lengths.front() -= transferBytes;
29 return blockedBytes;
30 }
31
32 bool MessageQueue::GetNextMessage()
33 {
34 if (NumberOfMessages() > 0 && !AnyRetrievable())
35 {
36 m_lengths.pop_front();
37 if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1)
38 m_messageCounts.pop_front();
39 return true;
40 }
41 else
42 return false;
43 }
44
45 unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
46 {
47 ByteQueue::Walker walker(m_queue);
48 std::deque<lword>::const_iterator it = m_lengths.begin();
49 unsigned int i;
50 for (i=0; i<count && it != --m_lengths.end(); ++i, ++it)
51 {
52 walker.TransferTo(target, *it, channel);
53 if (GetAutoSignalPropagation())
54 target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
55 }
56 return i;
57 }
58
59 void MessageQueue::swap(MessageQueue &rhs)
60 {
61 m_queue.swap(rhs.m_queue);
62 m_lengths.swap(rhs.m_lengths);
63 }
64
65 const byte * MessageQueue::Spy(size_t &contiguousSize) const
66 {
67 const byte *result = m_queue.Spy(contiguousSize);
68 contiguousSize = UnsignedMin(contiguousSize, MaxRetrievable());
69 return result;
70 }
71
72 // *************************************************************
73
74 unsigned int EqualityComparisonFilter::MapChannel(const std::string &channel) const
75 {
76 if (channel == m_firstChannel)
77 return 0;
78 else if (channel == m_secondChannel)
79 return 1;
80 else
81 return 2;
82 }
83
84 size_t EqualityComparisonFilter::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
85 {
86 if (!blocking)
87 throw BlockingInputOnly("EqualityComparisonFilter");
88
89 unsigned int i = MapChannel(channel);
90
91 if (i == 2)
92 return Output(3, inString, length, messageEnd, blocking, channel);
93 else if (m_mismatchDetected)
94 return 0;
95 else
96 {
97 MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
98
99 if (q2.AnyMessages() && q2.MaxRetrievable() < length)
100 goto mismatch;
101
102 while (length > 0 && q2.AnyRetrievable())
103 {
104 size_t len = length;
105 const byte *data = q2.Spy(len);
106 len = STDMIN(len, length);
107 if (memcmp(inString, data, len) != 0)
108 goto mismatch;
109 inString += len;
110 length -= len;
111 q2.Skip(len);
112 }
113
114 q1.Put(inString, length);
115
116 if (messageEnd)
117 {
118 if (q2.AnyRetrievable())
119 goto mismatch;
120 else if (q2.AnyMessages())
121 q2.GetNextMessage();
122 else if (q2.NumberOfMessageSeries() > 0)
123 goto mismatch;
124 else
125 q1.MessageEnd();
126 }
127
128 return 0;
129
130 mismatch:
131 return HandleMismatchDetected(blocking);
132 }
133 }
134
135 bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
136 {
137 unsigned int i = MapChannel(channel);
138
139 if (i == 2)
140 {
141 OutputMessageSeriesEnd(4, propagation, blocking, channel);
142 return false;
143 }
144 else if (m_mismatchDetected)
145 return false;
146 else
147 {
148 MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
149
150 if (q2.AnyRetrievable() || q2.AnyMessages())
151 goto mismatch;
152 else if (q2.NumberOfMessageSeries() > 0)
153 return Output(2, (const byte *)"\1", 1, 0, blocking) != 0;
154 else
155 q1.MessageSeriesEnd();
156
157 return false;
158
159 mismatch:
160 return HandleMismatchDetected(blocking);
161 }
162 }
163
164 bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking)
165 {
166 m_mismatchDetected = true;
167 if (m_throwIfNotEqual)
168 throw MismatchDetected();
169 const byte b[1] = {0};
170 return Output(1, b, 1, 0, blocking) != 0;
171 }
172
173 NAMESPACE_END
174
175 #endif
MessageQueue::AnyRetrievable
bool AnyRetrievable() const
Determines whether bytes are ready for retrieval.
Definition: mqueue.h:40
MessageQueue
Message Queue.
Definition: mqueue.h:14
BufferedTransformation::MessageSeriesEnd
virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
Marks the end of a series of messages, with signal propagation.
Definition: cryptlib.cpp:447
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1564
MessageQueue::CopyRangeTo2
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
Definition: mqueue.cpp:16
BufferedTransformation::MessageEnd
bool MessageEnd(int propagation=-1, bool blocking=true)
Signals the end of messages to the object.
Definition: cryptlib.h:1648
ByteQueue::TransferTo2
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
Definition: queue.cpp:344
BufferedTransformation::Put
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1586
EqualityComparisonFilter::ChannelMessageSeriesEnd
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Marks the end of a series of messages on a channel.
Definition: mqueue.cpp:135
MessageQueue::NumberOfMessages
unsigned int NumberOfMessages() const
Provides the number of meesages processed by this object.
Definition: mqueue.h:48
pch.h
Precompiled header file.
UnsignedMin
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:602
STDMIN
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:563
EqualityComparisonFilter::ChannelPut2
size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing on a channel.
Definition: mqueue.cpp:84
BufferedTransformation::BlockingInputOnly
Exception thrown by objects that have not implemented nonblocking input processing.
Definition: cryptlib.h:1688
MessageQueue::MaxRetrievable
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: mqueue.h:38
MessageQueue::GetNextMessage
bool GetNextMessage()
Start retrieving the next message.
Definition: mqueue.cpp:32
CryptoPP
Crypto++ library namespace.
MessageQueue::TransferTo2
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
Definition: mqueue.cpp:24
ByteQueue::Walker
A ByteQueue iterator.
Definition: queue.h:76
ByteQueue::CopyRangeTo2
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
Definition: queue.cpp:376
BufferedTransformation::ChannelMessageEnd
bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Signal the end of a message.
Definition: cryptlib.h:2121