Hi Luc,
Next time I will surely put the code in pre tag. I have pasted the header file and c file. I have to integrate this in my c++ project. It is a vendor code.
Regards
Arup
common_util.h
#ifndef BITOP_H_
#define BITOP_H_
#include "limetypes.hh"
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
namespace LimeBrokerage {
#endif /* __cplusplus */
#ifndef MIN
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#endif
#ifndef MAX
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#endif
enum BIT_FIELD_SIGN { BIT_FIELD_POSITIVE_SIGN, BIT_FIELD_NEGATIVE_SIGN };
#define CONCAT(x,y) x##y
#define _CT_ASSERT(expr,unique) char CONCAT(constraint,unique)[(expr)?1:-1]
#define COMPILE_TIME_ASSERT(expr) _CT_ASSERT(expr,__LINE__)
#define DECODE_DECLARATION_BODY(type, name, value) \
, type* name##_val
#define DECODE_DECLARATION(name, list) \
int name##_decode(name##_t* __result \
list(DECODE_DECLARATION_BODY) \
)
#define DECODE_DEBUG_DECLARATION(name, list) \
int name##_decode_debug(name##_t* __result \
list(DECODE_DECLARATION_BODY) \
)
#define DECODE_DEFINITION_BODY(type, name, value) \
__shift_bits -= name; \
__tmp = *__result >> __shift_bits; \
__tmp &= (__one << name) - 1; \
*name##_val = __tmp; \
__tmp = 0;
#define DECODE_BODY(name, list) \
{ \
name##_t __tmp = 0;\
name##_t __one = 1;\
int __shift_bits = sizeof(name##_t) * 8; \
list(DECODE_DEFINITION_BODY) \
#define DECODE_DEFINITION(name, list) \
DECODE_DECLARATION(name, list) \
DECODE_BODY(name, list) \
return 0; \
} \
#define POPULATE_RES_STRING(type, name, value) \
__pos += sprintf(&__output_str[__pos], "%d, ", (int) (* name##_val));
#define PRINT_RESULTS(function, name, list) \
int __pos = 0; \
char __output_str[1024*10]; \
list(POPULATE_RES_STRING) \
printf("%s: %lld = %s\n", #function, (long long int)(*__result), __output_str); \
return 0; \
#define DECODE_DEBUG_DEFINITION(name, list) \
DECODE_DEBUG_DECLARATION(name, list)\
DECODE_BODY(name, list) \
PRINT_RESULTS(decode, name, list) \
} \
#define ENCODE_DECLARATION_BODY(type, name, value) \
, type* name##_val
#define ENCODE_DECLARATION(name, list) \
int name##_encode(name##_t* __result \
list(ENCODE_DECLARATION_BODY) \
)
#define ENCODE_DEBUG_DECLARATION(name, list) \
int name##_encode_debug(name##_t* __result \
list(ENCODE_DECLARATION_BODY) \
)
#define ENCODE_DEFINITION_BODY(type, name, value) \
__shift_bits -= name; \
__tmp = *name##_val; \
__tmp = __tmp << __shift_bits; \
*__result |= __tmp;
#define ENCODE_BODY(name, list) \
{ \
name##_t __tmp = 0; \
name##_t __one = 1; \
int __shift_bits = sizeof(name##_t) * 8; \
list(ENCODE_DEFINITION_BODY) \
#define ENCODE_DEFINITION(name, list) \
ENCODE_DECLARATION(name, list) \
ENCODE_BODY(name, list) \
return 0; \
}
#define ENCODE_DEBUG_DEFINITION(name, list) \
ENCODE_DEBUG_DECLARATION(name, list) \
ENCODE_BODY(name, list) \
PRINT_RESULTS(encode, name, list) \
return 0; \
}
#define BITFIELD_SUM(type, name, value) \
+ name
#define BITOP_DEFINITION_BODY(type, name, value) \
name = value,
#define BITOP_DEFINITION(name, list) \
enum name##_bits { \
list(BITOP_DEFINITION_BODY) \
}; \
typedef enum name##_bits name##_bits_t; \
ENCODE_DECLARATION(name, list); \
DECODE_DECLARATION(name, list);
#define BITOP_COMPILE_TIME_ASSERT(name, list) \
COMPILE_TIME_ASSERT((sizeof(name##_t) * 8) == \
0 \
list(BITFIELD_SUM) \
);
typedef struct limeq_price {
int32_t mantissa;
int8_t exponent;
} limeq_price;
uint8_t greater_common_divider(void* set, size_t element_size, size_t element_offset, size_t nmemb);
void normalize_mantissa(limeq_price* price, int8_t* min_exponent);
bool normalize_exponent(limeq_price* set, size_t nmemb, int8_t* min_exponent);
#define SIAC_SALES_CONDITIONS_LEN 4
#define SIAC_LONG_MSG_SALE_CONDITIONS 1
bool decode_siac_sales_conditions(uint8_t siac_sales_conditions, uint8_t additionalProperties, char sales_conditions[SIAC_SALES_CONDITIONS_LEN]);
void encode_siac_sales_conditions(uint8_t *reserved, uint8_t *additional_prop, char sales_conditions[SIAC_SALES_CONDITIONS_LEN]);
uint64_t lime_ntohll(uint64_t);
uint64_t lime_htonll(uint64_t);
#ifdef __cplusplus
}
}
#endif /* __cplusplus */
#endif /* BITOP_H_ */
common_util.c
#include <stdio.h>
#include "common_util.h"
#include "limeq_def.h"
#ifdef __linux__
#include "byteswap.h"
#endif
#ifdef WIN32
#include <winsock2.h>
#include <Windows.h>
#endif
#ifdef __cplusplus
extern "C" {
namespace LimeBrokerage {
#endif /* __cplusplus */
const int power10[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
};
const int power10_size = sizeof(power10)/sizeof(power10[0]);
static const uint8_t _prime_numbers[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107,
109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167,
173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,
239, 241, 251
};
static const uint8_t _prime_numbers_size = sizeof(_prime_numbers)/sizeof(_prime_numbers[0]);
uint8_t* _get_element(void* array, int array_pos, size_t struct_size, size_t field_offset)
{
return (uint8_t*)((uint8_t*)array+(array_pos * struct_size) + field_offset);
}
#define MAX_ELEMENTS 1024
static uint8_t divided_set[MAX_ELEMENTS];
uint8_t greater_common_divider(void* set, size_t element_size, size_t element_offset, size_t nmemb)
{
uint8_t res = 1;
size_t es = element_size;
size_t eo = element_offset;
void* current_set = set;
if (nmemb > MAX_ELEMENTS) return 1;
for (int i = 0; i < _prime_numbers_size; i++) {
bool all_divided = true;
for (int j = 0; j < nmemb; j++) {
uint8_t* element = _get_element(current_set, j, es, eo);
if (_prime_numbers[i] > *element) {
return res;
}
if (((*element) % _prime_numbers[i]) == 0) {
divided_set[j] = (*element) / _prime_numbers[i];
}
else {
all_divided = false;
}
}
if (all_divided) {
res *= _prime_numbers[i];
current_set = divided_set;
es = 1;
eo = 0;
}
}
return res;
}
void normalize_mantissa(limeq_price* price, int8_t* min_exponent)
{
int zeroes = 0;
for (int i = 1; i < power10_size; i++) {
if ((price->mantissa % power10[i]) == 0) {
zeroes = i;
}
else {
break;
}
}
price->mantissa /= power10[zeroes];
price->exponent += zeroes;
if (abs(price->exponent) > power10_size) {
int diff = price->exponent - power10_size;
price->mantissa *= power10[diff];
price->exponent += diff;
}
*min_exponent = MIN(*min_exponent, price->exponent);
}
bool normalize_exponent(limeq_price* set, size_t nmemb, int8_t* min_exponent)
{
for (int i = 0; i < nmemb; i++) {
int8_t exp = set[i].exponent - *min_exponent;
if (abs(exp) > power10_size) {
printf("Exponent is too big %d\n", exp);
return false;
}
if (exp < 0) {
set[i].mantissa /= power10[exp * -1];
}
else {
set[i].mantissa *= power10[exp];
}
set[i].exponent = *min_exponent;
}
return true;
}
void encode_siac_sales_conditions(uint8_t *reserved, uint8_t *additional_prop,
char sales_conditions[SIAC_SALES_CONDITIONS_LEN]) {
*reserved = 0;
*additional_prop = 0;
switch (sales_conditions[0]) {
case '@':
*reserved |= 15 << 0;
break;
case ' ':
*reserved |= 14 << 0;
break;
case 'C':
*reserved |= 13 << 0;
break;
case 'N':
*reserved |= 12 << 0;
break;
case 'R':
*reserved |= 11 << 0;
break;
default:
*reserved |= 0 << 0;
break;
}
switch (sales_conditions[1]) {
case ' ':
*reserved |= 15 << 4;
break;
case 'F':
*reserved |= 14 << 4;
break;
case 'O':
*reserved |= 13 << 4;
break;
case '4':
*reserved |= 12 << 4;
break;
case '5':
*reserved |= 11 << 4;
break;
case '6':
*reserved |= 10 << 4;
break;
case '7':
*reserved |= 9 << 4;
break;
case '8':
*reserved |= 8 << 4;
break;
case '9':
*reserved |= 7 << 4;
break;
default:
*reserved |= 0 << 4;
break;
}
switch (sales_conditions[2]) {
case ' ':
*additional_prop |= 15 << 0;
break;
case 'L':
*additional_prop |= 14 << 0;
break;
case 'T':
*additional_prop |= 13 << 0;
break;
case 'U':
*additional_prop |= 12 << 0;
break;
case 'Z':
*additional_prop |= 11 << 0;
break;
default:
*additional_prop |= 0 << 0;
break;
}
switch (sales_conditions[3]) {
case ' ':
*additional_prop |= 15 << 4;
break;
case 'B':
*additional_prop |= 14 << 4;
break;
case 'E':
*additional_prop |= 13 << 4;
break;
case 'G':
*additional_prop |= 12 << 4;
break;
case 'H':
*additional_prop |= 11 << 4;
break;
case 'I':
*additional_prop |= 10 << 4;
break;
case 'K':
*additional_prop |= 9 << 4;
break;
case 'P':
*additional_prop |= 8 << 4;
break;
case 'Q':
*additional_prop |= 7 << 4;
break;
case 'X':
*additional_prop |= 6 << 4;
break;
default:
*additional_prop |= 0 << 4;
break;
}
}
bool decode_siac_sales_conditions(uint8_t siac_sales_conditions,
uint8_t additionalProperties,
char sales_conditions[SIAC_SALES_CONDITIONS_LEN]) {
uint8_t byte_0 = siac_sales_conditions & 0xF;
uint8_t byte_1 = ((siac_sales_conditions & 0xF0) >> 4);
uint8_t byte_2 = (additionalProperties & 0xF);
uint8_t byte_3 = ((additionalProperties & 0xF0) >> 4);
bool res = true;
switch (byte_0) {
case 15:
sales_conditions[0] = '@';
break;
case 14:
sales_conditions[0] = ' ';
break;
case 13:
sales_conditions[0] = 'C';
break;
case 12:
sales_conditions[0] = 'N';
break;
case 11:
sales_conditions[0] = 'R';
break;
default:
sales_conditions[0] = 13;
res = false;
break;
}
switch (byte_1) {
case 15:
sales_conditions[1] = ' ';
break;
case 14:
sales_conditions[1] = 'F';
break;
case 13:
sales_conditions[1] = 'O';
break;
case 12:
sales_conditions[1] = '4';
break;
case 11:
sales_conditions[1] = '5';
break;
case 10:
sales_conditions[1] = '6';
break;
case 9:
sales_conditions[1] = '7';
break;
case 8:
sales_conditions[1] = '8';
break;
case 7:
sales_conditions[1] = '9';
break;
default:
sales_conditions[1] = 13;
res = false;
break;
}
switch (byte_2) {
case 15:
sales_conditions[2] = ' ';
break;
case 14:
sales_conditions[2] = 'L';
break;
case 13:
sales_conditions[2] = 'T';
break;
case 12:
sales_conditions[2] = 'U';
break;
case 11:
sales_conditions[2] = 'Z';
break;
default:
sales_conditions[2] = 13;
res = false;
break;
}
switch (byte_3) {
case 15:
sales_conditions[3] = ' ';
break;
case 14:
sales_conditions[3] = 'B';
break;
case 13:
sales_conditions[3] = 'E';
break;
case 12:
sales_conditions[3] = 'G';
break;
case 11:
sales_conditions[3] = 'H';
break;
case 10:
sales_conditions[3] = 'I';
break;
case 9:
sales_conditions[3] = 'K';
break;
case 8:
sales_conditions[3] = 'P';
break;
case 7:
sales_conditions[3] = 'Q';
break;
case 6:
sales_conditions[3] = 'X';
break;
default:
sales_conditions[3] = 13;
res = false;
break;
}
return res;
}
ENCODE_DEFINITION(leg_def_data, LEG_INFO_REQUEST_BITS_LIST);
DECODE_DEFINITION(leg_def_data, LEG_INFO_REQUEST_BITS_LIST);
ENCODE_DEFINITION(spread_data, SPREAD_DATA_BITS_LIST);
DECODE_DEFINITION(spread_data, SPREAD_DATA_BITS_LIST);
#ifndef __bswap_64
#define __bswap_64(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) | (unsigned int)ntohl(((int)(x >> 32))))
#endif //__linux__
# if BYTE_ORDER == LITTLE_ENDIAN
# define htobe64(x) __bswap_64 (x)
# define htole64(x) (x)
# define be64toh(x) __bswap_64 (x)
# define le64toh(x) (x)
# else
# define htobe64(x) (x)
# define htole64(x) __bswap_64 (x)
# define be64toh(x) (x)
# define le64toh(x) __bswap_64 (x)
# endif
uint64_t lime_ntohll(uint64_t val) {
return be64toh(val);
}
uint64_t lime_htonll(uint64_t val) {
return htobe64(val);
}
#ifdef __cplusplus
}
}
#endif
|