xref: /aosp_15_r20/external/ot-br-posix/src/common/code_utils.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2017, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *    All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *    POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker /**
30*4a64e381SAndroid Build Coastguard Worker  * @file
31*4a64e381SAndroid Build Coastguard Worker  * This file includes utility macros for coding.
32*4a64e381SAndroid Build Coastguard Worker  */
33*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_COMMON_CODE_UTILS_HPP_
34*4a64e381SAndroid Build Coastguard Worker #define OTBR_COMMON_CODE_UTILS_HPP_
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #include "openthread-br/config.h"
37*4a64e381SAndroid Build Coastguard Worker 
38*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_LOG_TAG
39*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "UTILS"
40*4a64e381SAndroid Build Coastguard Worker #endif
41*4a64e381SAndroid Build Coastguard Worker 
42*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
43*4a64e381SAndroid Build Coastguard Worker #include <memory>
44*4a64e381SAndroid Build Coastguard Worker #include <stdlib.h>
45*4a64e381SAndroid Build Coastguard Worker 
46*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
47*4a64e381SAndroid Build Coastguard Worker 
48*4a64e381SAndroid Build Coastguard Worker /**
49*4a64e381SAndroid Build Coastguard Worker  *  This aligns the pointer to @p aAlignType.
50*4a64e381SAndroid Build Coastguard Worker  *
51*4a64e381SAndroid Build Coastguard Worker  *  @param[in] aMem        A pointer to arbitrary memory.
52*4a64e381SAndroid Build Coastguard Worker  *  @param[in] aAlignType  The type to align with and convert the pointer to this type.
53*4a64e381SAndroid Build Coastguard Worker  *
54*4a64e381SAndroid Build Coastguard Worker  *  @returns A pointer to aligned memory.
55*4a64e381SAndroid Build Coastguard Worker  */
56*4a64e381SAndroid Build Coastguard Worker #define OTBR_ALIGNED(aMem, aAlignType) \
57*4a64e381SAndroid Build Coastguard Worker     reinterpret_cast<aAlignType>(      \
58*4a64e381SAndroid Build Coastguard Worker         ((reinterpret_cast<unsigned long>(aMem) + sizeof(aAlignType) - 1) / sizeof(aAlignType)) * sizeof(aAlignType))
59*4a64e381SAndroid Build Coastguard Worker 
60*4a64e381SAndroid Build Coastguard Worker // Allocate the structure using "raw" storage.
61*4a64e381SAndroid Build Coastguard Worker #define OT_DEFINE_ALIGNED_VAR(name, size, align_type) \
62*4a64e381SAndroid Build Coastguard Worker     align_type name[(((size) + (sizeof(align_type) - 1)) / sizeof(align_type))]
63*4a64e381SAndroid Build Coastguard Worker 
64*4a64e381SAndroid Build Coastguard Worker #ifndef CONTAINING_RECORD
65*4a64e381SAndroid Build Coastguard Worker #define BASE 0x1
66*4a64e381SAndroid Build Coastguard Worker #define myoffsetof(s, m) (((size_t) & (((s *)BASE)->m)) - BASE)
67*4a64e381SAndroid Build Coastguard Worker #define CONTAINING_RECORD(address, type, field) ((type *)((uint8_t *)(address)-myoffsetof(type, field)))
68*4a64e381SAndroid Build Coastguard Worker #endif /* CONTAINING_RECORD */
69*4a64e381SAndroid Build Coastguard Worker 
70*4a64e381SAndroid Build Coastguard Worker /**
71*4a64e381SAndroid Build Coastguard Worker  *  This checks for the specified status, which is expected to
72*4a64e381SAndroid Build Coastguard Worker  *  commonly be successful, and branches to the local label 'exit' if
73*4a64e381SAndroid Build Coastguard Worker  *  the status is unsuccessful.
74*4a64e381SAndroid Build Coastguard Worker  *
75*4a64e381SAndroid Build Coastguard Worker  *  @param[in] aStatus  A scalar status to be evaluated against zero (0).
76*4a64e381SAndroid Build Coastguard Worker  */
77*4a64e381SAndroid Build Coastguard Worker #define SuccessOrExit(aStatus, ...) \
78*4a64e381SAndroid Build Coastguard Worker     do                              \
79*4a64e381SAndroid Build Coastguard Worker     {                               \
80*4a64e381SAndroid Build Coastguard Worker         if ((aStatus) != 0)         \
81*4a64e381SAndroid Build Coastguard Worker         {                           \
82*4a64e381SAndroid Build Coastguard Worker             __VA_ARGS__;            \
83*4a64e381SAndroid Build Coastguard Worker             goto exit;              \
84*4a64e381SAndroid Build Coastguard Worker         }                           \
85*4a64e381SAndroid Build Coastguard Worker     } while (false)
86*4a64e381SAndroid Build Coastguard Worker 
87*4a64e381SAndroid Build Coastguard Worker /**
88*4a64e381SAndroid Build Coastguard Worker  * This macro verifies a given error status to be successful (compared against value zero (0)), otherwise, it emits a
89*4a64e381SAndroid Build Coastguard Worker  * given error messages and exits the program.
90*4a64e381SAndroid Build Coastguard Worker  *
91*4a64e381SAndroid Build Coastguard Worker  * @param[in] aStatus   A scalar error status to be evaluated against zero (0).
92*4a64e381SAndroid Build Coastguard Worker  * @param[in] aMessage  A message (text string) to print on failure.
93*4a64e381SAndroid Build Coastguard Worker  */
94*4a64e381SAndroid Build Coastguard Worker #define SuccessOrDie(aStatus, aMessage)                                                   \
95*4a64e381SAndroid Build Coastguard Worker     do                                                                                    \
96*4a64e381SAndroid Build Coastguard Worker     {                                                                                     \
97*4a64e381SAndroid Build Coastguard Worker         if ((aStatus) != 0)                                                               \
98*4a64e381SAndroid Build Coastguard Worker         {                                                                                 \
99*4a64e381SAndroid Build Coastguard Worker             otbrLogEmerg("FAILED %s:%d - %d: %s", __FILE__, __LINE__, aStatus, aMessage); \
100*4a64e381SAndroid Build Coastguard Worker             exit(-1);                                                                     \
101*4a64e381SAndroid Build Coastguard Worker         }                                                                                 \
102*4a64e381SAndroid Build Coastguard Worker     } while (false)
103*4a64e381SAndroid Build Coastguard Worker 
104*4a64e381SAndroid Build Coastguard Worker /**
105*4a64e381SAndroid Build Coastguard Worker  *  This checks for the specified condition, which is expected to
106*4a64e381SAndroid Build Coastguard Worker  *  commonly be true, and both executes @a ... and branches to the
107*4a64e381SAndroid Build Coastguard Worker  *  local label 'exit' if the condition is false.
108*4a64e381SAndroid Build Coastguard Worker  *
109*4a64e381SAndroid Build Coastguard Worker  *  @param[in] aCondition  A Boolean expression to be evaluated.
110*4a64e381SAndroid Build Coastguard Worker  *  @param[in] ...         An expression or block to execute when the
111*4a64e381SAndroid Build Coastguard Worker  *                         assertion fails.
112*4a64e381SAndroid Build Coastguard Worker  */
113*4a64e381SAndroid Build Coastguard Worker #define VerifyOrExit(aCondition, ...) \
114*4a64e381SAndroid Build Coastguard Worker     do                                \
115*4a64e381SAndroid Build Coastguard Worker     {                                 \
116*4a64e381SAndroid Build Coastguard Worker         if (!(aCondition))            \
117*4a64e381SAndroid Build Coastguard Worker         {                             \
118*4a64e381SAndroid Build Coastguard Worker             __VA_ARGS__;              \
119*4a64e381SAndroid Build Coastguard Worker             goto exit;                \
120*4a64e381SAndroid Build Coastguard Worker         }                             \
121*4a64e381SAndroid Build Coastguard Worker     } while (false)
122*4a64e381SAndroid Build Coastguard Worker 
123*4a64e381SAndroid Build Coastguard Worker /**
124*4a64e381SAndroid Build Coastguard Worker  * This macro checks for the specified condition, which is expected to commonly be true,
125*4a64e381SAndroid Build Coastguard Worker  * and both prints the message and terminates the program if the condition is false.
126*4a64e381SAndroid Build Coastguard Worker  *
127*4a64e381SAndroid Build Coastguard Worker  * @param[in] aCondition  The condition to verify
128*4a64e381SAndroid Build Coastguard Worker  * @param[in] aMessage    A message (text string) to print on failure.
129*4a64e381SAndroid Build Coastguard Worker  */
130*4a64e381SAndroid Build Coastguard Worker #define VerifyOrDie(aCondition, aMessage)                                    \
131*4a64e381SAndroid Build Coastguard Worker     do                                                                       \
132*4a64e381SAndroid Build Coastguard Worker     {                                                                        \
133*4a64e381SAndroid Build Coastguard Worker         if (!(aCondition))                                                   \
134*4a64e381SAndroid Build Coastguard Worker         {                                                                    \
135*4a64e381SAndroid Build Coastguard Worker             otbrLogEmerg("FAILED %s:%d - %s", __FILE__, __LINE__, aMessage); \
136*4a64e381SAndroid Build Coastguard Worker             exit(-1);                                                        \
137*4a64e381SAndroid Build Coastguard Worker         }                                                                    \
138*4a64e381SAndroid Build Coastguard Worker     } while (false)
139*4a64e381SAndroid Build Coastguard Worker 
140*4a64e381SAndroid Build Coastguard Worker /**
141*4a64e381SAndroid Build Coastguard Worker  * This macro prints the message and terminates the program.
142*4a64e381SAndroid Build Coastguard Worker  *
143*4a64e381SAndroid Build Coastguard Worker  * @param[in] aMessage    A message (text string) to print.
144*4a64e381SAndroid Build Coastguard Worker  */
145*4a64e381SAndroid Build Coastguard Worker #define DieNow(aMessage)                                                 \
146*4a64e381SAndroid Build Coastguard Worker     do                                                                   \
147*4a64e381SAndroid Build Coastguard Worker     {                                                                    \
148*4a64e381SAndroid Build Coastguard Worker         otbrLogEmerg("FAILED %s:%d - %s", __FILE__, __LINE__, aMessage); \
149*4a64e381SAndroid Build Coastguard Worker         exit(-1);                                                        \
150*4a64e381SAndroid Build Coastguard Worker     } while (false)
151*4a64e381SAndroid Build Coastguard Worker 
152*4a64e381SAndroid Build Coastguard Worker /**
153*4a64e381SAndroid Build Coastguard Worker  *  This unconditionally executes @a ... and branches to the local
154*4a64e381SAndroid Build Coastguard Worker  *  label 'exit'.
155*4a64e381SAndroid Build Coastguard Worker  *
156*4a64e381SAndroid Build Coastguard Worker  *  @note The use of this interface implies neither success nor
157*4a64e381SAndroid Build Coastguard Worker  *        failure for the overall exit status of the enclosing
158*4a64e381SAndroid Build Coastguard Worker  *        function body.
159*4a64e381SAndroid Build Coastguard Worker  *
160*4a64e381SAndroid Build Coastguard Worker  *  @param[in] ...  An optional expression or block to execute
161*4a64e381SAndroid Build Coastguard Worker  *                  when the assertion fails.
162*4a64e381SAndroid Build Coastguard Worker  */
163*4a64e381SAndroid Build Coastguard Worker #define ExitNow(...) \
164*4a64e381SAndroid Build Coastguard Worker     do               \
165*4a64e381SAndroid Build Coastguard Worker     {                \
166*4a64e381SAndroid Build Coastguard Worker         __VA_ARGS__; \
167*4a64e381SAndroid Build Coastguard Worker         goto exit;   \
168*4a64e381SAndroid Build Coastguard Worker     } while (false)
169*4a64e381SAndroid Build Coastguard Worker 
170*4a64e381SAndroid Build Coastguard Worker #define OTBR_NOOP
171*4a64e381SAndroid Build Coastguard Worker #define OTBR_UNUSED_VARIABLE(variable) ((void)(variable))
172*4a64e381SAndroid Build Coastguard Worker 
MakeUnique(Args &&...args)173*4a64e381SAndroid Build Coastguard Worker template <typename T, typename... Args> std::unique_ptr<T> MakeUnique(Args &&...args)
174*4a64e381SAndroid Build Coastguard Worker {
175*4a64e381SAndroid Build Coastguard Worker     return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
176*4a64e381SAndroid Build Coastguard Worker }
177*4a64e381SAndroid Build Coastguard Worker 
178*4a64e381SAndroid Build Coastguard Worker /**
179*4a64e381SAndroid Build Coastguard Worker  * This method converts 8 uint8_t bytes into uint64_t using big-endian.
180*4a64e381SAndroid Build Coastguard Worker  *
181*4a64e381SAndroid Build Coastguard Worker  * @param[in] aValue  The input 8 uint8_t bytes.
182*4a64e381SAndroid Build Coastguard Worker  * @returns The converted uint64_t.
183*4a64e381SAndroid Build Coastguard Worker  */
184*4a64e381SAndroid Build Coastguard Worker uint64_t ConvertOpenThreadUint64(const uint8_t *aValue);
185*4a64e381SAndroid Build Coastguard Worker 
186*4a64e381SAndroid Build Coastguard Worker /**
187*4a64e381SAndroid Build Coastguard Worker  * This class makes any class that derives from it non-copyable. It is intended to be used as a private base class.
188*4a64e381SAndroid Build Coastguard Worker  */
189*4a64e381SAndroid Build Coastguard Worker class NonCopyable
190*4a64e381SAndroid Build Coastguard Worker {
191*4a64e381SAndroid Build Coastguard Worker public:
192*4a64e381SAndroid Build Coastguard Worker     NonCopyable(const NonCopyable &)            = delete;
193*4a64e381SAndroid Build Coastguard Worker     NonCopyable &operator=(const NonCopyable &) = delete;
194*4a64e381SAndroid Build Coastguard Worker 
195*4a64e381SAndroid Build Coastguard Worker protected:
196*4a64e381SAndroid Build Coastguard Worker     NonCopyable(void) = default;
197*4a64e381SAndroid Build Coastguard Worker };
198*4a64e381SAndroid Build Coastguard Worker 
199*4a64e381SAndroid Build Coastguard Worker template <typename T> class Optional
200*4a64e381SAndroid Build Coastguard Worker {
201*4a64e381SAndroid Build Coastguard Worker public:
202*4a64e381SAndroid Build Coastguard Worker     constexpr Optional(void) = default;
203*4a64e381SAndroid Build Coastguard Worker 
Optional(T aValue)204*4a64e381SAndroid Build Coastguard Worker     Optional(T aValue) { SetValue(aValue); }
205*4a64e381SAndroid Build Coastguard Worker 
~Optional(void)206*4a64e381SAndroid Build Coastguard Worker     ~Optional(void) { ClearValue(); }
207*4a64e381SAndroid Build Coastguard Worker 
Optional(const Optional & aOther)208*4a64e381SAndroid Build Coastguard Worker     Optional(const Optional &aOther) { AssignFrom(aOther); }
209*4a64e381SAndroid Build Coastguard Worker 
operator =(const Optional & aOther)210*4a64e381SAndroid Build Coastguard Worker     Optional &operator=(const Optional &aOther) { AssignFrom(aOther); }
211*4a64e381SAndroid Build Coastguard Worker 
operator ->(void) const212*4a64e381SAndroid Build Coastguard Worker     constexpr const T *operator->(void) const { return &GetValue(); }
213*4a64e381SAndroid Build Coastguard Worker 
operator *(void) const214*4a64e381SAndroid Build Coastguard Worker     constexpr const T &operator*(void) const { return GetValue(); }
215*4a64e381SAndroid Build Coastguard Worker 
HasValue(void) const216*4a64e381SAndroid Build Coastguard Worker     constexpr bool HasValue(void) const { return mHasValue; }
217*4a64e381SAndroid Build Coastguard Worker 
218*4a64e381SAndroid Build Coastguard Worker private:
GetValue(void) const219*4a64e381SAndroid Build Coastguard Worker     T &GetValue(void) const
220*4a64e381SAndroid Build Coastguard Worker     {
221*4a64e381SAndroid Build Coastguard Worker         assert(mHasValue);
222*4a64e381SAndroid Build Coastguard Worker         return *const_cast<T *>(reinterpret_cast<const T *>(&mStorage));
223*4a64e381SAndroid Build Coastguard Worker     }
224*4a64e381SAndroid Build Coastguard Worker 
ClearValue(void)225*4a64e381SAndroid Build Coastguard Worker     void ClearValue(void)
226*4a64e381SAndroid Build Coastguard Worker     {
227*4a64e381SAndroid Build Coastguard Worker         if (mHasValue)
228*4a64e381SAndroid Build Coastguard Worker         {
229*4a64e381SAndroid Build Coastguard Worker             GetValue().~T();
230*4a64e381SAndroid Build Coastguard Worker             mHasValue = false;
231*4a64e381SAndroid Build Coastguard Worker         }
232*4a64e381SAndroid Build Coastguard Worker     }
233*4a64e381SAndroid Build Coastguard Worker 
SetValue(const T & aValue)234*4a64e381SAndroid Build Coastguard Worker     void SetValue(const T &aValue)
235*4a64e381SAndroid Build Coastguard Worker     {
236*4a64e381SAndroid Build Coastguard Worker         ClearValue();
237*4a64e381SAndroid Build Coastguard Worker         new (&mStorage) T(aValue);
238*4a64e381SAndroid Build Coastguard Worker         mHasValue = true;
239*4a64e381SAndroid Build Coastguard Worker     }
240*4a64e381SAndroid Build Coastguard Worker 
AssignFrom(const Optional & aOther)241*4a64e381SAndroid Build Coastguard Worker     void AssignFrom(const Optional &aOther)
242*4a64e381SAndroid Build Coastguard Worker     {
243*4a64e381SAndroid Build Coastguard Worker         ClearValue();
244*4a64e381SAndroid Build Coastguard Worker         if (aOther.mHasValue)
245*4a64e381SAndroid Build Coastguard Worker         {
246*4a64e381SAndroid Build Coastguard Worker             SetValue(aOther.GetValue());
247*4a64e381SAndroid Build Coastguard Worker         }
248*4a64e381SAndroid Build Coastguard Worker     }
249*4a64e381SAndroid Build Coastguard Worker 
250*4a64e381SAndroid Build Coastguard Worker     alignas(T) unsigned char mStorage[sizeof(T)];
251*4a64e381SAndroid Build Coastguard Worker     bool mHasValue = false;
252*4a64e381SAndroid Build Coastguard Worker };
253*4a64e381SAndroid Build Coastguard Worker 
254*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_COMMON_CODE_UTILS_HPP_
255