00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _ENDIAN_H_
00036 #define _ENDIAN_H_
00037
00038 #ifdef MOTE
00039 # include "mote_types.h"
00040 #else
00041 # include <stdint.h>
00042 #endif
00043
00044
00045 #ifndef WORDSIZE
00046 # ifdef __WORDSIZE
00047 # if __WORDSIZE == 64
00048 # define WORDSIZE 8
00049 # define WORD int64_t
00050 # elif __WORDSIZE == 16
00051 # define WORDSIZE 2
00052 # define WORD int16_t
00053 # elif __WORDSIZE == 8
00054 # define WORDSIZE 1
00055 # define WORD int8_t
00056 # else
00057 # define WORDSIZE 4
00058 # define WORD int32_t
00059 # endif
00060 # else // no __WORDSIZE
00061 # define WORDSIZE 4
00062 # define WORD int32_t
00063 # endif
00064 #endif
00065
00066 #ifndef WORD
00067 # define WORD int32_t
00068 #endif
00069
00070
00071
00072 static inline uint8_t little_endian(void)
00073 {
00074 uint16_t word = 0x0001;
00075 uint8_t *byte = (uint8_t*)&word;
00076 return byte[0];
00077 }
00078
00079
00080 static inline void swap(uint8_t *a, uint8_t *b)
00081 {
00082 uint8_t tmp;
00083 tmp = *a;
00084 *a = *b;
00085 *b = tmp;
00086 }
00087
00088
00089 static inline void _byte_swap(uint8_t *bytes, size_t size)
00090 {
00091 if (little_endian()) {
00092 size_t i, j;
00093 for (i = 0, j = size - 1; i < j; i++, j--)
00094 swap(&bytes[i], &bytes[j]);
00095 }
00096
00097 }
00098
00099
00100
00101
00102
00103 static inline unsigned twos_complement(void)
00104 {
00105 int8_t value = -1;
00106 uint8_t rep = 0xff;
00107 uint8_t word = value;
00108 return (rep == word);
00109 }
00110
00111
00112 static inline unsigned ones_complement(void)
00113 {
00114 int8_t value = -1;
00115 uint8_t rep = 0xfe;
00116 uint8_t word = value;
00117 return (rep == word);
00118 }
00119
00120
00121 static inline unsigned signed_magnitude(void)
00122 {
00123 int8_t value = -1;
00124 uint8_t rep = 0x81;
00125 uint8_t word = value;
00126 return (rep == word);
00127 }
00128
00129
00130
00131 #define host_rep(x) \
00132 do { \
00133 if (ones_complement()) \
00134 (x) -= 1; \
00135 else if (signed_magnitude()) { \
00136 uint8_t *ptr = (uint8_t*)&(x); \
00137 (x) -= 1; \
00138 (x) = ~(x); \
00139 ptr[0] |= 0x80; \
00140 } \
00141 } while(0)
00142
00143
00144 static inline void host_order(WORD *var, uint8_t *bytes,
00145 size_t size, uint8_t convert, uint8_t sign)
00146 {
00147 uint8_t msb = little_endian() ? size - 1 : 0;
00148 uint8_t neg;
00149
00150 if (convert)
00151 _byte_swap(bytes, size);
00152 neg = bytes[msb] & 0x80;
00153
00154 if (size == 1) {
00155 if (sign) {
00156 int8_t val = *((int8_t*)bytes);
00157 if (neg) {
00158 host_rep(val);
00159 }
00160 *var = val;
00161 } else {
00162 uint8_t val = *((uint8_t*)bytes);
00163 *var = val;
00164 }
00165 }
00166 else if (size == 2) {
00167 if (sign) {
00168 int16_t val = *((int16_t*)bytes);
00169 if (neg) {
00170 host_rep(val);
00171 }
00172 *var = val;
00173 } else {
00174 uint16_t val = *((uint16_t*)bytes);
00175 *var = val;
00176 }
00177 }
00178 else if (size == 4) {
00179 if (sign) {
00180 int32_t val = *((int32_t*)bytes);
00181 if (neg) {
00182 host_rep(val);
00183 }
00184 *var = val;
00185 } else {
00186 uint32_t val = *((uint32_t*)bytes);
00187 *var = val;
00188 }
00189 }
00190 else if (size == 8) {
00191 if (sign) {
00192 int64_t val = *((int64_t*)bytes);
00193 if (neg) {
00194 host_rep(val);
00195 }
00196 *var = val;
00197 } else {
00198 uint64_t val = *((uint64_t*)bytes);
00199 *var = val;
00200 }
00201 }
00202 }
00203
00204
00205
00206 static inline void network_order(uint8_t *bytes, WORD var)
00207 {
00208 uint8_t sign = var < 0 ? 1: 0;
00209 uint8_t *ptr = (uint8_t*)&var;
00210 uint8_t msb = little_endian() ? WORDSIZE - 1 : 0;
00211 uint8_t neg = ptr[msb] & 0x80;
00212
00213 if (sign && neg) {
00214 if (ones_complement()) {
00215 var++;
00216 }
00217 else if (signed_magnitude()) {
00218 ptr[msb] &= ~0x80;
00219 var = ~var;
00220 var++;
00221 }
00222 }
00223 memcpy(bytes, &var, WORDSIZE);
00224 }
00225
00226
00227 #endif // _ENDIAN_H_