C/C++ API Reference
Loading...
Searching...
No Matches
service.h
1// Copyright 2020 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 <cstdint>
17#include <limits>
18
19#include "pw_containers/intrusive_list.h"
20#include "pw_preprocessor/compiler.h"
21#include "pw_rpc/internal/method.h"
22#include "pw_rpc/internal/method_union.h"
23#include "pw_rpc/service_id.h"
24#include "pw_span/span.h"
25
26namespace pw::rpc {
27
29
30// Base class for all RPC services. This cannot be instantiated directly; use a
31// generated subclass instead.
32//
33// Services store a span of concrete method implementation classes. To support
34// different Method implementations, Service stores a base MethodUnion* and the
35// size of the concrete MethodUnion object.
36class Service : public IntrusiveList<Service>::Item {
37 public:
38 Service(const Service&) = delete;
39 Service(Service&&) = delete;
40
41 Service& operator=(const Service&) = delete;
42 Service& operator=(Service&&) = delete;
43
44 ServiceId service_id() const { return internal::WrapServiceId(id_); }
45
46 protected:
47 // Note: despite being non-`::internal` and non-`private`, this constructor
48 // is not considered part of pigweed's public API: calling it requires
49 // constructing `methods`, which must have a `.data()` accessor which returns
50 // a `const internal::MethodUnion*`.
51 template <typename T, size_t kMethodCount>
52 constexpr Service(uint32_t id, const std::array<T, kMethodCount>& methods)
53 : id_(id),
54 methods_(methods.data()),
55 method_size_(sizeof(T)),
56 method_count_(static_cast<uint16_t>(kMethodCount)) {
58 // GCC 10 emits spurious -Wtype-limits warnings for the static_assert.
59 PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wtype-limits");
60 static_assert(kMethodCount <= std::numeric_limits<uint16_t>::max());
62 }
63
64 // For use by tests with only one method.
65 //
66 // Note: This constructor is not for direct use outside of pigweed, and
67 // is not considered part of the public API.
68 template <typename T>
69 constexpr Service(uint32_t id, const T& method)
70 : id_(id), methods_(&method), method_size_(sizeof(T)), method_count_(1) {}
71
72 private:
73 friend class Server;
74 friend class ServiceTestHelper;
75
76 // Finds the method with the provided method_id. Returns nullptr if no match.
77 const internal::Method* FindMethod(uint32_t method_id) const;
78
79 const uint32_t id_;
80 const internal::MethodUnion* const methods_;
81 const uint16_t method_size_;
82 const uint16_t method_count_;
83};
84
86
87} // namespace pw::rpc
Definition: intrusive_list.h:88
Definition: server.h:36
Definition: service.h:36
Definition: service_id.h:35
#define PW_MODIFY_DIAGNOSTICS_POP()
Definition: compiler.h:194
#define PW_MODIFY_DIAGNOSTIC_GCC(kind, option)
Definition: compiler.h:211
#define PW_MODIFY_DIAGNOSTICS_PUSH()
Definition: compiler.h:189