1 //
2 // Copyright 2017 The Abseil Authors.
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 // https://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
17 #ifndef ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
18 #define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
19
20 #include <string.h>
21
22 #include <cstdint>
23
24 #include "absl/base/attributes.h"
25 #include "absl/base/config.h"
26 #include "absl/base/nullability.h"
27
28 // unaligned APIs
29
30 // Portable handling of unaligned loads, stores, and copies.
31
32 // The unaligned API is C++ only. The declarations use C++ features
33 // (namespaces, inline) which are absent or incompatible in C.
34 #if defined(__cplusplus)
35 namespace absl {
36 ABSL_NAMESPACE_BEGIN
37 namespace base_internal {
38
UnalignedLoad16(absl::Nonnull<const void * > p)39 inline uint16_t UnalignedLoad16(absl::Nonnull<const void *> p) {
40 uint16_t t;
41 memcpy(&t, p, sizeof t);
42 return t;
43 }
44
UnalignedLoad32(absl::Nonnull<const void * > p)45 inline uint32_t UnalignedLoad32(absl::Nonnull<const void *> p) {
46 uint32_t t;
47 memcpy(&t, p, sizeof t);
48 return t;
49 }
50
UnalignedLoad64(absl::Nonnull<const void * > p)51 inline uint64_t UnalignedLoad64(absl::Nonnull<const void *> p) {
52 uint64_t t;
53 memcpy(&t, p, sizeof t);
54 return t;
55 }
56
UnalignedStore16(absl::Nonnull<void * > p,uint16_t v)57 inline void UnalignedStore16(absl::Nonnull<void *> p, uint16_t v) {
58 memcpy(p, &v, sizeof v);
59 }
60
UnalignedStore32(absl::Nonnull<void * > p,uint32_t v)61 inline void UnalignedStore32(absl::Nonnull<void *> p, uint32_t v) {
62 memcpy(p, &v, sizeof v);
63 }
64
UnalignedStore64(absl::Nonnull<void * > p,uint64_t v)65 inline void UnalignedStore64(absl::Nonnull<void *> p, uint64_t v) {
66 memcpy(p, &v, sizeof v);
67 }
68
69 } // namespace base_internal
70 ABSL_NAMESPACE_END
71 } // namespace absl
72
73 #define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
74 (absl::base_internal::UnalignedLoad16(_p))
75 #define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
76 (absl::base_internal::UnalignedLoad32(_p))
77 #define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
78 (absl::base_internal::UnalignedLoad64(_p))
79
80 #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
81 (absl::base_internal::UnalignedStore16(_p, _val))
82 #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
83 (absl::base_internal::UnalignedStore32(_p, _val))
84 #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
85 (absl::base_internal::UnalignedStore64(_p, _val))
86
87 #endif // defined(__cplusplus), end of unaligned API
88
89 #endif // ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_
90