in cli/mparser.cpp [527:648]
bool CModelData::ReadRowSeedFile( const wstring& filePath )
{
if( trim( filePath ).empty() ) return( true );
// Some implementations of wifstream only allow ANSI strings as file names so converting before using
string ansiFilePath = wideCharToAnsi( filePath );
wifstream file( ansiFilePath );
if ( !file )
{
PrintMessage( InputDataError, L"Couldn't open file:", filePath.data() );
return( false );
}
wstring line;
// parameter names
bool fileEmpty = false;
if ( readLineFromFile( file, line ))
{
if ( trim( line ).empty() ) fileEmpty = true;
}
else
{
fileEmpty = true;
}
if ( fileEmpty )
{
PrintMessage( RowSeedsWarning, L"Seeding file is empty" );
return( true );
}
EncodingType encoding = getEncodingType( line );
if ( encoding != EncodingType::ANSI
&& encoding != EncodingType::UTF8 )
{
PrintMessage( RowSeedsError, L"Only ANSI and UTF-8 are supported" );
return( false );
}
vector< vector<CModelParameter>::iterator > parameters;
wstrings params;
split( line, RESULT_DELIMITER, params );
for( auto & param : params )
{
vector<CModelParameter>::iterator found = FindParameterByName( param );
if ( found == Parameters.end())
{
PrintMessage( RowSeedsWarning, L"Parameter",
param.data(),
L"not found in the model. Skipping..." );
}
parameters.push_back( found );
}
// if any parameter equals to ModelData.Parameters.end()
// this parameter could not be found in the model
while( readLineFromFile( file, line ))
{
if ( trim(line).empty() ) break;
wstrings values;
split( line, RESULT_DELIMITER, values );
unsigned int n_param = 0;
CModelRowSeed rowSeed;
for ( wstrings::iterator i_value = values.begin();
i_value != values.end();
++i_value, ++n_param )
{
// There could be fewer parameter names (in the first line)
// than there is values in the following lines. This has
// to be detected and a warning issued
if ( n_param < (unsigned int) parameters.size() && parameters[ n_param ] != Parameters.end() )
{
CModelParameter ¶m = *(parameters[ n_param ]);
// remove the negative marker and match up the raw name
if ( i_value->length() > 0 && (*i_value)[ 0 ] == InvalidPrefix )
{
*i_value = trim( i_value->substr( 1, i_value->length() - 1 ));
}
// if any value could not be found, the whole seed row is not invalid
// we just remove that one offending value and the rest of the row can
// stay intact; we cannot really warn about this as in a model with
// submodels this is very normal
int found = param.GetValueOrdinal( *i_value, CaseSensitive );
if ( found == -1 )
{
if ( ! i_value->empty() )
{
PrintMessage( RowSeedsWarning, L"Value",
i_value->data(),
L"not found in the model. Skipping this value..." );
}
}
else
{
// we don't care about result parameters as we should not seed we expected results
if ( ! param.IsResultParameter )
{
rowSeed.push_back( make_pair( param.Name, *i_value ));
}
}
}
}
if ( ! rowSeed.empty() )
{
RowSeeds.push_back( rowSeed );
}
}
if( ! ValidateRowSeeds())
{
return( false );
}
return( true );
}