resources.cxx

Go to the documentation of this file.
00001 #include <cxxtls/resources.h>
00002 #include <iostream>
00003 #include <fstream>
00004 #include <ctype.h>
00005 #include <string>
00006 
00007 namespace cxxtls
00008 {
00009 
00010 typedef std::string      string;
00011 typedef Resources::StringList  StringList;
00012 
00013 using namespace std;
00014 
00015 Resources::
00016 Resources ()
00017 {
00018 }
00019 
00020 
00021 Resources::
00022 ~Resources ()
00023 {
00024 }
00025 
00026 Resources::
00027 Resources(StringList const &filenames)
00028 {
00029   read(filenames);
00030 }
00031 
00032 static void clean_ends(std::string &s)
00033   // remove leading and trailing spaces from the string, but leave
00034   // the middle ones alone.
00035 {
00036   size_t first_non_blank, end;
00037 
00038   char const *data = s.data();
00039 
00040   // remove leading blanks
00041 
00042   for(first_non_blank=0, end = s.size(); first_non_blank < end; ++first_non_blank)
00043   {
00044     if(! isspace(data[first_non_blank]) )
00045       break;
00046   }
00047 
00048   // remove trailing blanks
00049 
00050   while(end > first_non_blank)
00051   {
00052     if(isspace(data[end-1]))
00053       --end;
00054     else
00055       break;
00056   }
00057 
00058   if(first_non_blank != 0 || end != s.size())
00059     s = s.substr(first_non_blank, end-first_non_blank);
00060 
00061 }
00062 
00063 
00064 
00065 void
00066 Resources::
00067 read(StringList const &filenames)
00068 {
00069   StringList::const_iterator f, l;
00070 
00071   size_t name_count = filenames.size();
00072   size_t count;
00073 
00074   for(count = 0, f = filenames.begin(), filenames.end(); f != l && count < name_count; ++f, ++count)
00075   {
00076     // process each file and silently ignore failures
00077 
00078     string const &filename = *f;
00079 
00080     char const *curname = filename.c_str();
00081 
00082     std::fstream file(curname, ios::in);
00083 
00084     string line;
00085 
00086     while(!file.fail() && !file.eof())
00087     {
00088 
00089       // process each line:  discard comments and perform
00090       // settings on name=value pairs found on the lines
00091 
00092       getline(file, line);
00093 
00094       size_t offset = line.find_first_of('#');
00095 
00096       if(offset < line.size())
00097       {
00098         line = line.substr(0,offset);
00099       }
00100 
00101       offset = line.find_first_of('=');
00102 
00103       if(offset < line.size())
00104       {
00105         // found an equal sign on this line -- so perform the needed
00106         // settings
00107 
00108         // first:  remove trailing blanks from the variable nae
00109 
00110         size_t name_length = offset;
00111 
00112         while(name_length && isspace(line[name_length-1]))
00113           -- name_length;
00114 
00115         // name_length points 1 past the last non-blank character
00116         // in the name part of the line -- we are assuming that 
00117         // names begin in column 1.
00118 
00119         if(name_length == 0)
00120           continue; // this line is bad
00121 
00122         string name = line.substr(0,name_length);
00123         string value;
00124 
00125         ++offset;  // step past the = to get to the value
00126 
00127         // remove leading blanks
00128 
00129         while(offset < line.size() && isspace(line[offset]))
00130           ++offset;
00131           
00132         if(offset < line.size())
00133         {
00134           value = line.substr(offset, line.size()-offset);
00135         }
00136 
00137         // remove trailing blanks from the value
00138 
00139         offset = value.size();
00140 
00141         while(offset && isspace(value[offset-1]) )
00142           --offset;
00143 
00144         if(offset != value.size())
00145           value = value.substr(0,offset);
00146 
00147         // at this point, the value could be a continuation line -- handle
00148         // that case:
00149 
00150         if(value.size())
00151         {
00152           static string space(" ");
00153 
00154           while(value.size() && value[value.size()-1] == '\\')
00155           {
00156             offset = value.size()-1;
00157 
00158             while(offset && isspace(value[offset-1]))
00159               --offset;
00160 
00161             value = value.substr(0,offset);
00162 
00163 
00164             getline(file, line);
00165 
00166             offset = line.find_first_of("#");
00167 
00168             if(offset < line.size())
00169             {
00170               line = line.substr(0,offset);
00171             }
00172 
00173             clean_ends(line);
00174 
00175             value = value + space + line;
00176 
00177           }
00178         }
00179 
00180 
00181         Settings::iterator where = map_.find(name);
00182 
00183         if(where != map_.end())
00184           map_.erase(name);      // the last setting of a name/value pair wins
00185 
00186         map_[name] = value;
00187 
00188       }
00189 
00190     }
00191 
00192   }
00193 }
00194 
00195 
00196 
00197 Resources::ReturnString
00198 Resources::
00199 find (string const &name) const
00200 {
00201   Settings::const_iterator where = map_.find(name);
00202 
00203   if(where == map_.end())
00204   {
00205     return ReturnString("",false);
00206   }
00207 
00208   return ReturnString(where->second,true);
00209 
00210 }
00211 
00212 void
00213 Resources::
00214 set (string const &name, string const &value)
00215 {
00216   Settings::iterator where = map_.find(name);
00217 
00218   if(where != map_.end())
00219     map_.erase(where);
00220 
00221   map_[name] = value;
00222 }
00223 
00224 std::ostream &
00225 operator<< (std::ostream &s, Resources const &r )
00226 {
00227 
00228   Resources::Settings::const_iterator f, l;
00229 
00230   for(f = r.map_.begin(), l = r.map_.end(); f != l; ++f)
00231   {
00232     s << f->first << "='" << f->second << "'\n";
00233   }
00234 
00235   s.flush();
00236 
00237   return s;
00238 }
00239 
00240 void
00241 Resources::
00242 print() const
00243 {
00244   std::cout << *this;
00245 }
00246 
00247 } // namespace cxxtls
Generated on Wed Feb 29 22:50:05 2012 for CXXUtilities by  doxygen 1.6.3