NymphCast Client Library
bytebauble.h
1 /*
2  bytebauble.h - Header for the ByteBauble library.
3 
4  Revision 0
5 
6  Features:
7  -
8 
9  Notes:
10  -
11 
12  2019/05/31, Maya Posch
13 */
14 
15 
16 #ifndef BYTEBAUBLE_H
17 #define BYTEBAUBLE_H
18 
19 
20 #include <climits>
21 #include <cstdint>
22 #include <cstddef>
23 
24 #ifdef _MSC_VER
25 #include <stdlib.h>
26 #endif
27 
28 
29 enum BBEndianness {
30  BB_BE, // Big Endian
31  BB_LE // Little Endian
32 };
33 
34 
35 class ByteBauble {
36  BBEndianness globalEndian = BB_LE;
37  BBEndianness hostEndian = BB_LE;
38 
39 public:
40  ByteBauble();
41 
42  void detectHostEndian();
43  BBEndianness getHostEndian() { return hostEndian; }
44 
45  static uint32_t readPackedInt(uint32_t packed, uint32_t &output);
46  static uint32_t writePackedInt(uint32_t integer, uint32_t &output);
47 
48  void setGlobalEndianness(BBEndianness end) { globalEndian = end; }
49 
50  // --- TO GLOBAL ---
51  //
52  template <typename T>
53  T toGlobal(T in, BBEndianness end) {
54  // Convert to requested format, if different from global.
55  if (end == globalEndian) {
56  // Endianness matches, return input.
57  return in;
58  }
59 
60  // Perform the conversion.
61  // Flip the bytes, so that the MSB and LSB are switched.
62  // Compiler intrinsics in GCC/MinGW exist since ~4.3, for MSVC
63  std::size_t bytesize = sizeof(in);
64 #if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW64__)
65  if (bytesize == 2) {
66  return __builtin_bswap16(in);
67  }
68  else if (bytesize == 4) {
69  return __builtin_bswap32(in);
70  }
71  else if (bytesize == 8) {
72  return __builtin_bswap64(in);
73  }
74 #elif defined(_MSC_VER)
75  if (bytesize == 2) {
76  return _byteswap_ushort(in);
77  }
78  else if (bytesize == 4) {
79  return _byteswap_ulong(in);
80  }
81  else if (bytesize == 8) {
82  return _byteswap_uint64(in);
83  }
84 #endif
85 
86  // Fallback for other compilers.
87  // TODO: implement.
88  return 0;
89  }
90 
91  // --- TO HOST ---
92  //
93  template <typename T>
94  T toHost(T in, BBEndianness end) {
95  //
96 
97  // Convert to requested format, if different from host.
98  if (end == hostEndian) {
99  // Endianness matches, return input.
100  return in;
101  }
102 
103  // Perform the conversion.
104  // Flip the bytes, so that the MSB and LSB are switched.
105  // Compiler intrinsics in GCC/MinGW exist since ~4.3, for MSVC
106  std::size_t bytesize = sizeof(in);
107 #if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW64__)
108  if (bytesize == 2) {
109  return __builtin_bswap16(in);
110  }
111  else if (bytesize == 4) {
112  return __builtin_bswap32(in);
113  }
114  else if (bytesize == 8) {
115  return __builtin_bswap64(in);
116  }
117 #elif defined(_MSC_VER)
118  if (bytesize == 2) {
119  return _byteswap_ushort(in);
120  }
121  else if (bytesize == 4) {
122  return _byteswap_ulong(in);
123  }
124  else if (bytesize == 8) {
125  return _byteswap_uint64(in);
126  }
127 #endif
128 
129  // Fallback for other compilers.
130  // TODO: implement.
131  return 0;
132  }
133 };
134 
135 
136 #endif
Definition: bytebauble.h:35