Document DocumentSourceGroup::getCurrent() { if (!populated) populate(); dassert(!eof()); if (_spilled) { return makeDocument(_currentId, _currentAccumulators, pExpCtx->getInShard()); } else { return makeDocument(groupsIterator->first, groupsIterator->second, pExpCtx->getInShard()); } }
//when getBusStopMessage(const QString&) download finishes void ArrivalsLogic::onBusStopMessageReceived() { QList<QJsonDocument> document = makeDocument(reply_busStopMessage); if (document.empty()) { return; } //nothing to do QJsonArray versionArray = document.begin()->array(); if (versionArray.begin() + 2 < versionArray.end() ) { double serverTime = (*(versionArray.begin() + 2 )).toDouble(); QMultiMap<int,QString> messages; for (QList<QJsonDocument>::const_iterator iter = document.begin() + 1; iter < document.end(); ++iter) { if (iter->array().begin() + 4 < iter->array().end()) { int priority = (*(iter->array().begin() + 1)).toDouble(); QString text = (*(iter->array().begin() + 2)).toString(); double startTime = (*(iter->array().begin() + 3)).toDouble(); double expireTime = (*(iter->array().begin() + 4)).toDouble(); if (startTime <= serverTime && expireTime >= serverTime) { messages.insert(priority, text); } } else { qDebug() << "The array doesn't contain 4 elements."; break; } } fillCurrentStopMessages(messages); } else return; }
//gets called when bus stop data is downloaded and ready to be processed void ArrivalsLogic::onBusStopDataReceived() { downloadingStop = false; emit downloadStateChanged(); QList<QJsonDocument> document = makeDocument(reply_busStop); //only want the second array as the first one is the version array and there are only 2 arrays if (document.begin() + 1 >= document.end()) { return; } //there is nothing to do QList<QJsonDocument>::iterator dataArray = document.begin() + 1; if (currentStop) { if (dataArray->isArray() ) { if (dataArray->array().begin() + 6 >= dataArray->array().end()) { return; } //TODO throw //id is set in ArrivalsLogic::getBusStopByCode(const QString&) currentStop->setName( (*(dataArray->array().begin() + 1)).toString() ); currentStop->setTowards( (*(dataArray->array().begin() + 3)).toString() ); currentStop->setStopPointIndicator( (*(dataArray->array().begin() + 4)).toString() ); currentStop->setLatitude( (*(dataArray->array().begin() + 5)).toDouble() ); currentStop->setLongitude( (*(dataArray->array().begin() + 6)).toDouble() ); if ( (*(dataArray->array().begin() + 2)).toString() == QString("SLRS") ) { currentStop->setType(Stop::River); } else { currentStop->setType(Stop::Bus); } currentStop->updated(); emit stopDataChanged(); } else qDebug() << "Invalid QJsonArray"; } }
//gets called when bus progress data is downloaded and redy to be processed void ArrivalsLogic::onBusProgressReceived() { downloadingJourneyProgress = false; emit downloadStateChanged(); QList<QJsonDocument> document = makeDocument(reply_journeyProgress); if (document.begin() == document.end() || document.begin()->array().begin() + 2 >= document.begin()->array().end()) { return; }//nothing to do double serverTime = (*(document.begin()->array().begin() +2)).toDouble(); //BUG check why list might be empty, server or client error QList<QPair<QString, double>> list; if (document.begin() + 1 >= document.end()) { } for (QList<QJsonDocument>::iterator iter = document.begin() + 1; iter < document.end(); ++iter) { if (iter->array().begin() +2 >= iter->array().end()) { //TODO throw break; } QPair<QString, double> pair; pair.first = (*(iter->array().begin() +1)).toString(); pair.second = (*(iter->array().begin() +2)).toDouble(); list.append(pair); } if (journeyProgressContainer) { journeyProgressContainer->setTime(serverTime); journeyProgressContainer->refreshData(list); } }
//gets called when bus arrivals are downloaded and ready to be processed void ArrivalsLogic::onArrivalsDataReceived() { downloadingArrivals = false; emit downloadStateChanged(); QList<QJsonDocument> document = makeDocument(reply_arrivals); QList<QJsonDocument>::iterator first = document.begin(); //server time UTC in msec from Epoch at the time of request //use this to compare with expected arrival time, if device clock is not correctly set //the arrival times are still accurately presented to user if (first->array().begin() +2 >= first->array().end() ) { return; } //currentTime would be invalid double currentTime = (*(first->array().begin() +2)).toDouble(); ArrivalsContainer tempContainer(arrivalsModel); for (QList<QJsonDocument>::iterator iter = first + 1; iter < document.end(); ++iter) { Vehicle bus; if (iter->array().begin() + 5 >= iter->array().end() ) { qDebug() << ""; //TODO throw exception break; } bus.line = (*(iter->array().begin() + 1)).toString(); currentBusDirectionId = QString::number((*(iter->array().begin() + 2)).toDouble()); bus.destination = (*(iter->array().begin() + 3)).toString(); bus.id = (*(iter->array().begin() + 4)).toString();//registration number double delta = (*(iter->array().begin() + 5)).toDouble() - currentTime; double inSec = delta / 1000; double inMins = inSec / 60; //round to whole numbers bus.eta = std::round(inMins); tempContainer.add(bus); } if (arrivalsContainer) { arrivalsContainer->replace(tempContainer); } }
void DocumentSourceGroup::populate() { for(bool hasNext = !pSource->eof(); hasNext; hasNext = pSource->advance()) { intrusive_ptr<Document> pDocument(pSource->getCurrent()); /* get the _id document */ intrusive_ptr<const Value> pId(pIdExpression->evaluate(pDocument)); /* treat Undefined the same as NULL SERVER-4674 */ if (pId->getType() == Undefined) pId = Value::getNull(); /* Look for the _id value in the map; if it's not there, add a new entry with a blank accumulator. */ vector<intrusive_ptr<Accumulator> > *pGroup; GroupsType::iterator it(groups.find(pId)); if (it != groups.end()) { /* point at the existing accumulators */ pGroup = &it->second; } else { /* insert a new group into the map */ groups.insert(it, pair<intrusive_ptr<const Value>, vector<intrusive_ptr<Accumulator> > >( pId, vector<intrusive_ptr<Accumulator> >())); /* find the accumulator vector (the map value) */ it = groups.find(pId); pGroup = &it->second; /* add the accumulators */ const size_t n = vpAccumulatorFactory.size(); pGroup->reserve(n); for(size_t i = 0; i < n; ++i) { intrusive_ptr<Accumulator> pAccumulator( (*vpAccumulatorFactory[i])(pExpCtx)); pAccumulator->addOperand(vpExpression[i]); pGroup->push_back(pAccumulator); } } /* point at the existing key */ // unneeded atm // pId = it.first; /* tickle all the accumulators for the group we found */ const size_t n = pGroup->size(); for(size_t i = 0; i < n; ++i) (*pGroup)[i]->evaluate(pDocument); } /* start the group iterator */ groupsIterator = groups.begin(); if (groupsIterator != groups.end()) pCurrent = makeDocument(groupsIterator); populated = true; }
bool DocumentSourceGroup::advance() { if (!populated) populate(); assert(groupsIterator != groups.end()); ++groupsIterator; if (groupsIterator == groups.end()) { pCurrent.reset(); return false; } pCurrent = makeDocument(groupsIterator); return true; }
bool DocumentSourceGroup::advance() { DocumentSource::advance(); // check for interrupts if (!populated) populate(); verify(groupsIterator != groups.end()); ++groupsIterator; if (groupsIterator == groups.end()) { pCurrent.reset(); return false; } pCurrent = makeDocument(groupsIterator); return true; }
//gets called when the list of bus stops are downloaded by getBusStopsByName(name) void ArrivalsLogic::onListOfBusStopsReceived() { downloadingListOfStops = false; emit downloadStateChanged(); QList<QJsonDocument> document = makeDocument(reply_stops); QString stopPointType; //skip version array for (QList<QJsonDocument>::const_iterator iter = document.begin() + 1;iter < document.end();++iter) { if (iter->array().begin() + 7 >= iter->array().end()) { break; } //TODO throw Stop stop(databaseManager); stop.setName((*(iter->array().begin() + 1)).toString()); stop.setID((*(iter->array().begin() + 2)).toString()); stop.setTowards((*(iter->array().begin() + 4)).toString()); stop.setStopPointIndicator((*(iter->array().begin() + 5)).toString()); stop.setLatitude((*(iter->array().begin() + 6)).toDouble()); stop.setLongitude((*(iter->array().begin() + 7)).toDouble()); stopPointType = (*(iter->array().begin() + 3)).toString(); if ( stopPointType == QString("SLRS")) { stop.setType(Stop::River); } else { stop.setType(Stop::Bus); } //The meaning of these codes are documented in the Bus arrivals API documentation //only display sstops with these codes if (stopPointType == "STBR" || stopPointType == "STBC" || stopPointType == "SRVA" || stopPointType == "STZZ" || stopPointType == "STBN" || stopPointType == "SLRS" || stopPointType == "STBS" || stopPointType == "STSS") { //to prevent a bug when server returns a stop where code isNull() ie: Hammersmith Bus Station if (!(*(iter->array().begin() + 2)).isNull()) { stop.addToDb(); } } } if (stopsQueryModel) { stopsQueryModel->showStops(Stop::Bus); } }