blob: 8f0caf39113969071956780b65c9e45c07f5f0b2 [file] [log] [blame]
/*
* 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 <stdio.h>
#include <string.h>
#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<char *>(&word);
return cp[0] != 0;
}
inline bool IsBigEndian(void) {
return !IsLittleEndian();
}
template <typename T, unsigned int kValSize>
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 <typename T>
struct ByteSwapper<T, 1> {
static T Swap(const T &val) {
return val;
}
};
template <typename T>
struct ByteSwapper<T, 2> {
static T Swap(const T &val) {
T new_val;
const char *o = (const char *)&val;
char *p = reinterpret_cast<char *>(&new_val);
p[0] = o[1];
p[1] = o[0];
return new_val;
}
};
template <typename T>
struct ByteSwapper<T, 4> {
static T Swap(const T &val) {
T new_val;
const char *o = (const char *)&val;
char *p = reinterpret_cast<char *>(&new_val);
p[0] = o[3];
p[1] = o[2];
p[2] = o[1];
p[3] = o[0];
return new_val;
}
};
template <typename T>
struct ByteSwapper<T, 8> {
static T Swap(const T &val) {
T new_val = val;
const char *o = (const char *)&val;
char *p = reinterpret_cast<char *>(&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 <typename T>
T SwapBytes(const T &val, bool force_swap) {
if (force_swap) {
#if !defined(LE_FX__NEED_BYTESWAP)
return ByteSwapper<T, sizeof(T)>::Swap(val);
#else
return val;
#endif // !LE_FX_NEED_BYTESWAP
} else {
#if !defined(LE_FX_NEED_BYTESWAP)
return val;
#else
return ByteSwapper<T, sizeof(T)>::Swap(val);
#endif // !LE_FX_NEED_BYTESWAP
}
}
template <typename T>
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<T *>(vals);
for (unsigned int i = 0; i < num_items; i++) {
writeable_vals[i] = ByteSwapper<T, sizeof(T)>::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<T *>(vals);
for (unsigned int i = 0; i < num_items; i++) {
writeable_vals[i] = ByteSwapper<T, sizeof(T)>::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_