include/wipal/tool/endianness.hxx

00001 /*
00002  * WiPal - A library and a set of tools to manipulate wireless traces.
00003  * Copyright (C) 2007  Universite Pierre et Marie Curie - Paris 6
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  * MA  02110-1301  USA
00019  *
00020  * Author: Thomas Claveirole <thomas.claveirole@lip6.fr>
00021  */
00022 #ifndef TOOL_ENDIANNESS_HXX_
00023 # define TOOL_ENDIANNESS_HXX_
00024 
00025 # include <cassert>
00026 
00027 # include "endianness.hh"
00028 
00029 namespace tool
00030 {
00031 
00032   namespace endian
00033   {
00034 
00035     inline
00036     bool
00037     need_swap(endianness t, bool guess_swap)
00038     {
00039       static const int  i = 1;
00040       static const bool l = reinterpret_cast<const char*> (&i)[0];
00041 
00042       switch (t)
00043         {
00044         case big:
00045           return l;
00046 
00047         case little:
00048           return not l;
00049 
00050         case raw:
00051           return false;
00052 
00053         case swap:
00054           return true;
00055 
00056         case guess:
00057           return guess_swap;
00058 
00059         default:
00060           assert(! "Internal error: undefined endianness.");
00061           return false;
00062         }
00063     }
00064 
00065   } // End of namespace tool::endian.
00066 
00067 
00068   /*-------.
00069   | Shorts |
00070   `-------*/
00071 
00072   inline
00073   uint16_t
00074   extract_unswapped_short(const void* p)
00075   {
00076     return *static_cast<const uint16_t*> (p);
00077   }
00078 
00079   inline
00080   uint16_t
00081   extract_swapped_short(const uint16_t s)
00082   {
00083     return (s >> 8) | (s << 8);
00084   }
00085 
00086   inline
00087   uint16_t
00088   extract_swapped_short(const void* p)
00089   {
00090     return extract_swapped_short(extract_unswapped_short(p));
00091   }
00092 
00093   inline
00094   uint16_t
00095   extract_short(const uint16_t s, bool swapped)
00096   {
00097     return swapped ? extract_swapped_short(s) : s;
00098   }
00099 
00100 
00101   inline
00102   uint16_t
00103   extract_short(const void* p, bool swapped)
00104   {
00105     return swapped ? extract_swapped_short(p) : extract_unswapped_short(p);
00106   }
00107 
00108   inline
00109   uint16_t
00110   extract_big_endian_short(const void *p)
00111   {
00112     const uint8_t *const c = static_cast<const uint8_t*> (p);
00113 
00114     return uint16_t (*c) | uint16_t (*(c + 1)) << 8;
00115   }
00116 
00117 
00118   /*------.
00119   | Longs |
00120   `------*/
00121 
00122   inline
00123   uint32_t
00124   extract_swapped_long_u(const uint32_t l)
00125   {
00126     return (((l & 0xFF)         << 24) |
00127             ((l & 0xFF00)       <<  8) |
00128             ((l & 0xFF0000)     >>  8) |
00129             (l >> 24));
00130   }
00131 
00132   inline
00133   int32_t
00134   extract_swapped_long_s(const int32_t l)
00135   {
00136     return extract_swapped_long_u(l);
00137   }
00138 
00139   inline
00140   uint32_t
00141   extract_long_u(const uint32_t l, bool swapped)
00142   {
00143     return swapped ? extract_swapped_long_u(l) : l;
00144   }
00145 
00146   inline
00147   int32_t
00148   extract_long_s(const int32_t l, bool swapped)
00149   {
00150     return swapped ? extract_swapped_long_s(l) : l;
00151   }
00152 
00153   inline
00154   uint32_t
00155   extract_little_endian_long_u(const uint32_t l)
00156   {
00157     return need_swap(endian::little, false) ? extract_swapped_long_u(l) : l;
00158   }
00159 
00160 } // End of namespace tool.
00161 
00162 #endif // ! TOOL_ENDIANNESS_HXX_

Generated on Wed Jan 16 16:15:14 2008 for wipal by  doxygen 1.5.4