a_osloader.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       a_osloader.cc
00003 ///             OS files parser (multi ALX files parser)
00004 ///
00005 
00006 /*
00007     Copyright (C) 2010, Nicolas VIVIEN
00008     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019     See the GNU General Public License in the COPYING file at the
00020     root directory of this project for more details.
00021 */
00022 
00023 #include <iostream>
00024 #include <fstream>
00025 #include <algorithm>
00026 
00027 #include <sys/types.h>
00028 #include <dirent.h>
00029 #include <errno.h>
00030 
00031 #include "a_osloader.h"
00032 #include "a_alxparser.h"
00033 #include "vsmartptr.h"
00034 #include "error.h"
00035 #include "ios_state.h"
00036 
00037 
00038 namespace Barry {
00039 
00040 namespace ALX {
00041 
00042 
00043 OSLoader::OSLoader(void)
00044 {
00045 }
00046 
00047 
00048 OSLoader::~OSLoader(void)
00049 {
00050 }
00051 
00052 
00053 void OSLoader::Load(const std::string& pathname)
00054 {
00055 #define ALX_FILE_EXT    ".alx"
00056 
00057         int offset;
00058 
00059         struct dirent *entry;
00060 
00061         std::string alxfile;
00062         const std::string ext = ALX_FILE_EXT;
00063 
00064         // At first, we have to read platform properties...
00065         alxfile = pathname + "/Platform.alx";
00066         LoadALXFile(alxfile, false);
00067 
00068         // Then, we can read all ALX files
00069         // Wrap it in a smart pointer so exceptions are safe
00070         vLateSmartPtr<DIR, int (*)(DIR*)> path(&closedir);
00071         path.reset( opendir(pathname.c_str()) );
00072         if( path.get() == NULL )
00073                 throw Barry::ErrnoError("Could not opendir: " + pathname, errno);
00074 
00075         while ((entry = readdir(path.get())) != NULL) {
00076                 alxfile = entry->d_name;
00077 
00078                 if (alxfile.length() < ext.length())
00079                         continue;
00080 
00081                 offset = alxfile.length() - ext.length();
00082 
00083                 // Ignore all files except ".alx" files
00084                 if (alxfile.substr(offset, ext.length()) != ALX_FILE_EXT)
00085                         continue;
00086 
00087                 LoadALXFile(pathname + "/" + alxfile, true);
00088         }
00089 }
00090 
00091 
00092 void OSLoader::LoadALXFile(const std::string& alxfile, const bool enable)
00093 {
00094         std::ifstream file(alxfile.c_str());
00095         if( !file )
00096                 throw Barry::Error("Cannot open ALX file: " + alxfile);
00097 
00098         ALX::ALXParser parser(*this, file);
00099 
00100         parser.Run(enable);
00101 
00102         file.close();
00103 }
00104 
00105 
00106 void OSLoader::Dump(std::ostream &os) const
00107 {
00108         ios_format_state state(os);
00109 
00110         os << "OS Properties :" << std::endl;
00111 
00112         {
00113                 std::map<std::string, std::string>::const_iterator b = properties.begin(), e = properties.end();
00114 
00115                 for (; b != e; b++) {
00116                         os << "  - " << (*b).first << " = " << (*b).second << std::endl;
00117                 }
00118         }
00119 
00120         os << std::endl;
00121 
00122         os << "SFI File :" << std::endl;
00123         os << "  " << sfifile << std::endl;
00124         os << std::endl;
00125 
00126         os << "Applications :" << std::endl;
00127 
00128         {
00129                 CODSectionList::const_iterator b = applications.begin(), e = applications.end();
00130 
00131                 for (; b != e; b++) {
00132                         os << (**b) << std::endl;
00133                 }
00134         }
00135 
00136         os << "Libraries :" << std::endl;
00137 
00138         {
00139                 CODSectionList::const_iterator b = libraries.begin(), e = libraries.end();
00140 
00141                 for (; b != e; b++) {
00142                         os << (**b) << std::endl;
00143                 }
00144         }
00145 }
00146 
00147 
00148 void OSLoader::AddProperties(const std::string& property, const std::string& value)
00149 {
00150         properties[property] = value;
00151 
00152         if (property == "JVMLevel")
00153                 properties["Java"] = value;
00154 }
00155 
00156 
00157 void OSLoader::AddProperties(const xmlpp::SaxParser::AttributeList& attrs)
00158 {
00159         for (xmlpp::SaxParser::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end(); ++iter) {
00160                 std::string attribut(iter->name);
00161                 std::string value(iter->value);
00162 
00163                 AddProperties(attribut, value);
00164         }
00165 }
00166 
00167 
00168 void OSLoader::SetSFIFile(const std::string& name)
00169 {
00170         sfifile = name;
00171 }
00172 
00173 
00174 bool OSLoader::IsSupported(const xmlpp::SaxParser::AttributeList& attrs)
00175 {
00176         if (properties.empty())
00177                 return false;
00178 
00179         for (xmlpp::SaxParser::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end(); ++iter) {
00180                 std::string attribut(iter->name);
00181                 std::string value(iter->value);
00182 
00183                 std::string s = properties[attribut];
00184 
00185                 std::transform(value.begin(), value.end(), value.begin(), ::tolower);
00186                 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
00187 
00188                 if (value[0] == '~') {
00189                         value = value.substr(1, value.length()-1);
00190 
00191                         if (s == value)
00192                                 return false;
00193                 }
00194                 else {
00195                         if (s != value)
00196                                 return false;
00197                 }
00198         }
00199 
00200         return true;
00201 }
00202 
00203 
00204 void OSLoader::AddApplication(OSLoader::CODSectionPtr app)
00205 {
00206         applications.push_back(app);
00207 }
00208 
00209 
00210 void OSLoader::AddLibrary(OSLoader::CODSectionPtr lib)
00211 {
00212         libraries.push_back(lib);
00213 }
00214 
00215 
00216 } // namespace ALX
00217 
00218 } // namespace Barry
00219