1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /**
24   @file byteorder.h
25 
26   @brief The file contains functions to convert the byte encoding of integer
27   values to and from little-endian and big-endian byte order.
28 */
29 
30 #ifndef BYTEORDER_INCLUDED
31 #define BYTEORDER_INCLUDED
32 
33 #include "my_compiler.h"
34 #include "binlog_config.h"
35 #include <stdint.h>
36 #ifndef STANDALONE_BINLOG
37 #define HAVE_MYSYS 1
38 #endif
39 
40 /*
41   Methods for reading and storing in machine independent
42   format (low byte first).
43 */
44 
45 /*
46   Checking le16toh is required because the machine may have the header
47   but the functions might not be defined if the version of glibc < 2.9
48 */
49 #ifdef HAVE_ENDIAN_CONVERSION_MACROS
50   #include <endian.h>
51 #endif
52 
53 #if !defined(le16toh)
54 /**
55   Converting a 16 bit integer from little-endian byte order to host byteorder
56 
57   @param x  16-bit integer in little endian byte order
58   @return  16-bit integer in host byte order
59 */
le16toh(uint16_t x)60 uint16_t inline le16toh(uint16_t x)
61 {
62   #if !(IS_BIG_ENDIAN)
63     return x;
64   #else
65     return ((x >> 8) | (x << 8));
66   #endif
67 }
68 #endif
69 
70 #if !defined(le32toh)
71 /**
72   Converting a 32 bit integer from little-endian byte order to host byteorder
73 
74   @param x  32-bit integer in little endian byte order
75   @return  32-bit integer in host byte order
76 */
le32toh(uint32_t x)77 uint32_t inline le32toh(uint32_t x)
78 {
79   #if !(IS_BIG_ENDIAN)
80     return x;
81   #else
82     return (((x >> 24) & 0xff) |
83             ((x <<  8) & 0xff0000) |
84             ((x >>  8) & 0xff00) |
85             ((x << 24) & 0xff000000));
86   #endif
87 }
88 #endif
89 
90 #if !defined(be32toh)
91 /**
92   Converting a 32 bit integer from big-endian byte order to host byteorder
93 
94   @param x  32-bit integer in big endian byte order
95   @return  32-bit integer in host byte order
96 */
be32toh(uint32_t x)97 uint32_t inline be32toh(uint32_t x)
98 {
99   #if !(IS_BIG_ENDIAN)
100      return (((x >> 24) & 0xff) |
101              ((x <<  8) & 0xff0000) |
102              ((x >>  8) & 0xff00) |
103              ((x << 24) & 0xff000000));
104   #else
105      return x;
106   #endif
107 }
108 #endif
109 
110 #if !defined(le64toh)
111 /**
112   Converting a 64 bit integer from little-endian byte order to host byteorder
113 
114   @param x  64-bit integer in little endian byte order
115   @return  64-bit integer in host byte order
116 */
le64toh(uint64_t x)117 uint64_t inline le64toh(uint64_t x)
118 {
119   #if !(IS_BIG_ENDIAN)
120     return x;
121   #else
122     x = ((x << 8) & 0xff00ff00ff00ff00ULL) |
123         ((x >> 8) & 0x00ff00ff00ff00ffULL);
124     x = ((x << 16) & 0xffff0000ffff0000ULL) |
125         ((x >> 16) & 0x0000ffff0000ffffULL);
126     return (x << 32) | (x >> 32);
127   #endif
128 }
129 #endif
130 
131 #define do_compile_time_assert(X)                                              \
132   do                                                                        \
133   {                                                                         \
134     typedef char do_compile_time_assert[(X) ? 1 : -1] MY_ATTRIBUTE((unused)); \
135   } while(0)
136 #endif // BYTEORDER_INCLUDED
137