vs_output_stream.hpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #ifndef BOOST_PARSER_DETAIL_VS_OUTPUT_STREAM_HPP
  2. #define BOOST_PARSER_DETAIL_VS_OUTPUT_STREAM_HPP
  3. #include <array>
  4. #include <functional>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <Windows.h>
  8. namespace boost::parser::detail {
  9. template<class CharT, class TraitsT = std::char_traits<CharT>>
  10. class basic_debugbuf : public std::basic_stringbuf<CharT, TraitsT>
  11. {
  12. public:
  13. virtual ~basic_debugbuf() { sync_impl(); }
  14. protected:
  15. int sync_impl()
  16. {
  17. output_debug_string(this->str().c_str());
  18. this->str(std::basic_string<CharT>()); // Clear the string buffer
  19. return 0;
  20. }
  21. int sync() override { return sync_impl(); }
  22. void output_debug_string(const CharT * text);
  23. };
  24. template<>
  25. inline void basic_debugbuf<char>::output_debug_string(const char * text)
  26. {
  27. // Save in-memory logging buffer to a log file on error (from MSDN
  28. // example).
  29. std::wstring dest;
  30. int convert_result = MultiByteToWideChar(
  31. CP_UTF8, 0, text, static_cast<int>(std::strlen(text)), nullptr, 0);
  32. if (convert_result <= 0) {
  33. // cannot convert to wide-char -> use ANSI API
  34. ::OutputDebugStringA(text);
  35. } else {
  36. dest.resize(convert_result + 10);
  37. convert_result = MultiByteToWideChar(
  38. CP_UTF8,
  39. 0,
  40. text,
  41. static_cast<int>(std::strlen(text)),
  42. dest.data(),
  43. static_cast<int>(dest.size()));
  44. if (convert_result <= 0) {
  45. // cannot convert to wide-char -> use ANSI API
  46. ::OutputDebugStringA(text);
  47. } else {
  48. ::OutputDebugStringW(dest.c_str());
  49. }
  50. }
  51. }
  52. template<class CharT, class TraitsT = std::char_traits<CharT>>
  53. class basic_debug_ostream : public std::basic_ostream<CharT, TraitsT>
  54. {
  55. public:
  56. basic_debug_ostream() :
  57. std::basic_ostream<CharT, TraitsT>(
  58. new basic_debugbuf<CharT, TraitsT>())
  59. {}
  60. ~basic_debug_ostream() { delete this->rdbuf(); }
  61. };
  62. inline basic_debug_ostream<char> vs_cout;
  63. //
  64. }
  65. #endif