Flags.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "Flags.hxx"
00023
00024 #include <bitset>
00025 #include <string>
00026 #include <iostream>
00027 #include <iomanip>
00028 #include <sstream>
00029 #include "Component.hxx"
00030 #include "XMLAdapter.hxx"
00031
00032
00033 #include "Enum.hxx"
00034
00035 using namespace CLAM;
00036
00042 std::string FlagsBase::GetFlagString(unsigned int whichOne) const throw (IllegalValue) {
00043 for (unsigned int i = 0; mFlagValues[i].name; i++) {
00044 if (whichOne==mFlagValues[i].value)
00045 return mFlagValues[i].name;
00046 }
00047 throw IllegalValue("Name not defined for an active flag");
00048 return "UnnamedFlag";
00049 }
00055 unsigned int FlagsBase::GetFlagPosition(const std::string & whichOne) const throw (IllegalValue) {
00056 for (int i = 0; mFlagValues[i].name; i++) {
00057 if (whichOne==mFlagValues[i].name)
00058 return mFlagValues[i].value;
00059 }
00060 throw IllegalValue("Name not defined for an active flag");
00061 return this->GetNFlags();
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 void FlagsBase::StoreOn (Storage & storage) const {
00071 unsigned int N=GetNFlags();
00072 for (unsigned int i=0; i<N; i++) {
00073 if (!IsSetFlag(i)) continue;
00074 std::string s = GetFlagString(i);
00075 XMLAdapter<std::string> adapter(s);
00076 storage.Store(adapter);
00077 }
00078 }
00079
00080
00081
00082
00083
00084
00085 void FlagsBase::LoadFrom (Storage & storage) {
00086 unsigned int N=GetNFlags();
00087 for (unsigned int i=0; i<N; i++) {
00088 SetFlag(i,false);
00089 }
00090 do {
00091 std::string flagName;
00092 XMLAdapter<std::string> adapter(flagName);
00093 if (!storage.Load(adapter)) break;
00094 unsigned int i = GetFlagPosition(flagName);
00095 SetFlag(i,true);
00096 }
00097 while (true);
00098 }
00099
00100 std::istream & CLAM::operator >> (std::istream & is, FlagsBase & f) {
00101 const unsigned int N = f.GetNFlags();
00102 bool * bs = new bool[N];
00103 for (unsigned int i=N; i--; ) {
00104 bs[i]=false;
00105 }
00106 if (is.flags() & std::ios::skipws) {
00107 char c = '\0';
00108 do
00109 is.get(c);
00110 while (is && isspace(c));
00111 if (is) is.putback(c);
00112 }
00113 char c = '\0';
00114 is >> c;
00115 if (c!='{') {
00116 if (is) is.putback(c);
00117 std::cerr << "A flag starting with '" << c << "'" << std::endl;
00118 delete [] bs;
00119 return is;
00120 }
00121 std::string flagContent;
00122 std::getline(is,flagContent,'}');
00123 std::stringstream ss(flagContent);
00124 std::string flagName;
00125 while (ss>>flagName) {
00126 try {
00127 unsigned i = f.GetFlagPosition(flagName);
00128 bs[i]=true;
00129 }
00130 catch (IllegalValue) {
00131 delete [] bs;
00132 throw IllegalValue(std::string("Invalid flag name: '")+
00133 flagName+"'");
00134 }
00135 }
00136 for (unsigned i=N; i--;) f.SetFlag(i, bs[i]);
00137 delete [] bs;
00138 return is;
00139 }
00140
00141 std::ostream & CLAM::operator << (std::ostream & os, const FlagsBase & f) {
00142 const unsigned int N = f.GetNFlags();
00143 bool first = true;
00144 os << "{";
00145 for (unsigned int i=0; i<N; i++) {
00146 if (f.IsSetFlag(i)) {
00147 if (!first) os << " ";
00148 else first=false;
00149 os << f.GetFlagString(i);
00150 }
00151 }
00152 os << "}";
00153 return os;
00154 }
00155
00167 bool FlagsBase::CheckInvariant() {
00168
00169 if (!mFlagValues) {
00170 std::cerr << "Name definitions are a NULL pointer" << std::endl;
00171 return false;
00172 }
00173
00174 unsigned int top;
00175 for (top=0; top<=GetNFlags() && mFlagValues[top].name; top++) {
00176 if (top==GetNFlags() && mFlagValues[top].name) {
00177 std::cerr << "There are more names than flags or there is no NULL name "
00178 "at the end of the name array list" << std::endl;
00179 return false;
00180 }
00181 }
00182
00183 for (unsigned int i=0; i<top; i++) {
00184 for (unsigned int j=i+1; j<top; j++) {
00185 if (std::string(mFlagValues[i].name)==std::string(mFlagValues[j].name)) {
00186 std::cerr << "Warning: flag names '"<< mFlagValues[i].name
00187 << "' and '" << mFlagValues[j].name
00188 << "' are replicated" << std::endl;
00189 }
00190 if (mFlagValues[i].value==mFlagValues[j].value) {
00191 std::cerr << "Warning: flag values '"<< mFlagValues[i].value
00192 << "' and '" << mFlagValues[j].value
00193 << "' are replicated" << std::endl;
00194 }
00195 }
00196 }
00197 return true;
00198 }
00199