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.

259 lines
5.7 KiB

  1. // files.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #ifndef CRYPTOPP_IMPORTS
  4. #include "files.h"
  5. #include <limits>
  6. NAMESPACE_BEGIN(CryptoPP)
  7. using namespace std;
  8. #ifndef NDEBUG
  9. void Files_TestInstantiations()
  10. {
  11. FileStore f0;
  12. FileSource f1;
  13. FileSink f2;
  14. }
  15. #endif
  16. void FileStore::StoreInitialize(const NameValuePairs &parameters)
  17. {
  18. m_waiting = false;
  19. m_stream = NULL;
  20. m_file.release();
  21. const char *fileName = NULL;
  22. #if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400
  23. const wchar_t *fileNameWide = NULL;
  24. if (!parameters.GetValue(Name::InputFileNameWide(), fileNameWide))
  25. #endif
  26. if (!parameters.GetValue(Name::InputFileName(), fileName))
  27. {
  28. parameters.GetValue(Name::InputStreamPointer(), m_stream);
  29. return;
  30. }
  31. ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0);
  32. m_file.reset(new std::ifstream);
  33. #ifdef CRYPTOPP_UNIX_AVAILABLE
  34. std::string narrowed;
  35. if (fileNameWide)
  36. fileName = (narrowed = StringNarrow(fileNameWide)).c_str();
  37. #endif
  38. #if _MSC_VER >= 1400
  39. if (fileNameWide)
  40. {
  41. m_file->open(fileNameWide, ios::in | binary);
  42. if (!*m_file)
  43. throw OpenErr(StringNarrow(fileNameWide, false));
  44. }
  45. #endif
  46. if (fileName)
  47. {
  48. m_file->open(fileName, ios::in | binary);
  49. if (!*m_file)
  50. throw OpenErr(fileName);
  51. }
  52. m_stream = m_file.get();
  53. }
  54. lword FileStore::MaxRetrievable() const
  55. {
  56. if (!m_stream)
  57. return 0;
  58. streampos current = m_stream->tellg();
  59. streampos end = m_stream->seekg(0, ios::end).tellg();
  60. m_stream->seekg(current);
  61. return end-current;
  62. }
  63. size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
  64. {
  65. if (!m_stream)
  66. {
  67. transferBytes = 0;
  68. return 0;
  69. }
  70. lword size=transferBytes;
  71. transferBytes = 0;
  72. if (m_waiting)
  73. goto output;
  74. while (size && m_stream->good())
  75. {
  76. {
  77. size_t spaceSize = 1024;
  78. m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(0)-1, size), spaceSize);
  79. m_stream->read((char *)m_space, (unsigned int)STDMIN(size, (lword)spaceSize));
  80. }
  81. m_len = (size_t)m_stream->gcount();
  82. size_t blockedBytes;
  83. output:
  84. blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
  85. m_waiting = blockedBytes > 0;
  86. if (m_waiting)
  87. return blockedBytes;
  88. size -= m_len;
  89. transferBytes += m_len;
  90. }
  91. if (!m_stream->good() && !m_stream->eof())
  92. throw ReadErr();
  93. return 0;
  94. }
  95. size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
  96. {
  97. if (!m_stream)
  98. return 0;
  99. if (begin == 0 && end == 1)
  100. {
  101. int result = m_stream->peek();
  102. if (result == char_traits<char>::eof())
  103. return 0;
  104. else
  105. {
  106. size_t blockedBytes = target.ChannelPut(channel, byte(result), blocking);
  107. begin += 1-blockedBytes;
  108. return blockedBytes;
  109. }
  110. }
  111. // TODO: figure out what happens on cin
  112. streampos current = m_stream->tellg();
  113. streampos endPosition = m_stream->seekg(0, ios::end).tellg();
  114. streampos newPosition = current + (streamoff)begin;
  115. if (newPosition >= endPosition)
  116. {
  117. m_stream->seekg(current);
  118. return 0; // don't try to seek beyond the end of file
  119. }
  120. m_stream->seekg(newPosition);
  121. try
  122. {
  123. assert(!m_waiting);
  124. lword copyMax = end-begin;
  125. size_t blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
  126. begin += copyMax;
  127. if (blockedBytes)
  128. {
  129. const_cast<FileStore *>(this)->m_waiting = false;
  130. return blockedBytes;
  131. }
  132. }
  133. catch(...)
  134. {
  135. m_stream->clear();
  136. m_stream->seekg(current);
  137. throw;
  138. }
  139. m_stream->clear();
  140. m_stream->seekg(current);
  141. return 0;
  142. }
  143. lword FileStore::Skip(lword skipMax)
  144. {
  145. if (!m_stream)
  146. return 0;
  147. lword oldPos = m_stream->tellg();
  148. std::istream::off_type offset;
  149. if (!SafeConvert(skipMax, offset))
  150. throw InvalidArgument("FileStore: maximum seek offset exceeded");
  151. m_stream->seekg(offset, ios::cur);
  152. return (lword)m_stream->tellg() - oldPos;
  153. }
  154. void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
  155. {
  156. m_stream = NULL;
  157. m_file.release();
  158. const char *fileName = NULL;
  159. #if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400
  160. const wchar_t *fileNameWide = NULL;
  161. if (!parameters.GetValue(Name::OutputFileNameWide(), fileNameWide))
  162. #endif
  163. if (!parameters.GetValue(Name::OutputFileName(), fileName))
  164. {
  165. parameters.GetValue(Name::OutputStreamPointer(), m_stream);
  166. return;
  167. }
  168. ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0);
  169. m_file.reset(new std::ofstream);
  170. #ifdef CRYPTOPP_UNIX_AVAILABLE
  171. std::string narrowed;
  172. if (fileNameWide)
  173. fileName = (narrowed = StringNarrow(fileNameWide)).c_str();
  174. #endif
  175. #if _MSC_VER >= 1400
  176. if (fileNameWide)
  177. {
  178. m_file->open(fileNameWide, ios::out | ios::trunc | binary);
  179. if (!*m_file)
  180. throw OpenErr(StringNarrow(fileNameWide, false));
  181. }
  182. #endif
  183. if (fileName)
  184. {
  185. m_file->open(fileName, ios::out | ios::trunc | binary);
  186. if (!*m_file)
  187. throw OpenErr(fileName);
  188. }
  189. m_stream = m_file.get();
  190. }
  191. bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
  192. {
  193. if (!m_stream)
  194. throw Err("FileSink: output stream not opened");
  195. m_stream->flush();
  196. if (!m_stream->good())
  197. throw WriteErr();
  198. return false;
  199. }
  200. size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  201. {
  202. if (!m_stream)
  203. throw Err("FileSink: output stream not opened");
  204. while (length > 0)
  205. {
  206. std::streamsize size;
  207. if (!SafeConvert(length, size))
  208. size = numeric_limits<std::streamsize>::max();
  209. m_stream->write((const char *)inString, size);
  210. inString += size;
  211. length -= (size_t)size;
  212. }
  213. if (messageEnd)
  214. m_stream->flush();
  215. if (!m_stream->good())
  216. throw WriteErr();
  217. return 0;
  218. }
  219. NAMESPACE_END
  220. #endif