Lely core libraries  2.3.4
endian.c
Go to the documentation of this file.
1 
25 // Disable macro definitions of htobe*() and htole*(). This ensures our
26 // implementation of these functions is exported.
27 #define __NO_STRING_INLINES
28 
29 #include "util.h"
30 #define LELY_UTIL_ENDIAN_INLINE extern inline
31 #include <lely/util/endian.h>
32 
33 #include <assert.h>
34 
35 static inline void bitcpy(
36  uint_least8_t *dst, uint_least8_t src, uint_least8_t mask);
37 
38 void
39 bcpybe(uint_least8_t *dst, int dstbit, const uint_least8_t *src, int srcbit,
40  size_t n)
41 {
42  if (!n)
43  return;
44 
45  assert(dst);
46  assert(src);
47 
48  dst += dstbit / 8;
49  dstbit %= 8;
50  if (dstbit < 0) {
51  dst--;
52  dstbit += 8;
53  }
54 
55  src += srcbit / 8;
56  srcbit %= 8;
57  if (srcbit < 0) {
58  src--;
59  srcbit += 8;
60  }
61 
62  uint_least8_t first = 0xff >> dstbit;
63  uint_least8_t last = ~(0xff >> ((dstbit + n) % 8)) & 0xff;
64 
65  int shift = dstbit - srcbit;
66  if (shift) {
67  int right = shift & (8 - 1);
68  int left = -shift & (8 - 1);
69 
70  if (dstbit + n <= 8) {
71  if (last)
72  first &= last;
73  if (shift > 0) {
74  bitcpy(dst, *src >> right, first);
75  } else if (srcbit + n <= 8) {
76  bitcpy(dst, *src << left, first);
77  } else {
78  bitcpy(dst, *src << left | src[1] >> right,
79  first);
80  }
81  } else {
82  uint_least8_t b = *src++ & 0xff;
83  if (shift > 0) {
84  bitcpy(dst, b >> right, first);
85  } else {
86  bitcpy(dst, b << left | *src >> right, first);
87  b = *src++ & 0xff;
88  }
89  dst++;
90  n -= 8 - dstbit;
91 
92  n /= 8;
93  while (n--) {
94  *dst++ = (b << left | *src >> right) & 0xff;
95  b = *src++ & 0xff;
96  }
97 
98  if (last)
99  bitcpy(dst, b << left | *src >> right, last);
100  }
101  } else {
102  if (dstbit + n <= 8) {
103  if (last)
104  first &= last;
105  bitcpy(dst, *src, first);
106  } else {
107  if (dstbit > 0) {
108  bitcpy(dst++, *src++, first);
109  n -= 8 - dstbit;
110  }
111 
112  n /= 8;
113  while (n--)
114  *dst++ = *src++ & 0xff;
115 
116  if (last)
117  bitcpy(dst, *src, last);
118  }
119  }
120 }
121 
122 void
123 bcpyle(uint_least8_t *dst, int dstbit, const uint_least8_t *src, int srcbit,
124  size_t n)
125 {
126  if (!n)
127  return;
128 
129  assert(dst);
130  assert(src);
131 
132  dst += dstbit / 8;
133  dstbit %= 8;
134  if (dstbit < 0) {
135  dst--;
136  dstbit += 8;
137  }
138 
139  src += srcbit / 8;
140  srcbit %= 8;
141  if (srcbit < 0) {
142  src--;
143  srcbit += 8;
144  }
145 
146  uint_least8_t first = (0xff << dstbit) & 0xff;
147  uint_least8_t last = ~(0xff << ((dstbit + n) % 8)) & 0xff;
148 
149  int shift = dstbit - srcbit;
150  if (shift) {
151  int right = -shift & (8 - 1);
152  int left = shift & (8 - 1);
153 
154  if (dstbit + n <= 8) {
155  if (last)
156  first &= last;
157  if (shift > 0) {
158  bitcpy(dst, *src << left, first);
159  } else if (srcbit + n <= 8) {
160  bitcpy(dst, *src >> right, first);
161  } else {
162  bitcpy(dst, *src >> right | src[1] << left,
163  first);
164  }
165  } else {
166  uint_least8_t b = *src++ & 0xff;
167  if (shift > 0) {
168  bitcpy(dst, b << left, first);
169  } else {
170  bitcpy(dst, b >> right | *src << left, first);
171  b = *src++ & 0xff;
172  }
173  dst++;
174  n -= 8 - dstbit;
175 
176  n /= 8;
177  while (n--) {
178  *dst++ = (b >> right | *src << left) & 0xff;
179  b = *src++ & 0xff;
180  }
181 
182  if (last)
183  bitcpy(dst, b >> right | *src << left, last);
184  }
185  } else {
186  if (dstbit + n <= 8) {
187  if (last)
188  first &= last;
189  bitcpy(dst, *src, first);
190  } else {
191  if (dstbit > 0) {
192  bitcpy(dst++, *src++, first);
193  n -= 8 - dstbit;
194  }
195 
196  n /= 8;
197  while (n--)
198  *dst++ = *src++ & 0xff;
199 
200  if (last)
201  bitcpy(dst, *src, last);
202  }
203  }
204 }
205 
206 static inline void
207 bitcpy(uint_least8_t *dst, uint_least8_t src, uint_least8_t mask)
208 {
209  *dst = (((src ^ *dst) & mask) ^ *dst) & 0xff;
210 }
util.h
bcpyle
void bcpyle(uint_least8_t *dst, int dstbit, const uint_least8_t *src, int srcbit, size_t n)
Copies n bits from a source to a destination buffer.
Definition: endian.c:123
bcpybe
void bcpybe(uint_least8_t *dst, int dstbit, const uint_least8_t *src, int srcbit, size_t n)
Copies n bits from a source to a destination buffer.
Definition: endian.c:39
endian.h