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
35static inline void bitcpy(
36 uint_least8_t *dst, uint_least8_t src, uint_least8_t mask);
37
38void
39bcpybe(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
122void
123bcpyle(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
206static inline void
207bitcpy(uint_least8_t *dst, uint_least8_t src, uint_least8_t mask)
208{
209 *dst = (((src ^ *dst) & mask) ^ *dst) & 0xff;
210}
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
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
This header file is part of the utilities library; it contains the byte order (endianness) function d...
This is the internal header file of the utilities library.