| 1 | #ifndef FACT_ByteOrder | 
|---|
| 2 | #define FACT_ByteOrder | 
|---|
| 3 |  | 
|---|
| 4 | #include <string.h> | 
|---|
| 5 | #include <arpa/inet.h> | 
|---|
| 6 |  | 
|---|
| 7 | #include <vector> | 
|---|
| 8 | #include <algorithm> | 
|---|
| 9 | #include <typeinfo> | 
|---|
| 10 | #include <stdexcept> | 
|---|
| 11 |  | 
|---|
| 12 | template<typename S> | 
|---|
| 13 | void reset(S &s) | 
|---|
| 14 | { | 
|---|
| 15 | memset(&s, 0, sizeof(S)); | 
|---|
| 16 | } | 
|---|
| 17 |  | 
|---|
| 18 | template<typename S> | 
|---|
| 19 | void init(S &s) | 
|---|
| 20 | { | 
|---|
| 21 | if (sizeof(S)%2!=0) | 
|---|
| 22 | throw std::logic_error("size of "+std::string(typeid(S).name())+" not a multiple of 2."); | 
|---|
| 23 |  | 
|---|
| 24 | reset(s); | 
|---|
| 25 | } | 
|---|
| 26 |  | 
|---|
| 27 | template<typename S> | 
|---|
| 28 | void hton(S &s) | 
|---|
| 29 | { | 
|---|
| 30 | std::transform(reinterpret_cast<uint16_t*>(&s), | 
|---|
| 31 | reinterpret_cast<uint16_t*>(&s)+sizeof(S)/2, | 
|---|
| 32 | reinterpret_cast<uint16_t*>(&s), | 
|---|
| 33 | htons); | 
|---|
| 34 | } | 
|---|
| 35 |  | 
|---|
| 36 | template<typename S> | 
|---|
| 37 | void ntoh(S &s) | 
|---|
| 38 | { | 
|---|
| 39 | std::transform(reinterpret_cast<uint16_t*>(&s), | 
|---|
| 40 | reinterpret_cast<uint16_t*>(&s)+sizeof(S)/2, | 
|---|
| 41 | reinterpret_cast<uint16_t*>(&s), | 
|---|
| 42 | ntohs); | 
|---|
| 43 | } | 
|---|
| 44 |  | 
|---|
| 45 | template<typename S> | 
|---|
| 46 | S NtoH(const S &s) | 
|---|
| 47 | { | 
|---|
| 48 | S ret(s); | 
|---|
| 49 | ntoh(ret); | 
|---|
| 50 | return ret; | 
|---|
| 51 | } | 
|---|
| 52 |  | 
|---|
| 53 | template<typename S> | 
|---|
| 54 | S HtoN(const S &s) | 
|---|
| 55 | { | 
|---|
| 56 | S ret(s); | 
|---|
| 57 | hton(ret); | 
|---|
| 58 | return ret; | 
|---|
| 59 | } | 
|---|
| 60 |  | 
|---|
| 61 | template<typename S> | 
|---|
| 62 | void ntohcpy(const std::vector<uint16_t> &vec, S &s) | 
|---|
| 63 | { | 
|---|
| 64 | if (sizeof(S)!=vec.size()*2) | 
|---|
| 65 | throw std::logic_error("ntohcpy: size of vector mismatch "+std::string(typeid(S).name())); | 
|---|
| 66 |  | 
|---|
| 67 | std::transform(vec.begin(), vec.end(), | 
|---|
| 68 | reinterpret_cast<uint16_t*>(&s), ntohs); | 
|---|
| 69 | } | 
|---|
| 70 |  | 
|---|
| 71 | template<typename S> | 
|---|
| 72 | std::vector<uint16_t> htoncpy(const S &s) | 
|---|
| 73 | { | 
|---|
| 74 | if (sizeof(S)%2) | 
|---|
| 75 | throw std::logic_error("htoncpy: size of "+std::string(typeid(S).name())+" not a multiple of 2"); | 
|---|
| 76 |  | 
|---|
| 77 | std::vector<uint16_t> v(sizeof(S)/2); | 
|---|
| 78 |  | 
|---|
| 79 | std::transform(reinterpret_cast<const uint16_t*>(&s), | 
|---|
| 80 | reinterpret_cast<const uint16_t*>(&s)+sizeof(S)/2, | 
|---|
| 81 | v.begin(), htons); | 
|---|
| 82 |  | 
|---|
| 83 | return v; | 
|---|
| 84 | } | 
|---|
| 85 |  | 
|---|
| 86 | template<typename T, typename S> | 
|---|
| 87 | void bitcpy(T *target, size_t ntarget, const S *source, size_t nsource, size_t ss=0, size_t ts=0) | 
|---|
| 88 | { | 
|---|
| 89 | const size_t targetsize = ts==0 ? sizeof(T)*8 : std::min(ts, sizeof(T)*8); | 
|---|
| 90 | const size_t sourcesize = ss==0 ? sizeof(S)*8 : std::min(ss, sizeof(S)*8); | 
|---|
| 91 |  | 
|---|
| 92 | const S *const ends = source + nsource; | 
|---|
| 93 | const T *const endt = target + ntarget; | 
|---|
| 94 |  | 
|---|
| 95 | const S *s = source; | 
|---|
| 96 | T *t = target; | 
|---|
| 97 |  | 
|---|
| 98 | memset(t, 0, sizeof(T)*ntarget); | 
|---|
| 99 |  | 
|---|
| 100 | size_t targetpos = 0; | 
|---|
| 101 | size_t sourcepos = 0; | 
|---|
| 102 |  | 
|---|
| 103 | while (s<ends && t<endt) | 
|---|
| 104 | { | 
|---|
| 105 | // Start filling with "source size" - "position" bits | 
|---|
| 106 | *t |= (*s>>sourcepos)<<targetpos; | 
|---|
| 107 |  | 
|---|
| 108 | // Calculate how many bits were siuccessfully copied | 
|---|
| 109 | const int ncopy = std::min(sourcesize-sourcepos, targetsize-targetpos); | 
|---|
| 110 |  | 
|---|
| 111 | targetpos += ncopy; | 
|---|
| 112 | sourcepos += ncopy; | 
|---|
| 113 |  | 
|---|
| 114 | if (sourcepos>=sourcesize) | 
|---|
| 115 | { | 
|---|
| 116 | sourcepos %= sourcesize; | 
|---|
| 117 | s++; | 
|---|
| 118 | } | 
|---|
| 119 |  | 
|---|
| 120 | if (targetpos>=targetsize) | 
|---|
| 121 | { | 
|---|
| 122 | targetpos %= targetsize; | 
|---|
| 123 | t++; | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | } | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | template<typename T> | 
|---|
| 130 | void Reverse(T *t) | 
|---|
| 131 | { | 
|---|
| 132 | std::reverse((uint16_t*)t, ((uint16_t*)t)+sizeof(T)/2); | 
|---|
| 133 | } | 
|---|
| 134 |  | 
|---|
| 135 | #endif | 
|---|