Coverage Report

Created: 2024-11-21 07:03

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