bool test_l2msg_fmt2()

in src/dxapi-tests.cpp [671:841]


bool test_l2msg_fmt2(TickDb& db) {
    //static const uintptr_t preloadSize = 35000000;
    static const uintptr_t preloadSize = 24000000;
    enum MsgType { UNKNOWN = 0, LEVEL2ACTION, L2MESSAGE, LEVEL2MESSAGE };
    const char *messageNames[] = { "Unknown", "deltix.qsrv.hf.pub.Level2Action", 
        "deltix.qsrv.hf.pub.L2Message", "deltix.qsrv.hf.pub.Level2Message"
    };
    class Level2Action {
        int    level;                   // int8, non-nullable
        bool   isAsk;                   // boolean, non-nullable
        int    action;                  // enum 0..2
        double price;                   // Float 64, nullable
        double size;                    // Float 64, nullable
        int    numOfOrders;             // int32, nullable
        bool   has_price, has_size, has_numOfOrders;


    public:
        inline void readFrom(DataReader& reader)
        {
#define READER reader
            READ(level, Int8);
            READ(isAsk, Boolean);
            READ(action, Enum8); // TODO:
            READ_NULLABLE(price, Float64);
            READ_NULLABLE(size, Float64);
            READ_NULLABLE(numOfOrders, Int32);
        }
        virtual std::string toString() const
        {
            char tmp[0x1000];
            sprintf(tmp, "\n\t%1d %c %c %lf %lf %d", level, "BA??"[isAsk], "_+*-???"[action + 1], price, size, has_numOfOrders ? numOfOrders : -1);
            return std::string(tmp);
        }
    };

    class L2Message : public MarketMessage {
        vector<Level2Action> actions;
        std::string exchangeCode;
        bool isImplied, isSnapshot;
        int64_t sequenceId;
        bool has_actions, has_exchangeCode, has_sequenceId;

    public:
        inline void readFrom(DataReader &reader)
        {
            READ_NULLABLE(originalTimestamp, Timestamp);
            READ_NULLABLE(currencyCode, Int16);
            READ_NULLABLE(sequenceNumber, Int64);

            intptr_t count;
            //{ reader.skipArray(); return; }
            count = reader.readArrayStart();
            has_actions = false;
            if (count >= 0) {
                has_actions = true;
                actions.resize(count);
                for (intptr_t i = 0; i < count; ++i) {
                    if (reader.readObjectStart() >= 0) {
                        Level2Action act;
                        act.readFrom(reader);
                        actions[i] = act;
                        reader.readObjectEnd();
                    }
                }

                READ_NULLABLE2(exchangeCode, Alphanumeric, 10);
                READ(isImplied, Boolean);
                READ(isSnapshot, Boolean);
                READ_NULLABLE(sequenceId, Int64);
                reader.readArrayEnd();
            }
        }

        virtual std::string toString() const
        {
            char tmp[0x1000];
            sprintf(tmp, " currency: %d, actions(%d): ", (int)currencyCode, (int)actions.size());
            std::string s = MarketMessage::toString().append(tmp);
            for (intptr_t i = 0, count = actions.size(); i < count; ++i) {
                s/*.append(i ? "," : "")*/.append(actions[i].toString());
            }
            return s;
        }
    };

    class Level2Message : public MarketMessage {
        double price;                   // Float 64, nullable
        double size;                    // Float 64, nullable
        std::string exchangeCode;       // Alpha(10), nullable
        int8_t depth;                   // int8, nullable
        bool   isAsk;                   // boolean, non-nullable
        int    action;                  // enum 0..2
        bool   _isLast;                 // boolean, non-nullable
        int    numOfOrders;             // int32, nullable

        bool has_exchangeCode, has_price, has_size, has_depth, has_action, has_numOfOrders;

    public:
        inline void readFrom(DataReader &reader)
        {
            READ_NULLABLE(originalTimestamp, Timestamp);
            READ_NULLABLE(currencyCode, Int16);
            READ_NULLABLE(sequenceNumber, Int64);

            READ_NULLABLE(price, Float64);
            READ_NULLABLE(size, Float64);
            READ_NULLABLE2(exchangeCode, Alphanumeric, 10);
            READ_NULLABLE(depth, Int8);
            READ(isAsk, Boolean);
            READ(action, Enum8);
            READ(_isLast, Boolean);
            READ_NULLABLE(numOfOrders, Int32);
        }

        virtual std::string toString() const
        {
            return MarketMessage::toString().append("Price: ").append(::toString(price));
        }
    };

    SelectionOptions opt;

    //TickStream stream = db.getStream("l2msg");
    unique_ptr<TickStream>pstream(db.getStream("l2msg4"));
    TickStream &stream = *pstream;
    unique_ptr<TickCursor> pCursor(stream.select(TIMESTAMP_NULL, opt, NULL, NULL));
    TickCursor &cursor = *pCursor;

    for (intptr_t i = 0; i < COUNTOF(messageNames); ++i)
        cursor.registerMessageType((unsigned)i, messageNames[i]);

#ifdef PRELOAD
    preload(cursor, preloadSize, 0x400);
#endif

    //MessageHeader msg;
    MarketMessage marketMessage; // We are using this as a default type
    Level2Action l2Action;
    L2Message l2Message;
    Level2Message level2Message;

    START_TEST(L2Msg2);
    DataReader &reader = cursor.getReader();
    marketMessage.cursor = &cursor;
    // Note: C++ API is not a priority, it will be made better-looking, but that code is not useful for Managed API, so it is not written yet.

    while (cursor.next(&marketMessage) && nMessagesRead < 5000000) {
        switch (marketMessage.typeIdLocal) {
        case L2MESSAGE:
            l2Message.copyHeaderFrom(marketMessage);
            l2Message.readFrom(reader);
            PRINT(l2Message.toString().c_str());
            break;
        case LEVEL2MESSAGE:
            level2Message.copyHeaderFrom(marketMessage);
            level2Message.readFrom(reader);
            PRINT(level2Message.toString().c_str());
            break;
        default:
            printf("Unknown message <%s>. id: %d -> localId: %d", marketMessage.getTypeName()->c_str(), (int)marketMessage.typeId, (int)marketMessage.typeIdLocal);
            //puts(marketMessage.toString().c_str());
        }
        // Print contents
        //puts(msg->toString().c_str());
        ++nMessagesRead;
    }

    END_READING(L2Msg2);
    return true;
}