bool LocationIndex::VisitAdminRegionLocations(const AdminRegion& region, LocationVisitor& visitor, bool recursive) const { FileScanner scanner; bool stopped=false; if (!scanner.Open(AppendFileToDir(path, FILENAME_LOCATION_IDX), FileScanner::LowMemRandom, true)) { log.Error() << "Cannot open file '" << scanner.GetFilename() << "'!"; return false; } if (!scanner.SetPos(indexOffset)) { return false; } if (!scanner.SetPos(region.regionOffset)) { return false; } if (!VisitRegionLocationEntries(scanner, visitor, recursive, stopped)) { return false; } return !scanner.HasError() && scanner.Close(); }
bool LocationIndex::ResolveAdminRegionHierachie(const AdminRegionRef& adminRegion, std::map<FileOffset,AdminRegionRef >& refs) const { FileScanner scanner; if (!scanner.Open(AppendFileToDir(path, FILENAME_LOCATION_IDX), FileScanner::LowMemRandom, true)) { log.Error() << "Cannot open file '" << scanner.GetFilename() << "'!"; return false; } if (!scanner.SetPos(indexOffset)) { return false; } std::list<FileOffset> offsets; refs[adminRegion->regionOffset]=adminRegion; if (adminRegion->parentRegionOffset!=0) { offsets.push_back(adminRegion->parentRegionOffset); } while (!offsets.empty()) { std::list<FileOffset> newOffsets; for (const auto& offset : offsets) { if (refs.find(offset)!=refs.end()) { continue; } if (!scanner.SetPos(offset)) { return false; } AdminRegion adminRegion; if (!LoadAdminRegion(scanner, adminRegion)) { return false; } refs[adminRegion.regionOffset]=std::make_shared<AdminRegion>(adminRegion); if (adminRegion.parentRegionOffset!=0) { newOffsets.push_back(adminRegion.parentRegionOffset); } } offsets.clear(); std::swap(offsets, newOffsets); } return !scanner.HasError() && scanner.Close(); }
bool LocationIndex::VisitAdminRegions(AdminRegionVisitor& visitor) const { FileScanner scanner; if (!scanner.Open(AppendFileToDir(path, FILENAME_LOCATION_IDX), FileScanner::LowMemRandom, false)) { log.Error() << "Cannot open file '" << scanner.GetFilename() << "'!"; return false; } if (!scanner.SetPos(indexOffset)) { return false; } uint32_t regionCount; if (!scanner.ReadNumber(regionCount)) { return false; } for (size_t i=0; i<regionCount; i++) { AdminRegionVisitor::Action action; FileOffset nextChildOffset; if (!scanner.ReadFileOffset(nextChildOffset)) { return false; } action=VisitRegionEntries(scanner, visitor); if (action==AdminRegionVisitor::error) { return false; } else if (action==AdminRegionVisitor::stop) { return true; } else if (action==AdminRegionVisitor::skipChildren) { if (i+1<regionCount) { if (!scanner.SetPos(nextChildOffset)) { return false; } } } } return !scanner.HasError() && scanner.Close(); }
bool LocationIndex::VisitLocationAddressEntries(FileScanner& scanner, const AdminRegion& region, const Location& location, AddressVisitor& visitor, bool& stopped) const { uint32_t addressCount; if (!scanner.SetPos(location.addressesOffset)) { return false; } if (!scanner.ReadNumber(addressCount)) { return false; } ObjectFileRefStreamReader objectFileRefReader(scanner); for (size_t i=0; i<addressCount; i++) { Address address; if (!scanner.GetPos(address.addressOffset)) { return false; } address.locationOffset=location.locationOffset; address.regionOffset=location.regionOffset; if (!scanner.Read(address.name)) { return false; } if (!objectFileRefReader.Read(address.object)) { return false; } if (!visitor.Visit(region, location, address)) { stopped=true; break; } } return !scanner.HasError(); }
bool LocationIndex::VisitRegionLocationEntries(FileScanner& scanner, LocationVisitor& visitor, bool recursive, bool& stopped) const { AdminRegion region; FileOffset childrenOffset; uint32_t childCount; if (!LoadAdminRegion(scanner, region)) { return false; } if (!scanner.GetPos(childrenOffset)) { return false; } if (!scanner.SetPos(region.dataOffset)) { return false; } if (!LoadRegionDataEntry(scanner, region, visitor, stopped)) { return false; } if (stopped || !recursive) { return !scanner.HasError(); } if (!scanner.SetPos(childrenOffset)) { return false; } if (!scanner.ReadNumber(childCount)) { return false; } for (size_t i=0; i<childCount; i++) { FileOffset nextChildOffset; if (!scanner.ReadFileOffset(nextChildOffset)) { return false; } if (!VisitRegionLocationEntries(scanner, visitor, recursive, stopped)) { return false; } if (stopped) { break; } } return !scanner.HasError(); }
AdminRegionVisitor::Action LocationIndex::VisitRegionEntries(FileScanner& scanner, AdminRegionVisitor& visitor) const { AdminRegion region; uint32_t childCount; if (!LoadAdminRegion(scanner, region)) { return AdminRegionVisitor::error; } AdminRegionVisitor::Action action=visitor.Visit(region); switch (action) { case AdminRegionVisitor::stop: return action; case AdminRegionVisitor::error: return action; case AdminRegionVisitor::skipChildren: return AdminRegionVisitor::skipChildren; case AdminRegionVisitor::visitChildren: // just continue... break; } if (!scanner.ReadNumber(childCount)) { return AdminRegionVisitor::error; } for (size_t i=0; i<childCount; i++) { FileOffset nextChildOffset; if (!scanner.ReadFileOffset(nextChildOffset)) { return AdminRegionVisitor::error; } action=VisitRegionEntries(scanner, visitor); if (action==AdminRegionVisitor::stop || action==AdminRegionVisitor::error) { return action; } else if (action==AdminRegionVisitor::skipChildren) { if (i+1<childCount) { if (!scanner.SetPos(nextChildOffset)) { return AdminRegionVisitor::error; } } else { return AdminRegionVisitor::skipChildren; } } } if (scanner.HasError()) { return AdminRegionVisitor::error; } else { return AdminRegionVisitor::visitChildren; } }