21#include <freerdp/config.h>
23#include <freerdp/channels/log.h>
24#include <freerdp/utils/encoded_types.h>
27#define TAG CHANNELS_TAG("encoded_types")
39} EncodedTypeByteCount;
49 EncodedTypeByteCount c;
55} FOUR_BYTE_SIGNED_INTEGER;
59 EncodedTypeByteCount c;
68static inline FOUR_BYTE_SIGNED_INTEGER FOUR_BYTE_SIGNED_INTEGER_init(
void)
70 const FOUR_BYTE_SIGNED_INTEGER empty = {
71 .c = ONE_BYTE_VAL, .s = POSITIVE_VAL, .val1 = 0, .val2 = 0, .val3 = 0, .val4 = 0
76static inline FOUR_BYTE_FLOAT FOUR_BYTE_FLOAT_init(
void)
78 const FOUR_BYTE_FLOAT empty = {
79 .c = ONE_BYTE_VAL, .s = POSITIVE_VAL, .e = 0, .val1 = 0, .val2 = 0, .val3 = 0, .val4 = 0
84BOOL freerdp_read_four_byte_signed_integer(
wStream* s, INT32* value)
86 FOUR_BYTE_SIGNED_INTEGER si = FOUR_BYTE_SIGNED_INTEGER_init();
94 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
97 Stream_Read_UINT8(s,
byte);
99 si.c = (EncodedTypeByteCount)((
byte & 0xC0) >> 6);
100 si.s = (EncodedTypeSign)((
byte & 0x20) >> 5);
101 si.val1 = (
byte & 0x1F);
103 if (!Stream_CheckAndLogRequiredLength(TAG, s, si.c))
112 Stream_Read_UINT8(s, si.val2);
113 *value = (((INT32)si.val1) << 8) | ((INT32)si.val2);
116 Stream_Read_UINT8(s, si.val2);
117 Stream_Read_UINT8(s, si.val3);
118 *value = (((INT32)si.val1) << 16) | (((INT32)si.val2) << 8) | ((INT32)si.val3);
121 Stream_Read_UINT8(s, si.val2);
122 Stream_Read_UINT8(s, si.val3);
123 Stream_Read_UINT8(s, si.val4);
124 *value = (((INT32)si.val1) << 24) | (((INT32)si.val2) << 16) | (((INT32)si.val3) << 8) |
132 WLog_ERR(TAG,
"Invalid byte count value in si.c: %u", si.c);
136 if (si.s == NEGATIVE_VAL)
142BOOL freerdp_write_four_byte_signed_integer(
wStream* s, INT32 value)
144 FOUR_BYTE_SIGNED_INTEGER si = FOUR_BYTE_SIGNED_INTEGER_init();
147 if (value > FREERDP_FOUR_BYTE_SIGNED_INT_MAX)
149 if (value < FREERDP_FOUR_BYTE_SIGNED_INT_MIN)
161 si.val1 = value & 0x1f;
163 else if (value <= 0x1FFF)
166 si.val1 = (value >> 8) & 0x1f;
167 si.val2 = value & 0xff;
169 else if (value <= 0x1FFFFF)
171 si.c = THREE_BYTE_VAL;
172 si.val1 = (value >> 16) & 0x1f;
173 si.val2 = (value >> 8) & 0xff;
174 si.val3 = value & 0xff;
176 else if (value <= 0x1FFFFFFF)
178 si.c = FOUR_BYTE_VAL;
179 si.val1 = (value >> 24) & 0x1f;
180 si.val2 = (value >> 16) & 0xff;
181 si.val3 = (value >> 8) & 0xff;
182 si.val4 = value & 0xff;
186 WLog_ERR(TAG,
"Invalid byte count for value %" PRId32, value);
190 if (!Stream_EnsureRemainingCapacity(s, si.c + 1))
193 const BYTE
byte = ((si.c << 6) & 0xC0) | ((si.s << 5) & 0x20) | (si.val1 & 0x1F);
194 Stream_Write_UINT8(s,
byte);
201 Stream_Write_UINT8(s, si.val2);
204 Stream_Write_UINT8(s, si.val2);
205 Stream_Write_UINT8(s, si.val3);
208 Stream_Write_UINT8(s, si.val2);
209 Stream_Write_UINT8(s, si.val3);
210 Stream_Write_UINT8(s, si.val4);
217 WLog_ERR(TAG,
"Invalid byte count value in si.c: %u", si.c);
224BOOL freerdp_read_four_byte_float(
wStream* s,
double* value)
226 return freerdp_read_four_byte_float_exp(s, value, NULL);
229BOOL freerdp_read_four_byte_float_exp(
wStream* s,
double* value, BYTE* exp)
231 FOUR_BYTE_FLOAT f = FOUR_BYTE_FLOAT_init();
240 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
243 Stream_Read_UINT8(s,
byte);
245 f.c = (EncodedTypeByteCount)((
byte & 0xC0) >> 6);
246 f.s = (EncodedTypeSign)((
byte & 0x20) >> 5);
247 f.e = (
byte & 0x1C) >> 2;
248 f.val1 = (
byte & 0x03);
250 if (!Stream_CheckAndLogRequiredLength(TAG, s, f.c))
259 Stream_Read_UINT8(s, f.val2);
260 base = (((UINT32)f.val1) << 8) | ((UINT32)f.val2);
263 Stream_Read_UINT8(s, f.val2);
264 Stream_Read_UINT8(s, f.val3);
265 base = (((UINT32)f.val1) << 16) | (((UINT32)f.val2) << 8) | ((UINT32)f.val3);
268 Stream_Read_UINT8(s, f.val2);
269 Stream_Read_UINT8(s, f.val3);
270 Stream_Read_UINT8(s, f.val4);
271 base = (((UINT32)f.val1) << 24) | (((UINT32)f.val2) << 16) | (((UINT32)f.val3) << 8) |
279 WLog_ERR(TAG,
"Invalid byte count value in f.c: %u", f.c);
284 *value /= pow(10, f.e);
286 if (f.s == NEGATIVE_VAL)
295BOOL freerdp_write_four_byte_float(
wStream* s,
double value)
297 FOUR_BYTE_FLOAT si = FOUR_BYTE_FLOAT_init();
301 if (value > FREERDP_FOUR_BYTE_FLOAT_MAX)
303 if (value < FREERDP_FOUR_BYTE_FLOAT_MIN)
313 double ival = FP_NAN;
314 const double aval = fabs(value);
315 const double frac = modf(aval, &ival);
318 const double maxfrac = frac * 10000000.0;
321 else if (maxfrac <= 10.0)
323 else if (maxfrac <= 100.0)
325 else if (maxfrac <= 1000.0)
327 else if (maxfrac <= 10000.0)
329 else if (maxfrac <= 100000.0)
331 else if (maxfrac <= 1000000.0)
337 UINT64 base = (UINT64)llround(aval);
340 const double div = pow(10.0, exp);
341 const double dval = (aval * div);
343 if (base <= 0x03ffffff)
355 si.val1 = base & 0x03;
357 else if (base <= 0x03ff)
360 si.val1 = (base >> 8) & 0x03;
361 si.val2 = base & 0xff;
363 else if (base <= 0x03ffff)
365 si.c = THREE_BYTE_VAL;
366 si.val1 = (base >> 16) & 0x03;
367 si.val2 = (base >> 8) & 0xff;
368 si.val3 = base & 0xff;
370 else if (base <= 0x03ffffff)
372 si.c = FOUR_BYTE_VAL;
373 si.val1 = (base >> 24) & 0x03;
374 si.val2 = (base >> 16) & 0xff;
375 si.val3 = (base >> 8) & 0xff;
376 si.val4 = base & 0xff;
380 WLog_ERR(TAG,
"Invalid byte count for value %lf", value);
384 if (!Stream_EnsureRemainingCapacity(s, si.c + 1))
388 ((si.c << 6) & 0xC0) | ((si.s << 5) & 0x20) | ((si.e << 2) & 0x1c) | (si.val1 & 0x03);
389 Stream_Write_UINT8(s,
byte);
396 Stream_Write_UINT8(s, si.val2);
399 Stream_Write_UINT8(s, si.val2);
400 Stream_Write_UINT8(s, si.val3);
403 Stream_Write_UINT8(s, si.val2);
404 Stream_Write_UINT8(s, si.val3);
405 Stream_Write_UINT8(s, si.val4);
412 WLog_ERR(TAG,
"Invalid byte count value in si.c: %u", si.c);