1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #pragma once
17 
18 #include <inttypes.h>
19 
20 #include <android-base/endian.h>
21 
22 // The utilities in android-base/endian.h still require the use of regular int
23 // types to store values with any endianness, which requires the user to
24 // remember to manually do the required conversions, which is prone to errors.
25 // The types introduced here allow handling these values safely.
26 
27 namespace cuttlefish {
28 
29 #define DECLARE_TYPE(new_type, base_type, to_new, to_base)                \
30   class new_type {                                                        \
31    public:                                                                \
32     new_type() = default;                                                 \
33     explicit new_type(base_type val) : inner_(to_new(val)) {}             \
34     new_type(const new_type&) = default;                                  \
35     new_type& operator=(const new_type& other) = default;                 \
36     volatile new_type& operator=(const new_type& other) volatile {        \
37       inner_ = other.inner_;                                              \
38       return *this;                                                       \
39     }                                                                     \
40     base_type as_##base_type() const volatile { return to_base(inner_); } \
41                                                                           \
42    private:                                                               \
43     base_type inner_;                                                     \
44   };                                                                      \
45   static_assert(sizeof(new_type) == sizeof(base_type))
46 
47 DECLARE_TYPE(Le16, uint16_t, htole16, le16toh);
48 DECLARE_TYPE(Le32, uint32_t, htole32, le32toh);
49 DECLARE_TYPE(Le64, uint64_t, htole64, le64toh);
50 DECLARE_TYPE(Be16, uint16_t, htobe16, be16toh);
51 DECLARE_TYPE(Be32, uint32_t, htobe32, be32toh);
52 DECLARE_TYPE(Be64, uint64_t, htobe64, be64toh);
53 
54 #undef DECLARE_TYPE
55 
56 }  // namespace cuttlefish