1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// fgbdfname.cc
#include "fgbdfname.h"
#ifndef _FGSTRING_H
#include "fgstring.h"
#endif
#ifndef _FGMRANK_H
#include "fgmrank.h"
#endif
#ifndef _FGSCOMP_H
#include "fgscomp.h"
#endif
#ifndef _FGICOMP_H
#include "fgicomp.h"
#endif
#ifndef _FGDYYMMDDCOMP_H
#include "fgdyymmddcomp.h"
#endif
#ifndef _FGCHARCOMP_H
#include "fgcharcomp.h"
#endif
#ifndef _FGEXC_H
#include "fgexc.h"
#endif
#ifndef __SGI_STL_VECTOR_H
#include <vector>
#endif
struct FGBrokenDownFileName::Internal_FGBrokenDownFileName {
std::vector<FGFileNameComponent*> mComponents;
};
FGBrokenDownFileName::FGBrokenDownFileName(const FGString& fname)
{
mpInternals = new Internal_FGBrokenDownFileName;
// Need to catch exceptions to clean up above resources
try {
// We must now parse the supplied filename into components
unsigned int index = 0;
// Parse state
bool esc = false;
bool inTok = false;
FGString bit;
while (index <= fname.GetLength()) {
char c = fname[index++];
if (c == '\0') {
// End of string
if (inTok) {
// Error!
throw FGException(FGException::kParseEndOfString);
}
if (bit.GetLength() > 0) {
FGFileNameComponent* pNew;
pNew = new FGStringComponent(bit);
mpInternals->mComponents.push_back(pNew);
}
} else if (esc || (c != '\\' && c != '<' && c != '>')) {
bit += c;
esc = false;
} else if (c == '\\') {
esc = true;
} else if (c == '<') {
if (inTok) {
throw FGException(FGException::kParseUnexpectedChar, "<");
}
inTok = true;
if (bit.GetLength() > 0) {
FGFileNameComponent* pNew;
pNew = new FGStringComponent(bit);
mpInternals->mComponents.push_back(pNew);
}
bit.MakeEmpty();
} else {
// c == '>'
if (!inTok) {
throw FGException(FGException::kParseUnexpectedChar, ">");
}
FGString strInt("int");
FGString strYYMMDD("YYMMDD");
FGString strChar("char");
FGString strOptChar("optchar");
if (bit == strInt) {
FGFileNameComponent* pNew;
pNew = new FGIntegerComponent;
mpInternals->mComponents.push_back(pNew);
} else if (bit == strYYMMDD) {
FGFileNameComponent* pNew;
pNew = new FGDateYYMMDDComponent;
mpInternals->mComponents.push_back(pNew);
} else if (bit == strChar) {
FGFileNameComponent* pNew;
pNew = new FGCharacterComponent(false);
mpInternals->mComponents.push_back(pNew);
} else if (bit == strOptChar) {
FGFileNameComponent* pNew;
pNew = new FGCharacterComponent(true);
mpInternals->mComponents.push_back(pNew);
} else {
throw FGException(FGException::kUnrecognizedComponent, bit);
}
inTok = false;
bit.MakeEmpty();
}
} // end while (more chars to parse)
} // end try block
catch (FGException&) {
delete this;
throw;
}
}
FGBrokenDownFileName::~FGBrokenDownFileName()
{
if (mpInternals) {
// Free the vector of pointers
std::vector<FGFileNameComponent*>::iterator iComps;
for (iComps = mpInternals->mComponents.begin();
iComps != mpInternals->mComponents.end(); iComps++) {
delete *iComps;
}
delete mpInternals;
}
}
FGMatchRanking
FGBrokenDownFileName::GetRanking(const FGString& cmp) const
{
FGMatchRanking ret;
FGString mangleCompare(cmp);
// Iterate through components
std::vector<FGFileNameComponent*>::const_iterator iComps;
for (iComps = mpInternals->mComponents.begin();
iComps != mpInternals->mComponents.end(); iComps++) {
int result = -1;
bool matched = (*iComps)->MatchAndRankComponent(mangleCompare,
&result);
if (matched == false) {
// Oh dear
FGMatchRanking duffRet;
return duffRet;
}
if (result != -1) {
ret.AddValue(result);
}
}
// Not a match if any unmatched string remains
if (mangleCompare.GetLength() > 0) {
FGMatchRanking duffRet;
return duffRet;
}
// It's a match.. this return value indicates how good a match
// i.e. linux-2.2.1.tar.gz is better that linux-2.2.0.tar.gz
ret.SetMatch();
return ret;
}
|