WIP: add a Val struct as an input/output when calling a function

This commit is contained in:
2024-12-12 17:57:24 +01:00
parent 0ac4df97e9
commit 6f75664400
4 changed files with 503 additions and 279 deletions

View File

@@ -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();
}
/*

View File

@@ -142,12 +142,13 @@ private:
Item::Function & item_fun,
const std::wstring & fun_name,
std::vector<std::wstring> & fields,
Val & current,
Val & baseval,
std::vector<Val> & 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<std::wstring> & fields;
Val & current;
Val & baseval;
Val * currentval;
std::vector<Val> & 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<Val> & 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<UserFunction>(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<Val> & 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<pt::Date*>(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<morm::SpaceWrapper*>(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<morm::Model*>(find_helper.currentval->pointer);
}
else
if( find_helper.currentval->type == Val::TYPE_MODEL_CONTAINER_WRAPPER )
{
morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast<morm::ModelContainerWrapper*>(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<morm::Model*>(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<morm::ModelContainerWrapper*>(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<Item*>(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);
}
}

View File

@@ -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<morm::ModelContainerWrapper*>(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<morm::SpaceWrapper*>(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<morm::ModelContainerWrapper*>(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<morm::SpaceWrapper*>(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<pt::Stream*>(pointer);
return !stream->empty();
}
bool Val::to_bool_space() const
{
pt::Space * space = reinterpret_cast<pt::Space*>(pointer);
return space->to_bool();
}
bool Val::to_bool_space_wrapper() const
{
morm::SpaceWrapper * space_wrapper = reinterpret_cast<morm::SpaceWrapper*>(pointer);
return space_wrapper->get_space()->to_bool();
}
bool Val::to_bool_model_container_wrapper() const
{
morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast<morm::ModelContainerWrapper*>(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<void*>(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<ModelType> & model_container)
{
clear();
type = TYPE_MODEL_CONTAINER_WRAPPER;
this->model_container_wrapper = new morm::ModelWrapperVector<ModelType>(&model_container);
this->pointer = new morm::ModelWrapperVector<ModelType>(&model_container);
}
@@ -423,7 +483,7 @@ void Val::set(std::list<ModelType> & model_container)
{
clear();
type = TYPE_MODEL_CONTAINER_WRAPPER;
this->model_container_wrapper = new morm::ModelWrapperList<ModelType>(&model_container);
this->pointer = new morm::ModelWrapperList<ModelType>(&model_container);
}
@@ -432,7 +492,7 @@ void Val::set(std::vector<ModelType*> & model_container)
{
clear();
type = TYPE_MODEL_CONTAINER_WRAPPER;
this->model_container_wrapper = new morm::ModelWrapperVectorPointer<ModelType>(&model_container);
this->pointer = new morm::ModelWrapperVectorPointer<ModelType>(&model_container);
}
@@ -441,7 +501,7 @@ void Val::set(std::list<ModelType*> & model_container)
{
clear();
type = TYPE_MODEL_CONTAINER_WRAPPER;
this->model_container_wrapper = new morm::ModelWrapperListPointer<ModelType>(&model_container);
this->pointer = new morm::ModelWrapperListPointer<ModelType>(&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<pt::Space*>(pointer);
found = is_space_equal_string(*space, str);
}
else
if( type == Type::TYPE_STREAM && pointer )
{
pt::Stream * stream = reinterpret_cast<pt::Stream*>(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<pt::Stream*>(pointer);
str << *stream;
}
void Val::serialize_date_to(pt::Stream & str)
{
pt::Date * date = reinterpret_cast<pt::Date*>(pointer);
date->SerializeISO(str);
}
void Val::serialize_model_to(pt::Stream & str)
{
morm::Model * model = reinterpret_cast<morm::Model*>(pointer);
model->to_text(str);
}
void Val::serialize_model_container_wrapper_to(pt::Stream & str)
{
morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast<morm::ModelContainerWrapper*>(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<morm::SpaceWrapper*>(pointer);
space_wrapper->get_space()->serialize_to_string(str);
}
void Val::serialize_space_to(pt::Stream & str)
{
pt::Space * space = reinterpret_cast<pt::Space*>(pointer);
space->serialize_to_string(str);
}
void Val::assert_type_output_stream()
{
if( type != Val::TYPE_OUTPUT_STREAM )

View File

@@ -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