xref: /aosp_15_r20/external/pigweed/pw_bluetooth/public/pw_bluetooth/emboss_util.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include <type_traits>
17 
18 #include "pw_result/result.h"
19 #include "pw_span/span.h"
20 #include "pw_status/status.h"
21 
22 namespace pw::bluetooth {
23 
24 // Create an Emboss view and check that it is Ok().
25 // Returns Status::DataLoss() if the view is not Ok().
26 //
27 // The emboss type is determined by the template's first parameter.
28 template <typename EmbossT, typename... Params>
MakeEmbossView(Params &&...params)29 constexpr inline Result<EmbossT> MakeEmbossView(Params&&... params) {
30   auto view = EmbossT(std::forward<Params>(params)...);
31   if (view.Ok()) {
32     return view;
33   } else {
34     return Status::DataLoss();
35   }
36 }
37 
38 // Create an Emboss View from a pw::span value or reference and check that it is
39 // Ok(). Returns Status::DataLoss() if the view is not Ok().
40 //
41 // The emboss type is determined by the template's first parameter.
42 // Unlike the Emboss `Make*View` creation methods, this function accepts a
43 // reference so it can be used with rvalues. This is ok to do with pw::span
44 // since it doesn't own its underlying data.
45 template <typename EmbossT,
46           typename ContainerT,
47           typename = std::enable_if_t<
48               std::is_convertible_v<ContainerT, pw::span<const uint8_t>>>>
MakeEmbossView(ContainerT && buffer)49 constexpr inline Result<EmbossT> MakeEmbossView(ContainerT&& buffer) {
50   return MakeEmbossView<EmbossT>(buffer.data(), buffer.size());
51 }
52 
53 // Create an Emboss Writer and check that and check that the
54 // backing storage contains at least enough space for MinSizeInBytes().
55 // Returns Status::InvalidArgument() if the buffer isn't large enough for
56 // requested writer.
57 //
58 // The emboss type is determined by the template's first parameter.
59 template <typename EmbossT, typename... Params>
MakeEmbossWriter(Params &&...params)60 constexpr inline Result<EmbossT> MakeEmbossWriter(Params&&... params) {
61   auto view = EmbossT(std::forward<Params>(params)...);
62   if (view.BackingStorage().SizeInBytes() >=
63       static_cast<size_t>(EmbossT::MinSizeInBytes().Read())) {
64     return view;
65   } else {
66     return Status::InvalidArgument();
67   }
68 }
69 
70 // Create an Emboss Writer from a pw::span value or reference and check that the
71 // backing storage contains at least enough space for MinSizeInBytes(). Returns
72 // Status::InvalidArgument() if the buffer isn't large enough for requested
73 // writer.
74 //
75 // The emboss type is determined by the template's first parameter.
76 // Unlike the Emboss `Make*View` creation methods, this function accepts a
77 // reference so it can be used with rvalues. This is ok to do with pw::span
78 // since it doesn't own its underlying data.
79 template <typename EmbossT,
80           typename ContainerT,
81           typename = std::enable_if_t<
82               std::is_convertible_v<ContainerT, pw::span<uint8_t>>>>
MakeEmbossWriter(ContainerT && buffer)83 constexpr inline Result<EmbossT> MakeEmbossWriter(ContainerT&& buffer) {
84   return MakeEmbossWriter<EmbossT>(buffer.data(), buffer.size());
85 }
86 
87 }  // namespace pw::bluetooth
88