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-2011, 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 
00036 
00037 namespace Barry {
00038 
00039 namespace ALX {
00040 
00041 
00042 OSLoader::OSLoader(void)
00043 {
00044 }
00045 
00046 
00047 OSLoader::~OSLoader(void)
00048 {
00049 }
00050 
00051 
00052 void OSLoader::Load(const std::string& pathname)
00053 {
00054 #define ALX_FILE_EXT    ".alx"
00055 
00056         int offset;
00057 
00058         struct dirent *entry;
00059 
00060         std::string alxfile;
00061         const std::string ext = ALX_FILE_EXT;
00062 
00063         // At first, we have to read platform properties...
00064         alxfile = pathname + "/Platform.alx";
00065         LoadALXFile(alxfile, false);
00066 
00067         // Then, we can read all ALX files
00068         // Wrap it in a smart pointer so exceptions are safe
00069         vLateSmartPtr<DIR, int (*)(DIR*)> path(&closedir);
00070         path.reset( opendir(pathname.c_str()) );
00071         if( path.get() == NULL )
00072                 throw Barry::ErrnoError("Could not opendir: " + pathname, errno);
00073 
00074         while ((entry = readdir(path.get())) != NULL) {
00075                 alxfile = entry->d_name;
00076 
00077                 if (alxfile.length() < ext.length())
00078                         continue;
00079 
00080                 offset = alxfile.length() - ext.length();
00081 
00082                 // Ignore all files except ".alx" files
00083                 if (alxfile.substr(offset, ext.length()) != ALX_FILE_EXT)
00084                         continue;
00085 
00086                 LoadALXFile(pathname + "/" + alxfile, true);
00087         }
00088 }
00089 
00090 
00091 void OSLoader::LoadALXFile(const std::string& alxfile, const bool enable)
00092 {
00093         std::ifstream file(alxfile.c_str());
00094         if( !file )
00095                 throw Barry::Error("Cannot open ALX file: " + alxfile);
00096 
00097         ALX::ALXParser parser(*this, file);
00098 
00099         parser.Run(enable);
00100 
00101         file.close();
00102 }
00103 
00104 
00105 void OSLoader::Dump(std::ostream &os) const
00106 {
00107         os << "OS Properties :" << std::endl;
00108 
00109         {
00110                 std::map<std::string, std::string>::const_iterator b = properties.begin(), e = properties.end();
00111 
00112                 for (; b != e; b++) {
00113                         os << "  - " << (*b).first << " = " << (*b).second << std::endl;
00114                 }
00115         }
00116 
00117         os << std::endl;
00118 
00119         os << "SFI File :" << std::endl;
00120         os << "  " << sfifile << std::endl;
00121         os << std::endl;
00122 
00123         os << "Applications :" << std::endl;
00124 
00125         {
00126                 CODSectionList::const_iterator b = applications.begin(), e = applications.end();
00127 
00128                 for (; b != e; b++) {
00129                         os << (**b) << std::endl;
00130                 }
00131         }
00132 
00133         os << "Libraries :" << std::endl;
00134 
00135         {
00136                 CODSectionList::const_iterator b = libraries.begin(), e = libraries.end();
00137 
00138                 for (; b != e; b++) {
00139                         os << (**b) << std::endl;
00140                 }
00141         }
00142 }
00143 
00144 
00145 void OSLoader::AddProperties(const std::string& property, const std::string& value)
00146 {
00147         properties[property] = value;
00148 
00149         if (property == "JVMLevel")
00150                 properties["Java"] = value;
00151 }
00152 
00153 
00154 void OSLoader::AddProperties(const xmlpp::SaxParser::AttributeList& attrs)
00155 {
00156         for (xmlpp::SaxParser::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end(); ++iter) {
00157                 std::string attribut(iter->name);
00158                 std::string value(iter->value);
00159 
00160                 AddProperties(attribut, value);
00161         }
00162 }
00163 
00164 
00165 void OSLoader::SetSFIFile(const std::string& name)
00166 {
00167         sfifile = name;
00168 }
00169 
00170 
00171 bool OSLoader::IsSupported(const xmlpp::SaxParser::AttributeList& attrs)
00172 {
00173         if (properties.empty())
00174                 return false;
00175 
00176         for (xmlpp::SaxParser::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end(); ++iter) {
00177                 std::string attribut(iter->name);
00178                 std::string value(iter->value);
00179 
00180                 std::string s = properties[attribut];
00181 
00182                 std::transform(value.begin(), value.end(), value.begin(), ::tolower);
00183                 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
00184 
00185                 if (value[0] == '~') {
00186                         value = value.substr(1, value.length()-1);
00187 
00188                         if (s == value)
00189                                 return false;
00190                 }
00191                 else {
00192                         if (s != value)
00193                                 return false;
00194                 }
00195         }
00196 
00197         return true;
00198 }
00199 
00200 
00201 void OSLoader::AddApplication(OSLoader::CODSectionPtr app)
00202 {
00203         applications.push_back(app);
00204 }
00205 
00206 
00207 void OSLoader::AddLibrary(OSLoader::CODSectionPtr lib)
00208 {
00209         libraries.push_back(lib);
00210 }
00211 
00212 
00213 } // namespace ALX
00214 
00215 } // namespace Barry
00216