parent
							
								
									660745d7d5
								
							
						
					
					
						commit
						a50293a217
					
				|  | @ -19,13 +19,52 @@ | |||
| */ | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <syslog.h> | ||||
| #include <sys/stat.h> | ||||
| #include "Suite.h" | ||||
| #include <dirent.h> | ||||
| 
 | ||||
| /// Suite_InvalidUnitMember - Exception thrown when a Suite tries to access a contained Unit's value that is not
 | ||||
| /// present in the Unit.
 | ||||
| class Suite_InvalidUnitMember: public std::runtime_error { public: | ||||
|     // TODO rework this to accept the name of the member not able to be fetched.
 | ||||
|     Suite_InvalidUnitMember(): std::runtime_error("Suite: Attempted to access a member of a Unit that is not set.") {} | ||||
| class SuiteException: public std::exception | ||||
| { | ||||
| public: | ||||
|     /** Constructor (C strings).
 | ||||
|      *  @param message C-style string error message. | ||||
|      *                 The string contents are copied upon construction. | ||||
|      *                 Hence, responsibility for deleting the char* lies | ||||
|      *                 with the caller. | ||||
|      */ | ||||
|     explicit SuiteException(const char* message): | ||||
|             msg_(message) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     /** Constructor (C++ STL strings).
 | ||||
|      *  @param message The error message. | ||||
|      */ | ||||
|     explicit SuiteException(const std::string& message): | ||||
|             msg_(message) | ||||
|     {} | ||||
| 
 | ||||
|     /** Destructor.
 | ||||
|      * Virtual to allow for subclassing. | ||||
|      */ | ||||
|     virtual ~SuiteException() throw (){} | ||||
| 
 | ||||
|     /** Returns a pointer to the (constant) error description.
 | ||||
|      *  @return A pointer to a const char*. The underlying memory | ||||
|      *          is in posession of the Exception object. Callers must | ||||
|      *          not attempt to free the memory. | ||||
|      */ | ||||
|     virtual const char* what() const throw (){ | ||||
|         return msg_.c_str(); | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     /** Error message.
 | ||||
|      */ | ||||
|     std::string msg_; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -42,40 +81,115 @@ class Suite_InvalidUnitMember: public std::runtime_error { public: | |||
| /// if the implementor so desires.
 | ||||
| Suite::Suite(): JSON_Loader() {}; | ||||
| 
 | ||||
| 
 | ||||
| bool is_file( std::string path) | ||||
| { | ||||
|     struct stat buf; | ||||
|     stat( path.c_str(), &buf ); | ||||
|     return S_ISREG(buf.st_mode); | ||||
| } | ||||
| 
 | ||||
| bool is_dir( std::string path ) | ||||
| { | ||||
|     struct stat buf; | ||||
|     stat( path.c_str(), &buf ); | ||||
|     return S_ISDIR(buf.st_mode); | ||||
| } | ||||
| 
 | ||||
| void get_units_from_dir( std::vector<std::string> * files, std::string path ) | ||||
| { | ||||
|     DIR* dirFile = opendir( path.c_str() ); | ||||
|     if ( dirFile ) | ||||
|     { | ||||
|         std::string entry; | ||||
| 
 | ||||
|         struct dirent* hFile; | ||||
|         errno = 0; | ||||
|         while (( hFile = readdir( dirFile )) != NULL ) | ||||
|         { | ||||
|             if ( !strcmp( hFile->d_name, "."  )) continue; | ||||
|             if ( !strcmp( hFile->d_name, ".." )) continue; | ||||
| 
 | ||||
|             // hidden files
 | ||||
|             if ( hFile->d_name[0] == '.' ) continue; | ||||
| 
 | ||||
|             // dirFile.name is the name of the file. Do whatever string comparison
 | ||||
|             // you want here. Something like:
 | ||||
|             if ( strstr( hFile->d_name, ".units" )) | ||||
|             { | ||||
|                 std::string full_path = path + hFile->d_name; | ||||
|                 files->push_back( full_path ); | ||||
|             } | ||||
|         } | ||||
|         closedir( dirFile ); | ||||
|     } else { | ||||
|         std::cout << "file not found" << std::endl; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /// Suite::load_units_file - Uses the json_root buffer on each run to append intact Units as they're
 | ||||
| /// deserialized from the provided file.
 | ||||
| ///
 | ||||
| /// \param filename - The file to pull the JSON-formatted units from.
 | ||||
| /// \param units_path - The file to pull the JSON-formatted units from.
 | ||||
| /// \param verbose - Whether to print verbose output to STDOUT.
 | ||||
| void Suite::load_units_file( std::string filename, bool verbose ) | ||||
| void Suite::load_units_file( std::string units_path, bool verbose ) | ||||
| { | ||||
|     // will use json_root buffer on each run to append to this->units vector as valid units are found.
 | ||||
|     this->load_json_file( filename, verbose ); | ||||
|     std::vector<std::string> unit_files; | ||||
| 
 | ||||
|     // staging buffer
 | ||||
|     Json::Value jbuff; | ||||
| 
 | ||||
|     // fill the jbuff staging buffer with a json::value object in the supplied filename
 | ||||
|     if ( this->get_serialized( jbuff, "units", verbose ) == 0) | ||||
|     if ( is_dir( units_path ) ) | ||||
|     { | ||||
|         this->json_root = jbuff; | ||||
|         // we have a directory path.  find all files ending in *.units and load them into a vector<std::string>
 | ||||
|         get_units_from_dir( &unit_files, units_path ); | ||||
|     } | ||||
| 
 | ||||
|     // iterate through the json::value members that have been loaded.  append to this->units vector
 | ||||
|     // buffer for units to append:
 | ||||
|     Unit tmp_U; | ||||
|     for ( int index = 0; index < this->json_root.size(); index++ ) | ||||
|     if ( is_file( units_path ) ) | ||||
|     { | ||||
|         // assemble the unit from json_root using the built-in value operator
 | ||||
|         tmp_U.load_root( this->json_root[ index ] ); | ||||
|         if ( tmp_U.get_active() ) { | ||||
|             // append to this->units
 | ||||
|             this->units.push_back( tmp_U ); | ||||
|             if ( verbose ) { | ||||
|                 std::cout << "Added unit \"" << tmp_U.get_name() << "\" to Suite." << std::endl; | ||||
|         unit_files.push_back( units_path ); | ||||
|     } | ||||
| 
 | ||||
|     std::ostringstream infostring; | ||||
|     infostring << "Unit files found: " << unit_files.size() << std::endl; | ||||
|     syslog(LOG_INFO, infostring.str().c_str() ); | ||||
|     std::cerr << infostring.str(); | ||||
| 
 | ||||
|     for ( int i = 0; i < unit_files.size(); i++ ) | ||||
|     { | ||||
|         // will use json_root buffer on each run to append to this->units vector as valid units are found.
 | ||||
|         this->load_json_file( unit_files[i], verbose ); | ||||
| 
 | ||||
|         // staging buffer
 | ||||
|         Json::Value jbuff; | ||||
| 
 | ||||
|         // fill the jbuff staging buffer with a json::value object in the supplied units_path
 | ||||
|         if ( this->get_serialized( jbuff, "units", verbose ) == 0) | ||||
|         { | ||||
|             this->json_root = jbuff; | ||||
|         } | ||||
| 
 | ||||
|         // iterate through the json::value members that have been loaded.  append to this->units vector
 | ||||
|         // buffer for units to append:
 | ||||
|         Unit tmp_U; | ||||
|         for ( int index = 0; index < this->json_root.size(); index++ ) | ||||
|         { | ||||
|             // assemble the unit from json_root using the built-in value operator
 | ||||
|             tmp_U.load_root( this->json_root[ index ] ); | ||||
|             if ( tmp_U.get_active() ) { | ||||
|                 // append to this->units
 | ||||
|                 this->units.push_back( tmp_U ); | ||||
|                 if ( verbose ) { | ||||
|                     std::ostringstream infostring; | ||||
|                     infostring << "Added unit \"" << tmp_U.get_name() << "\" to Suite." << std::endl; | ||||
|                     syslog(LOG_INFO, infostring.str().c_str() ); | ||||
|                     std::cout << infostring.str(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /// Suite::get_unit - returns a contained Unit identified by name attribute.
 | ||||
|  | @ -99,8 +213,11 @@ void Suite::get_unit(Unit & result, std::string provided_name) | |||
| 
 | ||||
|     if (! foundMatch ) | ||||
|     { | ||||
|         std::cerr << "Unit name \"" << provided_name << "\" was referenced but not defined!" << std::endl; | ||||
|         throw Suite_InvalidUnitMember(); | ||||
|         std::ostringstream infostring; | ||||
|         infostring << "Unit name \"" << provided_name << "\" was referenced but not defined!" << std::endl; | ||||
|         syslog(LOG_ERR, infostring.str().c_str() ); | ||||
|         std::cerr << infostring.str(); | ||||
|         throw SuiteException( infostring.str() ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Phanes
						Phanes