string DeleteCommand::Execute ( ) { executionCounter++; Controller * controller = Controller::GetInstance( ); IdSet allAgregates = controller->GetAllAgregatesInDocument( ); vector<IdSet>::iterator parentsIterator = parentAgregates.begin( ); // For each object to delete for ( IdSet::iterator it = targets.begin( ); it != targets.end( ); ++it ) { // Remove it from the document controller->RemoveObjectFromDocument( *it ); // Find all agregates containing the deleted object // in order to remember them Agregate * currentAgregate; for ( IdSet::iterator jt = allAgregates.begin( ); jt != allAgregates.end( ); ++jt ) { currentAgregate = (Agregate *) controller->GetObjectById( *jt ); if ( currentAgregate->Contains( *it ) ) { currentAgregate->RemoveComponent( *it ); parentsIterator->insert( *jt ); } } parentsIterator++; } return STATUS_OK; }
size_t Private::IndexKeywords( std::string const & keyword, Table const & mapping, IdSetTable & id_set, bool is_keyword_complete) { IdSet set; if (is_keyword_complete) { auto iter = mapping.find(keyword); if (iter != mapping.end()) set.insert(iter->second); } else { for (auto & pair : mapping) if (pair.first.find(keyword) != std::string::npos) set.insert(pair.second); } if (!set.empty()) { auto iter = std::find(id_set.begin(), id_set.end(), set); if (iter == id_set.end()) { id_set.push_back(std::move(set)); return id_set.size() - 1U; } else return std::distance(id_set.begin(), iter); } return ~size_t(0U); }
SSATmp* least_common_ancestor(SSATmp* s1, SSATmp* s2) { if (s1 == s2) return s1; if (s1 == nullptr || s2 == nullptr) return nullptr; IdSet<SSATmp> seen; auto const step = [] (SSATmp* v) { assertx(v != nullptr); return v->inst()->isPassthrough() ? v->inst()->getPassthroughValue() : nullptr; }; auto const process = [&] (SSATmp*& v) { if (v == nullptr) return false; if (seen[v]) return true; seen.add(v); v = step(v); return false; }; while (s1 != nullptr || s2 != nullptr) { if (process(s1)) return s1; if (process(s2)) return s2; } return nullptr; }
static inline bool Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id, bool enumerable, uintN flags, IdSet& ht, AutoIdVector *props) { JS_ASSERT_IF(flags & JSITER_OWNONLY, obj == pobj); if (!(flags & JSITER_OWNONLY) || pobj->isProxy() || pobj->getOps()->enumerate) { /* If we've already seen this, we definitely won't add it. */ IdSet::AddPtr p = ht.lookupForAdd(id); if (JS_UNLIKELY(!!p)) return true; /* * It's not necessary to add properties to the hash table at the end of * the prototype chain, but custom enumeration behaviors might return * duplicated properties, so always add in such cases. */ if ((pobj->getProto() || pobj->isProxy() || pobj->getOps()->enumerate) && !ht.add(p, id)) return false; } if (enumerable || (flags & JSITER_HIDDEN)) return props->append(id); return true; }
IdSet InputFrame::unpackIdSet(){ IdSet set; uint32_t msize = unpackInt(); for(uint32_t i = 0; i < msize; ++i){ set.insert( unpackInt() ); } return set; }
IdSet MoonInstanceScript::BuildIdSet(uint32 pCount, ...) { IdSet NewSet; va_list List; va_start(List, pCount); for(uint32 i = 0; i < pCount; ++i) NewSet.insert(va_arg(List, uint32)); va_end(List); return NewSet; }
void DesignStore::init(){ Persistence* persistence = Game::getGame()->getPersistence(); next_designid = persistence->getMaxDesignId() + 1; next_componentid = persistence->getMaxComponentId() + 1; next_propertyid = persistence->getMaxPropertyId() + 1; next_categoryid = persistence->getMaxCategoryId() + 1; IdSet ids = persistence->getCategoryIds(); fill_by_set( designs, persistence->getDesignIds(), Design::Ptr() ); fill_by_set( categories, persistence->getCategoryIds(), Category::Ptr() ); fill_by_set( components, persistence->getComponentIds(), Component::Ptr() ); ids = persistence->getPropertyIds(); for(IdSet::iterator itcurr = ids.begin(); itcurr != ids.end(); ++itcurr){ properties[*itcurr] = persistence->retrieveProperty(*itcurr); propertyIndex[properties[*itcurr]->getName()] = (*itcurr); } }
void CountryInfoGetter::GetMatchedRegions(string const & enNamePrefix, IdSet & regions) const { for (size_t i = 0; i < m_countries.size(); ++i) { // Match english name with region file name (they are equal in almost all cases). // @todo Do it smarter in future. string s = m_countries[i].m_name; strings::AsciiToLower(s); if (strings::StartsWith(s, enNamePrefix.c_str())) regions.push_back(i); } }
static inline bool Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id, bool enumerable, bool sharedPermanent, uintN flags, IdSet& ht, AutoIdVector *props) { IdSet::AddPtr p = ht.lookupForAdd(id); JS_ASSERT_IF(obj == pobj && !obj->isProxy(), !p); /* If we've already seen this, we definitely won't add it. */ if (JS_UNLIKELY(!!p)) return true; /* * It's not necessary to add properties to the hash table at the end of the * prototype chain -- but a proxy might return duplicated properties, so * always add for them. */ if ((pobj->getProto() || pobj->isProxy()) && !ht.add(p, id)) return false; if (JS_UNLIKELY(flags & JSITER_OWNONLY)) { /* * Shared-permanent hack: If this property is shared permanent * and pobj and obj have the same class, then treat it as an own * property of obj, even if pobj != obj. (But see bug 575997.) * * Omit the magic __proto__ property so that JS code can use * Object.getOwnPropertyNames without worrying about it. */ if (!pobj->getProto() && id == ATOM_TO_JSID(cx->runtime->atomState.protoAtom)) return true; if (pobj != obj && !(sharedPermanent && pobj->getClass() == obj->getClass())) return true; } if (enumerable || (flags & JSITER_HIDDEN)) return props->append(id); return true; }
bool removeUnreachable(IRUnit& unit) { FTRACE(2, "removing unreachable blocks\n"); auto modified = false; IdSet<Block> visited; smart::stack<Block*> stack; stack.push(unit.entry()); // Find all blocks reachable from the entry block. while (!stack.empty()) { auto* b = stack.top(); stack.pop(); if (visited[b]) continue; visited.add(b); if (auto* taken = b->taken()) { if (!visited[taken]) stack.push(taken); } if (auto* next = b->next()) { if (!visited[next]) stack.push(next); } } // Erase any blocks not found above. auto* trace = unit.main(); auto& blocks = trace->blocks(); for (auto it = blocks.begin(); it != blocks.end(); ) { auto* b = *it; if (!visited[b]) { FTRACE(3, "removing unreachable B{}\n", b->id()); it = trace->erase(it); modified = true; } else { ++it; } } return modified; }
static inline bool Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id, bool enumerable, uintN flags, IdSet& ht, AutoIdVector *props) { JS_ASSERT_IF(flags & JSITER_OWNONLY, obj == pobj); /* * We implement __proto__ using a property on |Object.prototype|, but * because __proto__ is highly deserving of removal, we don't want it to * show up in property enumeration, even if only for |Object.prototype| * (think introspection by Prototype-like frameworks that add methods to * the built-in prototypes). So exclude __proto__ if the object where the * property was found has no [[Prototype]] and might be |Object.prototype|. */ if (JS_UNLIKELY(!pobj->getProto() && JSID_IS_ATOM(id, cx->runtime->atomState.protoAtom))) return true; if (!(flags & JSITER_OWNONLY) || pobj->isProxy() || pobj->getOps()->enumerate) { /* If we've already seen this, we definitely won't add it. */ IdSet::AddPtr p = ht.lookupForAdd(id); if (JS_UNLIKELY(!!p)) return true; /* * It's not necessary to add properties to the hash table at the end of * the prototype chain, but custom enumeration behaviors might return * duplicated properties, so always add in such cases. */ if ((pobj->getProto() || pobj->isProxy() || pobj->getOps()->enumerate) && !ht.add(p, id)) return false; } if (enumerable || (flags & JSITER_HIDDEN)) return props->append(id); return true; }
ListParameter::Options BuildFleet::generateListOptions(){ ListParameter::Options options; IdSet designs = Game::getGame()->getPlayerManager()->getPlayer(((Planet*)(Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId())->getObjectBehaviour()))->getOwner())->getPlayerView()->getUsableDesigns(); Game::getGame()->getObjectManager()->doneWithObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); DesignStore::Ptr ds = Game::getGame()->getDesignStore(); std::set<Design::Ptr> usable; for(IdSet::iterator itcurr = designs.begin(); itcurr != designs.end(); ++itcurr){ Design::Ptr design = ds->getDesign(*itcurr); if(design->getCategoryId() == 1){ usable.insert(design); } } for(std::set<Design::Ptr>::iterator itcurr = usable.begin(); itcurr != usable.end(); ++itcurr){ Design::Ptr design = (*itcurr); options[design->getDesignId()] = ListParameter::Option(design->getName(), 100); } Logger::getLogger()->debug("Exiting BuildFleet::generateListOptions"); return options; }
/** Statically analyse the given ast. * * \param ast_ The AST. * \param in_object Whether or not ast_ is within the lexical scope of an object AST. * \param vars The variables defined within lexical scope of ast_. * \returns The free variables in ast_. */ static IdSet static_analysis(AST *ast_, bool in_object, const IdSet &vars) { IdSet r; if (auto *ast = dynamic_cast<const Apply*>(ast_)) { append(r, static_analysis(ast->target, in_object, vars)); for (AST *arg : ast->arguments) append(r, static_analysis(arg, in_object, vars)); } else if (auto *ast = dynamic_cast<const Array*>(ast_)) { for (AST *el : ast->elements) append(r, static_analysis(el, in_object, vars)); } else if (auto *ast = dynamic_cast<const Binary*>(ast_)) { append(r, static_analysis(ast->left, in_object, vars)); append(r, static_analysis(ast->right, in_object, vars)); } else if (dynamic_cast<const BuiltinFunction*>(ast_)) { // Nothing to do. } else if (auto *ast = dynamic_cast<const Conditional*>(ast_)) { append(r, static_analysis(ast->cond, in_object, vars)); append(r, static_analysis(ast->branchTrue, in_object, vars)); append(r, static_analysis(ast->branchFalse, in_object, vars)); } else if (auto *ast = dynamic_cast<const Error*>(ast_)) { return static_analysis(ast->expr, in_object, vars); } else if (auto *ast = dynamic_cast<const Function*>(ast_)) { auto new_vars = vars; IdSet params; for (auto *p : ast->parameters) { if (params.find(p) != params.end()) { throw StaticError(ast_->location, "Duplicate function parameter: " + p->name); } params.insert(p); new_vars.insert(p); } auto fv = static_analysis(ast->body, in_object, new_vars); for (auto *p : ast->parameters) fv.erase(p); append(r, fv); } else if (dynamic_cast<const Import*>(ast_)) { // Nothing to do. } else if (dynamic_cast<const Importstr*>(ast_)) { // Nothing to do. } else if (auto *ast = dynamic_cast<const Index*>(ast_)) { append(r, static_analysis(ast->target, in_object, vars)); append(r, static_analysis(ast->index, in_object, vars)); } else if (auto *ast = dynamic_cast<const Local*>(ast_)) { IdSet ast_vars; for (const auto &bind: ast->binds) { ast_vars.insert(bind.first); } auto new_vars = vars; append(new_vars, ast_vars); IdSet fvs; for (const auto &bind: ast->binds) append(fvs, static_analysis(bind.second, in_object, new_vars)); append(fvs, static_analysis(ast->body, in_object, new_vars)); for (const auto &bind: ast->binds) fvs.erase(bind.first); append(r, fvs); } else if (dynamic_cast<const LiteralBoolean*>(ast_)) { // Nothing to do. } else if (dynamic_cast<const LiteralNumber*>(ast_)) { // Nothing to do. } else if (dynamic_cast<const LiteralString*>(ast_)) { // Nothing to do. } else if (dynamic_cast<const LiteralNull*>(ast_)) { // Nothing to do. } else if (auto *ast = dynamic_cast<Object*>(ast_)) { for (auto field : ast->fields) { append(r, static_analysis(field.name, in_object, vars)); append(r, static_analysis(field.body, true, vars)); } } else if (auto *ast = dynamic_cast<ObjectComposition*>(ast_)) { auto new_vars = vars; new_vars.insert(ast->id); append(r, static_analysis(ast->field, false, new_vars)); append(r, static_analysis(ast->value, true, new_vars)); r.erase(ast->id); append(r, static_analysis(ast->array, in_object, vars)); } else if (dynamic_cast<const Self*>(ast_)) { if (!in_object) throw StaticError(ast_->location, "Can't use self outside of an object."); } else if (dynamic_cast<const Super*>(ast_)) { if (!in_object) throw StaticError(ast_->location, "Can't use super outside of an object."); } else if (auto *ast = dynamic_cast<const Unary*>(ast_)) { append(r, static_analysis(ast->expr, in_object, vars)); } else if (auto *ast = dynamic_cast<const Var*>(ast_)) { if (vars.find(ast->id) == vars.end()) { throw StaticError(ast->location, "Unknown variable: "+ast->id->name); } r.insert(ast->id); } else { std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl; std::abort(); } for (auto *id : r) ast_->freeVariables.push_back(id); return r; }
/** Inserts all of s into r. */ static void append(IdSet &r, const IdSet &s) { r.insert(s.begin(), s.end()); }
void RSPCombat::doCombat(std::map<uint32_t, IdSet> sides) { Game* game = Game::getGame(); PlayerManager::Ptr playermanager = game->getPlayerManager(); ObjectManager* objectmanager = game->getObjectManager(); DesignStore::Ptr ds = game->getDesignStore(); const char * const rsp[] = {"rock", "scissors", "paper"}; IdSet listallobids; IdSet listallplayerids; std::map<uint32_t, std::vector<Combatant*> > fleetcache; battlelogger.reset(new BattleXML::BattleLogger()); msgstrings.clear(); for(std::map<uint32_t, IdSet>::iterator itmap = sides.begin(); itmap != sides.end(); ++itmap) { std::vector<Combatant*> pcombatant; Player::Ptr player = playermanager->getPlayer(itmap->first); battlelogger->startSide(player->getName()); IdSet theset = itmap->second; for(IdSet::iterator itset = theset.begin(); itset != theset.end(); ++itset) { listallobids.insert(*itset); IGObject::Ptr obj = objectmanager->getObject (*itset); objectcache[*itset] = obj; if(obj->getType() == obT_Fleet) { Fleet* f2 = (Fleet*)(obj->getObjectBehaviour()); IdMap shiplist = f2->getShips(); uint32_t damage = f2->getDamage(); for(IdMap::reverse_iterator itship = shiplist.rbegin(); itship != shiplist.rend(); ++itship) { for(uint32_t i = 0; i < itship->second; i++) { Combatant* f1 = new Combatant(); f1->setOwner(itmap->first); f1->setObject(obj->getID()); f1->setShipType(itship->first); uint32_t mydamage = damage / std::max(1U, (unsigned int)(shiplist.size() - i)); f1->setDamage(mydamage); damage -= mydamage; std::string type = ds->getDesign(itship->first)->getName(); f1->setBattleXmlType(type); f1->setBattleXmlId(str(boost::format("%1%-%2%-%3%") % type % obj->getID() % i)); f1->setBattleXmlName(str(boost::format("%1%'s %2%, %3% %4%") % player->getName() % obj->getName() % type % i)); battlelogger->addCombatant(f1); pcombatant.push_back(f1); } } } else { int shipcount = 2; int homeplanetid = game->getResourceManager()->getResourceDescription("Home Planet")->getResourceType(); if(((Planet*)(obj->getObjectBehaviour()))->getResource(homeplanetid) == 1) { //three more for home planets shipcount += 3; } for(int i = 0; i < shipcount; i++) { Combatant* f1 = new Combatant(); f1->setOwner(itmap->first); f1->setObject(obj->getID()); f1->setShipType(0); f1->setBattleXmlType("planet"); f1->setBattleXmlId(str(boost::format("planet-%1%-%2%") % obj->getID() % i)); f1->setBattleXmlName(str(boost::format("%1%'s colony on %2%, Defense battery %3%") % player->getName() % obj->getName() % i)); battlelogger->addCombatant(f1); pcombatant.push_back(f1); } } } listallplayerids.insert(itmap->first); battlelogger->endSide(); //sort combatant list by ship type, descending sort(pcombatant.begin(), pcombatant.end(), CombatantSorter()); fleetcache[itmap->first] = pcombatant; } for(std::set<uint32_t>::iterator itplayer = listallplayerids.begin(); itplayer != listallplayerids.end(); ++itplayer) { msgstrings[*itplayer] = ""; } Random* random = Game::getGame()->getRandom(); Logger::getLogger()->debug("Combat start"); while(fleetcache.size() >= 2) { battlelogger->startRound(); uint32_t pos1, pos2; if(fleetcache.size() == 2) { pos1 = 0; pos2 = 1; } else { pos1 = pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1))); while(pos2 == pos1) { pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1))); } } std::map<uint32_t, std::vector<Combatant*> >::iterator itpa = fleetcache.begin(); advance(itpa, pos1); std::map<uint32_t, std::vector<Combatant*> >::iterator itpb = fleetcache.begin(); advance(itpb, pos2); std::vector<Combatant*> f1 = itpa->second; std::vector<Combatant*> f2 = itpb->second; uint32_t ownerid1 = f1[0]->getOwner(); uint32_t ownerid2 = f2[0]->getOwner(); std::string p1name = playermanager->getPlayer(ownerid1)->getName(); std::string p2name = playermanager->getPlayer(ownerid2)->getName(); int32_t r1 = random->getInRange((int32_t)0, (int32_t)2); int32_t r2 = random->getInRange((int32_t)0, (int32_t)2); std::map<Combatant*, uint32_t> d1, d2; battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p1name % rsp[r2])); battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p2name % rsp[(r2 + r1) % 3])); if(r1 == 0) { //draw battlelogger->log("It's a draw"); d1 = buildShotList(f1, true); d2 = buildShotList(f2, true); if(d1.size() != 0) doDamage(d1, f2); if(d2.size() != 0) doDamage(d2, f1); } else { if(r1 == 1) { //pa win battlelogger->log(str(boost::format("%1% wins.") % p1name)); d1 = buildShotList(f1); if(d1.size() == 0) { battlelogger->log(str(boost::format("%1%'s forces escape") % p1name)); msgstrings[ownerid1] += "Your Fleet escaped. "; for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1) continue; msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p1name); } resolveCombatantsToObjects(f1); for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpa); battlelogger->endRound(); continue; } doDamage(d1, f2); } else { //pb win battlelogger->log(str(boost::format("%1% wins.") % p2name)); d2 = buildShotList(f2); if(d2.size() == 0) { battlelogger->log(str(boost::format("%1%'s forces escape") % p2name)); msgstrings[ownerid2] += "Your Fleet escaped. "; for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid2) continue; msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p2name); } resolveCombatantsToObjects(f2); for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpb); battlelogger->endRound(); continue; } doDamage(d2, f1); } } if(isAllDead(f1)) { msgstrings[ownerid1] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p2name); msgstrings[ownerid2] += str(boost::format("You destroyed %1%'s fleet. ") % p1name); std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p1name % p2name); for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1 || msgit->first == ownerid2) continue; msgit->second += deathmsg; } resolveCombatantsToObjects(f1); for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpa); } if(isAllDead(f2)) { msgstrings[ownerid2] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p1name); msgstrings[ownerid1] += str(boost::format("You destroyed %1%'s fleet. ") % p2name); std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p2name % p1name); for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1 || msgit->first == ownerid2) continue; msgit->second += deathmsg; } resolveCombatantsToObjects(f2); for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpb); } battlelogger->endRound(); } std::string file = battlelogger->save(); if(!fleetcache.empty()) { std::vector<Combatant*> flast = fleetcache.begin()->second; resolveCombatantsToObjects(flast); msgstrings[flast[0]->getOwner()] += "Your Fleet survived combat."; for(std::vector<Combatant*>::iterator itcombatant = flast.begin(); itcombatant != flast.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(fleetcache.begin()); if(!fleetcache.empty()) { Logger::getLogger()->warning("fleetcache not empty at end of combat"); } } for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { Message::Ptr msg( new Message() ); msg->setSubject("Combat"); for(std::set<uint32_t>::iterator itob = listallobids.begin(); itob != listallobids.end(); ++itob) { msg->addReference(rst_Object, *itob); } for(std::set<uint32_t>::iterator itpl = listallplayerids.begin(); itpl != listallplayerids.end(); ++itpl) { msg->addReference(rst_Player, *itpl); } msg->setBody(msgit->second); Game::getGame()->getPlayerManager()->getPlayer(msgit->first)->postToBoard(msg); } for(std::map<uint32_t, IGObject::Ptr>::iterator itob = objectcache.begin(); itob != objectcache.end(); ++itob) { Game::getGame()->getObjectManager()->doneWithObject(itob->first); } objectcache.clear(); }
bool listAllSeries(const std::string& rootCategory, const std::string& outputFile) { bool result(false); using namespace fredcpp; // Initialize Api api; api.withLogger(external::SimpleLogger::getInstance()) .withExecutor(external::CurlHttpClient::getInstance()) .withParser(external::PugiXmlParser::getInstance()) ; external::SimpleLogger::getInstance().enableInfo(); FREDCPP_LOG_INFO(FREDCPP_FACILITY << " version " << FREDCPP_VERSION_STRING << " (" << FREDCPP_BRIEF << ")"); FREDCPP_LOG_INFO("Getting API key from environment variable " << ENV_API_KEY << " ..."); api.withKey(getKeyFromEnv(ENV_API_KEY)); // Build a list of available sub-categories under the root FREDCPP_LOG_INFO("Building list of available sub-categories of category " << rootCategory << " ..."); ChildrenByIdMap categoryTree; if ( 0 == buildCategoryTree(api, categoryTree, rootCategory)) { FREDCPP_LOG_FATAL("Unable to retrieve categories"); exit(EXIT_FAILURE); } FREDCPP_LOG_INFO("Available categories count:" << categoryTree.size()); FREDCPP_LOG_INFO("Creating output data file " << outputFile << " ..."); std::ofstream output(outputFile.c_str()); if (!output) { exitOnBadOutputFile(outputFile); } // Get series IdSet uniqueSeries; ApiResponse response; for (ChildrenByIdMap::iterator it = categoryTree.begin(); it != categoryTree.end(); ++it) { std::string categoryId(it->first); api.get(ApiRequestBuilder::CategorySeries(categoryId) , response) || exitOnApiError(response); if (!response.entities.size()) { FREDCPP_LOG_INFO("category:" << categoryId << " contains no series"); } // Print series // NOTE: a given series can belong to multiple categories, // so keep track of unique series for (std::size_t n = 0; n < response.entities.size(); ++n) { std::string seriesId (response.entities[n].attribute("id")); if (uniqueSeries.find(seriesId) != uniqueSeries.end()) { continue; } uniqueSeries.insert(seriesId); output << response.entities[n].attribute("id") << "|" << response.entities[n].attribute("frequency_short") << "|" << response.entities[n].attribute("title") << "|" << response.entities[n].attribute("observation_start") << "|" << response.entities[n].attribute("observation_end") << "|" << std::endl; } } // Report stats FREDCPP_LOG_INFO("root-category:" << rootCategory << " sub-categories-count:" << categoryTree.size() - 1 << " series-count:" << uniqueSeries.size()); output.close(); FREDCPP_LOG_INFO("Successfully created file " << outputFile); result = true; return (result); }
std::size_t buildCategoryTree(fredcpp::Api& api, ChildrenByIdMap& tree, const std::string& rootCategory) { std::size_t categoryCount; using namespace fredcpp; tree.clear(); // Request children categories for sub-categories starting from rootCategory std::string parentId(rootCategory); // Add top-level categories categoryCount = addCategoryToTree(api, tree, parentId); if (categoryCount == 0) { return (categoryCount); } std::list<IdSet> parentLevels; IdSet parents; IdSet children = tree[parentId]; if (children.size()) { parentLevels.push_back(children); } else { return (categoryCount); } while (parentLevels.size()) { parents = parentLevels.front(); for (IdSet::iterator itNextParent = parents.begin(); itNextParent != parents.end(); ++itNextParent) { for (IdSet::iterator itChild = children.begin(); itChild != children.end(); ++itChild) { std::string childId(*itChild); //FREDCPP_LOG_INFO("category:" << childId << " parent:" << parentId); categoryCount += addCategoryToTree(api, tree, childId); } parentId = *itNextParent; children = tree[parentId]; if (children.size()) { parentLevels.push_back(children); } } parentLevels.pop_front(); } return (categoryCount); }