static http::request_data assemble(http::request_data const& data, buffer_type& header) { namespace spirit = boost::spirit; char const sp[] = " "; char const ver[] = "HTTP/"; char const crlf[] = "\r\n"; //! собираем start-line header.insert(header.end(), data.method.begin(), data.method.end()); header.insert(header.end(), sp, sp + sizeof(sp) - 1); header.insert(header.end(), data.uri.begin(), data.uri.end()); header.insert(header.end(), sp, sp + sizeof(sp) - 1); header.insert(header.end(), ver, ver + sizeof(ver) - 1); header.insert(header.end(), data.ver.begin(), data.ver.end()); header.insert(header.end(), crlf, crlf + sizeof(crlf) - 1); //! собираем message-header в плоский буфер detail::assemble(data.hdrs, header); //! разбираем сформированнй буфер и создаем структуру пакета http::request_data req_data; http::request req(&req_data); char const* begin = &header[0]; char const* end = &header[0] + header.size(); spirit::parse_info<> info = spirit::parse(begin, end, req); return req_data; }
void instance::write(execution_unit* ctx, buffer_type& buf, header& hdr, payload_writer* pw) { CAF_LOG_TRACE(CAF_ARG(hdr)); try { if (pw) { auto pos = buf.size(); // write payload first (skip first 72 bytes and write header later) char placeholder[basp::header_size]; buf.insert(buf.end(), std::begin(placeholder), std::end(placeholder)); binary_serializer bs{ctx, buf}; (*pw)(bs); auto plen = buf.size() - pos - basp::header_size; CAF_ASSERT(plen <= std::numeric_limits<uint32_t>::max()); hdr.payload_len = static_cast<uint32_t>(plen); stream_serializer<charbuf> out{ctx, buf.data() + pos, basp::header_size}; out << hdr; } else { binary_serializer bs{ctx, buf}; bs << hdr; } } catch (std::exception& e) { CAF_LOG_ERROR(CAF_ARG(e.what())); } }
/// @pre `n <= buf_.size()` static chunk_type get_chunk(buffer_type& buf, size_t n) { CAF_LOG_TRACE(CAF_ARG(buf) << CAF_ARG(n)); chunk_type xs; if (!buf.empty() && n > 0) { xs.reserve(std::min(n, buf.size())); if (n < buf.size()) { auto first = buf.begin(); auto last = first + static_cast<ptrdiff_t>(n); std::move(first, last, std::back_inserter(xs)); buf.erase(first, last); } else { std::move(buf.begin(), buf.end(), std::back_inserter(xs)); buf.clear(); } } return xs; }
void instance::write(buffer_type& buf, message_type operation, uint32_t* payload_len, uint64_t operation_data, const node_id& source_node, const node_id& dest_node, actor_id source_actor, actor_id dest_actor, payload_writer* pw) { if (! pw) { binary_serializer bs{std::back_inserter(buf), &get_namespace()}; source_node.serialize(bs); dest_node.serialize(bs); bs.write(source_actor) .write(dest_actor) .write(uint32_t{0}) .write(static_cast<uint32_t>(operation)) .write(operation_data); } else { // reserve space in the buffer to write the payload later on auto wr_pos = static_cast<ptrdiff_t>(buf.size()); char placeholder[basp::header_size]; buf.insert(buf.end(), std::begin(placeholder), std::end(placeholder)); auto pl_pos = buf.size(); { // lifetime scope of first serializer (write payload) binary_serializer bs1{std::back_inserter(buf), &get_namespace()}; (*pw)(bs1); } // write broker message to the reserved space binary_serializer bs2{buf.begin() + wr_pos, &get_namespace()}; auto plen = static_cast<uint32_t>(buf.size() - pl_pos); source_node.serialize(bs2); dest_node.serialize(bs2); bs2.write(source_actor) .write(dest_actor) .write(plen) .write(static_cast<uint32_t>(operation)) .write(operation_data); if (payload_len) *payload_len = plen; } }
const_iterator end() const { return buf_.end(); }
iterator end() { return buf_.end(); }
void reset() { cur_ = buf_.begin(); end_ = buf_.end(); }
buffer(Elem const* from, size_t length) : buf_(static_cast<value_type const*>(from), static_cast<value_type const*>(from)+length) , cur_(buf_.begin()) , end_(buf_.end()) { }
buffer(InputIterator begin, InputIterator end) : buf_(begin, end) , cur_(buf_.begin()) , end_(buf_.end()) { }
buffer(Source const& source) : buf_(source.begin(), source.end()) , cur_(buf_.begin()) , end_(buf_.end()) { }
buffer(buffer&& source) : buf_(std::move(source.buf_)) , cur_(buf_.begin()) , end_(buf_.end()) { }
buffer() : buf_() , cur_(buf_.begin()) , end_(buf_.end()) { }
/// fills the buffer using the generator void fill_buffer(buffer_type& buffer) { for (typename buffer_type::iterator it=buffer.begin();it!=buffer.end();++it) *it=generator_(); }