This source file includes following definitions.
- flex128_init
- flex128_finalize
- flex128_get_max_size
- flex128_encode_int
- flex128_decode_int
- flex_pack_integer
- flex_unpack_integer
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <src/include/pmix_config.h>
14
15 #include <pmix_common.h>
16
17 #include "src/include/pmix_socket_errno.h"
18 #include "src/include/pmix_globals.h"
19 #include "src/util/argv.h"
20 #include "src/util/error.h"
21 #include "src/util/output.h"
22
23 #include <unistd.h>
24 #ifdef HAVE_SYS_TYPES_H
25 #include <sys/types.h>
26 #endif
27
28 #include "src/mca/psquash/base/base.h"
29 #include "psquash_flex128.h"
30
31
32 #define FLEX_BASE7_MAX_BUF_SIZE (SIZEOF_SIZE_T+1)
33 #define FLEX_BASE7_MASK ((1<<7) - 1)
34 #define FLEX_BASE7_SHIFT 7
35 #define FLEX_BASE7_CONT_FLAG (1<<7)
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #define FLEX128_PACK_CONVERT_SIGNED(type, ptr, out) \
52 do { \
53 type __tbuf = 0; \
54 size_t __tmp; \
55 int __sign = 0; \
56 memcpy(&__tbuf, (ptr), sizeof(type)); \
57 __tmp = __tbuf; \
58 (out) = (size_t)__tmp; \
59 if (__tmp & (1UL << (sizeof(__tmp)*CHAR_BIT-1))) { \
60 __sign = 1; \
61 out = ~(out); \
62 } \
63 (out) = ((out) << 1) + __sign; \
64 } while (0)
65
66
67
68
69
70
71
72
73
74
75
76
77 #define FLEX128_PACK_CONVERT_UNSIGNED(type, ptr, out) \
78 do { \
79 type __tbuf = 0; \
80 memcpy(&__tbuf, (ptr), sizeof(type)); \
81 out = __tbuf; \
82 } while (0)
83
84
85
86
87
88
89
90
91
92
93
94 #define FLEX128_PACK_CONVERT(r, t, s, d) \
95 do { \
96 (r) = PMIX_SUCCESS; \
97 switch (t) { \
98 case PMIX_INT16: \
99 FLEX128_PACK_CONVERT_SIGNED(int16_t, s, d); \
100 break; \
101 case PMIX_UINT16: \
102 FLEX128_PACK_CONVERT_UNSIGNED(uint16_t, s, d); \
103 break; \
104 case PMIX_INT: \
105 case PMIX_INT32: \
106 FLEX128_PACK_CONVERT_SIGNED(int32_t, s, d); \
107 break; \
108 case PMIX_UINT: \
109 case PMIX_UINT32: \
110 FLEX128_PACK_CONVERT_UNSIGNED(uint32_t, s, d); \
111 break; \
112 case PMIX_INT64: \
113 FLEX128_PACK_CONVERT_SIGNED(int64_t, s, d); \
114 break; \
115 case PMIX_SIZE: \
116 FLEX128_PACK_CONVERT_UNSIGNED(size_t, s, d); \
117 break; \
118 case PMIX_UINT64: \
119 FLEX128_PACK_CONVERT_UNSIGNED(uint64_t, s, d); \
120 break; \
121 default: \
122 (r) = PMIX_ERR_BAD_PARAM; \
123 } \
124 } while(0)
125
126
127
128
129
130
131
132
133
134
135 #define FLEX128_UNPACK_CONVERT_SIGNED(type, val, ptr) \
136 do { \
137 type __tbuf = 0; \
138 size_t __tmp = val; \
139 int sign = (__tmp) & 1; \
140 __tmp >>= 1; \
141 if (sign) { \
142 __tmp = ~__tmp; \
143 } \
144 __tbuf = (type)__tmp; \
145 memcpy(ptr, &__tbuf, sizeof(type)); \
146 } while (0)
147
148
149
150
151
152
153
154
155
156
157 #define FLEX128_UNPACK_CONVERT_UNSIGNED(type, val, ptr) \
158 do { \
159 type __tbuf = 0; \
160 __tbuf = (type)val; \
161 memcpy(ptr, &__tbuf, sizeof(type)); \
162 } while (0)
163
164
165
166
167
168
169
170
171
172
173
174
175 #define FLEX128_UNPACK_CONVERT(r, t, s, d) \
176 do { \
177 (r) = PMIX_SUCCESS; \
178 switch (t) { \
179 case PMIX_INT16: \
180 FLEX128_UNPACK_CONVERT_SIGNED(int16_t, s, d); \
181 break; \
182 case PMIX_UINT16: \
183 FLEX128_UNPACK_CONVERT_UNSIGNED(uint16_t, s, d); \
184 break; \
185 case PMIX_INT: \
186 case PMIX_INT32: \
187 FLEX128_UNPACK_CONVERT_SIGNED(int32_t, s, d); \
188 break; \
189 case PMIX_UINT: \
190 case PMIX_UINT32: \
191 FLEX128_UNPACK_CONVERT_UNSIGNED(uint32_t, s, d); \
192 break; \
193 case PMIX_INT64: \
194 FLEX128_UNPACK_CONVERT_SIGNED(int64_t, s, d); \
195 break; \
196 case PMIX_SIZE: \
197 FLEX128_UNPACK_CONVERT_UNSIGNED(size_t, s, d); \
198 break; \
199 case PMIX_UINT64: \
200 FLEX128_UNPACK_CONVERT_UNSIGNED(uint64_t, s, d); \
201 break; \
202 default: \
203 (r) = PMIX_ERR_BAD_PARAM; \
204 } \
205 } while(0)
206
207 static pmix_status_t flex128_init(void);
208
209 static void flex128_finalize(void);
210
211 static pmix_status_t flex128_get_max_size(pmix_data_type_t type, size_t *size);
212
213 static pmix_status_t flex128_encode_int(pmix_data_type_t type, void *src,
214 void *dst, size_t *size);
215
216 static pmix_status_t flex128_decode_int(pmix_data_type_t type, void *src,
217 size_t src_len, void *dest,
218 size_t *dst_size);
219
220 static size_t flex_pack_integer(size_t val,
221 uint8_t out_buf[FLEX_BASE7_MAX_BUF_SIZE]);
222
223 static size_t flex_unpack_integer(const uint8_t in_buf[], size_t buf_size,
224 size_t *out_val, size_t *out_val_size);
225
226 pmix_psquash_base_module_t pmix_flex128_module = {
227 .name = "flex128",
228 .int_type_is_encoded = true,
229 .init = flex128_init,
230 .finalize = flex128_finalize,
231 .get_max_size = flex128_get_max_size,
232 .encode_int = flex128_encode_int,
233 .decode_int = flex128_decode_int
234 };
235
236
237 static pmix_status_t flex128_init(void)
238 {
239 pmix_output_verbose(2, pmix_globals.debug_output,
240 "psquash: flex128 init");
241 return PMIX_SUCCESS;
242 }
243
244 static void flex128_finalize(void)
245 {
246 pmix_output_verbose(2, pmix_globals.debug_output,
247 "psquash: flex128 finalize");
248 }
249
250 static pmix_status_t flex128_get_max_size(pmix_data_type_t type, size_t *size)
251 {
252 pmix_status_t rc;
253 PMIX_SQUASH_TYPE_SIZEOF(rc, type, *size);
254
255
256 *size += 1;
257 return rc;
258 }
259
260 static pmix_status_t flex128_encode_int(pmix_data_type_t type, void *src,
261 void *dst, size_t *size)
262 {
263 pmix_status_t rc = PMIX_SUCCESS;
264 uint8_t tmp_buf[FLEX_BASE7_MAX_BUF_SIZE];
265 uint64_t tmp;
266
267 FLEX128_PACK_CONVERT(rc, type, (uint8_t*)src, tmp);
268 if (PMIX_SUCCESS != rc) {
269 PMIX_ERROR_LOG(rc);
270 return rc;
271 }
272 *size = flex_pack_integer(tmp, tmp_buf);
273 memcpy(dst, tmp_buf, *size);
274
275 return rc;
276 }
277
278 static pmix_status_t flex128_decode_int(pmix_data_type_t type, void *src,
279 size_t src_len, void *dest, size_t *dst_size)
280 {
281 pmix_status_t rc = PMIX_SUCCESS;
282 size_t tmp;
283 size_t val_size, unpack_val_size;
284
285 PMIX_SQUASH_TYPE_SIZEOF(rc, type, val_size);
286 if (PMIX_SUCCESS != rc) {
287 PMIX_ERROR_LOG(rc);
288 return rc;
289 }
290 *dst_size = flex_unpack_integer(src, src_len, &tmp, &unpack_val_size);
291
292 if( val_size < unpack_val_size ) {
293 rc = PMIX_ERR_UNPACK_FAILURE;
294 PMIX_ERROR_LOG(rc);
295 return rc;
296 }
297 FLEX128_UNPACK_CONVERT(rc, type, tmp, (uint8_t*)dest);
298 if (PMIX_SUCCESS != rc) {
299 PMIX_ERROR_LOG(rc);
300 return rc;
301 }
302
303 return rc;
304 }
305
306
307
308
309
310
311
312
313
314
315
316 static size_t flex_pack_integer(size_t val,
317 uint8_t out_buf[FLEX_BASE7_MAX_BUF_SIZE])
318 {
319 size_t tmp = val;
320 size_t idx = 0;
321
322 do {
323 uint8_t val = tmp & FLEX_BASE7_MASK;
324 tmp >>= FLEX_BASE7_SHIFT;
325 if (PMIX_UNLIKELY(tmp)) {
326 val |= FLEX_BASE7_CONT_FLAG;
327 }
328 out_buf[idx++] = val;
329 } while(tmp && idx < SIZEOF_SIZE_T);
330
331
332 if (PMIX_UNLIKELY(SIZEOF_SIZE_T == idx && tmp)) {
333 out_buf[idx++] = tmp;
334 }
335
336 return idx;
337 }
338
339
340
341
342 static size_t flex_unpack_integer(const uint8_t in_buf[], size_t buf_size,
343 size_t *out_val, size_t *out_val_size)
344 {
345 size_t value = 0, shift = 0, shift_last = 0;
346 size_t idx = 0;
347 uint8_t val = 0, val_last = 0;
348 uint8_t hi_bit = 0;
349 size_t flex_size = buf_size;
350
351
352 if (buf_size > FLEX_BASE7_MAX_BUF_SIZE) {
353 flex_size = FLEX_BASE7_MAX_BUF_SIZE;
354 }
355
356 do {
357 val = in_buf[idx++];
358 val_last = val;
359 shift_last = shift;
360 value = value + (((uint64_t)val & FLEX_BASE7_MASK) << shift);
361 shift += FLEX_BASE7_SHIFT;
362 } while(PMIX_UNLIKELY((val & FLEX_BASE7_CONT_FLAG) &&
363 (idx < (flex_size-1))));
364
365 if (PMIX_UNLIKELY((flex_size-1) == idx &&
366 (val & FLEX_BASE7_CONT_FLAG))) {
367 val = in_buf[idx++];
368 val_last = val;
369 value = value + ((uint64_t)val << shift);
370 shift_last = shift;
371 }
372
373 while (val_last != 0) {
374 val_last >>= 1;
375 hi_bit++;
376 }
377
378 *out_val_size = (hi_bit + shift_last)/CHAR_BIT +
379 !!((hi_bit + shift_last) & (CHAR_BIT - 1));
380 *out_val = value;
381
382 return idx;
383 }