#include<iostream>
namespace FIX
{
typedef int signed_int;
typedef unsigned int unsigned_int;
#define UNSIGNED_VALUE_OF( x ) ( ( x < 0 ) ? -unsigned_int(x) : unsigned_int(x) )
#define IS_SPACE( x ) ( x == ' ' )
#define IS_DIGIT( x ) ( unsigned_int( x - '0' ) < 10 )
inline int number_of_symbols_in(const signed_int value)
{
unsigned_int number = UNSIGNED_VALUE_OF(value);
int symbols = 0;
while (number > 9999)
{
symbols += 4;
number /= 10000;
}
// small tweak to make comparison times consistent
// always 2 comparisons instead of [1 - 4]
if (number > 99)
{
if (number > 999)
symbols += 4;
else
symbols += 3;
}
else
{
if (number > 9)
symbols += 2;
else
symbols += 1;
}
if (value < 0)
symbols += 1;
return symbols;
}
static const char digit_pairs[201] = {
"00010203040506070809"
"10111213141516171819"
"20212223242526272829"
"30313233343536373839"
"40414243444546474849"
"50515253545556575859"
"60616263646566676869"
"70717273747576777879"
"80818283848586878889"
"90919293949596979899"
};
inline char* integer_to_string(char* buf, const size_t len, signed_int t)
{
const bool isNegative = t < 0;
char* p = buf + len;
unsigned_int number = UNSIGNED_VALUE_OF(t);
while (number > 99)
{
unsigned_int pos = number % 100;
number /= 100;
*--p = digit_pairs[2 * pos + 1];
*--p = digit_pairs[2 * pos];
}
if (number > 9)
{
*--p = digit_pairs[2 * number + 1];
*--p = digit_pairs[2 * number];
}
else
{
*--p = '0' + char(number);
}
if (isNegative)
*--p = '-';
return p;
}
inline char* integer_to_string_padded(char* buf, const size_t len, signed_int t,const char paddingChar = '0')
{
char* p = integer_to_string(buf, len, t);
while (p > buf)
*--p = paddingChar;
return p;
}
/// Empty converter is a no-op.
struct EmptyConvertor
{
static const std::string& convert(const std::string& value)
{
return value;
}
};
/// Base QuickFIX exception type.
struct Exception
{
Exception(std::string str, std::string str2){}
std::string type;
std::string detail;
};
/// Unable to convert field into its native format
struct FieldConvertError : public Exception
{
FieldConvertError(const std::string& what = ""): Exception("Could not convert field", what) {}
};
/// Field has a badly formatted value
struct IncorrectDataFormat : public Exception
{
IncorrectDataFormat(int f = 0, const std::string& what = ""): Exception("Incorrect data format for value", what),field(f) {}
int field;
};
struct IntConvertor
{
static std::string convert(signed_int value)
{
// buffer is big enough for significant digits and extra digit,
// minus and null
char buffer[std::numeric_limits<signed_int>::digits10 + 2];
const char* const start= integer_to_string(buffer, sizeof(buffer), value);
return std::string(start, buffer + sizeof(buffer) - start);
}
static bool convert(std::string::const_iterator str,std::string::const_iterator end,signed_int& result)
{
bool isNegative = false;
signed_int x = 0;
if (str == end)
return false;
if (*str == '-')
{
isNegative = true;
if (++str == end)
return false;
}
do
{
const unsigned_int c = *str - '0';
if (c > 9) return false;
x = 10 * x + c;
} while (++str != end);
if (isNegative)
x = -unsigned_int(x);
result = x;
return true;
}
static bool convert(const std::string& value, signed_int& result)
{
return convert(value.begin(), value.end(), result);
}
static signed_int convert(const std::string& value)throw(FieldConvertError)
{
signed_int result = 0;
if (!convert(value.begin(), value.end(), result))
throw FieldConvertError(value);
else
return result;
}
};
class FieldBase
{
/// Class used to store field metrics like total length and checksum
class field_metrics
{
public:
field_metrics(const size_t length, const int checksum): m_length(length), m_checksum(checksum)
{}
size_t getLength() const
{
return m_length;
}
int getCheckSum() const
{
return m_checksum;
}
bool isValid() const
{
return m_length > 0;
}
private:
size_t m_length;
int m_checksum;
};
friend class Message;
/// Constructor which also calculates field metrics
FieldBase(int tag,std::string::const_iterator valueStart,std::string::const_iterator valueEnd,
std::string::const_iterator tagStart,std::string::const_iterator tagEnd)
: m_tag(tag), m_string(valueStart, valueEnd), m_metrics(calculateMetrics(tagStart, tagEnd))
{}
public:
FieldBase(int tag, const std::string& string)
: m_tag(tag), m_string(string), m_metrics(no_metrics())
{}
virtual ~FieldBase() {}
FieldBase(const FieldBase& rhs)
: m_tag(rhs.getTag())
, m_string(rhs.m_string)
, m_metrics(rhs.m_metrics)
{
}
FieldBase& operator=(const FieldBase& rhs)
{
m_tag = rhs.getTag();
m_string = rhs.m_string;
m_metrics = rhs.m_metrics;
m_data.clear();
return *this;
}
void swap(FieldBase& rhs)
{
std::swap(m_tag, rhs.m_tag);
std::swap(m_metrics, rhs.m_metrics);
m_string.swap(rhs.m_string);
m_data.swap(rhs.m_data);
}
void setTag(int tag)
{
m_tag = tag;
m_metrics = no_metrics();
m_data.clear();
}
/// @deprecated Use setTag
void setField(int field)
{
setTag(field);
}
void setString(const std::string& string)
{
m_string = string;
m_metrics = no_metrics();
m_data.clear();
}
/// Get the fields integer tag.
int getTag() const
{
return m_tag;
}
/// @deprecated Use getTag
int getField() const
{
return getTag();
}
/// Get the string representation of the fields value.
const std::string& getString() const
{
return m_string;
}
/// Get the string representation of the Field (i.e.) 55=MSFT[SOH]
const std::string& getFixString() const
{
if (m_data.empty())
encodeTo(m_data);
return m_data;
}
/// Get the length of the fields string representation
size_t getLength() const
{
calculate();
return m_metrics.getLength();
}
/// Get the total value the fields characters added together
int getTotal() const
{
calculate();
return m_metrics.getCheckSum();
}
/// Compares fields based on their tag numbers
bool operator < (const FieldBase& field) const
{
return m_tag < field.m_tag;
}
private:
void calculate() const
{
if (m_metrics.isValid()) return;
m_metrics = calculateMetrics(getFixString());
}
/// Serializes string representation of the Field to input string
void encodeTo(std::string& result) const
{
size_t tagLength = FIX::number_of_symbols_in(m_tag);
size_t totalLength = tagLength + m_string.length() + 2;
result.resize(totalLength);
char * buf = (char*)result.c_str();
FIX::integer_to_string(buf, tagLength, m_tag);
buf[tagLength] = '=';
memcpy(buf + tagLength + 1, m_string.data(), m_string.length());
buf[totalLength - 1] = '\001';
}
static field_metrics no_metrics()
{
return field_metrics(0, 0);
}
/// Calculate metrics for any input string
static field_metrics calculateMetrics(std::string::const_iterator const start,std::string::const_iterator const end)
{
int checksum = 0;
for (std::string::const_iterator str = start; str != end; ++str)
checksum += (unsigned char)(*str);
#if defined(__SUNPRO_CC)
std::ptrdiff_t d;
std::distance(start, end, d);
return field_metrics(d, checksum);
#else
return field_metrics(std::distance(start, end), checksum);
#endif
}
static field_metrics calculateMetrics(const std::string& field)
{
return calculateMetrics(field.begin(), field.end());
}
int m_tag;
std::string m_string;
mutable std::string m_data;
mutable field_metrics m_metrics;
};
/// Field that contains an integer value
class IntField : public FieldBase
{
public:
explicit IntField(int field, int data): FieldBase(field, IntConvertor::convert(data)) {}
IntField(int field): FieldBase(field, "") {}
void setValue(int value)
{
setString(IntConvertor::convert(value));
}
int getValue() const throw (IncorrectDataFormat)
{
try
{
return IntConvertor::convert(getString());
}
catch (FieldConvertError&)
{
throw IncorrectDataFormat(getTag(), getString());
}
}
operator const int() const
{
return getValue();
}
};
typedef int INT;
namespace FIELD
{
const int OrderAttributeType = 2594;
}
#define DEFINE_FIELD_CLASS_NUM( NAME, TOK, TYPE, NUM ) \
class NAME : public TOK##Field { public: \
NAME() : TOK##Field(NUM) {} \
NAME(const TYPE& value) : TOK##Field(NUM, value) {} \
}
#define DEFINE_FIELD_CLASS( NAME, TOK, TYPE ) DEFINE_FIELD_CLASS_NUM(NAME, TOK, TYPE, FIELD::NAME)
#define DEFINE_INT( NAME ) DEFINE_FIELD_CLASS(NAME, Int, FIX::INT)
}
namespace FIX
{
DEFINE_INT(OrderAttributeType);
}
void test2()
{
using namespace FIX;
OrderAttributeType obt = OrderAttributeType(3);
}
int main()
{
test2();
getchar();
return 0;
}