16cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi/*
26cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * Copyright (C) 2013 The Android Open Source Project
36cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi *
46cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
56cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * you may not use this file except in compliance with the License.
66cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * You may obtain a copy of the License at
76cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi *
86cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
96cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi *
106cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
116cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
126cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * See the License for the specific language governing permissions and
146cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi * limitations under the License.
156cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi */
166cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
176cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#ifndef LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_
186cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#define LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_
196cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
206cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#include <stdio.h>
216cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#include <string.h>
226cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
236cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#include "common/core/basic_types.h"
246cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#include "common/core/os.h"
256cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
266cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivinamespace le_fx {
276cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
286cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivinamespace arch {
296cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
306cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Triviinline bool IsLittleEndian(void) {
316cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  int16 word = 1;
326cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  char *cp = reinterpret_cast<char *>(&word);
336cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  return cp[0] != 0;
346cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi}
356cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
366cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Triviinline bool IsBigEndian(void) {
376cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  return !IsLittleEndian();
386cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi}
396cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
406cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T, unsigned int kValSize>
416cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivistruct ByteSwapper {
426cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  static T Swap(const T &val) {
436cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    T new_val = val;
446cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    char *first = &new_val, *last = first + kValSize - 1, x;
456cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    for (; first < last; ++first, --last) {
466cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi      x = *last;
476cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi      *last = *first;
486cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi      *first = x;
496cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    }
506cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return new_val;
516cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
526cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi};
536cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
546cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T>
556cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivistruct ByteSwapper<T, 1> {
566cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  static T Swap(const T &val) {
576cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return val;
586cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
596cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi};
606cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
616cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T>
626cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivistruct ByteSwapper<T, 2> {
636cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  static T Swap(const T &val) {
646cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    T new_val;
656cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    const char *o = (const char *)&val;
666cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    char *p = reinterpret_cast<char *>(&new_val);
676cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[0] = o[1];
686cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[1] = o[0];
696cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return new_val;
706cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
716cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi};
726cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
736cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T>
746cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivistruct ByteSwapper<T, 4> {
756cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  static T Swap(const T &val) {
766cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    T new_val;
776cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    const char *o = (const char *)&val;
786cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    char *p = reinterpret_cast<char *>(&new_val);
796cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[0] = o[3];
806cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[1] = o[2];
816cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[2] = o[1];
826cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[3] = o[0];
836cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return new_val;
846cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
856cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi};
866cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
876cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T>
886cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivistruct ByteSwapper<T, 8> {
896cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  static T Swap(const T &val) {
906cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    T new_val = val;
916cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    const char *o = (const char *)&val;
926cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    char *p = reinterpret_cast<char *>(&new_val);
936cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[0] = o[7];
946cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[1] = o[6];
956cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[2] = o[5];
966cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[3] = o[4];
976cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[4] = o[3];
986cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[5] = o[2];
996cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[6] = o[1];
1006cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    p[7] = o[0];
1016cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return new_val;
1026cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
1036cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi};
1046cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
1056cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T>
1066cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel TriviT SwapBytes(const T &val, bool force_swap) {
1076cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  if (force_swap) {
1086cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#if !defined(LE_FX__NEED_BYTESWAP)
1096cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return ByteSwapper<T, sizeof(T)>::Swap(val);
1106cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#else
1116cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return val;
1126cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#endif  // !LE_FX_NEED_BYTESWAP
1136cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  } else {
1146cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#if !defined(LE_FX_NEED_BYTESWAP)
1156cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return val;
1166cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#else
1176cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return ByteSwapper<T, sizeof(T)>::Swap(val);
1186cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#endif  // !LE_FX_NEED_BYTESWAP
1196cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
1206cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi}
1216cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
1226cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivitemplate <typename T>
1236cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Triviconst T *SwapBytes(const T *vals, unsigned int num_items, bool force_swap) {
1246cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  if (force_swap) {
1256cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#if !defined(LE_FX_NEED_BYTESWAP)
1266cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    T *writeable_vals = const_cast<T *>(vals);
1276cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    for (unsigned int i = 0; i < num_items; i++) {
1286cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi      writeable_vals[i] = ByteSwapper<T, sizeof(T)>::Swap(vals[i]);
1296cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    }
1306cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return writeable_vals;
1316cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#else
1326cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return vals;
1336cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#endif  // !LE_FX_NEED_BYTESWAP
1346cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  } else {
1356cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#if !defined(LE_FX_NEED_BYTESWAP)
1366cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return vals;
1376cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#else
1386cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    T *writeable_vals = const_cast<T *>(vals);
1396cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    for (unsigned int i = 0; i < num_items; i++) {
1406cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi      writeable_vals[i] = ByteSwapper<T, sizeof(T)>::Swap(vals[i]);
1416cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    }
1426cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi    return writeable_vals;
1436cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#endif  // !LE_FX_NEED_BYTESWAP
1446cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi  }
1456cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi}
1466cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
1476cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi}  // namespace arch
1486cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
1496cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi}  // namespace le_fx
1506cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi
1516cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3cJean-Michel Trivi#endif  // LE_FX_ENGINE_COMMON_CORE_BYTE_SWAPPER_H_
152