bool test_l2msg_fmt3()

in src/dxapi-tests.cpp [844:1030]


bool test_l2msg_fmt3(TickDb& db) {
    //static const uintptr_t preloadSize = 1000000000;
    static const uintptr_t preloadSize = 307000000;
    //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   is_null, 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<Nullable<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();
                    }
                    else {
                        DBG_BREAK();
                    }
                }

                reader.readArrayEnd();
            }

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

        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].has_value() ? actions[i].get().toString() : "<NULL>");
            }

            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("mftest"));
    TickStream &stream = *pstream;
    assert(&stream != NULL);
    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(mftest);
    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.

    int nSkip = 6;
    while (cursor.next(&marketMessage) && nMessagesRead < 5000000) {
        const char * name = marketMessage.getTypeName()->c_str();

        if (nSkip) {
            --nSkip;
        }
        else {
            if (strstr(name, "L2Message")) {
                l2Message.copyHeaderFrom(marketMessage);
                l2Message.readFrom(reader);
                PRINT(l2Message.toString().c_str());
            }
            else if (strstr(name, "Level2Message")) {
                level2Message.copyHeaderFrom(marketMessage);
                level2Message.readFrom(reader);
                PRINT(level2Message.toString().c_str());
            }
            else {
                printf("Unknown message <%s>. id: %d -> localId: %d", marketMessage.getTypeName()->c_str(), (int)marketMessage.typeId, (int)marketMessage.typeIdLocal);
                //puts(marketMessage.toString().c_str());
            }
            //_getch();
        }
        // Print contents
        //puts(msg->toString().c_str());
        ++nMessagesRead;
    }

    END_READING(mftest);
    return true;
}