diff --git a/src/generator.h b/src/generator.h index f49f90c..276f5de 100644 --- a/src/generator.h +++ b/src/generator.h @@ -331,6 +331,9 @@ private: void CallObject(BaseObj & base_obj, int method_index, FunInfo & info); + void CallSpace(morm::ModelWrapper & model_wrapper, pt::Space & root_space, FindHelper & find_helper, std::vector & fields, size_t field_index, + std::vector & parameters, StreamType & out_stream); + #ifdef EZC_HAS_MORM_LIBRARY bool CallModel(morm::Model & model, const std::wstring & field, std::vector parameters, StreamType & out_stream, const StreamType & in_stream); CallModelHelper FindLastModelWrapper(morm::ModelWrapper & models_base, std::vector & fields); @@ -365,7 +368,10 @@ private: void TrimWhite(const wchar_t *& start, const wchar_t *& end); void SkipWhite(const wchar_t *& str); size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0); - bool ShouldEscapeValue(std::vector parameters); + bool ShouldEscapeValue(std::vector & parameters); + bool ShouldMakeDump(std::vector & parameters); + bool IsCurrentParam(std::vector & parameters); + void CopyTmpStreamToOutputStreams(Item::Function & fun, StreamType & ezc_out_tmp_stream, StreamType & previous_stream); @@ -1186,7 +1192,7 @@ void Generator::CallObject(BaseObj & base_obj, int metho template -bool Generator::ShouldEscapeValue(std::vector parameters) +bool Generator::ShouldEscapeValue(std::vector & parameters) { for(Var & var : parameters) { @@ -1203,6 +1209,164 @@ bool Generator::ShouldEscapeValue(std::vector parameters) } +template +bool Generator::ShouldMakeDump(std::vector & parameters) +{ + for(Var & var : parameters) + { + if( !var.is_function ) + { + if( var.str == L"dump" || var.str == L"to_str" ) + { + return true; + } + } + } + + return false; +} + + +template +bool Generator::IsCurrentParam(std::vector & parameters) +{ + for(Var & var : parameters) + { + if( !var.is_function ) + { + if( var.str == L"current" ) + { + return true; + } + } + } + + return false; +} + + +template +void Generator::CallSpace(morm::ModelWrapper & model_wrapper, pt::Space & root_space, FindHelper & find_helper, std::vector & fields, size_t field_index, + std::vector & parameters, StreamType & out_stream) +{ + pt::Space * space = &root_space; + last_res = false; + std::wstring * field = nullptr; + + for(size_t i=field_index ; i < fields.size() + 1 ; ++i) + { + bool is_last_field = (i == fields.size()); + + if( i == 0 ) + field = find_helper.fun_name; + else + field = &fields[i - 1]; + + + if( space->is_object() ) + { + if( is_last_field ) + { + if( ShouldMakeDump(parameters) ) + { + space->serialize_to_json_stream(out_stream); // we can add pretty print + } + } + else + { + 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; + } + } + } + else + if( space->is_table() ) + { + pt::Space::TableType * table = space->get_table(); + size_t space_index = i - field_index; + + // add testing space_index range [0..MODEL_WRAPPER_SPACE_INDICES_TABLE_SIZE - 1] + + if( is_last_field ) + { + if( stack_tab[stack_index-1].is_for ) + { + // 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()); + } + 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(space_index); + + if( iterator_value < table->size() ) + { + (*table)[iterator_value]->serialize_to_json_stream(out_stream); + } + } + } + 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; + } + } + } + else + { + if( is_last_field ) + { + space->serialize_to_string(out_stream); + } + else + { + if( plog ) + { + (*plog) << pt::Log::log2 << "Ezc: " << (*field) << " is not a model not a model container nor a space" << pt::Log::logend; + } + + break; + } + } + } +} + + #ifdef EZC_HAS_MORM_LIBRARY @@ -1250,31 +1414,31 @@ typename Generator::CallModelHelper Generator::FindLastM helper.model_wrapper = &models_base; helper.model = nullptr; - for(; helper.field_index < fields.size() ; ++helper.field_index) + for(; helper.field_index < fields.size() && !helper.model_wrapper->get_space() ; ++helper.field_index) { std::wstring & field = fields[helper.field_index]; - morm::ModelWrapper * child_models_base = helper.model_wrapper->find_child(field); + morm::ModelWrapper * child_model_wrapper = helper.model_wrapper->find_child(field); - if( !child_models_base ) + if( !child_model_wrapper ) { helper.model = helper.model_wrapper->get_model(); // this can return null for lists/vectors in a case when the iterator is not pointing to a valid item if( helper.model ) { - child_models_base = helper.model->get_model_wrapper(nullptr, field.c_str(), false); + child_model_wrapper = helper.model->get_model_wrapper(nullptr, field.c_str(), false); - if( child_models_base ) + if( child_model_wrapper ) { - helper.model_wrapper->add_child(field, child_models_base); + helper.model_wrapper->add_child(field, child_model_wrapper); } } } - if( !child_models_base ) + if( !child_model_wrapper ) break; - helper.model_wrapper = child_models_base; + helper.model_wrapper = child_model_wrapper; helper.model = nullptr; } @@ -1294,13 +1458,22 @@ void Generator::CallModelWrapper(FindHelper & find_helper, std::vect // helper.field_index == fields.size()-1 - last field is not a model nor a models container // helper.field_index < fields.size()-1 - incorrect + //morm::Model * model = helper.model_wrapper->get_model(); + pt::Space * space = helper.model_wrapper->get_space(); + if( helper.field_index + 1 < fields.size() ) { - CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", ", fields[helper.field_index].c_str(), L" is not a model nor a model container"); - last_res = false; - return; + if( space ) + { + CallSpace(*helper.model_wrapper, *space, find_helper, fields, helper.field_index, parameters, out_stream); + } + else + { + CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", ", fields[helper.field_index].c_str(), L" is not a model nor a model container nor a space"); + last_res = false; + } } - + else if( helper.field_index + 1 == fields.size() ) { // last field is not a model nor a models container @@ -1313,18 +1486,23 @@ void Generator::CallModelWrapper(FindHelper & find_helper, std::vect } } else + if( space ) + { + CallSpace(*helper.model_wrapper, *space, find_helper, fields, helper.field_index, parameters, out_stream); + } + else { last_res = false; - CreateMsg(L"model ", *find_helper.fun_name, fields, L" is not initialized, have you forgotten to use [for ...] statement?"); + CreateMsg(L"model ", *find_helper.fun_name, fields, L" is not initialized, have you forgotten to use [for ...] statement?"); // a different msg if we are using Space? } } else { // all fields items are models or models containers // this is usualy in [for...] or [if ...] statements - // helper.model_wrapper is always set if( stack_tab[stack_index-1].is_for ) { + // helper.model_wrapper is always set helper.model_wrapper->increment_iterator(); helper.model_wrapper->clear_childs(); last_res = helper.model_wrapper->is_iterator_correct();