00001 /* 00002 * WiPal - A library and a set of tools to manipulate wireless traces. 00003 * Copyright (C) 2007, 2008 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 | Unsigned shorts | 00070 `----------------*/ 00071 00072 inline 00073 uint16_t 00074 extract_unswapped_short_u(const void* p) 00075 { 00076 return *static_cast<const uint16_t*> (p); 00077 } 00078 00079 inline 00080 uint16_t 00081 extract_swapped_short_u(const uint16_t s) 00082 { 00083 return (s >> 8) | (s << 8); 00084 } 00085 00086 inline 00087 uint16_t 00088 extract_swapped_short_u(const void* p) 00089 { 00090 return extract_swapped_short_u(extract_unswapped_short_u(p)); 00091 } 00092 00093 inline 00094 uint16_t 00095 extract_short_u(const void* p, bool swapped) 00096 { 00097 return swapped ? extract_swapped_short_u(p) : extract_unswapped_short_u(p); 00098 } 00099 00100 inline 00101 uint16_t 00102 extract_short_u(const uint16_t s, bool swapped) 00103 { 00104 return swapped ? extract_swapped_short_u(s) : s; 00105 } 00106 00107 inline 00108 uint16_t 00109 extract_big_endian_short_u(const void *p) 00110 { 00111 const uint8_t *const c = static_cast<const uint8_t*> (p); 00112 00113 return uint16_t (c[1]) | uint16_t (c[0]) << 8; 00114 } 00115 00116 inline 00117 uint16_t 00118 extract_big_endian_short_u(const uint16_t s) 00119 { 00120 return extract_big_endian_short_u(&s); 00121 } 00122 00123 inline 00124 uint16_t 00125 extract_little_endian_short_u(const void *p) 00126 { 00127 const uint8_t *const c = static_cast<const uint8_t*> (p); 00128 00129 return uint16_t (c[0]) | uint16_t (c[1]) << 8; 00130 } 00131 00132 inline 00133 uint16_t 00134 extract_little_endian_short_u(const uint16_t s) 00135 { 00136 return extract_little_endian_short_u(&s); 00137 } 00138 00139 /*---------------. 00140 | Unsigned longs | 00141 `---------------*/ 00142 00143 inline 00144 uint32_t 00145 extract_unswapped_long_u(const void* p) 00146 { 00147 return *static_cast<const uint32_t*> (p); 00148 } 00149 00150 inline 00151 uint32_t 00152 extract_swapped_long_u(const uint32_t l) 00153 { 00154 return (l >> 24) | ((l & 0xFF0000) >> 8) | ((l & 0xFF00) << 8) | (l << 24); 00155 } 00156 00157 inline 00158 uint32_t 00159 extract_swapped_long_u(const void* p) 00160 { 00161 return extract_swapped_long_u(extract_unswapped_long_u(p)); 00162 } 00163 00164 inline 00165 uint32_t 00166 extract_long_u(const void* p, bool swapped) 00167 { 00168 return swapped ? extract_swapped_long_u(p) : extract_unswapped_long_u(p); 00169 } 00170 00171 inline 00172 uint32_t 00173 extract_long_u(const uint32_t l, bool swapped) 00174 { 00175 return swapped ? extract_swapped_long_u(l) : l; 00176 } 00177 00178 inline 00179 uint32_t 00180 extract_big_endian_long_u(const void* p) 00181 { 00182 const uint8_t *const c = static_cast<const uint8_t*> (p); 00183 00184 return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; 00185 } 00186 00187 inline 00188 uint32_t 00189 extract_big_endian_long_u(const uint32_t l) 00190 { 00191 return extract_big_endian_long_u(&l); 00192 } 00193 00194 inline 00195 uint32_t 00196 extract_little_endian_long_u(const void* p) 00197 { 00198 const uint8_t *const c = static_cast<const uint8_t*> (p); 00199 00200 return (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; 00201 } 00202 00203 inline 00204 uint32_t 00205 extract_little_endian_long_u(const uint32_t l) 00206 { 00207 return extract_little_endian_long_u(&l); 00208 } 00209 00210 /*-------------. 00211 | Signed longs | 00212 `-------------*/ 00213 00214 inline 00215 int32_t 00216 extract_unswapped_long_s(const void* p) 00217 { 00218 return int32_t (extract_unswapped_long_u(p)); 00219 } 00220 00221 inline 00222 int32_t 00223 extract_swapped_long_s(const int32_t l) 00224 { 00225 return int32_t (extract_swapped_long_u(l)); 00226 } 00227 00228 inline 00229 int32_t 00230 extract_swapped_long_s(const void* p) 00231 { 00232 return int32_t (extract_swapped_long_u(p)); 00233 } 00234 00235 inline 00236 int32_t 00237 extract_long_s(const void* p, bool swapped) 00238 { 00239 return int32_t (extract_long_u(p, swapped)); 00240 } 00241 00242 inline 00243 int32_t 00244 extract_long_s(const int32_t l, bool swapped) 00245 { 00246 return int32_t (extract_long_u(l, swapped)); 00247 } 00248 00249 inline 00250 int32_t 00251 extract_big_endian_long_s(const void* p) 00252 { 00253 return int32_t (extract_big_endian_long_u(p)); 00254 } 00255 00256 inline 00257 int32_t 00258 extract_big_endian_long_s(const int32_t l) 00259 { 00260 return int32_t (extract_big_endian_long_u(l)); 00261 } 00262 00263 inline 00264 int32_t 00265 extract_little_endian_long_s(const void* p) 00266 { 00267 return int32_t (extract_little_endian_long_u(p)); 00268 } 00269 00270 inline 00271 int32_t 00272 extract_little_endian_long_s(const int32_t l) 00273 { 00274 return int32_t (extract_little_endian_long_u(l)); 00275 } 00276 00277 } // End of namespace tool. 00278 00279 #endif // ! TOOL_ENDIANNESS_HXX_