Example #1
0
    DeckItem ParserItemScan(const ParserItemType * self , std::shared_ptr< RawRecord > rawRecord) {
        auto deckItem = DeckItem::make< ValueType >( self->name(), rawRecord->size() );

        if (self->sizeType() == ALL) {
            while (rawRecord->size() > 0) {
                auto token = rawRecord->pop_front();

                std::string countString;
                std::string valueString;
                if (isStarToken(token, countString, valueString)) {
                    StarToken st(token, countString, valueString);
                    ValueType value;

                    if (st.hasValue()) {
                        value = readValueToken<ValueType>(st.valueString());
                        deckItem.push_back( value , st.count());
                    } else {
                        value = self->getDefault();
                        for (size_t i=0; i < st.count(); i++)
                            deckItem.push_backDefault( value );
                    }
                } else {
                    deckItem.push_back( readValueToken<ValueType>( token ) );
                }
            }
        } else {
            if (rawRecord->size() == 0) {
                // if the record was ended prematurely,
                if (self->hasDefault()) {
                    // use the default value for the item, if there is one...
                    deckItem.push_backDefault( self->getDefault() );
                } else {
                    // ... otherwise indicate that the deck item should throw once the
                    // item's data is accessed.
                    deckItem.push_backDummyDefault();
                }
            } else {
                // The '*' should be interpreted as a repetition indicator, but it must
                // be preceeded by an integer...
                auto token = rawRecord->pop_front();
                std::string countString;
                std::string valueString;
                if (isStarToken(token, countString, valueString)) {
                    StarToken st(token, countString, valueString);

                    if (!st.hasValue()) {
                        if (self->hasDefault())
                            deckItem.push_backDefault( self->getDefault() );
                        else
                            deckItem.push_backDummyDefault();
                    } else
                        deckItem.push_back(readValueToken<ValueType>(st.valueString()));

                    // replace the first occurence of "N*FOO" by a sequence of N-1 times
                    // "1*FOO". this is slightly hacky, but it makes it work if the
                    // number of defaults pass item boundaries...
                    std::string singleRepetition;
                    if (st.hasValue())
                        singleRepetition = st.valueString();
                    else
                        singleRepetition = "1*";

                    for (size_t i=0; i < st.count() - 1; i++)
                        rawRecord->push_front(singleRepetition);
                } else {
                    deckItem.push_back( readValueToken<ValueType>( token ) );
                }
            }
        }

        return deckItem;
    }
Example #2
0
    DeckItem ParserItemScan(const ParserItemType * self, RawRecord& rawRecord ) {
        auto deckItem = DeckItem::make< ValueType >( self->name(), rawRecord.size() );

        if (self->sizeType() == ALL) {
            while (rawRecord.size() > 0) {
                auto token = rawRecord.pop_front();

                std::string countString;
                std::string valueString;
                if (isStarToken(token, countString, valueString)) {
                    StarToken st(token, countString, valueString);
                    ValueType value;

                    if (st.hasValue()) {
                        value = readValueToken<ValueType>(st.valueString());
                        deckItem.push_back( value , st.count());
                    } else {
                        value = self->getDefault();
                        for (size_t i=0; i < st.count(); i++)
                            deckItem.push_backDefault( value );
                    }
                } else {
                    deckItem.push_back( readValueToken<ValueType>( token ) );
                }
            }
        } else {
            if (rawRecord.size() == 0) {
                // if the record was ended prematurely,
                if (self->hasDefault()) {
                    // use the default value for the item, if there is one...
                    deckItem.push_backDefault( self->getDefault() );
                } else {
                    // ... otherwise indicate that the deck item should throw once the
                    // item's data is accessed.
                    deckItem.push_backDummyDefault();
                }
            } else {
                // The '*' should be interpreted as a repetition indicator, but it must
                // be preceeded by an integer...
                auto token = rawRecord.pop_front();
                std::string countString;
                std::string valueString;
                if (isStarToken(token, countString, valueString)) {
                    StarToken st(token, countString, valueString);

                    if (!st.hasValue()) {
                        if (self->hasDefault())
                            deckItem.push_backDefault( self->getDefault() );
                        else
                            deckItem.push_backDummyDefault();
                    } else
                        deckItem.push_back(readValueToken<ValueType>(st.valueString()));

                    const auto value_start = token.size() - valueString.size();
                    // replace the first occurence of "N*FOO" by a sequence of N-1 times
                    // "FOO". this is slightly hacky, but it makes it work if the
                    // number of defaults pass item boundaries...
                    // We can safely make a string_view of one_star because it
                    // has static storage
                    static const char* one_star = "1*";
                    string_view rep = !st.hasValue()
                                    ? string_view{ one_star }
                                    : string_view{ token.begin() + value_start, token.end() };

                    rawRecord.prepend( st.count() - 1, rep );
                } else {
                    deckItem.push_back( readValueToken<ValueType>( token ) );
                }
            }
        }

        return deckItem;
    }