CommonIO.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file CommonIO.h
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. *
  18. * File & stream I/O routines.
  19. */
  20. #pragma once
  21. #include <map>
  22. #include <set>
  23. #include <unordered_map>
  24. #include <unordered_set>
  25. #include <array>
  26. #include <list>
  27. #include <memory>
  28. #include <vector>
  29. #include <array>
  30. #include <sstream>
  31. #include <string>
  32. #include <iostream>
  33. #include <chrono>
  34. #include "Common.h"
  35. #include "Base64.h"
  36. namespace dev
  37. {
  38. /// Requests the user to enter a password on the console.
  39. std::string getPassword(std::string const& _prompt);
  40. /// Retrieve and returns the contents of the given file.
  41. /// If the file doesn't exist or isn't readable, returns an empty container / bytes.
  42. bytes contents(std::string const& _file);
  43. /// Secure variation.
  44. bytesSec contentsSec(std::string const& _file);
  45. /// Retrieve and returns the contents of the given file as a std::string.
  46. /// If the file doesn't exist or isn't readable, returns an empty container / bytes.
  47. std::string contentsString(std::string const& _file);
  48. /// Retrieve and returns the allocated contents of the given file; if @_dest is given, don't allocate, use it directly.
  49. /// If the file doesn't exist or isn't readable, returns bytesRef(). Don't forget to delete [] the returned value's data when finished.
  50. bytesRef contentsNew(std::string const& _file, bytesRef _dest = bytesRef());
  51. /// Write the given binary data into the given file, replacing the file if it pre-exists.
  52. /// Throws exception on error.
  53. /// @param _writeDeleteRename useful not to lose any data: If set, first writes to another file in
  54. /// the same directory and then moves that file.
  55. void writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename = false);
  56. /// Write the given binary data into the given file, replacing the file if it pre-exists.
  57. inline void writeFile(std::string const& _file, bytes const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(&_data), _writeDeleteRename); }
  58. inline void writeFile(std::string const& _file, std::string const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(_data), _writeDeleteRename); }
  59. /// Nicely renders the given bytes to a string, optionally as HTML.
  60. /// @a _bytes: bytes array to be rendered as string. @a _width of a bytes line.
  61. std::string memDump(bytes const& _bytes, unsigned _width = 8, bool _html = false);
  62. // Stream I/O functions.
  63. // Provides templated stream I/O for all STL collections so they can be shifted on to any iostream-like interface.
  64. template <class S, class T> struct StreamOut { static S& bypass(S& _out, T const& _t) { _out << _t; return _out; } };
  65. template <class S> struct StreamOut<S, uint8_t> { static S& bypass(S& _out, uint8_t const& _t) { _out << (int)_t; return _out; } };
  66. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::vector<T> const& _e);
  67. template <class T, std::size_t Z> inline std::ostream& operator<<(std::ostream& _out, std::array<T, Z> const& _e);
  68. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::pair<T, U> const& _e);
  69. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::list<T> const& _e);
  70. template <class T1, class T2, class T3> inline std::ostream& operator<<(std::ostream& _out, std::tuple<T1, T2, T3> const& _e);
  71. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::map<T, U> const& _e);
  72. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::unordered_map<T, U> const& _e);
  73. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::set<T, U> const& _e);
  74. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::unordered_set<T, U> const& _e);
  75. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::multimap<T, U> const& _e);
  76. template <class _S, class _T> _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p);
  77. #if defined(_WIN32)
  78. template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "%Y-%m-%d %H:%M:%S")
  79. #else
  80. template <class T> inline std::string toString(std::chrono::time_point<T> const& _e, std::string _format = "%F %T")
  81. #endif
  82. {
  83. unsigned long milliSecondsSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(_e.time_since_epoch()).count();
  84. auto const durationSinceEpoch = std::chrono::milliseconds(milliSecondsSinceEpoch);
  85. std::chrono::time_point<std::chrono::system_clock> const tpAfterDuration(durationSinceEpoch);
  86. tm timeValue;
  87. auto time = std::chrono::system_clock::to_time_t(tpAfterDuration);
  88. #if defined(_WIN32)
  89. gmtime_s(&timeValue, &time);
  90. #else
  91. gmtime_r(&time, &timeValue);
  92. #endif
  93. unsigned const millisRemainder = milliSecondsSinceEpoch % 1000;
  94. char buffer[1024];
  95. if (strftime(buffer, sizeof(buffer), _format.c_str(), &timeValue))
  96. return std::string(buffer) + "." + (millisRemainder < 1 ? "000" : millisRemainder < 10 ? "00" : millisRemainder < 100 ? "0" : "") + std::to_string(millisRemainder) + "Z";
  97. return std::string();
  98. }
  99. template <class S, class T>
  100. inline S& streamout(S& _out, std::vector<T> const& _e)
  101. {
  102. _out << "[";
  103. if (!_e.empty())
  104. {
  105. StreamOut<S, T>::bypass(_out, _e.front());
  106. for (auto i = ++_e.begin(); i != _e.end(); ++i)
  107. StreamOut<S, T>::bypass(_out << ",", *i);
  108. }
  109. _out << "]";
  110. return _out;
  111. }
  112. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::vector<T> const& _e) { streamout(_out, _e); return _out; }
  113. template <class S, class T, std::size_t Z>
  114. inline S& streamout(S& _out, std::array<T, Z> const& _e)
  115. {
  116. _out << "[";
  117. if (!_e.empty())
  118. {
  119. StreamOut<S, T>::bypass(_out, _e.front());
  120. auto i = _e.begin();
  121. for (++i; i != _e.end(); ++i)
  122. StreamOut<S, T>::bypass(_out << ",", *i);
  123. }
  124. _out << "]";
  125. return _out;
  126. }
  127. template <class T, std::size_t Z> inline std::ostream& operator<<(std::ostream& _out, std::array<T, Z> const& _e) { streamout(_out, _e); return _out; }
  128. template <class S, class T>
  129. inline S& streamout(S& _out, std::list<T> const& _e)
  130. {
  131. _out << "[";
  132. if (!_e.empty())
  133. {
  134. _out << _e.front();
  135. for (auto i = ++_e.begin(); i != _e.end(); ++i)
  136. _out << "," << *i;
  137. }
  138. _out << "]";
  139. return _out;
  140. }
  141. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::list<T> const& _e) { streamout(_out, _e); return _out; }
  142. template <class S, class T, class U>
  143. inline S& streamout(S& _out, std::pair<T, U> const& _e)
  144. {
  145. _out << "(" << _e.first << "," << _e.second << ")";
  146. return _out;
  147. }
  148. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::pair<T, U> const& _e) { streamout(_out, _e); return _out; }
  149. template <class S, class T1, class T2, class T3>
  150. inline S& streamout(S& _out, std::tuple<T1, T2, T3> const& _t)
  151. {
  152. _out << "(" << std::get<0>(_t) << "," << std::get<1>(_t) << "," << std::get<2>(_t) << ")";
  153. return _out;
  154. }
  155. template <class T1, class T2, class T3> inline std::ostream& operator<<(std::ostream& _out, std::tuple<T1, T2, T3> const& _e) { streamout(_out, _e); return _out; }
  156. template <class S, class T, class U>
  157. S& streamout(S& _out, std::map<T, U> const& _v)
  158. {
  159. if (_v.empty())
  160. return _out << "{}";
  161. int i = 0;
  162. for (auto p: _v)
  163. _out << (!(i++) ? "{ " : "; ") << p.first << " => " << p.second;
  164. return _out << " }";
  165. }
  166. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::map<T, U> const& _e) { streamout(_out, _e); return _out; }
  167. template <class S, class T, class U>
  168. S& streamout(S& _out, std::unordered_map<T, U> const& _v)
  169. {
  170. if (_v.empty())
  171. return _out << "{}";
  172. int i = 0;
  173. for (auto p: _v)
  174. _out << (!(i++) ? "{ " : "; ") << p.first << " => " << p.second;
  175. return _out << " }";
  176. }
  177. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::unordered_map<T, U> const& _e) { streamout(_out, _e); return _out; }
  178. template <class S, class T>
  179. S& streamout(S& _out, std::set<T> const& _v)
  180. {
  181. if (_v.empty())
  182. return _out << "{}";
  183. int i = 0;
  184. for (auto p: _v)
  185. _out << (!(i++) ? "{ " : ", ") << p;
  186. return _out << " }";
  187. }
  188. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::set<T> const& _e) { streamout(_out, _e); return _out; }
  189. template <class S, class T>
  190. S& streamout(S& _out, std::unordered_set<T> const& _v)
  191. {
  192. if (_v.empty())
  193. return _out << "{}";
  194. int i = 0;
  195. for (auto p: _v)
  196. _out << (!(i++) ? "{ " : ", ") << p;
  197. return _out << " }";
  198. }
  199. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::unordered_set<T> const& _e) { streamout(_out, _e); return _out; }
  200. template <class S, class T>
  201. S& streamout(S& _out, std::multiset<T> const& _v)
  202. {
  203. if (_v.empty())
  204. return _out << "{}";
  205. int i = 0;
  206. for (auto p: _v)
  207. _out << (!(i++) ? "{ " : ", ") << p;
  208. return _out << " }";
  209. }
  210. template <class T> inline std::ostream& operator<<(std::ostream& _out, std::multiset<T> const& _e) { streamout(_out, _e); return _out; }
  211. template <class S, class T, class U>
  212. S& streamout(S& _out, std::multimap<T, U> const& _v)
  213. {
  214. if (_v.empty())
  215. return _out << "{}";
  216. T l;
  217. int i = 0;
  218. for (auto p: _v)
  219. if (!(i++))
  220. _out << "{ " << (l = p.first) << " => " << p.second;
  221. else if (l == p.first)
  222. _out << ", " << p.second;
  223. else
  224. _out << "; " << (l = p.first) << " => " << p.second;
  225. return _out << " }";
  226. }
  227. template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::multimap<T, U> const& _e) { streamout(_out, _e); return _out; }
  228. template <class _S, class _T> _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p) { if (_p) _out << "@" << (*_p); else _out << "nullptr"; return _out; }
  229. // Functions that use streaming stuff.
  230. /// Converts arbitrary value to string representation using std::stringstream.
  231. template <class _T>
  232. std::string toString(_T const& _t)
  233. {
  234. std::ostringstream o;
  235. o << _t;
  236. return o.str();
  237. }
  238. }