1 /* 2 * Copyright (C) 2013 The Android Open Source Project 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 * http://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 LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_ 18 #define LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_ 19 20 #include <stdio.h> 21 #include <string.h> 22 23 #include "common/core/basic_types.h" 24 #include "common/core/os.h" 25 26 namespace le_fx { 27 28 namespace arch { 29 30 inline bool IsLittleEndian(void) { 31 int16 word = 1; 32 char *cp = reinterpret_cast<char *>(&word); 33 return cp[0] != 0; 34 } 35 36 inline bool IsBigEndian(void) { 37 return !IsLittleEndian(); 38 } 39 40 template <typename T, unsigned int kValSize> 41 struct ByteSwapper { 42 static T Swap(const T &val) { 43 T new_val = val; 44 char *first = &new_val, *last = first + kValSize - 1, x; 45 for (; first < last; ++first, --last) { 46 x = *last; 47 *last = *first; 48 *first = x; 49 } 50 return new_val; 51 } 52 }; 53 54 template <typename T> 55 struct ByteSwapper<T, 1> { 56 static T Swap(const T &val) { 57 return val; 58 } 59 }; 60 61 template <typename T> 62 struct ByteSwapper<T, 2> { 63 static T Swap(const T &val) { 64 T new_val; 65 const char *o = (const char *)&val; 66 char *p = reinterpret_cast<char *>(&new_val); 67 p[0] = o[1]; 68 p[1] = o[0]; 69 return new_val; 70 } 71 }; 72 73 template <typename T> 74 struct ByteSwapper<T, 4> { 75 static T Swap(const T &val) { 76 T new_val; 77 const char *o = (const char *)&val; 78 char *p = reinterpret_cast<char *>(&new_val); 79 p[0] = o[3]; 80 p[1] = o[2]; 81 p[2] = o[1]; 82 p[3] = o[0]; 83 return new_val; 84 } 85 }; 86 87 template <typename T> 88 struct ByteSwapper<T, 8> { 89 static T Swap(const T &val) { 90 T new_val = val; 91 const char *o = (const char *)&val; 92 char *p = reinterpret_cast<char *>(&new_val); 93 p[0] = o[7]; 94 p[1] = o[6]; 95 p[2] = o[5]; 96 p[3] = o[4]; 97 p[4] = o[3]; 98 p[5] = o[2]; 99 p[6] = o[1]; 100 p[7] = o[0]; 101 return new_val; 102 } 103 }; 104 105 template <typename T> 106 T SwapBytes(const T &val, bool force_swap) { 107 if (force_swap) { 108 #if !defined(LE_FX__NEED_BYTESWAP) 109 return ByteSwapper<T, sizeof(T)>::Swap(val); 110 #else 111 return val; 112 #endif // !LE_FX_NEED_BYTESWAP 113 } else { 114 #if !defined(LE_FX_NEED_BYTESWAP) 115 return val; 116 #else 117 return ByteSwapper<T, sizeof(T)>::Swap(val); 118 #endif // !LE_FX_NEED_BYTESWAP 119 } 120 } 121 122 template <typename T> 123 const T *SwapBytes(const T *vals, unsigned int num_items, bool force_swap) { 124 if (force_swap) { 125 #if !defined(LE_FX_NEED_BYTESWAP) 126 T *writeable_vals = const_cast<T *>(vals); 127 for (unsigned int i = 0; i < num_items; i++) { 128 writeable_vals[i] = ByteSwapper<T, sizeof(T)>::Swap(vals[i]); 129 } 130 return writeable_vals; 131 #else 132 return vals; 133 #endif // !LE_FX_NEED_BYTESWAP 134 } else { 135 #if !defined(LE_FX_NEED_BYTESWAP) 136 return vals; 137 #else 138 T *writeable_vals = const_cast<T *>(vals); 139 for (unsigned int i = 0; i < num_items; i++) { 140 writeable_vals[i] = ByteSwapper<T, sizeof(T)>::Swap(vals[i]); 141 } 142 return writeable_vals; 143 #endif // !LE_FX_NEED_BYTESWAP 144 } 145 } 146 147 } // namespace arch 148 149 } // namespace le_fx 150 151 #endif // LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_ 152