Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / ryzom / common / src / game_share / cst_loader.h
blob51fa6e9aa61be065b9209e67b643b48ea7751535
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef CST_LOADER_H
20 #define CST_LOADER_H
22 #include "nel/misc/types_nl.h"
23 #include "nel/misc/debug.h"
25 #include <map>
26 #include <vector>
27 #include <string>
30 /**
31 * CSTLoader
32 * \author Stephane Coutelas
33 * \author Nevrax France
34 * \date 2001
36 class CSTLoader
38 public:
40 /// data type
41 enum TDataType
43 UINT8,
44 SINT8,
45 UINT16,
46 SINT16,
47 UINT32,
48 SINT32,
49 FLOAT,
50 STRING,
51 BOOL
54 private:
56 /// cst file
57 FILE *_File;
59 /// name of the cst file (used for debug information)
60 std::string _FileName;
62 /// separators
63 std::string _Seps;
65 /// current line in the file
66 uint _LineCount;
68 /// columns label of the actually readen data file
69 std::vector<std::string> _Columns;
71 /// file format expected
72 std::map<std::string,TDataType> _FileFormat;
74 /// tokens for each expected columns
75 std::map<std::string, std::string> _Tokens;
77 public:
79 /// constructor
80 CSTLoader()
82 _Seps = "\t;";
83 _LineCount = 0;
86 /**
87 * Set the separators to extract tokens
88 * \param seps all characters than can be a separator
90 void setSeparators( std::string seps )
92 _Seps = seps;
96 /**
97 * (For files respecting the dynamical column label format : name<type>)
98 * Open a file, and init the file format. Each column has a label and a data type
100 * \param fileName the name of the file
101 * \param fileFormat the name of the columns and their data type
103 void buildTableFormat( const std::string &fileName, std::list<std::pair< std::string,TDataType> >& tableFormat );
107 * (For files respecting the dynamical column label format : name<type>)
108 * Read all the data of the file. For each object it fills a list of value(string)
110 * \param data the list of the name of the columns and their data type
112 void readData( std::list<std::list<std::string> >& data );
115 * Open a file, and init the file format
116 * \param fileName the name of the file
117 * \param fileFormat the name of the columns and their data type
119 void init( const std::string &fileName, const std::map<std::string,TDataType>& fileFormat);
123 * read a line in the file and check validity of token data type
124 * \return false if the ned of file has been reached, true else.
126 bool readLine();
130 * return the value corresponding to the given column in the current file line
131 * \param value a value in the table
133 template<class T> void getValue( const std::string& columnLabel, T& value )
135 std::map<std::string,std::string>::const_iterator itt = _Tokens.find( columnLabel );
136 if( itt == _Tokens.end() )
138 nlerror("The value for the column %s has not been read in the line",columnLabel.c_str());
141 std::map<std::string,TDataType>::const_iterator itf = _FileFormat.find( columnLabel );
142 if( itf == _FileFormat.end() )
144 nlerror("The column %s is not in the file format",columnLabel.c_str());
147 nlassert( (*itf).second != STRING && (*itf).second != BOOL );
149 switch( (*itf).second )
151 case UINT8 :
152 case SINT8 :
153 case UINT16 :
154 case SINT16 :
155 case UINT32 :
156 case SINT32 :
157 case FLOAT :
158 fromString((*itt).second, value);
159 break;
160 default:
161 break;
166 * return the string value corresponding to the given column in the current file line
167 * \param value a string value in the table
169 void getStringValue( const std::string& columnLabel, std::string& value )
171 std::map<std::string,std::string>::const_iterator itt = _Tokens.find( columnLabel );
172 if( itt == _Tokens.end() )
174 nlerror("The value for the column %s has not been read in the line",columnLabel.c_str());
177 std::map<std::string,TDataType>::const_iterator itf = _FileFormat.find( columnLabel );
178 if( itf == _FileFormat.end() )
180 nlerror("The column %s is not in the file format",columnLabel.c_str());
183 nlassert( (*itf).second == STRING );
185 value = (*itt).second;
189 * return the bool value corresponding to the given column in the current file line
190 * \param value a bool value in the table
192 void getBoolValue( const std::string& columnLabel, bool& value )
194 std::map<std::string,std::string>::const_iterator itt = _Tokens.find( columnLabel );
195 if( itt == _Tokens.end() )
197 nlerror("The value for the column %s has not been read in the line",columnLabel.c_str());
200 std::map<std::string,TDataType>::const_iterator itf = _FileFormat.find( columnLabel );
201 if( itf == _FileFormat.end() )
203 nlerror("The column %s is not in the file format",columnLabel.c_str());
206 nlassert( (*itf).second == BOOL );
208 NLMISC::fromString((*itt).second, value);
212 /// close file
213 void close()
215 fclose(_File);
216 _File = NULL;
220 void Load(const std::string &fileName)
222 // Generates the base class
223 std::list< std::pair<std::string,TDataType> > format;
224 buildTableFormat( fileName, format );
225 generateBaseClass( format);
227 // Generates a derived class for each type of object
228 std::list< std::list<std::string> > data;
229 readData( data );
230 generateDerivedClasses( format, data );
233 void generateBaseClass(const std::list< std::pair<std::string,TDataType> > &/* format */)
235 std::string content;
236 content += "From Agent : Define Item\n";
237 content += "{\n";
238 /* content += "\tComponent:\n";
240 std::list< std::pair<std::string,TDataType> >::iterator it_obj = format.begin();
241 it_obj++;
242 while ( it_obj != format.end() )
244 content += "\t\t" + convertFromType((*it_obj).second);
245 content += "<'" + (*it_obj).first + "', Static>;\n";
246 it_obj++;
249 content += "\tEnd\n"; */
250 content += "}\n";
251 content += "\n";
253 fwrite(content.c_str(), 1, content.length(), _File);
256 void generateDerivedClasses(const std::list< std::pair<std::string, TDataType> > &, const std::list< std::list< std::string> > &);
258 TDataType convertType(const std::string &type_str)
260 if ( type_str == "UINT8")
261 return UINT8;
262 if ( type_str == "SINT8")
263 return SINT8;
264 if ( type_str == "UINT16")
265 return UINT16;
266 if ( type_str == "SINT16")
267 return SINT16;
268 if ( type_str == "UINT32")
269 return UINT32;
270 if ( type_str == "SINT32")
271 return SINT32;
272 if ( type_str == "FLOAT")
273 return FLOAT;
274 if ( type_str == "STRING")
275 return STRING;
276 if ( type_str == "BOOL")
277 return BOOL;
278 return (TDataType)0;
281 std::string convertFromType(TDataType type);
283 std::string convertName(const std::string &name) const
285 int i = 0;
286 char buffer[1024];
287 std::string::const_iterator it_c = name.begin();
288 while ( it_c != name.end() )
290 char c = *it_c;
291 switch ( c )
293 case ' ':
294 case '.':
295 buffer[i] = '_';
296 break;
298 case ',':
299 buffer[i] = '.';
300 break;
302 default:
303 buffer[i] = *it_c;
305 i++;
306 it_c++;
308 buffer[i] = 0;
309 return std::string( buffer );
313 #endif // CST_LOADER_H