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