source: trunk/FACT++/src/ByteOrder.h@ 19808

Last change on this file since 19808 was 10747, checked in by tbretz, 14 years ago
Improved exception output.
File size: 2.9 KB
Line 
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
12template<typename S>
13void reset(S &s)
14{
15 memset(&s, 0, sizeof(S));
16}
17
18template<typename S>
19void 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
27template<typename S>
28void 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
36template<typename S>
37void 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
45template<typename S>
46S NtoH(const S &s)
47{
48 S ret(s);
49 ntoh(ret);
50 return ret;
51}
52
53template<typename S>
54S HtoN(const S &s)
55{
56 S ret(s);
57 hton(ret);
58 return ret;
59}
60
61template<typename S>
62void 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
71template<typename S>
72std::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
86template<typename T, typename S>
87void 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
129template<typename T>
130void Reverse(T *t)
131{
132 std::reverse((uint16_t*)t, ((uint16_t*)t)+sizeof(T)/2);
133}
134
135#endif
Note: See TracBrowser for help on using the repository browser.