Android-cuttlefish cvd tool
msg_formatting.h
Go to the documentation of this file.
1/*
2 *
3 * Copyright 2017, The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef TEEUI_MSG_FORMATTING_H_
19#define TEEUI_MSG_FORMATTING_H_
20
21#include <algorithm>
22#include <stddef.h>
23#include <stdint.h>
24#include <tuple>
25#include <type_traits>
26#include <utility>
27
28#include <teeui/utils.h>
29
30namespace teeui {
31namespace msg {
32
33template <typename... fields> class Message {};
34
35template <size_t... idx, typename... T>
36std::tuple<std::remove_reference_t<T>&&...> tuple_move_helper(std::index_sequence<idx...>,
37 std::tuple<T...>&& t) {
38 return {std::move(std::get<idx>(t))...};
39}
40
41template <typename... T>
42std::tuple<std::remove_reference_t<T>&&...> tuple_move(std::tuple<T...>&& t) {
43 return tuple_move_helper(std::make_index_sequence<sizeof...(T)>(), std::move(t));
44}
45
46template <typename... T>
47std::tuple<std::remove_reference_t<T>&&...> tuple_move(std::tuple<T...>& t) {
48 return tuple_move_helper(std::make_index_sequence<sizeof...(T)>(), std::move(t));
49}
50
51void zero(volatile uint8_t* begin, const volatile uint8_t* end);
52
53template <typename T> class StreamState {
54 public:
55 static_assert(
56 sizeof(T) == 1,
57 "StreamState must be instantiated with 1 byte sized type, e.g., uint8_t or const uint8_t.");
58 using ptr_t = T*;
59 template <size_t size>
60 StreamState(T (&buffer)[size]) : begin_(&buffer[0]), end_(&buffer[size]), pos_(begin_) {}
61 StreamState(T* buffer, size_t size) : begin_(buffer), end_(buffer + size), pos_(begin_) {}
62 StreamState() : begin_(nullptr), end_(nullptr), pos_(nullptr) {}
63 StreamState& operator+=(size_t offset) {
64 auto good_ = pos_ != nullptr && pos_ + offset <= end_;
65 if (good_) {
66 pos_ += offset;
67 } else {
68 pos_ = nullptr;
69 }
70 return *this;
71 }
72
73 operator bool() const { return pos_ != nullptr; }
74 ptr_t pos() const { return pos_; };
75
76 template <typename U = T>
77 bool insertFieldSize(typename std::enable_if<!std::is_const<U>::value, uint32_t>::type size) {
78 // offset to the nearest n * 8 + 4 boundary from beginning of the buffer! (not memory).
79 uintptr_t pos = pos_ - begin_;
80 auto offset = (((pos + 11UL) & ~7UL) - 4UL) - pos;
81 if (*this += offset + sizeof(size)) {
82 // zero out the gaps
83 zero(pos_ - offset - sizeof(size), pos_ - sizeof(size));
84 *reinterpret_cast<uint32_t*>(pos_ - sizeof(size)) = size;
85 return true;
86 }
87 return false;
88 }
89
90 template <typename U = T>
91 typename std::enable_if<std::is_const<U>::value, uint32_t>::type extractFieldSize() {
92 // offset to the nearest n * 8 + 4 boundary from beginning of the buffer! (not memory).
93 uintptr_t pos = pos_ - begin_;
94 auto offset = (((pos + 11UL) & ~7UL) - 4UL) - pos;
95 if (*this += offset + sizeof(uint32_t)) {
96 return *reinterpret_cast<const uint32_t*>(pos_ - sizeof(uint32_t));
97 }
98 return 0;
99 }
100
101 void bad() { pos_ = nullptr; };
102
103 private:
107};
108
111
112inline void zero(const volatile uint8_t*, const volatile uint8_t*) {}
115// template <typename T>
116// StreamState<T> unalign(StreamState<T> s) {
117// auto result = s;
118// auto offset = (((uintptr_t(s.pos_) + 11UL) & ~7UL) - 4UL) - uintptr_t(s.pos_);
119// result += offset;
120// // zero out the gaps when writing
121// if (result) zero(s.pos_, result.pos_);
122// return result;
123//}
124
125WriteStream write(WriteStream out, const uint8_t* buffer, uint32_t size);
126
127template <uint32_t size> WriteStream write(WriteStream out, const uint8_t (&v)[size]) {
128 return write(out, v, size);
129}
130
131std::tuple<ReadStream, ReadStream::ptr_t, uint32_t> read(ReadStream in);
132
133template <typename T> std::tuple<ReadStream, T> readSimpleType(ReadStream in) {
134 auto [in_, pos, size] = read(in);
135 T result = {};
136 if (in_ && size == sizeof(T))
137 result = *reinterpret_cast<const T*>(pos);
138 else
139 in_.bad();
140 return {in_, result};
141}
142
144 return out;
145}
146
147template <typename Head, typename... Tail>
148WriteStream write(Message<Head, Tail...>, WriteStream out, const Head& head, const Tail&... tail) {
149 out = write(out, head);
150 return write(Message<Tail...>(), out, tail...);
151}
152
153template <typename... Msg> std::tuple<ReadStream, Msg...> read(Message<Msg...>, ReadStream in) {
154 return {in, [&in]() -> Msg {
155 Msg result;
156 std::tie(in, result) = read(Message<Msg>(), in);
157 return result;
158 }()...};
159}
160
161template <typename T> struct msg2tuple {};
162
163template <typename... T> struct msg2tuple<Message<T...>> { using type = std::tuple<T...>; };
164
165template <typename T> using msg2tuple_t = typename msg2tuple<T>::type;
166
167template <size_t first_idx, size_t... idx, typename HEAD, typename... T>
168std::tuple<T&&...> tuple_tail(std::index_sequence<first_idx, idx...>, std::tuple<HEAD, T...>&& t) {
169 return {std::move(std::get<idx>(t))...};
170}
171
172template <size_t first_idx, size_t... idx, typename HEAD, typename... T>
173std::tuple<const T&...> tuple_tail(std::index_sequence<first_idx, idx...>,
174 const std::tuple<HEAD, T...>& t) {
175 return {std::get<idx>(t)...};
176}
177
178template <typename HEAD, typename... Tail>
179std::tuple<Tail&&...> tuple_tail(std::tuple<HEAD, Tail...>&& t) {
180 return tuple_tail(std::make_index_sequence<sizeof...(Tail) + 1>(), std::move(t));
181}
182
183template <typename HEAD, typename... Tail>
184std::tuple<const Tail&...> tuple_tail(const std::tuple<HEAD, Tail...>& t) {
185 return tuple_tail(std::make_index_sequence<sizeof...(Tail) + 1>(), t);
186}
187
188} // namespace msg
189
190using msg::Message;
191using msg::msg2tuple;
192using msg::msg2tuple_t;
193using msg::read;
195using msg::ReadStream;
196using msg::tuple_tail;
197using msg::write;
198using msg::WriteStream;
199
200} // namespace teeui
201
202#endif // TEEUI_MSG_FORMATTING_H_
Definition: msg_formatting.h:33
Definition: msg_formatting.h:53
StreamState(T *buffer, size_t size)
Definition: msg_formatting.h:61
ptr_t pos() const
Definition: msg_formatting.h:74
void bad()
Definition: msg_formatting.h:101
StreamState & operator+=(size_t offset)
Definition: msg_formatting.h:63
StreamState()
Definition: msg_formatting.h:62
ptr_t end_
Definition: msg_formatting.h:105
std::enable_if< std::is_const< U >::value, uint32_t >::type extractFieldSize()
Definition: msg_formatting.h:91
T * ptr_t
Definition: msg_formatting.h:58
StreamState(T(&buffer)[size])
Definition: msg_formatting.h:60
ptr_t begin_
Definition: msg_formatting.h:104
bool insertFieldSize(typename std::enable_if<!std::is_const< U >::value, uint32_t >::type size)
Definition: msg_formatting.h:77
ptr_t pos_
Definition: msg_formatting.h:106
uint32_t size
Definition: io.h:2
std::vector< std::uint8_t > Message
Definition: tcp_socket.h:30
std::tuple< ReadStream, MsgVector< uint8_t > > read(Message< MsgVector< uint8_t > >, ReadStream in)
Definition: common_message_types.h:127
typename msg2tuple< T >::type msg2tuple_t
Definition: msg_formatting.h:165
std::tuple< std::remove_reference_t< T > &&... > tuple_move(std::tuple< T... > &&t)
Definition: msg_formatting.h:42
WriteStream write(WriteStream out, const MsgVector< uint8_t > &v)
Definition: common_message_types.h:130
std::tuple< T &&... > tuple_tail(std::index_sequence< first_idx, idx... >, std::tuple< HEAD, T... > &&t)
Definition: msg_formatting.h:168
std::tuple< ReadStream, T > readSimpleType(ReadStream in)
Definition: msg_formatting.h:133
void zero(volatile uint8_t *begin, const volatile uint8_t *end)
StreamState< const uint8_t > ReadStream
Definition: msg_formatting.h:110
std::tuple< std::remove_reference_t< T > &&... > tuple_move_helper(std::index_sequence< idx... >, std::tuple< T... > &&t)
Definition: msg_formatting.h:36
StreamState< uint8_t > WriteStream
Definition: msg_formatting.h:109
Definition: layout.h:28
uint8_t type
Definition: pairing_connection.h:0
std::tuple< T... > type
Definition: msg_formatting.h:163
Definition: msg_formatting.h:161