BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_byteorder.h
Go to the documentation of this file.
1/// @file bsls_byteorder.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_byteorder.h -*-C++-*-
8#ifndef INCLUDED_BSLS_BYTEORDER
9#define INCLUDED_BSLS_BYTEORDER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_byteorder bsls_byteorder
15/// @brief Provide byte-order manipulation macros.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_byteorder
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_byteorder-purpose"> Purpose</a>
25/// * <a href="#bsls_byteorder-classes"> Classes </a>
26/// * <a href="#bsls_byteorder-macros"> Macros </a>
27/// * <a href="#bsls_byteorder-description"> Description </a>
28/// * <a href="#bsls_byteorder-usage"> Usage </a>
29///
30/// # Purpose {#bsls_byteorder-purpose}
31/// Provide byte-order manipulation macros.
32///
33/// # Classes {#bsls_byteorder-classes}
34///
35///
36/// @see bsls_byteorderutil
37///
38/// # Macros {#bsls_byteorder-macros}
39///
40/// - BSLS_BYTEORDER_HTON(x): Convert value from host to network order
41/// - BSLS_BYTEORDER_HTONS(x): Convert 16-bit value from host to network order
42/// - BSLS_BYTEORDER_HTONL(x): Convert 32-bit value from host to network order
43/// - BSLS_BYTEORDER_HTONLL(x): Convert 64-bit value from host to network order
44/// - BSLS_BYTEORDER_NTOH(x): Convert value from network to host order
45/// - BSLS_BYTEORDER_NTOHS(x): Convert 16-bit value from network to host order
46/// - BSLS_BYTEORDER_NTOHL(x): Convert 32-bit value from network to host order
47/// - BSLS_BYTEORDER_NTOHLL(x): Convert 64-bit value from network to host order
48/// - ---
49/// - BSLS_BYTEORDER_HTON_CONSTANT(x): static host to network order
50/// - BSLS_BYTEORDER_HTONS_CONSTANT(x): static 16-bit network to host order
51/// - BSLS_BYTEORDER_HTONL_CONSTANT(x): static 32-bit network to host order
52/// - BSLS_BYTEORDER_HTONLL_CONSTANT(x): static 64-bit network to host order
53/// - BSLS_BYTEORDER_NTOH_CONSTANT(x): static network to host order
54/// - BSLS_BYTEORDER_NTOHS_CONSTANT(x): static 16-bit network to host order
55/// - BSLS_BYTEORDER_NTOHL_CONSTANT(x): static 32-bit network to host order
56/// - BSLS_BYTEORDER_NTOHLL_CONSTANT(x): static 64-bit network to host order
57/// - ---
58/// - BSLS_BYTEORDER_LE_TO_HOST(x): little-endian to host-endian
59/// - BSLS_BYTEORDER_LE_U16_TO_HOST(x): 16-bit little-endian to host-endian
60/// - BSLS_BYTEORDER_LE_U32_TO_HOST(x): 32-bit little-endian to host-endian
61/// - BSLS_BYTEORDER_LE_U64_TO_HOST(x): 64-bit little-endian to host-endian
62/// - BSLS_BYTEORDER_BE_TO_HOST(x): big-endian to host-endian
63/// - BSLS_BYTEORDER_BE_U16_TO_HOST(x): 16-bit big-endian to host-endian
64/// - BSLS_BYTEORDER_BE_U32_TO_HOST(x): 32-bit big-endian to host-endian
65/// - BSLS_BYTEORDER_BE_U64_TO_HOST(x): 64-bit big-endian to host-endian
66/// - ---
67/// - BSLS_BYTEORDER_HOST_TO_LE(x): host-endian to little-endian
68/// - BSLS_BYTEORDER_HOST_U16_TO_LE(x): 16-bit host-endian to little-endian
69/// - BSLS_BYTEORDER_HOST_U32_TO_LE(x): 32-bit host-endian to little-endian
70/// - BSLS_BYTEORDER_HOST_U64_TO_LE(x): 64-bit host-endian to little-endian
71/// - BSLS_BYTEORDER_HOST_TO_BE(x): host-endian to big-endian
72/// - BSLS_BYTEORDER_HOST_U16_TO_BE(x): 16-bit host-endian to big-endian
73/// - BSLS_BYTEORDER_HOST_U32_TO_BE(x): 32-bit host-endian to big-endian
74/// - BSLS_BYTEORDER_HOST_U64_TO_BE(x): 64-bit host-endian to big-endian
75///
76/// # Description {#bsls_byteorder-description}
77/// This component provides a set of byte-order manipulation macros
78/// that replace the standard `htonl`, `htons`, `ntohl`, and `ntohs` functions,
79/// and which do not require including any system header files:
80/// @code
81/// BSLS_BYTEORDER_HTON(x)
82/// BSLS_BYTEORDER_HTONS(x)
83/// BSLS_BYTEORDER_HTONL(x)
84/// BSLS_BYTEORDER_HTONLL(x)
85/// BSLS_BYTEORDER_NTOH(x)
86/// BSLS_BYTEORDER_NTOHS(x)
87/// BSLS_BYTEORDER_NTOHL(x)
88/// BSLS_BYTEORDER_NTOHLL(x)
89/// @endcode
90/// The "S", "L", and "LL" suffices in the names of the above macros indicate
91/// their applicability to 16-bit (`short`), 32-bit (`int`, *not* `long`), and
92/// 64-bit (`long long`) values, respectively.
93///
94/// The macros without "S", "L", or "LL" suffices in their names indicate that
95/// they take the word size to be swapped from the word size of `x`, and return
96/// a value of the same type as `x`. These should only be passed fundamental
97/// integral types, and not `enum` values, as the sizes of `enum` values are
98/// implementation defined.
99///
100/// This set of host-to-network and network-to-host conversion macros are very
101/// efficient, but sacrifices the ability to perform compile-time
102/// initialization. To compensate, the following set of functionally equivalent
103/// "CONSTANT" macros are provided. These macros can be used for compile-time
104/// initialization, but are less efficient than non-"CONSTANT" versions:
105/// @code
106/// BSLS_BYTEORDER_HTONS_CONSTANT(x)
107/// BSLS_BYTEORDER_HTONL_CONSTANT(x)
108/// BSLS_BYTEORDER_HTONLL_CONSTANT(x)
109/// BSLS_BYTEORDER_NTOHS_CONSTANT(x)
110/// BSLS_BYTEORDER_NTOHL_CONSTANT(x)
111/// BSLS_BYTEORDER_NTOHLL_CONSTANT(x)
112/// @endcode
113/// Another set of macros provides conversion from big-endian or little-endian
114/// byte order to host-endian order. The macros take 16-, 32- or 64-bit values
115/// and perform the indicated byte-order conversion on those values:
116/// @code
117/// BSLS_BYTEORDER_LE_TO_HOST(x)
118/// BSLS_BYTEORDER_LE_U16_TO_HOST(x)
119/// BSLS_BYTEORDER_LE_U32_TO_HOST(x)
120/// BSLS_BYTEORDER_LE_U64_TO_HOST(x)
121/// BSLS_BYTEORDER_BE_TO_HOST(x)
122/// BSLS_BYTEORDER_BE_U16_TO_HOST(x)
123/// BSLS_BYTEORDER_BE_U32_TO_HOST(x)
124/// BSLS_BYTEORDER_BE_U64_TO_HOST(x)
125/// @endcode
126/// The "LE" and "BE" embedded in the above macro names indicate Little-Endian
127/// and Big-Endian, respectively.
128///
129/// Finally, a complementary set of macros provides conversion from host-endian
130/// byte order to big-endian or little-endian order:
131/// @code
132/// BSLS_BYTEORDER_HOST_TO_LE(x)
133/// BSLS_BYTEORDER_HOST_U16_TO_LE(x)
134/// BSLS_BYTEORDER_HOST_U32_TO_LE(x)
135/// BSLS_BYTEORDER_HOST_U64_TO_LE(x)
136/// BSLS_BYTEORDER_HOST_TO_BE(x)
137/// BSLS_BYTEORDER_HOST_U16_TO_BE(x)
138/// BSLS_BYTEORDER_HOST_U32_TO_BE(x)
139/// BSLS_BYTEORDER_HOST_U64_TO_BE(x)
140/// @endcode
141///
142/// ## Usage {#bsls_byteorder-usage}
143///
144///
145/// To use these macros, simply pass a 16-, 32-, or 64-bit value to the macros.
146/// To demonstrate the change in byte order effected by the macros, we first
147/// write a function to print, in hex, a character buffer of a specified size:
148/// @code
149/// void printHex(const char *c, int size)
150/// // Print the specified character array 'c', having the specified 'size'
151/// // (in bytes), to 'stdout' in hex.
152/// {
153/// const char *hex = "0123456789abcdef";
154/// for (int i = 0; i < size; ++i) {
155/// std::cout << hex[(c[i] >> 4) & 0xf]
156/// << hex[ c[i] & 0xf];
157/// }
158/// }
159///
160/// template <class T>
161/// void printHex(T x)
162/// // Print the specified object 'x' of parameterized type 'T' in hex.
163/// {
164/// printHex((const char*)&x, sizeof x);
165/// }
166/// @endcode
167/// For example, to use the little-endian/big-endian to host-endian macros:
168/// @code
169/// short x = static_cast<short>(0xabcd);
170/// int y = 0xabcdef12;
171/// bsls::Types::Int64 z = 0xabcdef1234567890LL;
172///
173/// // Note the use of macros within the calls to 'printHex'.
174///
175/// printf("\nLE to Host(x): ");
176/// printHex(BSLS_BYTEORDER_LE_U16_TO_HOST(x));
177///
178/// printf("\nLE to Host(y): ");
179/// printHex(BSLS_BYTEORDER_LE_U32_TO_HOST(y));
180///
181/// printf("\nLE to Host(z): ");
182/// printHex(BSLS_BYTEORDER_LE_U64_TO_HOST(z));
183///
184/// printf("\nBE to Host(x): ");
185/// printHex(BSLS_BYTEORDER_BE_U16_TO_HOST(x));
186///
187/// printf("\nBE to Host(y): ");
188/// printHex(BSLS_BYTEORDER_BE_U32_TO_HOST(y));
189///
190/// printf("\nBE to Host(z): ");
191/// printHex(BSLS_BYTEORDER_BE_U64_TO_HOST(z));
192/// @endcode
193/// On little-endian machines (e.g., x86, IA64), this will print the following
194/// to `stdout`:
195/// @code
196/// LE to Host(x): abcd
197/// LE to Host(y): abcdef12
198/// LE to Host(z): abcdef1234567890
199/// BE to Host(x): cdab
200/// BE to Host(y): 12efcdab
201/// BE to Host(z): 9078563412efcdab
202/// @endcode
203/// On big-endian machines (e.g., sparc, powerpc), the following will be printed
204/// instead:
205/// @code
206/// LE to Host(x): cdab
207/// LE to Host(y): 12efcdab
208/// LE to Host(z): 9078563412efcdab
209/// BE to Host(x): abcd
210/// BE to Host(y): abcdef12
211/// BE to Host(z): abcdef1234567890
212/// @endcode
213/// The other macros can be used in a similar manner.
214/// @}
215/** @} */
216/** @} */
217
218/** @addtogroup bsl
219 * @{
220 */
221/** @addtogroup bsls
222 * @{
223 */
224/** @addtogroup bsls_byteorder
225 * @{
226 */
227
228#include <bsls_byteorderutil.h>
229#include <bsls_platform.h>
230
231// ============================================================================
232// MACROS
233// ======
234
235// STANDARD NETWORK AND HOST CONVERSIONS
236
237#if defined(BSLS_PLATFORM_IS_BIG_ENDIAN)
238
239#define BSLS_BYTEORDER_NTOH(x) (x)
240#define BSLS_BYTEORDER_NTOHS(x) (x)
241#define BSLS_BYTEORDER_NTOHL(x) (x)
242#define BSLS_BYTEORDER_NTOHLL(x) (x)
243
244#define BSLS_BYTEORDER_HTON(x) (x)
245#define BSLS_BYTEORDER_HTONS(x) (x)
246#define BSLS_BYTEORDER_HTONL(x) (x)
247#define BSLS_BYTEORDER_HTONLL(x) (x)
248
249#define BSLS_BYTEORDER_NTOHS_CONSTANT(x) (x)
250#define BSLS_BYTEORDER_NTOHL_CONSTANT(x) (x)
251#define BSLS_BYTEORDER_NTOHLL_CONSTANT(x) (x)
252
253#define BSLS_BYTEORDER_HTONS_CONSTANT(x) (x)
254#define BSLS_BYTEORDER_HTONL_CONSTANT(x) (x)
255#define BSLS_BYTEORDER_HTONLL_CONSTANT(x) (x)
256
257#else // BSLS_PLATFORM_IS_LITTLE_ENDIAN
258
259#define BSLS_BYTEORDER_NTOH(x) BloombergLP::bsls::ByteOrderUtil::swapBytes(x)
260
261#define BSLS_BYTEORDER_NTOHS(x) \
262 BloombergLP::bsls::ByteOrderUtil::swapBytes16(x)
263
264#define BSLS_BYTEORDER_NTOHL(x) \
265 BloombergLP::bsls::ByteOrderUtil::swapBytes32(x)
266
267#define BSLS_BYTEORDER_NTOHLL(x) \
268 BloombergLP::bsls::ByteOrderUtil::swapBytes64(x)
269
270#define BSLS_BYTEORDER_HTON(x) BSLS_BYTEORDER_NTOH(x)
271
272#define BSLS_BYTEORDER_HTONS(x) BSLS_BYTEORDER_NTOHS(x)
273
274#define BSLS_BYTEORDER_HTONL(x) BSLS_BYTEORDER_NTOHL(x)
275
276#define BSLS_BYTEORDER_HTONLL(x) BSLS_BYTEORDER_NTOHLL(x)
277
278#define BSLS_BYTEORDER_NTOHS_CONSTANT(x) \
279 static_cast<unsigned short>( \
280 (static_cast<unsigned short>(x) >> 8) | \
281 (static_cast<unsigned short>(x) << 8))
282
283// The "NO_MSB" versions of the byte-swapping macros always move a 0 bit into
284// the most significant bit of the result, in order to avoid undefined behavior
285// caused by left shifting a 1 into the sign bit of a signed positive value.
286// These versions are invoked by the user versions of the macros, which first
287// test whether that bit is 1, and if so, perform the operation on the
288// complement of the value and complement the result. The "NO_MSB" macros are
289// intended to be private to the implementation.
290#define BSLS_BYTEORDER_NTOHL_CONSTANT_NO_MSB(x) \
291 ((((x) >> 24) & 0x000000FF) | (((x) & 0x00FF0000) >> 8) \
292 /* note 0x7F */ | (((x) & 0x0000FF00) << 8) | (((x) & 0x0000007F) << 24))
293#define BSLS_BYTEORDER_NTOHL_CONSTANT(x) \
294 ((x) & 0x80 ? ~BSLS_BYTEORDER_NTOHL_CONSTANT_NO_MSB(~(x)) \
295 : BSLS_BYTEORDER_NTOHL_CONSTANT_NO_MSB(x))
296
297#define BSLS_BYTEORDER_NTOHLL_CONSTANT_NO_MSB(x) \
298 /* note 0x7F */ ((((x) & 0x000000000000007FLL) << 56) \
299 | (((x) & 0x000000000000FF00LL) << 40) \
300 | (((x) & 0x0000000000FF0000LL) << 24) \
301 | (((x) & 0x00000000FF000000LL) << 8) \
302 | (((x) & 0x000000FF00000000LL) >> 8) \
303 | (((x) & 0x0000FF0000000000LL) >> 24) \
304 | (((x) & 0x00FF000000000000LL) >> 40) \
305 | (((x) >> 56) & 0x00000000000000FFLL))
306#define BSLS_BYTEORDER_NTOHLL_CONSTANT(x) \
307 ((x) & 0x80 ? ~BSLS_BYTEORDER_NTOHLL_CONSTANT_NO_MSB(~(x)) \
308 : BSLS_BYTEORDER_NTOHLL_CONSTANT_NO_MSB(x))
309
310#define BSLS_BYTEORDER_HTONS_CONSTANT(x) BSLS_BYTEORDER_NTOHS_CONSTANT(x)
311
312#define BSLS_BYTEORDER_HTONL_CONSTANT(x) BSLS_BYTEORDER_NTOHL_CONSTANT(x)
313
314#define BSLS_BYTEORDER_HTONLL_CONSTANT(x) BSLS_BYTEORDER_NTOHLL_CONSTANT(x)
315
316#endif // BSLS_PLATFORM_IS_BIG_ENDIAN
317
318// ----------------------------------------------------------------------------
319
320// ENDIAN CONVERSION MACROS
321
322#if defined(BSLS_PLATFORM_IS_LITTLE_ENDIAN)
323
324#define BSLS_BYTEORDER_LE_U16_TO_HOST(x) (x)
325#define BSLS_BYTEORDER_LE_U32_TO_HOST(x) (x)
326#define BSLS_BYTEORDER_LE_U64_TO_HOST(x) (x)
327
328#define BSLS_BYTEORDER_HOST_U16_TO_LE(x) (x)
329#define BSLS_BYTEORDER_HOST_U32_TO_LE(x) (x)
330#define BSLS_BYTEORDER_HOST_U64_TO_LE(x) (x)
331
332#define BSLS_BYTEORDER_BE_U16_TO_HOST(x) \
333 BloombergLP::bsls::ByteOrderUtil::swapBytes16(x)
334#define BSLS_BYTEORDER_BE_U32_TO_HOST(x) \
335 BloombergLP::bsls::ByteOrderUtil::swapBytes32(x)
336#define BSLS_BYTEORDER_BE_U64_TO_HOST(x) \
337 BloombergLP::bsls::ByteOrderUtil::swapBytes64(x)
338
339#define BSLS_BYTEORDER_HOST_U16_TO_BE(x) \
340 BloombergLP::bsls::ByteOrderUtil::swapBytes16(x)
341#define BSLS_BYTEORDER_HOST_U32_TO_BE(x) \
342 BloombergLP::bsls::ByteOrderUtil::swapBytes32(x)
343#define BSLS_BYTEORDER_HOST_U64_TO_BE(x) \
344 BloombergLP::bsls::ByteOrderUtil::swapBytes64(x)
345
346#define BSLS_BYTEORDER_LE_TO_HOST(x) (x)
347#define BSLS_BYTEORDER_HOST_TO_LE(x) (x)
348#define BSLS_BYTEORDER_BE_TO_HOST(x) \
349 BloombergLP::bsls::ByteOrderUtil::swapBytes(x)
350#define BSLS_BYTEORDER_HOST_TO_BE(x) \
351 BloombergLP::bsls::ByteOrderUtil::swapBytes(x)
352
353#else // BSLS_PLATFORM_IS_BIG_ENDIAN
354
355#define BSLS_BYTEORDER_LE_U16_TO_HOST(x) \
356 BloombergLP::bsls::ByteOrderUtil::swapBytes16(x)
357#define BSLS_BYTEORDER_LE_U32_TO_HOST(x) \
358 BloombergLP::bsls::ByteOrderUtil::swapBytes32(x)
359#define BSLS_BYTEORDER_LE_U64_TO_HOST(x) \
360 BloombergLP::bsls::ByteOrderUtil::swapBytes64(x)
361
362#define BSLS_BYTEORDER_HOST_U16_TO_LE(x) \
363 BloombergLP::bsls::ByteOrderUtil::swapBytes16(x)
364#define BSLS_BYTEORDER_HOST_U32_TO_LE(x) \
365 BloombergLP::bsls::ByteOrderUtil::swapBytes32(x)
366#define BSLS_BYTEORDER_HOST_U64_TO_LE(x) \
367 BloombergLP::bsls::ByteOrderUtil::swapBytes64(x)
368
369#define BSLS_BYTEORDER_BE_U16_TO_HOST(x) (x)
370#define BSLS_BYTEORDER_BE_U32_TO_HOST(x) (x)
371#define BSLS_BYTEORDER_BE_U64_TO_HOST(x) (x)
372
373#define BSLS_BYTEORDER_HOST_U16_TO_BE(x) (x)
374#define BSLS_BYTEORDER_HOST_U32_TO_BE(x) (x)
375#define BSLS_BYTEORDER_HOST_U64_TO_BE(x) (x)
376
377#define BSLS_BYTEORDER_LE_TO_HOST(x) \
378 BloombergLP::bsls::ByteOrderUtil::swapBytes(x)
379#define BSLS_BYTEORDER_HOST_TO_LE(x) \
380 BloombergLP::bsls::ByteOrderUtil::swapBytes(x)
381#define BSLS_BYTEORDER_BE_TO_HOST(x) (x)
382#define BSLS_BYTEORDER_HOST_TO_BE(x) (x)
383
384#endif // BSLS_PLATFORM_IS_LITTLE_ENDIAN
385
386#endif
387
388// ----------------------------------------------------------------------------
389// Copyright 2013 Bloomberg Finance L.P.
390//
391// Licensed under the Apache License, Version 2.0 (the "License");
392// you may not use this file except in compliance with the License.
393// You may obtain a copy of the License at
394//
395// http://www.apache.org/licenses/LICENSE-2.0
396//
397// Unless required by applicable law or agreed to in writing, software
398// distributed under the License is distributed on an "AS IS" BASIS,
399// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
400// See the License for the specific language governing permissions and
401// limitations under the License.
402// ----------------------------- END-OF-FILE ----------------------------------
403
404/** @} */
405/** @} */
406/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195