CCF
Loading...
Searching...
No Matches
message.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "ds/serialized.h"
6
7#include <arpa/inet.h>
8#include <vector>
9
10namespace ccf::grpc
11{
12 namespace impl
13 {
14 using CompressedFlag = uint8_t;
15 using MessageLength = uint32_t;
16
17 static constexpr size_t message_frame_length =
18 sizeof(CompressedFlag) + sizeof(MessageLength);
19
20 static MessageLength read_message_frame(const uint8_t*& data, size_t& size)
21 {
22 auto compressed_flag = serialized::read<CompressedFlag>(data, size);
23 if (compressed_flag >= 1)
24 {
25 throw std::logic_error(fmt::format(
26 "gRPC compressed flag has unexpected value {} - currently only "
27 "support "
28 "unencoded gRPC payloads",
29 compressed_flag));
30 }
31 return ntohl(serialized::read<MessageLength>(data, size));
32 }
33
34 static void write_message_frame(
35 uint8_t*& data, size_t& size, size_t message_size)
36 {
37 CompressedFlag compressed_flag = 0;
38 serialized::write(data, size, compressed_flag);
39 serialized::write(data, size, htonl(message_size));
40 }
41 }
42
43 template <typename T>
44 static std::vector<uint8_t> serialise_grpc_message(T proto_data)
45 {
46 const auto data_length = proto_data.ByteSizeLong();
47 size_t r_size = ccf::grpc::impl::message_frame_length + data_length;
48 std::vector<uint8_t> msg(r_size);
49 auto r_data = msg.data();
50
51 ccf::grpc::impl::write_message_frame(r_data, r_size, data_length);
52
53 if (!proto_data.SerializeToArray(r_data, r_size))
54 {
55 throw std::logic_error(fmt::format(
56 "Error serialising protobuf object of type {}, size {}",
57 proto_data.GetTypeName(),
58 data_length));
59 }
60 return msg;
61 }
62
63 template <typename T>
64 static std::vector<uint8_t> serialise_grpc_messages(
65 const std::vector<T>& proto_data)
66 {
67 size_t r_size = std::accumulate(
68 proto_data.begin(),
69 proto_data.end(),
70 0,
71 [](size_t current, const T& data) {
72 return current + impl::message_frame_length + data.ByteSizeLong();
73 });
74 std::vector<uint8_t> msgs(r_size);
75 auto r_data = msgs.data();
76
77 for (const T& d : proto_data)
78 {
79 const auto data_length = d.ByteSizeLong();
80 impl::write_message_frame(r_data, r_size, data_length);
81
82 if (!d.SerializeToArray(r_data, r_size))
83 {
84 throw std::logic_error(fmt::format(
85 "Error serialising protobuf object of type {}, size {}",
86 d.GetTypeName(),
87 data_length));
88 }
89
90 r_data += data_length;
91 r_size += data_length;
92 }
93
94 return msgs;
95 }
96}
uint8_t CompressedFlag
Definition message.h:14
uint32_t MessageLength
Definition message.h:15
Definition grpc_status.h:98
void write(uint8_t *&data, size_t &size, const T &v)
Definition serialized.h:106