summaryrefslogtreecommitdiffstats
path: root/blocks/src/lib/op25_yank.h
blob: 621c316afe7e0ffa54cf1ff57d1298e28892aa5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#ifndef INCLUDED_SWAB_H
#define INCLUDED_SWAB_H

/**
 * Yank in[bits[0]..bits[bits_sz]) to out[where,where+bits_sz).
 *
 * \param in A const reference to the source.
 * \param bits An array specifying the ordinals of the bits to copy.
 * \param bits_sz The size of the bits array.
 * \param out A reference to the destination.
 * \param where The offset of the first bit to write.
 */
template <class X, class Y>
void yank(const X& in, const size_t bits[], size_t bits_sz, Y& out, size_t where)
{
   for(size_t i = 0; i < bits_sz; ++i) {
      out[where+i] = in[bits[i]];
   }
}

/**
 * Yank back from in[where,where+bits_sz) to out[bits[0]..bits[bits_sz]).
 *
 * \param in A const reference to the source.
 * \param where The offset of the first bit to read.
 * \param out A reference to the destination.
 * \param bits An array specifying the ordinals of the bits to copy.
 * \param bits_sz The size of the bits array.
 */
template <class X, class Y>
void yank_back(const X& in, size_t where, Y& out, const size_t bits[], size_t bits_sz)
{
   for(size_t i = 0; i < bits_sz; ++i) {
      out[bits[i]] = in[where+i];
   }
}

/**
 * Extract a bit_vector in[begin,end) to an octet buffer.
 *
 * \param in A const reference to the source.
 * \param begin The offset of the first bit to extract (the MSB).
 * \param end The offset of the end bit.
 * \param out Address of the octet buffer to write into.
 * \return The number of octers written.
 */
template<class X>
size_t extract(const X& in, int begin, int end, uint8_t *out)
{
   const size_t out_sz = (7 + end - begin) / 8;
	std::fill(out, out + out_sz, 0);
   for(int i = begin, j = 0; i < end; ++i, ++j) {
      out[j / 8] |= (in[i] ? 1 << (7 - (j % 8)) : 0);
   }
   return out_sz;
}

/**
 * Extract a bit_vector in[bits[0)..bits[bits_sz)) to an octet buffer.
 *
 * \param in A const reference to the source.
 * \param bits An array specifying the ordinals of the bits to extract.
 * \param bits_sz The size of the bits array.
 * \param out Address of the octet buffer to write into.
 * \return The number of octers written.
 */
template<class X>
size_t extract(const X& in, const size_t bits[], size_t bits_sz, uint8_t *out)
{
   const size_t out_sz = (7 + bits_sz) / 8;
	std::fill(out, out + out_sz, 0);
   for(size_t i = 0; i < bits_sz; ++i) {
      out[i / 8] ^= in[bits[i]] << (7 - (i % 8));
   }
   return out_sz;
}

/**
 * Extract value of bits from in[bits[0..bits_sz)).
 *
 * \param in The input const_bit_vector.
 * \param begin The offset of the first bit to extract (the MSB).
 * \param end The offset of the end bit.
 * \return A uint64_t containing the value
 */
template<class X>
uint64_t extract(const X& in, int begin, int end)
{
   uint64_t x = 0LL;
   for(int i = begin; i < end; ++i) {
      x =  (x << 1) | (in[i] ? 1 : 0);
   }
   return x;
}

/**
 * Extract value of bits from in[bits[0..bits_sz)).
 *
 * \param in A const reference to the source.
 * \param bits An array specifying the ordinals of the bits to extract.
 * \param bits_sz The size of the bits array.
 * \return A uint64_t containing the value
 */
template<class X>
uint64_t extract(const X& in, const size_t bits[], size_t bits_sz)
{
   uint64_t x = 0LL;
   for(size_t i = 0; i < bits_sz; ++i) {
      x =  (x << 1) | (in[bits[i]] ? 1 : 0);
   }
   return x;
}

#endif // INCLUDED_SWAB_H