monotone

monotone Mtn Source Tree

Root/cryptopp/mqueue.cpp

1// mqueue.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "mqueue.h"
5
6NAMESPACE_BEGIN(CryptoPP)
7
8MessageQueue::MessageQueue(unsigned int nodeSize)
9: m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U)
10{
11}
12
13unsigned int MessageQueue::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
14{
15if (begin >= MaxRetrievable())
16return 0;
17
18return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking);
19}
20
21unsigned int MessageQueue::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
22{
23transferBytes = STDMIN(MaxRetrievable(), transferBytes);
24unsigned int blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking);
25m_lengths.front() -= transferBytes;
26return blockedBytes;
27}
28
29bool MessageQueue::GetNextMessage()
30{
31if (NumberOfMessages() > 0 && !AnyRetrievable())
32{
33m_lengths.pop_front();
34if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1)
35m_messageCounts.pop_front();
36return true;
37}
38else
39return false;
40}
41
42unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
43{
44ByteQueue::Walker walker(m_queue);
45std::deque<unsigned long>::const_iterator it = m_lengths.begin();
46unsigned int i;
47for (i=0; i<count && it != --m_lengths.end(); ++i, ++it)
48{
49walker.TransferTo(target, *it, channel);
50if (GetAutoSignalPropagation())
51target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
52}
53return i;
54}
55
56void MessageQueue::swap(MessageQueue &rhs)
57{
58m_queue.swap(rhs.m_queue);
59m_lengths.swap(rhs.m_lengths);
60}
61
62const byte * MessageQueue::Spy(unsigned int &contiguousSize) const
63{
64const byte *result = m_queue.Spy(contiguousSize);
65contiguousSize = (unsigned int)STDMIN((unsigned long)contiguousSize, MaxRetrievable());
66return result;
67}
68
69// *************************************************************
70
71unsigned int EqualityComparisonFilter::MapChannel(const std::string &channel) const
72{
73if (channel == m_firstChannel)
74return 0;
75else if (channel == m_secondChannel)
76return 1;
77else
78return 2;
79}
80
81unsigned int EqualityComparisonFilter::ChannelPut2(const std::string &channel, const byte *inString, unsigned int length, int messageEnd, bool blocking)
82{
83if (!blocking)
84throw BlockingInputOnly("EqualityComparisonFilter");
85
86unsigned int i = MapChannel(channel);
87
88if (i == 2)
89return Output(3, inString, length, messageEnd, blocking, channel);
90else if (m_mismatchDetected)
91return 0;
92else
93{
94MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
95
96if (q2.AnyMessages() && q2.MaxRetrievable() < length)
97goto mismatch;
98
99while (length > 0 && q2.AnyRetrievable())
100{
101unsigned int len = length;
102const byte *data = q2.Spy(len);
103len = STDMIN(len, length);
104if (memcmp(inString, data, len) != 0)
105goto mismatch;
106inString += len;
107length -= len;
108q2.Skip(len);
109}
110
111q1.Put(inString, length);
112
113if (messageEnd)
114{
115if (q2.AnyRetrievable())
116goto mismatch;
117else if (q2.AnyMessages())
118q2.GetNextMessage();
119else if (q2.NumberOfMessageSeries() > 0)
120goto mismatch;
121else
122q1.MessageEnd();
123}
124
125return 0;
126
127mismatch:
128return HandleMismatchDetected(blocking);
129}
130}
131
132void EqualityComparisonFilter::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
133{
134unsigned int i = MapChannel(channel);
135
136if (i == 2)
137PropagateInitialize(parameters, propagation, channel);
138else
139{
140m_q[i].Initialize();
141m_mismatchDetected = false;
142}
143}
144
145bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
146{
147unsigned int i = MapChannel(channel);
148
149if (i == 2)
150{
151OutputMessageSeriesEnd(4, propagation, blocking, channel);
152return false;
153}
154else if (m_mismatchDetected)
155return false;
156else
157{
158MessageQueue &q1 = m_q[i], &q2 = m_q[1-i];
159
160if (q2.AnyRetrievable() || q2.AnyMessages())
161goto mismatch;
162else if (q2.NumberOfMessageSeries() > 0)
163return Output(2, (const byte *)"\1", 1, 0, blocking) != 0;
164else
165q1.MessageSeriesEnd();
166
167return false;
168
169mismatch:
170return HandleMismatchDetected(blocking);
171}
172}
173
174bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking)
175{
176m_mismatchDetected = true;
177if (m_throwIfNotEqual)
178throw MismatchDetected();
179return Output(1, (const byte *)"\0", 1, 0, blocking) != 0;
180}
181
182NAMESPACE_END

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status