Team Fortress 2 Source Code as on 22/4/2020
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.

247 lines
5.7 KiB

  1. // basecode.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "config.h"
  4. #if CRYPTOPP_MSC_VERSION
  5. # pragma warning(disable: 4100)
  6. #endif
  7. #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
  8. # pragma GCC diagnostic ignored "-Wunused-value"
  9. #endif
  10. #ifndef CRYPTOPP_IMPORTS
  11. #include "basecode.h"
  12. #include "fltrimpl.h"
  13. #include <ctype.h>
  14. NAMESPACE_BEGIN(CryptoPP)
  15. void BaseN_Encoder::IsolatedInitialize(const NameValuePairs &parameters)
  16. {
  17. parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet);
  18. parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar);
  19. if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
  20. throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive");
  21. byte padding;
  22. bool pad;
  23. if (parameters.GetValue(Name::PaddingByte(), padding))
  24. pad = parameters.GetValueWithDefault(Name::Pad(), true);
  25. else
  26. pad = false;
  27. m_padding = pad ? padding : -1;
  28. m_bytePos = m_bitPos = 0;
  29. int i = 8;
  30. while (i%m_bitsPerChar != 0)
  31. i += 8;
  32. m_outputBlockSize = i/m_bitsPerChar;
  33. m_outBuf.New(m_outputBlockSize);
  34. }
  35. size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
  36. {
  37. FILTER_BEGIN;
  38. while (m_inputPosition < length)
  39. {
  40. if (m_bytePos == 0)
  41. memset(m_outBuf, 0, m_outputBlockSize);
  42. {
  43. unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8;
  44. while (true)
  45. {
  46. assert(m_bitPos < m_bitsPerChar);
  47. unsigned int bitsLeftInTarget = m_bitsPerChar-m_bitPos;
  48. m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget);
  49. if (bitsLeftInSource >= bitsLeftInTarget)
  50. {
  51. m_bitPos = 0;
  52. ++m_bytePos;
  53. bitsLeftInSource -= bitsLeftInTarget;
  54. if (bitsLeftInSource == 0)
  55. break;
  56. b <<= bitsLeftInTarget;
  57. b &= 0xff;
  58. }
  59. else
  60. {
  61. m_bitPos += bitsLeftInSource;
  62. break;
  63. }
  64. }
  65. }
  66. assert(m_bytePos <= m_outputBlockSize);
  67. if (m_bytePos == m_outputBlockSize)
  68. {
  69. int i;
  70. for (i=0; i<m_bytePos; i++)
  71. {
  72. assert(m_outBuf[i] < (1 << m_bitsPerChar));
  73. m_outBuf[i] = m_alphabet[m_outBuf[i]];
  74. }
  75. FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
  76. m_bytePos = m_bitPos = 0;
  77. }
  78. }
  79. if (messageEnd)
  80. {
  81. if (m_bitPos > 0)
  82. ++m_bytePos;
  83. int i;
  84. for (i=0; i<m_bytePos; i++)
  85. m_outBuf[i] = m_alphabet[m_outBuf[i]];
  86. if (m_padding != -1 && m_bytePos > 0)
  87. {
  88. memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos);
  89. m_bytePos = m_outputBlockSize;
  90. }
  91. FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
  92. m_bytePos = m_bitPos = 0;
  93. }
  94. FILTER_END_NO_MESSAGE_END;
  95. }
  96. void BaseN_Decoder::IsolatedInitialize(const NameValuePairs &parameters)
  97. {
  98. parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup);
  99. parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar);
  100. if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
  101. throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive");
  102. m_bytePos = m_bitPos = 0;
  103. int i = m_bitsPerChar;
  104. while (i%8 != 0)
  105. i += m_bitsPerChar;
  106. m_outputBlockSize = i/8;
  107. m_outBuf.New(m_outputBlockSize);
  108. }
  109. size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
  110. {
  111. FILTER_BEGIN;
  112. while (m_inputPosition < length)
  113. {
  114. unsigned int value;
  115. value = m_lookup[begin[m_inputPosition++]];
  116. if (value >= 256)
  117. continue;
  118. if (m_bytePos == 0 && m_bitPos == 0)
  119. memset(m_outBuf, 0, m_outputBlockSize);
  120. {
  121. int newBitPos = m_bitPos + m_bitsPerChar;
  122. if (newBitPos <= 8)
  123. m_outBuf[m_bytePos] |= value << (8-newBitPos);
  124. else
  125. {
  126. m_outBuf[m_bytePos] |= value >> (newBitPos-8);
  127. m_outBuf[m_bytePos+1] |= value << (16-newBitPos);
  128. }
  129. m_bitPos = newBitPos;
  130. while (m_bitPos >= 8)
  131. {
  132. m_bitPos -= 8;
  133. ++m_bytePos;
  134. }
  135. }
  136. if (m_bytePos == m_outputBlockSize)
  137. {
  138. FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
  139. m_bytePos = m_bitPos = 0;
  140. }
  141. }
  142. if (messageEnd)
  143. {
  144. FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
  145. m_bytePos = m_bitPos = 0;
  146. }
  147. FILTER_END_NO_MESSAGE_END;
  148. }
  149. void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
  150. {
  151. std::fill(lookup, lookup+256, -1);
  152. for (unsigned int i=0; i<base; i++)
  153. {
  154. if (caseInsensitive && isalpha(alphabet[i]))
  155. {
  156. assert(lookup[toupper(alphabet[i])] == -1);
  157. lookup[toupper(alphabet[i])] = i;
  158. assert(lookup[tolower(alphabet[i])] == -1);
  159. lookup[tolower(alphabet[i])] = i;
  160. }
  161. else
  162. {
  163. assert(lookup[alphabet[i]] == -1);
  164. lookup[alphabet[i]] = i;
  165. }
  166. }
  167. }
  168. void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
  169. {
  170. m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0);
  171. ConstByteArrayParameter separator, terminator;
  172. if (m_groupSize)
  173. parameters.GetRequiredParameter("Grouper", Name::Separator(), separator);
  174. else
  175. parameters.GetValue(Name::Separator(), separator);
  176. parameters.GetValue(Name::Terminator(), terminator);
  177. m_separator.Assign(separator.begin(), separator.size());
  178. m_terminator.Assign(terminator.begin(), terminator.size());
  179. m_counter = 0;
  180. }
  181. size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
  182. {
  183. FILTER_BEGIN;
  184. if (m_groupSize)
  185. {
  186. while (m_inputPosition < length)
  187. {
  188. if (m_counter == m_groupSize)
  189. {
  190. FILTER_OUTPUT(1, m_separator, m_separator.size(), 0);
  191. m_counter = 0;
  192. }
  193. size_t len;
  194. FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter),
  195. begin+m_inputPosition, len, 0);
  196. m_inputPosition += len;
  197. m_counter += len;
  198. }
  199. }
  200. else
  201. FILTER_OUTPUT(3, begin, length, 0);
  202. if (messageEnd)
  203. {
  204. FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
  205. m_counter = 0;
  206. }
  207. FILTER_END_NO_MESSAGE_END
  208. }
  209. NAMESPACE_END
  210. #endif