Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
4.1 KiB

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