Ejemplo n.º 1
0
typename std::enable_if<
    is_const_buffer_sequence<ConstBufferSequence>::value,
        std::size_t>::type
buffer_count(ConstBufferSequence const& buffers)
{
    return std::distance(buffers.begin(), buffers.end());
}
Ejemplo n.º 2
0
Archivo: stdio.hpp Proyecto: aldot/cgi
 std::size_t write_some(ConstBufferSequence const& buf
                       , boost::system::error_code& ec)
 {
   ec = boost::system::error_code();
   
   std::size_t bytes_transferred(0);
   for(typename ConstBufferSequence::const_iterator i = buf.begin(),
       end (buf.end())
      ; !ec && i != end; ++i)
   {
     std::size_t buf_len = boost::asio::buffer_size(*i);
     bytes_transferred += buf_len;
     //int ret(fputs(boost::asio::buffer_cast<const char*>(*i), stdout));
     //if (ret == EOF)
     //{
     //  return ::BOOST_CGI_NAMESPACE::error::broken_pipe;
     //}
     //std::cerr<< "[buf] " 
     // << std::string(boost::asio::buffer_cast<const char*>(*i), buf_len)
     // << std::endl;
     if (!std::fwrite(boost::asio::buffer_cast<const void *>(*i)
                    , buf_len, 1, stdout))
     {
       if (std::feof(stdout))
         ec = ::BOOST_CGI_NAMESPACE::error::eof;
       else
       if (std::ferror(stdout))
         ec = ::BOOST_CGI_NAMESPACE::error::bad_write;
       else
         ec = ::BOOST_CGI_NAMESPACE::error::broken_pipe;
     }
   }
   return bytes_transferred;
 }
Ejemplo n.º 3
0
 buffered_handshake_op(stream_base::handshake_type type,
     const ConstBufferSequence& buffers)
   : type_(type),
     buffers_head_(buffers.begin()),
     buffers_end_(buffers.end())
 {
 }
Ejemplo n.º 4
0
typename std::enable_if<
    is_const_buffer_sequence<ConstBufferSequence>::value,
        std::size_t>::type
size_rev_pre(ConstBufferSequence const& buffers)
{
    std::size_t n = 0;
    for(auto it = buffers.end(); it != buffers.begin();)
        n += boost::asio::buffer_size(*--it);
    return n;
}
Ejemplo n.º 5
0
typename std::enable_if<
    is_ConstBufferSequence<ConstBufferSequence>::value,
        std::size_t>::type
size_rev_post(ConstBufferSequence const& buffers)
{
    std::size_t n = 0;
    for(auto it = buffers.end(); it != buffers.begin();)
    {
        it--;
        n += boost::asio::buffer_size(*it);
    }
    return n;
}
Ejemplo n.º 6
0
 void send(const ConstBufferSequence& buffers) {
   for (auto i = buffers.begin(); i != buffers.end(); ++i) {
     size_t buf_size = asio::buffer_size(*i);
     size_t new_size = buf_size + data_size;
     unsigned char* buf = const_cast<unsigned char*>(asio::buffer_cast<const unsigned char*>(*i));
     unsigned char* new_data = new unsigned char[new_size];
     memcpy(new_data, data, data_size);
     memcpy(new_data+data_size, buf, buf_size);
     delete[] data;
     data = new_data;
     data_size = new_size;
   }
 }
Ejemplo n.º 7
0
 std::size_t write_some(ConstBufferSequence& buf
                       , boost::system::error_code& ec)
 {
   ec = boost::system::error_code();
   std::size_t bytes_transferred(0);
   for(typename ConstBufferSequence::const_iterator i = buf.begin(),
       end (buf.end())
      ; !ec && i != end; ++i)
   {
     std::size_t buf_len = boost::asio::buffer_size(*i);
     bytes_transferred += write_some(boost::asio::buffer_cast<const char *>(*i), buf_len, ec);
   }
   return bytes_transferred;
 }
Ejemplo n.º 8
0
typename std::enable_if<
    is_const_buffer_sequence<ConstBufferSequence>::value,
        std::size_t>::type
size_pre(ConstBufferSequence const& buffers)
{
    std::size_t n = 0;
    for(auto it = buffers.begin(); it != buffers.end(); ++it)
    {
        typename ConstBufferSequence::const_iterator it0(std::move(it));
        typename ConstBufferSequence::const_iterator it1(it0);
        typename ConstBufferSequence::const_iterator it2;
        it2 = it1;
        n += boost::asio::buffer_size(*it2);
        it = std::move(it2);
    }
    return n;
}
Ejemplo n.º 9
0
    void
    operator()(error_code& ec, ConstBufferSequence const& buffers) const
    {
        // These asio functions are needed to access a buffer's contents
        using boost::asio::buffer_cast;
        using boost::asio::buffer_size;

        // Error codes must be cleared on success
        ec = {};

        // Keep a running total of how much we wrote
        std::size_t bytes_transferred = 0;

        // Loop over the buffer sequence
        for(auto it = buffers.begin(); it != buffers.end(); ++ it)
        {
            // This is the next buffer in the sequence
            boost::asio::const_buffer const buffer = *it;

            // Write it to the std::ostream
            os_.write(
                buffer_cast<char const*>(buffer),
                buffer_size(buffer));

            // If the std::ostream fails, convert it to an error code
            if(os_.fail())
            {
                ec = make_error_code(errc::io_error);
                return;
            }

            // Adjust our running total
            bytes_transferred += buffer_size(buffer);
        }

        // Inform the serializer of the amount we consumed
        sr_.consume(bytes_transferred);
    }
 // Create an iterator for the specified position.
 const_buffers_iterator(const ConstBufferSequence& buffers,
     std::size_t position)
   : begin_(buffers.begin()),
     current_(buffers.begin()),
     end_(buffers.end()),
     position_(0)
 {
   while (current_ != end_)
   {
     current_buffer_ = *current_;
     std::size_t buffer_size = boost::asio::buffer_size(current_buffer_);
     if (position - position_ < buffer_size)
     {
       current_buffer_position_ = position - position_;
       position_ = position;
       return;
     }
     position_ += buffer_size;
     ++current_;
   }
   current_buffer_ = boost::asio::const_buffer();
   current_buffer_position_ = 0;
 }
Ejemplo n.º 11
0
  void async_write_some_at(implementation_type& impl, boost::uint64_t offset,
      const ConstBufferSequence& buffers, Handler handler)
  {
    if (!is_open(impl))
    {
      this->get_io_service().post(bind_handler(handler,
            boost::asio::error::bad_descriptor, 0));
      return;
    }

    // Update the ID of the thread from which cancellation is safe.
    if (impl.safe_cancellation_thread_id_ == 0)
      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
      impl.safe_cancellation_thread_id_ = ~DWORD(0);

    // Allocate and construct an operation to wrap the handler.
    typedef write_operation<ConstBufferSequence, Handler> value_type;
    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
    raw_handler_ptr<alloc_traits> raw_ptr(handler);
    handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, buffers, handler);

    // Find first buffer of non-zero length.
    boost::asio::const_buffer buffer;
    typename ConstBufferSequence::const_iterator iter = buffers.begin();
    typename ConstBufferSequence::const_iterator end = buffers.end();
    for (DWORD i = 0; iter != end; ++iter, ++i)
    {
      buffer = boost::asio::const_buffer(*iter);
      if (boost::asio::buffer_size(buffer) != 0)
        break;
    }

    // A request to write 0 bytes on a handle is a no-op.
    if (boost::asio::buffer_size(buffer) == 0)
    {
      boost::asio::io_service::work work(this->get_io_service());
      ptr.reset();
      boost::system::error_code error;
      iocp_service_.post(bind_handler(handler, error, 0));
      return;
    }

    // Write the data.
    DWORD bytes_transferred = 0;
    ptr.get()->Offset = offset & 0xFFFFFFFF;
    ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
    BOOL ok = ::WriteFile(impl.handle_,
        boost::asio::buffer_cast<LPCVOID>(buffer),
        static_cast<DWORD>(boost::asio::buffer_size(buffer)),
        &bytes_transferred, ptr.get());
    DWORD last_error = ::GetLastError();

    // Check if the operation completed immediately.
    if (!ok && last_error != ERROR_IO_PENDING)
    {
      boost::asio::io_service::work work(this->get_io_service());
      ptr.reset();
      boost::system::error_code ec(last_error,
          boost::asio::error::get_system_category());
      iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
    }
    else
    {
      ptr.release();
    }
  }
Ejemplo n.º 12
0
  size_t write_some_at(implementation_type& impl, boost::uint64_t offset,
      const ConstBufferSequence& buffers, boost::system::error_code& ec)
  {
    if (!is_open(impl))
    {
      ec = boost::asio::error::bad_descriptor;
      return 0;
    }

    // Find first buffer of non-zero length.
    boost::asio::const_buffer buffer;
    typename ConstBufferSequence::const_iterator iter = buffers.begin();
    typename ConstBufferSequence::const_iterator end = buffers.end();
    for (DWORD i = 0; iter != end; ++iter, ++i)
    {
      buffer = boost::asio::const_buffer(*iter);
      if (boost::asio::buffer_size(buffer) != 0)
        break;
    }

    // A request to write 0 bytes on a handle is a no-op.
    if (boost::asio::buffer_size(buffer) == 0)
    {
      ec = boost::system::error_code();
      return 0;
    }

    overlapped_wrapper overlapped(ec);
    if (ec)
    {
      return 0;
    }

    // Write the data. 
    overlapped.Offset = offset & 0xFFFFFFFF;
    overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
    BOOL ok = ::WriteFile(impl.handle_,
        boost::asio::buffer_cast<LPCVOID>(buffer),
        static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
    if (!ok) 
    {
      DWORD last_error = ::GetLastError();
      if (last_error != ERROR_IO_PENDING)
      {
        ec = boost::system::error_code(last_error,
            boost::asio::error::get_system_category());
        return 0;
      }
    }

    // Wait for the operation to complete.
    DWORD bytes_transferred = 0;
    ok = ::GetOverlappedResult(impl.handle_,
        &overlapped, &bytes_transferred, TRUE);
    if (!ok)
    {
      DWORD last_error = ::GetLastError();
      ec = boost::system::error_code(last_error,
          boost::asio::error::get_system_category());
    }

    ec = boost::system::error_code();
    return bytes_transferred;
  }