From 6f756644004cd23b6ad348942ccdf1d359dfa1c1 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 12 Dec 2024 17:57:24 +0100 Subject: [PATCH] WIP: add a Val struct as an input/output when calling a function --- src/env.h | 2 +- src/generator.h | 326 ++++++++++++++++++++------------------ src/val.cpp | 404 ++++++++++++++++++++++++++++++++++-------------- src/val.h | 50 ++++-- 4 files changed, 503 insertions(+), 279 deletions(-) diff --git a/src/env.h b/src/env.h index a8f5958..1693739 100644 --- a/src/env.h +++ b/src/env.h @@ -233,7 +233,6 @@ struct Env void Clear() { - res = false; // result is false by default is_for = false; is_if = false; is_if_def = false; @@ -243,6 +242,7 @@ struct Env iter = 0; stack_tab = 0; stack_index = 0; + res.clear(); } /* diff --git a/src/generator.h b/src/generator.h index 053f53c..36822ee 100644 --- a/src/generator.h +++ b/src/generator.h @@ -142,12 +142,13 @@ private: Item::Function & item_fun, const std::wstring & fun_name, std::vector & fields, - Val & current, + Val & baseval, std::vector & parameters, Val & result, pt::Stream & out_stream, const pt::Stream & in_stream) : - item_fun(item_fun), fun_name(fun_name), fields(fields), current(current), parameters(parameters), result(result), out_stream(out_stream), in_stream(in_stream) + item_fun(item_fun), fun_name(fun_name), fields(fields), baseval(baseval), currentval(&baseval), + parameters(parameters), result(result), out_stream(out_stream), in_stream(in_stream) { #ifdef EZC_HAS_MORM_LIBRARY field_index = 0; @@ -159,7 +160,8 @@ private: Item::Function & item_fun; const std::wstring & fun_name; std::vector & fields; - Val & current; + Val & baseval; + Val * currentval; std::vector & parameters; Val & result; pt::Stream & out_stream; @@ -358,8 +360,10 @@ private: #ifdef EZC_HAS_MORM_LIBRARY bool CallModelField(FindHelper & find_helper, morm::Model & model); bool CallModel(FindHelper & find_helper, morm::Model & model); + Val WrapperToVal(morm::Wrapper & wrapper); void FindLastModelWrapper(FindHelper & find_helper); - bool CallWrapper(FindHelper & find_helper); + bool CallModel(FindHelper & find_helper); + bool CallModelContainerWrapper(FindHelper & find_helper); #endif void CallObject(BaseObj & base_obj, @@ -376,7 +380,7 @@ private: // pt::Stream & out_stream, // const pt::Stream & in_stream); - bool PrepareParameters(FindHelper & find_helper); + void PrepareParameters(FindHelper & find_helper); bool ReduceFields(FindHelper & find_helper); bool CallValue(FindHelper & find_helper); void CleanupParameters(std::vector & parameters); @@ -1057,7 +1061,7 @@ bool Generator::CheckBlockArgument(FindHelper & find_helper) if( size_t(find_helper.item_fun.arg) < block_stack.args.size() ) { - find_helper.current.set(block_stack.args[find_helper.item_fun.arg]); + find_helper.baseval.set(block_stack.args[find_helper.item_fun.arg]); return true; } } @@ -1115,25 +1119,25 @@ bool Generator::FindInModels(FindHelper & find_helper) { if( m->model ) { - find_helper.current.set(*m->model); + find_helper.baseval.set(*m->model); found = true; } else if( m->model_container_wrapper ) { - find_helper.current.set(*m->model_container_wrapper); + find_helper.baseval.set(*m->model_container_wrapper); found = true; } else if( m->date ) { - find_helper.current.set(*m->date); + find_helper.baseval.set(*m->date); found = true; } else if( m->space_wrapper ) { - find_helper.current.set(*m->space_wrapper); + find_helper.baseval.set(*m->space_wrapper); found = true; } } @@ -1166,7 +1170,7 @@ bool Generator::FindInFunctionsAndBlocks(FindHelper & find_helper) if( i != pfunctions->End() ) { - find_helper.current.set(i->second); + find_helper.baseval.set(i->second); return true; } } @@ -1177,7 +1181,7 @@ bool Generator::FindInFunctionsAndBlocks(FindHelper & find_helper) if( i != pblocks->End() ) { - find_helper.current.set(i->second); + find_helper.baseval.set(i->second); return true; } } @@ -1195,7 +1199,7 @@ bool Generator::FindInVariables(FindHelper & find_helper) if( i != pvals->end() ) { - find_helper.current.set(i->second); + find_helper.baseval.set(i->second); return true; } } @@ -1277,8 +1281,14 @@ void Generator::CallFunction(FindHelper & find_helper) { if( !IsTestingFunctionExistence() ) { - Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); - CallFunction(find_helper.current.user_function, env); + if( find_helper.baseval.type == Val::TYPE_FUNCTION && find_helper.baseval.pointer ) + { + using UserFunction = void (*)(Env &); + UserFunction user_function = reinterpret_cast(find_helper.baseval.pointer); + + Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + CallFunction(user_function, env); + } } } @@ -1295,15 +1305,10 @@ bool Generator::HasParam(std::vector & parameters, const wchar_t * param1, { for(Val & val : parameters) { - /* - if( !val.is_function ) + if( val.is_equal_string(param1) || (param2 && val.is_equal_string(param2)) ) { - if( val.str == param1 || (param2 && val.str == param2) ) - { - return true; - } + return true; } - */ } return false; @@ -1375,7 +1380,7 @@ void Generator::DumpModelIfNeeded(FindHelper & find_helper, morm::Model & model) // pt::TextStream temp_str; // model.to_text(temp_str, false, false); // find_helper.out_stream << temp_str; - model.to_text(find_helper.out_stream); + model.to_text(find_helper.out_stream, false, false); } } } @@ -1472,23 +1477,35 @@ bool Generator::CallDate(FindHelper & find_helper) bool found = true; bool all_fields_known = (find_helper.field_index == find_helper.fields.size()); bool last_field_not_known = (find_helper.field_index + 1 == find_helper.fields.size()); + pt::Date * date = nullptr; + + if( find_helper.baseval.type == Val::TYPE_DATE && find_helper.baseval.pointer ) + { + date = reinterpret_cast(find_helper.baseval.pointer); + } if( all_fields_known ) { - PrintDate(find_helper, find_helper.current.date); + if( date ) + { + PrintDate(find_helper, date); + } } else if( last_field_not_known ) { - if( !PrintDatePart(find_helper, find_helper.current.date) ) + if( date ) { - if( !IsTestingFunctionExistence() ) + if( !PrintDatePart(find_helper, date) ) { - CreateMsg(L"cannot find ", find_helper.fun_name, find_helper.fields, L", unknown property ", - find_helper.fields[find_helper.field_index].c_str(), L" of a Date object"); - } + if( !IsTestingFunctionExistence() ) + { + CreateMsg(L"cannot find ", find_helper.fun_name, find_helper.fields, L", unknown property ", + find_helper.fields[find_helper.field_index].c_str(), L" of a Date object"); + } - found = false; + found = false; + } } } else @@ -1551,7 +1568,7 @@ void Generator::CallSpaceTableForLastField( // we are in [for...]statement, increment iterator and check the range space_wrapper.increment_iterator(model_wrapper_space_table_index, table->size()); space_wrapper.invalidate_iterators(model_wrapper_space_table_index + 1); - size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); + //size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); //last_res = (iterator_value < table->size()); } else @@ -1631,7 +1648,7 @@ void Generator::PrintLastSpaceField(FindHelper & find_helper, pt::Space * space) bool Generator::CallSpace(FindHelper & find_helper) { - morm::SpaceWrapper * space_wrapper = find_helper.current.space_wrapper; + morm::SpaceWrapper * space_wrapper = reinterpret_cast(find_helper.baseval.pointer); pt::Space * space = space_wrapper->get_space(); //last_res = false; size_t field_index = find_helper.field_index; @@ -1733,16 +1750,11 @@ bool Generator::CallSpace(FindHelper & find_helper) bool Generator::CallModelField(FindHelper & find_helper, morm::Model & model) { - const std::wstring & field = find_helper.fields[find_helper.field_index]; - - /* - * if 'field' is a POD type then 'str' will be used in get_raw_value() - * if 'field' is a getter method with pt::Stream then 'str' will be used too - * if 'field' is a getter method which takes FunInfo<> then out_stream will be used and 'str' will be empty - * - */ - pt::WTextStream str; bool found = false; + const std::wstring & field = find_helper.fields[find_helper.field_index]; + bool no_escape = HasParam(find_helper.parameters, L"raw", L"noescape"); + + find_helper.result.output_stream->escape_input(!no_escape); if( find_helper.parameters.empty() ) { @@ -1750,21 +1762,13 @@ bool Generator::CallModelField(FindHelper & find_helper, morm::Model & model) Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); PrepareEnvStruct(env); - found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, str, false); - //last_res = env.res; + found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, find_helper.out_stream, false); } else { Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); PrepareEnvStruct(env); - found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, str, false); - //last_res = env.res; - } - - if( found && !str.empty()) - { - bool no_escape = HasParam(find_helper.parameters, L"raw", L"noescape"); - CopyStream(str, find_helper.out_stream, !no_escape); + found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, find_helper.out_stream, false); } return found; @@ -1816,28 +1820,50 @@ bool Generator::CallModel(FindHelper & find_helper, morm::Model & model) } +Val Generator::WrapperToVal(morm::Wrapper & wrapper) +{ + Val child(output_stream); + + if( wrapper.model ) + child.set(*wrapper.model); + else + if( wrapper.model_container_wrapper ) + child.set(*wrapper.model_container_wrapper); + else + if( wrapper.space_wrapper ) + child.set(*wrapper.space_wrapper); + else + if( wrapper.date ) + child.set(*wrapper.date); + + return child; +} void Generator::FindLastModelWrapper(FindHelper & find_helper) { - for(find_helper.field_index = 0 ; find_helper.field_index < find_helper.fields.size() && find_helper.current.has_model_object() ; ++find_helper.field_index) + for(find_helper.field_index = 0 ; find_helper.field_index < find_helper.fields.size() && find_helper.currentval->has_model_object() ; ++find_helper.field_index) { std::wstring & field = find_helper.fields[find_helper.field_index]; - Val * child_wrapper = find_helper.current.find_child(field); + Val * child_wrapper = find_helper.currentval->find_child(field); if( !child_wrapper ) { morm::Model * model = nullptr; - if( find_helper.current.type == Val::TYPE_MODEL && find_helper.current.model ) + if( find_helper.currentval->pointer ) { - model = find_helper.current.model; - } - else - if( find_helper.current.type == Val::TYPE_MODEL_CONTAINER_WRAPPER && find_helper.current.model_container_wrapper ) - { - model = find_helper.current.model_container_wrapper->get_model(); - // this can return null for lists/vectors in a case when the iterator is not pointing to a valid item + if( find_helper.currentval->type == Val::TYPE_MODEL ) + { + model = reinterpret_cast(find_helper.currentval->pointer); + } + else + if( find_helper.currentval->type == Val::TYPE_MODEL_CONTAINER_WRAPPER ) + { + morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast(find_helper.currentval->pointer); + model = model_container_wrapper->get_model(); + // this can return null for lists/vectors in a case when the iterator is not pointing to a valid item + } } if( model ) @@ -1848,24 +1874,10 @@ void Generator::FindLastModelWrapper(FindHelper & find_helper) if( new_wrapper.has_object() ) { - //child_wrapper = find_helper.wrapper->add_child(field, new_wrapper); - - Val child; - - if( new_wrapper.model ) - child.set(model); - else - if( new_wrapper.model_container_wrapper ) - child.set(new_wrapper.model_container_wrapper); - else - if( new_wrapper.space_wrapper ) - child.set(new_wrapper.space_wrapper); - else - if( new_wrapper.date ) - child.set(new_wrapper.date); + Val child = WrapperToVal(new_wrapper); if( child.type != Val::TYPE_VOID ) - child_wrapper = find_helper.current.add_child(field, child); + child_wrapper = find_helper.currentval->add_child(field, child); } } } @@ -1874,21 +1886,24 @@ void Generator::FindLastModelWrapper(FindHelper & find_helper) break; //find_helper.wrapper = child_wrapper; - find_helper.current.set(*child_wrapper); + find_helper.currentval = child_wrapper; } } +bool Generator::CallModel(FindHelper & find_helper) +{ + morm::Model * model = reinterpret_cast(find_helper.currentval->pointer); + return CallModel(find_helper, *model); +} -bool Generator::CallWrapper(FindHelper & find_helper) + + +bool Generator::CallModelContainerWrapper(FindHelper & find_helper) { bool found = true; //last_res = false; - // this should be moved to Reduce() method - // and here should be only a calling - FindLastModelWrapper(find_helper); - // if: // helper.field_index == fields.size() - all fields items are either models, models containers, space or a date // helper.field_index == fields.size()-1 - only the last field is not known @@ -1897,52 +1912,35 @@ bool Generator::CallWrapper(FindHelper & find_helper) bool all_fields_known = (find_helper.field_index == find_helper.fields.size()); bool last_field_not_known = (find_helper.field_index + 1 == find_helper.fields.size()); - if( find_helper.current.space_wrapper ) + morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast(find_helper.currentval->pointer); + morm::Model * model = model_container_wrapper->get_model(); + + if( model ) { - found = CallSpace(find_helper); + found = CallModel(find_helper, *model); } - - if( find_helper.current.date ) + else { - found = CallDate(find_helper); - } - - if( find_helper.current.model ) - { - found = CallModel(find_helper, *find_helper.current.model); - } - - if( find_helper.current.model_container_wrapper ) - { - morm::Model * model = find_helper.current.model_container_wrapper->get_model(); - - if( model ) + if( last_field_not_known ) { - found = CallModel(find_helper, *model); + // can be printed even for [if-def...] + CreateMsg(L"model ", find_helper.fun_name, find_helper.fields, L" is not initialized, have you forgotten to use [for ...] statement?"); + found = false; + } + } + + if( all_fields_known ) + { + if( is_generating_for ) + { + model_container_wrapper->increment_iterator(); + find_helper.currentval->clear_childs(); // or current? + //last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct(); } else { - if( last_field_not_known ) - { - // can be printed even for [if-def...] - CreateMsg(L"model ", find_helper.fun_name, find_helper.fields, L" is not initialized, have you forgotten to use [for ...] statement?"); - found = false; - } - } - - if( all_fields_known ) - { - if( is_generating_for ) - { - find_helper.current.model_container_wrapper->increment_iterator(); - find_helper.current.clear_childs(); - //last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct(); - } - else - { - // for [if-def...] last_res will be set later - //last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty(); - } + // for [if-def...] last_res will be set later + //last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty(); } } @@ -1991,10 +1989,11 @@ bool Generator::CallBlock(FindHelper & find_helper) ClearStream(*output_stream); block_stack_index += 1; - MakeText(*find_helper.current.item_block); + Item * item_block = reinterpret_cast(find_helper.baseval.pointer); + MakeText(*item_block); //CopyStream(*output_stream, find_helper.out_stream); - // last_res is set by [return ...] statement or other last evaluated function + // last_res is set by [return ...] statement or other last evaluated function IMPROVE ME now it is changed? ClearStream(*output_stream); output_stream = old_stream; @@ -2026,7 +2025,7 @@ bool Generator::CallBlock(FindHelper & find_helper) // } -bool Generator::PrepareParameters(FindHelper & find_helper) +void Generator::PrepareParameters(FindHelper & find_helper) { find_helper.parameters.resize(find_helper.item_fun.parameters.size()); @@ -2053,43 +2052,66 @@ bool Generator::PrepareParameters(FindHelper & find_helper) } + // give me a better name bool Generator::ReduceFields(FindHelper & find_helper) { + if( find_helper.baseval.has_model_object() ) + { + #ifdef EZC_HAS_MORM_LIBRARY + FindLastModelWrapper(find_helper); + #endif + } + else + { + // space ? + } + return true; } bool Generator::CallValue(FindHelper & find_helper) { -#ifdef EZC_HAS_MORM_LIBRARY - if( find_helper.current.type == Val::TYPE_MODEL && find_helper.current.model ) - return CallWrapper(find_helper); - else - if( find_helper.current.type == Val::TYPE_MODEL_CONTAINER_WRAPPER && find_helper.current.model_container_wrapper ) - return CallWrapper(find_helper); - else - if( find_helper.current.type == Val::TYPE_DATE && find_helper.current.date ) - return CallWrapper(find_helper); - else - if( find_helper.current.type == Val::TYPE_SPACE_WRAPPER && find_helper.current.space_wrapper ) - return CallWrapper(find_helper); - else -#endif - // if( find_helper.base_obj ) // OBJECTS WILL BE REMOVED - // CallObject(*find_helper.base_obj, find_helper.method_index, parameters, result, out_stream, in_stream); - //else - if( find_helper.current.type == Val::TYPE_FUNCTION && find_helper.current.user_function ) - CallFunction(find_helper); - else - if( find_helper.current.type == Val::TYPE_ITEM_BLOCK && find_helper.current.item_block ) - return CallBlock(find_helper); // result? - - // else - // if( find_helper.variable ) - // return CallVariable(item_fun, *find_helper.variable, parameters, result, out_stream, in_stream); + if( find_helper.baseval.pointer && find_helper.currentval->pointer ) + { + #ifdef EZC_HAS_MORM_LIBRARY + if( find_helper.baseval.type == Val::TYPE_MODEL ) + { + //return CallWrapper(find_helper); + return CallModel(find_helper); + } + else + if( find_helper.baseval.type == Val::TYPE_MODEL_CONTAINER_WRAPPER ) + return CallModelContainerWrapper(find_helper); + else + if( find_helper.baseval.type == Val::TYPE_DATE ) + //return CallWrapper(find_helper); + return CallDate(find_helper); + else + if( find_helper.baseval.type == Val::TYPE_SPACE_WRAPPER ) + return CallSpace(find_helper); + //return CallWrapper(find_helper); + else + #endif + // if( find_helper.base_obj ) // OBJECTS WILL BE REMOVED + // CallObject(*find_helper.base_obj, find_helper.method_index, parameters, result, out_stream, in_stream); + //else + if( find_helper.baseval.type == Val::TYPE_FUNCTION ) + { + CallFunction(find_helper); + return true; + } + else + if( find_helper.baseval.type == Val::TYPE_ITEM_BLOCK ) + return CallBlock(find_helper); + // else + // if( find_helper.variable ) + // return CallVariable(item_fun, *find_helper.variable, parameters, result, out_stream, in_stream); + } + return false; } @@ -2133,7 +2155,6 @@ bool Generator::Call(Item::Function & item_fun, // out_stream.Escape(true); //out_stream.escape_input(true); - if( !Find(find_helper) ) return false; @@ -2608,6 +2629,7 @@ void Generator::MakeTextFunction(Item & item) // does we need both seperate: result and output_stream? if( Call(item.function, nullptr, result, *output_stream, *empty_stream) ) { + output_stream->escape_input(true); result.serialize_to(*output_stream); } } diff --git a/src/val.cpp b/src/val.cpp index 9d20216..67912c9 100644 --- a/src/val.cpp +++ b/src/val.cpp @@ -77,31 +77,47 @@ Val & Val::operator=(const Val & val) void Val::copy(const Val & val) { type = val.type; - user_function = val.user_function; - model = val.model; - model_container_wrapper = val.model_container_wrapper; - date = val.date; - space_wrapper = val.space_wrapper; - space_local = val.space_local; - stream = val.stream; - space = val.space; + pointer = val.pointer; + + // user_function = val.user_function; + // model = val.model; + // model_container_wrapper = val.model_container_wrapper; + // date = val.date; + // space_wrapper = val.space_wrapper; + // space_local = val.space_local; + // stream = val.stream; + // space = val.space; + output_stream = val.output_stream; output_stream_original_size = val.output_stream_original_size; - if( model_container_wrapper ) - { - model_container_wrapper->increment_reference_counter(); - } - - if( space_wrapper ) - { - space_wrapper->increment_reference_counter(); - } + increment_model_container_wrapper_ref(); + increment_space_wrapper_ref(); // childs_map don't need to be copied } +void Val::increment_model_container_wrapper_ref() +{ + if( type == Type::TYPE_MODEL_CONTAINER_WRAPPER && pointer ) + { + morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast(pointer); + model_container_wrapper->increment_reference_counter(); + } +} + + +void Val::increment_space_wrapper_ref() +{ + if( type == Type::TYPE_SPACE_WRAPPER && pointer ) + { + morm::SpaceWrapper * space_wrapper = reinterpret_cast(pointer); + space_wrapper->increment_reference_counter(); + } +} + + Val::~Val() { clear(); @@ -125,21 +141,34 @@ void Val::set_output_stream(pt::Stream & output_stream) void Val::initialize_empty() { type = TYPE_VOID; - user_function = nullptr; - model = nullptr; - model_container_wrapper = nullptr; - date = nullptr; - space_wrapper = nullptr; - space = nullptr; - stream = nullptr; - item_block = nullptr; + pointer = nullptr; + + // user_function = nullptr; + // model = nullptr; + // model_container_wrapper = nullptr; + // date = nullptr; + // space_wrapper = nullptr; + // space = nullptr; + // stream = nullptr; + // item_block = nullptr; } void Val::clear() { - if( model_container_wrapper ) + clear_model_container_wrapper(); + clear_space_wrapper(); + initialize_empty(); + space_local.clear(); + clear_childs(); +} + + +void Val::clear_model_container_wrapper() +{ + if( type == Type::TYPE_MODEL_CONTAINER_WRAPPER && pointer ) { + morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast(pointer); model_container_wrapper->decrement_reference_counter(); if( model_container_wrapper->get_reference_counter() == 0 && model_container_wrapper->should_be_auto_removed() ) @@ -147,9 +176,14 @@ void Val::clear() delete model_container_wrapper; } } +} - if( space_wrapper ) + +void Val::clear_space_wrapper() +{ + if( type == Type::TYPE_SPACE_WRAPPER && pointer ) { + morm::SpaceWrapper * space_wrapper = reinterpret_cast(pointer); space_wrapper->decrement_reference_counter(); if( space_wrapper->get_reference_counter() == 0 && space_wrapper->should_be_auto_removed() ) @@ -157,10 +191,6 @@ void Val::clear() delete space_wrapper; } } - - initialize_empty(); - space_local.clear(); - clear_childs(); } @@ -200,7 +230,9 @@ bool Val::has_object() bool Val::has_model_object() { - return model || model_container_wrapper; + return (type == Type::TYPE_MODEL || type == Type::TYPE_MODEL_CONTAINER_WRAPPER) && pointer; + + //return model || model_container_wrapper; } @@ -215,7 +247,7 @@ bool Val::to_bool() const return space_local.to_bool(); case TYPE_STREAM: - return !stream->empty(); + return to_bool_stream(); case TYPE_FUNCTION: case TYPE_DATE: // date can be evaluated to true if it's different than the Unix epoch @@ -224,13 +256,13 @@ bool Val::to_bool() const break; case TYPE_SPACE_WRAPPER: - return space_wrapper->get_space()->to_bool(); + return to_bool_space_wrapper(); case TYPE_SPACE: - return space->to_bool(); + return to_bool_space(); case TYPE_MODEL_CONTAINER_WRAPPER: - return !model_container_wrapper->is_container_empty(); + return to_bool_model_container_wrapper(); case TYPE_OUTPUT_STREAM: return output_stream->size() != output_stream_original_size; @@ -240,6 +272,34 @@ bool Val::to_bool() const } +bool Val::to_bool_stream() const +{ + pt::Stream * stream = reinterpret_cast(pointer); + return !stream->empty(); +} + + +bool Val::to_bool_space() const +{ + pt::Space * space = reinterpret_cast(pointer); + return space->to_bool(); +} + + +bool Val::to_bool_space_wrapper() const +{ + morm::SpaceWrapper * space_wrapper = reinterpret_cast(pointer); + return space_wrapper->get_space()->to_bool(); +} + + +bool Val::to_bool_model_container_wrapper() const +{ + morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast(pointer); + return !model_container_wrapper->is_container_empty(); +} + + void Val::set(const char * str) { clear(); @@ -372,7 +432,7 @@ void Val::set(pt::Stream & str) { clear(); type = TYPE_STREAM; - this->stream = &str; + this->pointer = &str; } @@ -380,7 +440,7 @@ void Val::set(UserFunction user_function) { clear(); type = TYPE_FUNCTION; - this->user_function = user_function; + this->pointer = reinterpret_cast(user_function); } @@ -388,7 +448,7 @@ void Val::set(pt::Date & date) { clear(); type = TYPE_DATE; - this->date = &date; + this->pointer = &date; } @@ -396,7 +456,7 @@ void Val::set(morm::Model & model) { clear(); type = TYPE_MODEL; - this->model = &model; + this->pointer = &model; } @@ -404,8 +464,8 @@ void Val::set(morm::ModelContainerWrapper & model_container_wrapper) { clear(); type = TYPE_MODEL_CONTAINER_WRAPPER; - this->model_container_wrapper = &model_container_wrapper; - this->model_container_wrapper->increment_reference_counter(); + this->pointer = &model_container_wrapper; + model_container_wrapper.increment_reference_counter(); } @@ -414,7 +474,7 @@ void Val::set(std::vector & model_container) { clear(); type = TYPE_MODEL_CONTAINER_WRAPPER; - this->model_container_wrapper = new morm::ModelWrapperVector(&model_container); + this->pointer = new morm::ModelWrapperVector(&model_container); } @@ -423,7 +483,7 @@ void Val::set(std::list & model_container) { clear(); type = TYPE_MODEL_CONTAINER_WRAPPER; - this->model_container_wrapper = new morm::ModelWrapperList(&model_container); + this->pointer = new morm::ModelWrapperList(&model_container); } @@ -432,7 +492,7 @@ void Val::set(std::vector & model_container) { clear(); type = TYPE_MODEL_CONTAINER_WRAPPER; - this->model_container_wrapper = new morm::ModelWrapperVectorPointer(&model_container); + this->pointer = new morm::ModelWrapperVectorPointer(&model_container); } @@ -441,7 +501,7 @@ void Val::set(std::list & model_container) { clear(); type = TYPE_MODEL_CONTAINER_WRAPPER; - this->model_container_wrapper = new morm::ModelWrapperListPointer(&model_container); + this->pointer = new morm::ModelWrapperListPointer(&model_container); } @@ -449,8 +509,8 @@ void Val::set(morm::SpaceWrapper & space_wrapper) { clear(); type = TYPE_SPACE_WRAPPER; - this->space_wrapper = &space_wrapper; - this->space_wrapper->increment_reference_counter(); + this->pointer = &space_wrapper; + space_wrapper.increment_reference_counter(); } @@ -461,12 +521,12 @@ void Val::set(pt::Space & space, bool create_wrapper) if( create_wrapper ) { type = TYPE_SPACE_WRAPPER; - this->space_wrapper = new morm::SpaceWrapper(&space); + this->pointer = new morm::SpaceWrapper(&space); } else { type = TYPE_SPACE; - this->space = &space; + this->pointer = &space; } } @@ -475,51 +535,57 @@ void Val::set(Val & val) { clear(); - switch(val.type) - { - case TYPE_VOID: - break; + type = val.type; + pointer = val.pointer; - case TYPE_SPACE_LOCAL: - space_local = val.space_local; - break; + increment_model_container_wrapper_ref(); + increment_space_wrapper_ref(); - case TYPE_STREAM: - stream = val.stream; - break; + // switch(val.type) + // { + // case TYPE_VOID: + // break; - case TYPE_FUNCTION: - user_function = val.user_function; - break; + // case TYPE_SPACE_LOCAL: + // space_local = val.space_local; + // break; - case TYPE_DATE: - date = val.date; - break; + // case TYPE_STREAM: + // stream = val.stream; + // break; - case TYPE_MODEL: - model = val.model; - break; + // case TYPE_FUNCTION: + // user_function = val.user_function; + // break; - case TYPE_SPACE_WRAPPER: - space_wrapper = val.space_wrapper; - break; + // case TYPE_DATE: + // date = val.date; + // break; - case TYPE_SPACE: - space = val.space; - break; + // case TYPE_MODEL: + // model = val.model; + // break; - case TYPE_MODEL_CONTAINER_WRAPPER: - model_container_wrapper = val.model_container_wrapper; - break; + // case TYPE_SPACE_WRAPPER: + // space_wrapper = val.space_wrapper; + // break; - case TYPE_OUTPUT_STREAM: - output_stream = val.output_stream; - break; + // case TYPE_SPACE: + // space = val.space; + // break; - case TYPE_ITEM_BLOCK: - item_block = val.item_block; - break; - } + // case TYPE_MODEL_CONTAINER_WRAPPER: + // model_container_wrapper = val.model_container_wrapper; + // break; + + // case TYPE_OUTPUT_STREAM: + // output_stream = val.output_stream; + // break; + + // case TYPE_ITEM_BLOCK: + // item_block = val.item_block; + // break; + // } } @@ -527,7 +593,7 @@ void Val::set(Item & item_block) { clear(); type = TYPE_ITEM_BLOCK; - this->item_block = &item_block; + this->pointer = &item_block; } @@ -662,30 +728,97 @@ void Val::set(Item & item_block) -// bool Val::is_equal_string(const wchar_t * str) const -// { -// if( space_local.is_wstr() ) -// { -// return space_local.is_equal(str); -// } -// else -// if( space_local.is_str() ) -// { -// std::string str_utf8; -// pt::wide_to_utf8(str, str_utf8); -// return space_local.is_equal(str_utf8); -// } +bool Val::is_equal_string(const wchar_t * str) const +{ + bool found = false; -// return false; -// } + if( type == Type::TYPE_SPACE_LOCAL ) + { + found = is_space_equal_string(space_local, str); + } + else + if( type == Type::TYPE_SPACE && pointer ) + { + pt::Space * space = reinterpret_cast(pointer); + found = is_space_equal_string(*space, str); + } + else + if( type == Type::TYPE_STREAM && pointer ) + { + pt::Stream * stream = reinterpret_cast(pointer); + found = is_stream_equal_string(*stream, str); + } + else + if( type == Type::TYPE_OUTPUT_STREAM && output_stream ) + { + found = is_stream_equal_string(*output_stream, str); + } + + return found; +} + + + +bool Val::is_space_equal_string(const pt::Space & space, const wchar_t * str) const +{ + bool found = false; + + if( space.is_wstr() ) + { + found = space.is_equal(str); + } + else + if( space.is_str() ) + { + std::string str_utf8; + pt::wide_to_utf8(str, str_utf8); + found = space.is_equal(str_utf8); + } + + return found; +} + + +// IMPROVEME move me to pikotools? +bool Val::is_stream_equal_string(const pt::Stream & stream, const wchar_t * str) const +{ + size_t i = 0; + + if( stream.is_wchar_stream() ) + { + for(; i < stream.size() && str[i] != 0 ; ++i) + { + if( stream.get_wchar(i) != str[i] ) + return false; + } + + if( i != stream.size() || str[i] != 0 ) + return false; + } + else + if( stream.is_char_stream() ) + { + for(; i < stream.size() && str[i] != 0 ; ++i) + { + if( (wchar_t)(unsigned char)stream.get_char(i) != str[i] ) + return false; + } + + if( i != stream.size() || str[i] != 0 ) + return false; + } + else + { + return false; + } + + return true; +} void Val::serialize_to(pt::Stream & str) { - str.escape_input(true); - morm::Model * m; - switch(type) { case TYPE_SPACE_LOCAL: @@ -693,31 +826,27 @@ void Val::serialize_to(pt::Stream & str) break; case TYPE_STREAM: - str << stream; // operator(void*) will be taken? !!!! + serialize_stream_to(str); break; case TYPE_DATE: - date->SerializeISO(str); + serialize_date_to(str); break; case TYPE_MODEL: - model->to_text(str); + serialize_model_to(str); break; case TYPE_MODEL_CONTAINER_WRAPPER: - m = model_container_wrapper->get_model(); - - if( m ) - m->to_text(str); - + serialize_model_container_wrapper_to(str); break; case TYPE_SPACE_WRAPPER: - space_wrapper->get_space()->serialize_to_string(str); + serialize_space_wrapper_to(str); break; case TYPE_SPACE: - space->serialize_to_string(str); + serialize_space_to(str); break; case TYPE_VOID: @@ -729,6 +858,53 @@ void Val::serialize_to(pt::Stream & str) } +void Val::serialize_stream_to(pt::Stream & str) +{ + pt::Stream * stream = reinterpret_cast(pointer); + str << *stream; +} + + +void Val::serialize_date_to(pt::Stream & str) +{ + pt::Date * date = reinterpret_cast(pointer); + date->SerializeISO(str); +} + + +void Val::serialize_model_to(pt::Stream & str) +{ + morm::Model * model = reinterpret_cast(pointer); + model->to_text(str); +} + + +void Val::serialize_model_container_wrapper_to(pt::Stream & str) +{ + morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast(pointer); + morm::Model * model = model_container_wrapper->get_model(); + + if( model ) + { + model->to_text(str); + } +} + + +void Val::serialize_space_wrapper_to(pt::Stream & str) +{ + morm::SpaceWrapper * space_wrapper = reinterpret_cast(pointer); + space_wrapper->get_space()->serialize_to_string(str); +} + + +void Val::serialize_space_to(pt::Stream & str) +{ + pt::Space * space = reinterpret_cast(pointer); + space->serialize_to_string(str); +} + + void Val::assert_type_output_stream() { if( type != Val::TYPE_OUTPUT_STREAM ) diff --git a/src/val.h b/src/val.h index 6ed4bf7..4351203 100644 --- a/src/val.h +++ b/src/val.h @@ -64,7 +64,7 @@ class Val { public: - typedef void (*UserFunction)(Env &); + using UserFunction = void (*)(Env &); enum Type { @@ -188,19 +188,21 @@ public: Type type; pt::Space space_local; - UserFunction user_function; + void * pointer; - // Wrapper - morm::Model * model; - morm::ModelContainerWrapper * model_container_wrapper; - pt::Date * date; - morm::SpaceWrapper * space_wrapper; - // + // UserFunction user_function; - pt::Space * space; - pt::Stream * stream; + // // Wrapper + // morm::Model * model; + // morm::ModelContainerWrapper * model_container_wrapper; + // pt::Date * date; + // morm::SpaceWrapper * space_wrapper; + // // - Item * item_block; + // pt::Space * space; + // pt::Stream * stream; + + // Item * item_block; @@ -208,6 +210,10 @@ public: pt::Stream * output_stream; size_t output_stream_original_size; + + bool is_equal_string(const wchar_t * str) const; + + private: @@ -215,15 +221,35 @@ private: void initialize_empty(); void copy(const Val & val); + void increment_model_container_wrapper_ref(); + void increment_space_wrapper_ref(); + + + void clear_model_container_wrapper(); + void clear_space_wrapper(); // bool is_equal_bool(const char * str) const; // bool is_equal_string(const char * str) const; // bool is_equal_bool(const wchar_t * str) const; - // bool is_equal_string(const wchar_t * str) const; + + bool is_space_equal_string(const pt::Space & space, const wchar_t * str) const; + bool is_stream_equal_string(const pt::Stream & stream, const wchar_t * str) const; void assert_type_output_stream(); + bool to_bool_stream() const; + bool to_bool_space() const; + bool to_bool_space_wrapper() const; + bool to_bool_model_container_wrapper() const; + + void serialize_stream_to(pt::Stream & str); + void serialize_date_to(pt::Stream & str); + void serialize_model_to(pt::Stream & str); + void serialize_model_container_wrapper_to(pt::Stream & str); + void serialize_space_wrapper_to(pt::Stream & str); + void serialize_space_to(pt::Stream & str); + /* * old