PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/boost/cgi/connections/stdio.hpp

http://github.com/darrengarvey/cgi
C++ Header | 154 lines | 112 code | 19 blank | 23 comment | 9 complexity | 6db2049aef5764eaf8d4b3d5a78e0d45 MD5 | raw file
  1. // -- stdio.hpp --
  2. //
  3. // Copyright (c) Darren Garvey 2007.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. ////////////////////////////////////////////////////////////////
  9. #ifndef CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
  10. #define CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
  11. #include <cstdio>
  12. #include <string>
  13. #include <boost/config.hpp>
  14. #if BOOST_WINDOWS
  15. # include <stdio.h> // for _setmode
  16. # include <io.h> // for _setmode
  17. # include <fcntl.h> // for _setmode
  18. #endif // BOOST_WINDOWS
  19. ///////////////////////////////////////////////////////////
  20. #include <boost/system/error_code.hpp>
  21. #include <boost/asio.hpp>
  22. ///////////////////////////////////////////////////////////
  23. #include "boost/cgi/error.hpp"
  24. #include "boost/cgi/common/tags.hpp"
  25. #include "boost/cgi/basic_connection.hpp"
  26. #include "boost/cgi/detail/push_options.hpp"
  27. #include "boost/cgi/common/connection_base.hpp"
  28. #include "boost/cgi/fwd/basic_connection_fwd.hpp"
  29. //#include "boost/cgi/common/protocol_traits.hpp"
  30. BOOST_CGI_NAMESPACE_BEGIN
  31. namespace common {
  32. template<>
  33. class basic_connection<tags::stdio>
  34. : public connection_base
  35. {
  36. public:
  37. typedef boost::shared_ptr<basic_connection<tags::stdio> > pointer;
  38. basic_connection()
  39. : is_open_(true)
  40. {
  41. #if BOOST_WINDOWS
  42. // We have to open stdin in binary mode on windows,
  43. // or "\r\n" sequences are truncated to "\n".
  44. _setmode(_fileno(stdin),_O_BINARY);
  45. _setmode(_fileno(stdout),_O_BINARY);
  46. _setmode(_fileno(stderr),_O_BINARY);
  47. #endif
  48. }
  49. template<typename T>
  50. basic_connection(T&)
  51. : is_open_(true)
  52. {
  53. #if BOOST_WINDOWS
  54. // We have to open stdin in binary mode on windows,
  55. // or "\r\n" sequences are truncated to "\n".
  56. _setmode(_fileno(stdin),_O_BINARY);
  57. _setmode(_fileno(stdout),_O_BINARY);
  58. _setmode(_fileno(stderr),_O_BINARY);
  59. #endif
  60. }
  61. bool is_open() const
  62. {
  63. return is_open_;
  64. }
  65. void close()
  66. {
  67. is_open_ = false;
  68. }
  69. static pointer create()
  70. {
  71. return pointer(new basic_connection<tags::stdio>());
  72. }
  73. template<typename MutableBufferSequence>
  74. std::size_t read_some(const MutableBufferSequence buf
  75. , boost::system::error_code& ec)
  76. {
  77. if (std::fread(boost::asio::buffer_cast<void *>(buf)
  78. , boost::asio::buffer_size(buf)
  79. , 1, stdin))
  80. {
  81. return strlen(boost::asio::buffer_cast<char *>(buf));
  82. }
  83. if (std::feof(stdin))
  84. ec = ::BOOST_CGI_NAMESPACE::error::eof;
  85. else
  86. if (std::ferror(stdin))
  87. ec = ::BOOST_CGI_NAMESPACE::error::bad_read;
  88. else
  89. ec = ::BOOST_CGI_NAMESPACE::error::broken_pipe;
  90. return 0;
  91. }
  92. template<typename ConstBufferSequence>
  93. std::size_t write_some(ConstBufferSequence const& buf
  94. , boost::system::error_code& ec)
  95. {
  96. ec = boost::system::error_code();
  97. std::size_t bytes_transferred(0);
  98. for(typename ConstBufferSequence::const_iterator i = buf.begin(),
  99. end (buf.end())
  100. ; !ec && i != end; ++i)
  101. {
  102. std::size_t buf_len = boost::asio::buffer_size(*i);
  103. bytes_transferred += buf_len;
  104. //int ret(fputs(boost::asio::buffer_cast<const char*>(*i), stdout));
  105. //if (ret == EOF)
  106. //{
  107. // return ::BOOST_CGI_NAMESPACE::error::broken_pipe;
  108. //}
  109. //std::cerr<< "[buf] "
  110. // << std::string(boost::asio::buffer_cast<const char*>(*i), buf_len)
  111. // << std::endl;
  112. if (!std::fwrite(boost::asio::buffer_cast<const void *>(*i)
  113. , buf_len, 1, stdout))
  114. {
  115. if (std::feof(stdout))
  116. ec = ::BOOST_CGI_NAMESPACE::error::eof;
  117. else
  118. if (std::ferror(stdout))
  119. ec = ::BOOST_CGI_NAMESPACE::error::bad_write;
  120. else
  121. ec = ::BOOST_CGI_NAMESPACE::error::broken_pipe;
  122. }
  123. }
  124. return bytes_transferred;
  125. }
  126. protected:
  127. bool is_open_;
  128. };
  129. } // namespace common
  130. namespace connections {
  131. typedef common::basic_connection<common::tags::stdio> stdio;
  132. } // namespace connections
  133. BOOST_CGI_NAMESPACE_END
  134. #include "boost/cgi/detail/pop_options.hpp"
  135. #endif // CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__