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())); } }
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(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; } }