// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef CST_LOADER_H #define CST_LOADER_H #include "nel/misc/types_nl.h" #include "nel/misc/debug.h" #include #include #include #include /** * CSTLoader * \author Stephane Coutelas * \author Nevrax France * \date 2001 */ class CSTLoader { public: /// data type enum TDataType { UINT8, SINT8, UINT16, SINT16, UINT32, SINT32, FLOAT, STRING, BOOL }; private: /// cst file std::ifstream * _File; /// name of the cst file (used for debug information) std::string _FileName; /// separators std::string _Seps; /// current line in the file uint _LineCount; /// columns label of the actually readen data file std::vector _Columns; /// file format expected std::map _FileFormat; /// tokens for each expected columns std::map _Tokens; public: /// constructor CSTLoader() { _Seps = "\t;"; _LineCount = 0; } /** * Set the separators to extract tokens * \param seps all characters than can be a separator */ void setSeparators( std::string seps ) { _Seps = seps; } /** * (For files respecting the dynamical column label format : name) * Open a file, and init the file format. Each column has a label and a data type * * \param fileName the name of the file * \param fileFormat the name of the columns and their data type */ void buildTableFormat( std::string fileName, std::list >& tableFormat ); /** * (For files respecting the dynamical column label format : name) * Read all the data of the file. For each object it fills a list of value(string) * * \param data the list of the name of the columns and their data type */ void readData( std::list >& data ); /** * Open a file, and init the file format * \param fileName the name of the file * \param fileFormat the name of the columns and their data type */ void init( std::string fileName, const std::map& fileFormat); /** * read a line in the file and check validity of token data type * \return false if the ned of file has been reached, true else. */ bool readLine(); /** * return the value corresponding to the given column in the current file line * \param value a value in the table */ template void getValue( const std::string& columnLabel, T& value ) { std::map::const_iterator itt = _Tokens.find( columnLabel ); if( itt == _Tokens.end() ) { nlerror("The value for the column %s has not been read in the line",columnLabel.c_str()); } std::map::const_iterator itf = _FileFormat.find( columnLabel ); if( itf == _FileFormat.end() ) { nlerror("The column %s is not in the file format",columnLabel.c_str()); } nlassert( (*itf).second != STRING && (*itf).second != BOOL ); switch( (*itf).second ) { case UINT8 : case SINT8 : case UINT16 : case SINT16 : case UINT32 : case SINT32 : case FLOAT : fromString((*itt).second, value); break; } } /** * return the string value corresponding to the given column in the current file line * \param value a string value in the table */ void getStringValue( const std::string& columnLabel, std::string& value ) { std::map::const_iterator itt = _Tokens.find( columnLabel ); if( itt == _Tokens.end() ) { nlerror("The value for the column %s has not been read in the line",columnLabel.c_str()); } std::map::const_iterator itf = _FileFormat.find( columnLabel ); if( itf == _FileFormat.end() ) { nlerror("The column %s is not in the file format",columnLabel.c_str()); } nlassert( (*itf).second == STRING ); value = (*itt).second; } /** * return the bool value corresponding to the given column in the current file line * \param value a bool value in the table */ void getBoolValue( const std::string& columnLabel, bool& value ) { std::map::const_iterator itt = _Tokens.find( columnLabel ); if( itt == _Tokens.end() ) { nlerror("The value for the column %s has not been read in the line",columnLabel.c_str()); } std::map::const_iterator itf = _FileFormat.find( columnLabel ); if( itf == _FileFormat.end() ) { nlerror("The column %s is not in the file format",columnLabel.c_str()); } nlassert( (*itf).second == BOOL ); NLMISC::fromString((*itt).second, value); } /// close file void close() { _File->close(); delete _File; } void Load(std::string fileName,std::ofstream &script_file) { // Generates the base class std::list< std::pair > format; buildTableFormat( fileName, format ); generateBaseClass( script_file, format); // Generates a derived class for each type of object std::list< std::list > data; readData( data ); generateDerivedClasses( script_file, format, data ); } void generateBaseClass(std::ofstream &file, std::list< std::pair > &/* format */) { file << "From Agent : Define Item" << std::endl; file << "{" << std::endl; /* file << "\tComponent:" << std::endl; std::list< std::pair >::iterator it_obj = format.begin(); it_obj++; while ( it_obj != format.end() ) { file << "\t\t"; switch ( (*it_obj).second ) { case UINT8: file << "uint8"; break; case SINT8: file << "sint8"; break; case UINT16: file << "uint16"; break; case SINT16: file << "sint16"; break; case UINT32: file << "uint32"; break; case SINT32: file << "sint32"; break; case FLOAT: file << "Float"; break; case STRING: file << "String"; break; case BOOL: file << "Bool"; break; } file << "<'" << (*it_obj).first << "', Static>;" << std::endl; it_obj++; } file << "\tEnd" << std::endl;*/ file << "}" << std::endl; file << std::endl; } void generateDerivedClasses(std::ofstream &, std::list< std::pair > &, std::list< std::list< std::string> > &); TDataType convertType(std::string type_str) { if ( type_str == "UINT8") return UINT8; if ( type_str == "SINT8") return SINT8; if ( type_str == "UINT16") return UINT16; if ( type_str == "SINT16") return SINT16; if ( type_str == "UINT32") return UINT32; if ( type_str == "SINT32") return SINT32; if ( type_str == "FLOAT") return FLOAT; if ( type_str == "STRING") return STRING; if ( type_str == "BOOL") return BOOL; return (TDataType)0; } std::string convertName(std::string &name) { int i = 0; char buffer[1024]; std::string::iterator it_c = name.begin(); while ( it_c != name.end() ) { char c = *it_c; switch ( c ) { case ' ': case '.': buffer[i] = '_'; break; case ',': buffer[i] = '.'; break; default: buffer[i] = *it_c; } i++; it_c++; } buffer[i] = 0; return std::string( buffer ); } }; #endif // CST_LOADER_H