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