FIX协议字段生成分析

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值