00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <inttypes.h>
00021
00022 #include <archon/util/memory.H>
00023
00024
00025 namespace Archon
00026 {
00027 namespace Utilities
00028 {
00029 vector<bool> detectNativeEndianness()
00030 {
00031 uintmax_t v = 1;
00032 char *p = reinterpret_cast<char *>(&v);
00033
00034
00035 int i;
00036 for(i=0; i<static_cast<int>(sizeof(v)); ++i) if(p[i]) break;
00037
00038 vector<bool> r;
00039
00040 int n = 0;
00041 int w = sizeof(v) >> 1;
00042 while(w)
00043 {
00044 r.push_back(i&w);
00045 w >>= 1;
00046 ++n;
00047 }
00048 reverse(r.begin(), r.end());
00049 return r;
00050 }
00051
00052
00053 bool compareEndianness(const vector<bool> &a, const vector<bool> &b,
00054 int levels)
00055 {
00056 vector<bool> c;
00057 if(b.empty())
00058 {
00059 if(a.empty()) return true;
00060 c = detectNativeEndianness();
00061 }
00062 else c = b;
00063
00064 if(!levels) levels = max(a.size(), c.size());
00065
00066 for(int i=0; i<levels; ++i)
00067 if(a[i < static_cast<int>(a.size()) ? i : a.size()-1] !=
00068 c[i < static_cast<int>(c.size()) ? i : c.size()-1]) return false;
00069
00070 return true;
00071 }
00072
00073
00074 vector<int> computeBytePermutation(const vector<bool> &endianness,
00075 int levels)
00076 {
00077 vector<bool> native = detectNativeEndianness();
00078
00079
00080 int n = 1<<levels;
00081 vector<int> permutation(n);
00082 for(int i=0; i<n; ++i) permutation[i] = i;
00083
00084
00085 for(int i=0; i<levels; ++i)
00086 {
00087
00088 if(native[i < static_cast<int>(native.size()) ? i : native.size()-1] ==
00089 endianness[i < static_cast<int>(endianness.size()) ? i :
00090 endianness.size()-1]) continue;
00091
00092 int swapBlockSize = 1 << i+1;
00093 int numberOfSwapBlocks = n / swapBlockSize;
00094 int numberOfSwapsPerBlock = swapBlockSize / 2;
00095
00096
00097 for(int j=0; j<numberOfSwapBlocks; ++j)
00098 {
00099
00100 for(int k=0; k<numberOfSwapsPerBlock; ++k)
00101 {
00102 int offset = j * swapBlockSize + k;
00103 swap(permutation[offset],
00104 permutation[offset+numberOfSwapsPerBlock]);
00105 }
00106 }
00107 }
00108
00109 return permutation;
00110 }
00111 }
00112 }