/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_ #define LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_ #include #include #include "common/core/basic_types.h" #include "common/core/os.h" namespace le_fx { namespace arch { inline bool IsLittleEndian(void) { int16 word = 1; char *cp = reinterpret_cast(&word); return cp[0] != 0; } inline bool IsBigEndian(void) { return !IsLittleEndian(); } template struct ByteSwapper { static T Swap(const T &val) { T new_val = val; char *first = &new_val, *last = first + kValSize - 1, x; for (; first < last; ++first, --last) { x = *last; *last = *first; *first = x; } return new_val; } }; template struct ByteSwapper { static T Swap(const T &val) { return val; } }; template struct ByteSwapper { static T Swap(const T &val) { T new_val; const char *o = (const char *)&val; char *p = reinterpret_cast(&new_val); p[0] = o[1]; p[1] = o[0]; return new_val; } }; template struct ByteSwapper { static T Swap(const T &val) { T new_val; const char *o = (const char *)&val; char *p = reinterpret_cast(&new_val); p[0] = o[3]; p[1] = o[2]; p[2] = o[1]; p[3] = o[0]; return new_val; } }; template struct ByteSwapper { static T Swap(const T &val) { T new_val = val; const char *o = (const char *)&val; char *p = reinterpret_cast(&new_val); p[0] = o[7]; p[1] = o[6]; p[2] = o[5]; p[3] = o[4]; p[4] = o[3]; p[5] = o[2]; p[6] = o[1]; p[7] = o[0]; return new_val; } }; template T SwapBytes(const T &val, bool force_swap) { if (force_swap) { #if !defined(LE_FX__NEED_BYTESWAP) return ByteSwapper::Swap(val); #else return val; #endif // !LE_FX_NEED_BYTESWAP } else { #if !defined(LE_FX_NEED_BYTESWAP) return val; #else return ByteSwapper::Swap(val); #endif // !LE_FX_NEED_BYTESWAP } } template const T *SwapBytes(const T *vals, unsigned int num_items, bool force_swap) { if (force_swap) { #if !defined(LE_FX_NEED_BYTESWAP) T *writeable_vals = const_cast(vals); for (unsigned int i = 0; i < num_items; i++) { writeable_vals[i] = ByteSwapper::Swap(vals[i]); } return writeable_vals; #else return vals; #endif // !LE_FX_NEED_BYTESWAP } else { #if !defined(LE_FX_NEED_BYTESWAP) return vals; #else T *writeable_vals = const_cast(vals); for (unsigned int i = 0; i < num_items; i++) { writeable_vals[i] = ByteSwapper::Swap(vals[i]); } return writeable_vals; #endif // !LE_FX_NEED_BYTESWAP } } } // namespace arch } // namespace le_fx #endif // LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_