1
0
Fork 0

Make ident/name searches on FGPositioned case-insensitive (for the GPS, especially)

This commit is contained in:
James Turner 2010-08-14 20:24:30 +01:00
parent ae7342ebe7
commit 8d5021f670

View file

@ -357,13 +357,17 @@ addToIndices(FGPositioned* aPos)
{ {
assert(aPos); assert(aPos);
if (!aPos->ident().empty()) { if (!aPos->ident().empty()) {
std::string u(boost::to_upper_copy(aPos->ident()));
global_identIndex.insert(global_identIndex.begin(), global_identIndex.insert(global_identIndex.begin(),
std::make_pair(aPos->ident(), aPos)); std::make_pair(u, aPos));
} }
if (!aPos->name().empty()) { if (!aPos->name().empty()) {
std::string u(boost::to_upper_copy(aPos->name()));
global_nameIndex.insert(global_nameIndex.begin(), global_nameIndex.insert(global_nameIndex.begin(),
std::make_pair(aPos->name(), aPos)); std::make_pair(u, aPos));
} }
if (!Octree::global_spatialOctree) { if (!Octree::global_spatialOctree) {
@ -380,8 +384,9 @@ removeFromIndices(FGPositioned* aPos)
assert(aPos); assert(aPos);
if (!aPos->ident().empty()) { if (!aPos->ident().empty()) {
NamedPositionedIndex::iterator it = global_identIndex.find(aPos->ident()); std::string u(boost::to_upper_copy(aPos->ident()));
while (it != global_identIndex.end() && (it->first == aPos->ident())) { NamedPositionedIndex::iterator it = global_identIndex.find(u);
while (it != global_identIndex.end() && (it->first == u)) {
if (it->second == aPos) { if (it->second == aPos) {
global_identIndex.erase(it); global_identIndex.erase(it);
break; break;
@ -392,8 +397,9 @@ removeFromIndices(FGPositioned* aPos)
} }
if (!aPos->name().empty()) { if (!aPos->name().empty()) {
NamedPositionedIndex::iterator it = global_nameIndex.find(aPos->name()); std::string u(boost::to_upper_copy(aPos->name()));
while (it != global_nameIndex.end() && (it->first == aPos->name())) { NamedPositionedIndex::iterator it = global_nameIndex.find(u);
while (it != global_nameIndex.end() && (it->first == u)) {
if (it->second == aPos) { if (it->second == aPos) {
global_nameIndex.erase(it); global_nameIndex.erase(it);
break; break;
@ -415,28 +421,12 @@ public:
} }
}; };
/** void findInIndex(NamedPositionedIndex& aIndex, const std::string& aFind, std::vector<FGPositioned*>& aResult)
* A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
* implement the AirportList dialog. It's unfortunate that it needs to reside
* here, but for now it's least ugly solution.
*/
char** searchAirportNamesAndIdents(const std::string& aFilter)
{ {
const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(std::locale()); NamedPositionedIndex::const_iterator it = aIndex.begin();
std::string filter(aFilter); NamedPositionedIndex::const_iterator end = aIndex.end();
bool hasFilter = !filter.empty();
if (hasFilter) {
ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size());
}
NamedPositionedIndex::const_iterator it = global_identIndex.begin(); bool haveFilter = !aFind.empty();
NamedPositionedIndex::const_iterator end = global_identIndex.end();
// note this is a vector of raw pointers, not smart pointers, because it
// may get very large and smart-pointer-atomicity-locking then becomes a
// bottleneck for this case.
std::vector<FGPositioned*> matches;
std::string upper;
for (; it != end; ++it) { for (; it != end; ++it) {
FGPositioned::Type ty = it->second->type(); FGPositioned::Type ty = it->second->type();
@ -444,15 +434,32 @@ char** searchAirportNamesAndIdents(const std::string& aFilter)
continue; continue;
} }
if (hasFilter && (it->second->ident().find(aFilter) == std::string::npos)) { if (haveFilter && it->first.find(aFind) == std::string::npos) {
upper = it->second->name(); // string copy, sadly
ct.toupper((char *)upper.data(), (char *)upper.data() + upper.size());
if (upper.find(aFilter) == std::string::npos) {
continue; continue;
} }
aResult.push_back(it->second);
} // of index iteration
} }
matches.push_back(it->second); /**
* A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
* implement the AirportList dialog. It's unfortunate that it needs to reside
* here, but for now it's least ugly solution.
*/
char** searchAirportNamesAndIdents(const std::string& aFilter)
{
// note this is a vector of raw pointers, not smart pointers, because it
// may get very large and smart-pointer-atomicity-locking then becomes a
// bottleneck for this case.
std::vector<FGPositioned*> matches;
if (!aFilter.empty()) {
std::string filter = boost::to_upper_copy(aFilter);
findInIndex(global_identIndex, filter, matches);
findInIndex(global_nameIndex, filter, matches);
} else {
findInIndex(global_identIndex, std::string(), matches);
} }
// sort alphabetically on name // sort alphabetically on name
@ -518,10 +525,11 @@ findAll(const NamedPositionedIndex& aIndex,
return result; return result;
} }
std::string upperBoundId = aName; std::string name = boost::to_upper_copy(aName);
std::string upperBoundId = name;
upperBoundId[upperBoundId.size()-1]++; upperBoundId[upperBoundId.size()-1]++;
NamedPositionedIndex::const_iterator upperBound = aIndex.lower_bound(upperBoundId); NamedPositionedIndex::const_iterator upperBound = aIndex.lower_bound(upperBoundId);
NamedPositionedIndex::const_iterator it = aIndex.lower_bound(aName); NamedPositionedIndex::const_iterator it = aIndex.lower_bound(name);
for (; it != upperBound; ++it) { for (; it != upperBound; ++it) {
FGPositionedRef candidate = it->second; FGPositionedRef candidate = it->second;