Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
Loading...
Searching...
No Matches
endian_ops.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Roc Streaming authors
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 */
8
9//! @file roc_core/endian_ops.h
10//! @brief Endian operations.
11
12#ifndef ROC_CORE_ENDIAN_OPS_H_
13#define ROC_CORE_ENDIAN_OPS_H_
14
15#include "roc_core/cpu_traits.h"
16#include "roc_core/stddefs.h"
17
18namespace roc {
19namespace core {
20
21//! Endian operations.
22class EndianOps {
23public:
24 //! Swap between endians.
25 template <class T> static inline T swap_endian(T v) {
26 return reverse_octets_(v);
27 }
28
29#if ROC_CPU_BIG_ENDIAN
30 //! Swap between native endian and big endian.
31 template <class T> static inline T swap_native_be(T v) {
32 return v;
33 }
34#else
35 //! Swap between native endian and big endian.
36 template <class T> static inline T swap_native_be(T v) {
37 return reverse_octets_(v);
38 }
39#endif
40
41#if ROC_CPU_BIG_ENDIAN
42 //! Swap between native endian and little endian.
43 template <class T> static inline T swap_native_le(T v) {
44 return reverse_octets_(v);
45 }
46#else
47 //! Swap between native endian and little endian.
48 template <class T> static inline T swap_native_le(T v) {
49 return v;
50 }
51#endif
52
53private:
54 static inline uint8_t reverse_octets_(uint8_t v) {
55 return v;
56 }
57
58 static inline int8_t reverse_octets_(int8_t v) {
59 return v;
60 }
61
62 static inline uint16_t reverse_octets_(uint16_t v) {
63 return uint16_t((v >> 8) & 0xffu) | uint16_t((v & 0xffu) << 8);
64 }
65
66 static inline int16_t reverse_octets_(int16_t v) {
67 return (int16_t)reverse_octets_((uint16_t)v);
68 }
69
70 static inline uint32_t reverse_octets_(uint32_t v) {
71 return (((v & 0xff000000u) >> 24) | ((v & 0x00ff0000u) >> 8)
72 | ((v & 0x0000ff00u) << 8) | ((v & 0x000000ffu) << 24));
73 }
74
75 static inline int32_t reverse_octets_(int32_t v) {
76 return (int32_t)reverse_octets_((uint32_t)v);
77 }
78
79 static inline uint64_t reverse_octets_(uint64_t v) {
80 return ((v & 0x00000000ffffffffu) << 32) | ((v & 0xffffffff00000000u) >> 32)
81 | ((v & 0x0000ffff0000ffffu) << 16) | ((v & 0xffff0000ffff0000u) >> 16)
82 | ((v & 0x00ff00ff00ff00ffu) << 8) | ((v & 0xff00ff00ff00ff00u) >> 8);
83 }
84
85 static inline int64_t reverse_octets_(int64_t v) {
86 return (int64_t)reverse_octets_((uint64_t)v);
87 }
88
89 template <class T> static inline T reverse_octets_(T v) {
90 enum { NumOctets = sizeof(T) };
91
92 union {
93 T value;
94 char octets[sizeof(T)];
95 } u;
96
97 u.value = v;
98
99 switch (NumOctets) {
100 case 0:
101 case 1:
102 break;
103
104 case 2:
105 std::swap(u.octets[0], u.octets[1]);
106 break;
107
108 case 3:
109 std::swap(u.octets[0], u.octets[2]);
110 break;
111
112 case 4:
113 std::swap(u.octets[0], u.octets[3]);
114 std::swap(u.octets[1], u.octets[2]);
115 break;
116
117 case 5:
118 std::swap(u.octets[0], u.octets[4]);
119 std::swap(u.octets[1], u.octets[3]);
120 break;
121
122 case 6:
123 std::swap(u.octets[0], u.octets[5]);
124 std::swap(u.octets[1], u.octets[4]);
125 std::swap(u.octets[2], u.octets[3]);
126 break;
127
128 case 7:
129 std::swap(u.octets[0], u.octets[6]);
130 std::swap(u.octets[1], u.octets[5]);
131 std::swap(u.octets[2], u.octets[4]);
132 break;
133
134 case 8:
135 std::swap(u.octets[0], u.octets[7]);
136 std::swap(u.octets[1], u.octets[6]);
137 std::swap(u.octets[2], u.octets[5]);
138 std::swap(u.octets[3], u.octets[4]);
139 break;
140
141 default:
142 for (size_t n = 0; n < NumOctets / 2; n++) {
143 std::swap(u.octets[n], u.octets[NumOctets - n - 1]);
144 }
145 break;
146 }
147
148 return v;
149 }
150};
151
152} // namespace core
153} // namespace roc
154
155#endif // ROC_CORE_ENDIAN_OPS_H_
Endian operations.
Definition endian_ops.h:22
static T swap_native_be(T v)
Swap between native endian and big endian.
Definition endian_ops.h:36
static T swap_native_le(T v)
Swap between native endian and little endian.
Definition endian_ops.h:48
static T swap_endian(T v)
Swap between endians.
Definition endian_ops.h:25
Root namespace.
Commonly used types and functions.