fixed in Generator::CallSpace() when a middle field was a table: last_res should be set only for last field

refactoring in Generator::CallSpace()
This commit is contained in:
Tomasz Sowa 2021-06-25 16:16:30 +02:00
parent 5bd8eef3f2
commit 3926793a17
1 changed files with 143 additions and 81 deletions

View File

@ -331,8 +331,18 @@ private:
void CallObject(BaseObj<StreamType> & base_obj, int method_index, FunInfo<StreamType> & info);
void CallSpace(morm::ModelWrapper & model_wrapper, pt::Space & root_space, FindHelper & find_helper, std::vector<std::wstring> & fields, size_t field_index,
std::vector<Var> & parameters, StreamType & out_stream);
void CallSpaceObjectForLastField(std::vector<Var> & parameters, StreamType & out_stream, pt::Space * space);
pt::Space * CallSpaceObjectForMiddleField(std::wstring & root_space_name, std::vector<std::wstring> & fields, size_t field_index, pt::Space * space);
void CallSpaceTableForLastField(morm::ModelWrapper & model_wrapper, std::vector<Var> & parameters, StreamType & out_stream,
pt::Space * space, size_t model_wrapper_space_table_index);
pt::Space * CallSpaceTableForMiddleField(morm::ModelWrapper & model_wrapper, std::wstring & root_space_name, std::vector<std::wstring> & fields,
size_t field_index, pt::Space * space, size_t model_wrapper_space_table_index);
void CallSpace(morm::ModelWrapper & model_wrapper, pt::Space & root_space, FindHelper & find_helper, std::vector<std::wstring> & fields,
size_t root_field_index, std::vector<Var> & parameters, StreamType & out_stream);
#ifdef EZC_HAS_MORM_LIBRARY
bool CallModel(morm::Model & model, const std::wstring & field, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
@ -376,6 +386,9 @@ private:
void CopyTmpStreamToOutputStreams(Item::Function & fun, StreamType & ezc_out_tmp_stream, StreamType & previous_stream);
void CreateMsg(const wchar_t * type, const std::wstring & model_name, std::vector<std::wstring> & fields, size_t how_many_fields_print,
const wchar_t * arg = nullptr, const wchar_t * arg2 = nullptr, const wchar_t * arg3 = nullptr);
void CreateMsg(const wchar_t * type, const std::wstring & model_name, std::vector<std::wstring> & fields,
const wchar_t * arg = nullptr, const wchar_t * arg2 = nullptr, const wchar_t * arg3 = nullptr);
@ -1245,106 +1258,149 @@ bool Generator<StreamType>::IsCurrentParam(std::vector<Var> & parameters)
}
template<class StreamType>
void Generator<StreamType>::CallSpace(morm::ModelWrapper & model_wrapper, pt::Space & root_space, FindHelper & find_helper, std::vector<std::wstring> & fields, size_t field_index,
std::vector<Var> & parameters, StreamType & out_stream)
void Generator<StreamType>::CallSpaceObjectForLastField(std::vector<Var> & parameters, StreamType & out_stream, pt::Space * space)
{
// should we convert the last value to last_res?
if( ShouldMakeDump(parameters) )
{
space->serialize_to_json_stream(out_stream); // we can add pretty print
}
}
template<class StreamType>
pt::Space * Generator<StreamType>::CallSpaceObjectForMiddleField(std::wstring & root_space_name, std::vector<std::wstring> & fields, size_t field_index, pt::Space * space)
{
std::wstring & next_field = fields[field_index];
space = space->get_object_field(next_field);
if( !space )
{
CreateMsg(L"cannot find space field: ", root_space_name, fields, field_index + 1);
}
return space;
}
template<class StreamType>
void Generator<StreamType>::CallSpaceTableForLastField(morm::ModelWrapper & model_wrapper, std::vector<Var> & parameters, StreamType & out_stream,
pt::Space * space, size_t model_wrapper_space_table_index)
{
pt::Space::TableType * table = space->get_table();
if( stack_tab[stack_index-1].is_for )
{
// we are in [for...]statement, increment iterator and check the range
model_wrapper.increment_iterator(model_wrapper_space_table_index, table->size());
size_t iterator_value = model_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
last_res = (iterator_value < table->size());
}
else
{
// we are not in [for..], it can be for example [if...], return true if the table is not empty
last_res = !table->empty();
}
if( ShouldMakeDump(parameters) )
{
space->serialize_to_json_stream(out_stream);
}
if( IsCurrentParam(parameters) )
{
size_t iterator_value = model_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
if( iterator_value < table->size() )
{
(*table)[iterator_value]->serialize_to_json_stream(out_stream);
}
}
}
template<class StreamType>
pt::Space * Generator<StreamType>::CallSpaceTableForMiddleField(morm::ModelWrapper & model_wrapper, std::wstring & root_space_name, std::vector<std::wstring> & fields,
size_t field_index, pt::Space * space, size_t model_wrapper_space_table_index)
{
pt::Space::TableType * table = space->get_table();
// check the current iterator, if it is correct then select the item from the table
size_t iterator_value = model_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
if( iterator_value < table->size() )
{
space = (*table)[iterator_value];
}
else
{
CreateMsg(L"space table: ", root_space_name, fields, field_index, L" is not initialized, have you forgotten to use [for...] statement?");
space = nullptr;
}
return space;
}
template<class StreamType>
void Generator<StreamType>::CallSpace(morm::ModelWrapper & model_wrapper, pt::Space & root_space, FindHelper & find_helper, std::vector<std::wstring> & fields,
size_t root_field_index, std::vector<Var> & parameters, StreamType & out_stream)
{
pt::Space * space = &root_space;
last_res = false;
std::wstring * field = nullptr;
size_t field_index = root_field_index;
for(size_t i=field_index ; i < fields.size() + 1 ; )
/*
*
* we are iterating through such objects:
* [root_space, fields[field_index], fields[field_index+1], fields[field_index+2], fields[field_index+3] ...]
* the first item is the root_space with a find_helper.fun_name name
*
*/
while( (field_index < fields.size() + 1) && space )
{
bool is_last_field = (i == fields.size());
field = (i == 0) ? find_helper.fun_name : &fields[i - 1];
bool is_last_field = (field_index == fields.size());
if( space->is_object() )
{
if( is_last_field )
{
if( ShouldMakeDump(parameters) )
{
space->serialize_to_json_stream(out_stream); // we can add pretty print
}
CallSpaceObjectForLastField(parameters, out_stream, space);
}
else
{
pt::Space * old = space;
std::wstring & next_field = fields[i];
space = space->get_object_field(next_field);
if( !space )
{
if( plog )
{
(*plog) << pt::Log::log2 << "Ezc: there is no " << next_field << " property of object " << *field << pt::Log::logend;
}
break;
}
space = CallSpaceObjectForMiddleField(*find_helper.fun_name, fields, field_index, space);
}
++i;
field_index += 1;
}
else
if( space->is_table() )
{
pt::Space::TableType * table = space->get_table();
size_t space_index = i - field_index;
size_t model_wrapper_space_table_index = field_index - root_field_index;
// add testing space_index range [0..MODEL_WRAPPER_SPACE_INDICES_TABLE_SIZE - 1]
if( is_last_field )
if( model_wrapper_space_table_index < model_wrapper.space_indices_table_size() )
{
if( stack_tab[stack_index-1].is_for )
if( is_last_field )
{
// we are in [for...]statement, increment iterator and check the range
model_wrapper.increment_iterator(space_index, table->size());
size_t iterator_value = model_wrapper.get_space_iterator_value(space_index);
last_res = (iterator_value < table->size());
CallSpaceTableForLastField(model_wrapper, parameters, out_stream, space, model_wrapper_space_table_index);
field_index += 1;
}
else
{
// we are not in [for..], it can be for example [if...], return true if the table is not empty
last_res = !table->empty();
space = CallSpaceTableForMiddleField(model_wrapper, *find_helper.fun_name, fields, field_index, space, model_wrapper_space_table_index);
// don't increment field_index
}
if( ShouldMakeDump(parameters) )
{
space->serialize_to_json_stream(out_stream);
}
if( IsCurrentParam(parameters) )
{
size_t iterator_value = model_wrapper.get_space_iterator_value(space_index);
if( iterator_value < table->size() )
{
(*table)[iterator_value]->serialize_to_json_stream(out_stream);
}
}
++i;
}
else
{
// check the current iterator, if it is correct then select the item from the table
size_t iterator_value = model_wrapper.get_space_iterator_value(space_index);
last_res = (iterator_value < table->size());
if( last_res )
{
space = (*table)[iterator_value];
}
else
{
// IMPROVEME use CreateMsg()
if( plog )
{
(*plog) << pt::Log::log1 << "Ezc: table: " << field << " is not initialized, have you forgotten to use [for...] statement?" << pt::Log::logend;
}
break;
}
CreateMsg(L"", *find_helper.fun_name, fields, field_index, L" exceeded the maximum number of fields for a space object");
break;
}
}
else
@ -1352,15 +1408,11 @@ void Generator<StreamType>::CallSpace(morm::ModelWrapper & model_wrapper, pt::Sp
if( is_last_field )
{
space->serialize_to_string(out_stream);
++i;
field_index += 1;
}
else
{
if( plog )
{
(*plog) << pt::Log::log2 << "Ezc: " << (*field) << " is not a model not a model container nor a space" << pt::Log::logend;
}
CreateMsg(L"", *find_helper.fun_name, fields, field_index, L" is not a model, model container nor a space");
break;
}
}
@ -1915,16 +1967,16 @@ void Generator<StreamType>::CreateMsg(const wchar_t * type, const wchar_t * arg)
template<class StreamType>
void Generator<StreamType>::CreateMsg(const wchar_t * type, const std::wstring & model_name, std::vector<std::wstring> & fields,
void Generator<StreamType>::CreateMsg(const wchar_t * type, const std::wstring & model_name, std::vector<std::wstring> & fields, size_t how_many_fields_print,
const wchar_t * arg, const wchar_t * arg2, const wchar_t * arg3)
{
if( plog )
{
(*plog) << pt::Log::log2 << L"Ezc: " << type << model_name;
for(std::wstring & str : fields)
for(size_t i=0 ; i < how_many_fields_print && i < fields.size() ; ++i)
{
(*plog) << '.' << str;
(*plog) << '.' << fields[i];
}
if( arg )
@ -1947,6 +1999,16 @@ void Generator<StreamType>::CreateMsg(const wchar_t * type, const std::wstring &
}
template<class StreamType>
void Generator<StreamType>::CreateMsg(const wchar_t * type, const std::wstring & model_name, std::vector<std::wstring> & fields,
const wchar_t * arg, const wchar_t * arg2, const wchar_t * arg3)
{
CreateMsg(type, model_name, fields, fields.size(), arg, arg2, arg3);
}
template<class StreamType>
void Generator<StreamType>::CreateMsg(const std::wstring & type, const std::wstring & arg)
{