| 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
|
|---|