renamed macro: EZC_HAS_SPECIAL_STREAM -> EZC_GENERATOR_HAS_PT_STREAM
added macro EZC_GENERATOR_HAS_WINIX_STREAM which is used by Generator::CopyStream(pt::WTextStream & src_stream, StreamType & dst_stream, bool should_escape) if this macro is defined then Generator is able to escape output stream
This commit is contained in:
parent
9c4fe51790
commit
615bad7372
206
src/generator.h
206
src/generator.h
|
@ -50,6 +50,9 @@
|
||||||
#include "expressionparser.h"
|
#include "expressionparser.h"
|
||||||
#include "models.h"
|
#include "models.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
|
#include "utf8/utf8.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef EZC_HAS_MORM_LIBRARY
|
#ifdef EZC_HAS_MORM_LIBRARY
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
@ -288,6 +291,11 @@ private:
|
||||||
void ClearEzcFrameTab();
|
void ClearEzcFrameTab();
|
||||||
|
|
||||||
void ClearStream(StreamType & str);
|
void ClearStream(StreamType & str);
|
||||||
|
void CopyStreamToString(StreamType & src_stream, std::wstring & dst_string);
|
||||||
|
void CopyStream(StreamType & src_stream, StreamType & dst_stream);
|
||||||
|
void CopyStream(pt::WTextStream & src_stream, StreamType & dst_stream, bool should_escape);
|
||||||
|
|
||||||
|
|
||||||
void RemoveStackFunData(Stack & sitem);
|
void RemoveStackFunData(Stack & sitem);
|
||||||
|
|
||||||
bool ConvertToBool(const std::wstring & str);
|
bool ConvertToBool(const std::wstring & str);
|
||||||
|
@ -357,7 +365,6 @@ private:
|
||||||
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
|
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
|
||||||
void SkipWhite(const wchar_t *& str);
|
void SkipWhite(const wchar_t *& str);
|
||||||
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0);
|
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0);
|
||||||
void CopyStream(pt::TextStream src_stream, StreamType & dst_stream, bool should_escape);
|
|
||||||
bool ShouldEscapeValue(std::vector<Var> parameters);
|
bool ShouldEscapeValue(std::vector<Var> parameters);
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,7 +386,7 @@ private:
|
||||||
void MakeTextFor(Item & item);
|
void MakeTextFor(Item & item);
|
||||||
void MakeItemText(Item & item);
|
void MakeItemText(Item & item);
|
||||||
void MakeTextContainer(Item & item);
|
void MakeTextContainer(Item & item);
|
||||||
void MakeTextNormal(Item & item);
|
void MakeTextFunction(Item & item);
|
||||||
void MakeTextDefine(Item & item, Var & var);
|
void MakeTextDefine(Item & item, Var & var);
|
||||||
void MakeTextDefine(Item & item);
|
void MakeTextDefine(Item & item);
|
||||||
void MakeTextDefineIfNotSet(Item & item);
|
void MakeTextDefineIfNotSet(Item & item);
|
||||||
|
@ -708,14 +715,91 @@ void Generator<StreamType>::ClearForStack()
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::ClearStream(StreamType & str)
|
void Generator<StreamType>::ClearStream(StreamType & str)
|
||||||
{
|
{
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||||
str.Clear();
|
str.clear();
|
||||||
#else
|
#else
|
||||||
str.str(L"");
|
str.str(L"");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::CopyStreamToString(StreamType & src_stream, std::wstring & dst_string)
|
||||||
|
{
|
||||||
|
if constexpr (sizeof(wchar_t) == sizeof(typename StreamType::char_type))
|
||||||
|
{
|
||||||
|
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||||
|
src_stream.to_str(dst_string);
|
||||||
|
#else
|
||||||
|
dst_string = src_stream.str();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||||
|
src_stream.to_str(dst_string);
|
||||||
|
#else
|
||||||
|
std::string tmp = src_stream.str();
|
||||||
|
pt::utf8_to_wide(tmp, dst_string);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::CopyStream(StreamType & src_stream, StreamType & dst_stream)
|
||||||
|
{
|
||||||
|
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||||
|
dst_stream << src_stream;
|
||||||
|
#else
|
||||||
|
dst_stream << src_stream.str();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::CopyStream(pt::WTextStream & src_stream, StreamType & dst_stream, bool should_escape)
|
||||||
|
{
|
||||||
|
if constexpr(sizeof(char) == sizeof(typename StreamType::char_type))
|
||||||
|
{
|
||||||
|
// winix html stream is always wide (wchar_t)
|
||||||
|
// so if we are here then the dst_stream cannot be a Winix::HtmlTextStream
|
||||||
|
#ifndef EZC_GENERATOR_HAS_WINIX_STREAM
|
||||||
|
|
||||||
|
wide_stream_to_utf8(src_stream, dst_stream, false);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pt::WTextStream::iterator i = src_stream.begin();
|
||||||
|
|
||||||
|
while( i != src_stream.end() )
|
||||||
|
{
|
||||||
|
#ifdef EZC_GENERATOR_HAS_WINIX_STREAM
|
||||||
|
|
||||||
|
// IMPROVEME we need a better api from winix htmltextstream
|
||||||
|
|
||||||
|
if( should_escape )
|
||||||
|
{
|
||||||
|
dst_stream << *i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst_stream.write(&(*i), 1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
dst_stream.write(&(*i), 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::RemoveStackFunData(Stack & s)
|
void Generator<StreamType>::RemoveStackFunData(Stack & s)
|
||||||
{
|
{
|
||||||
|
@ -1008,6 +1092,13 @@ bool Generator<StreamType>::Find(Item::Function & item_fun, FindHelper & find_he
|
||||||
#ifdef EZC_HAS_MORM_LIBRARY
|
#ifdef EZC_HAS_MORM_LIBRARY
|
||||||
if( FindInModels(find_helper) )
|
if( FindInModels(find_helper) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if( !item_fun.fields.empty() )
|
||||||
|
{
|
||||||
|
CreateMsg(L"unknown model", find_helper.fun_name->c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( CheckBlockArgument(item_fun.arg, find_helper) )
|
if( CheckBlockArgument(item_fun.arg, find_helper) )
|
||||||
|
@ -1092,34 +1183,6 @@ void Generator<StreamType>::CallObject(BaseObj<StreamType> & base_obj, int metho
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::CopyStream(pt::TextStream src_stream, StreamType & dst_stream, bool should_escape)
|
|
||||||
{
|
|
||||||
pt::TextStream::iterator i = src_stream.begin();
|
|
||||||
|
|
||||||
while( i != src_stream.end() )
|
|
||||||
{
|
|
||||||
if( should_escape )
|
|
||||||
{
|
|
||||||
dst_stream << *i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if constexpr(sizeof(pt::TextStream::char_type) == sizeof(typename StreamType::char_type))
|
|
||||||
{
|
|
||||||
dst_stream.write(&(*i), 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wchar_t buf = static_cast<unsigned char>(*i);
|
|
||||||
dst_stream.write(&buf, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
|
@ -1148,11 +1211,11 @@ bool Generator<StreamType>::CallModel(morm::Model & model, const std::wstring &
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* if 'field' is a POD type then 'str' will be used in get_raw_value()
|
* if 'field' is a POD type then 'str' will be used in get_raw_value()
|
||||||
* if 'field' is a getter method with pt::TextStream then 'str' will be used too
|
* 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
|
* if 'field' is a getter method which takes FunInfo<> then out_stream will be used and 'str' will be empty
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
pt::TextStream str;
|
pt::WTextStream str;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
if( parameters.empty() )
|
if( parameters.empty() )
|
||||||
|
@ -1168,7 +1231,7 @@ bool Generator<StreamType>::CallModel(morm::Model & model, const std::wstring &
|
||||||
last_res = info.res;
|
last_res = info.res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( found )
|
if( found && !str.empty())
|
||||||
{
|
{
|
||||||
bool should_escape = ShouldEscapeValue(parameters);
|
bool should_escape = ShouldEscapeValue(parameters);
|
||||||
CopyStream(str, out_stream, should_escape);
|
CopyStream(str, out_stream, should_escape);
|
||||||
|
@ -1320,13 +1383,7 @@ bool Generator<StreamType>::CallBlock(Item & item_block,
|
||||||
|
|
||||||
MakeText(item_block);
|
MakeText(item_block);
|
||||||
|
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
CopyStream(*output_stream, out_stream);
|
||||||
const std::wstring & str = output_stream->Str();
|
|
||||||
#else
|
|
||||||
const std::wstring & str = output_stream->str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
out_stream.write(str.c_str(), str.size());
|
|
||||||
// last_res is set by [return ...] statement or other last evaluated function
|
// last_res is set by [return ...] statement or other last evaluated function
|
||||||
|
|
||||||
ClearStream(*output_stream);
|
ClearStream(*output_stream);
|
||||||
|
@ -1392,12 +1449,7 @@ std::vector<Var> parameters;
|
||||||
StreamType local_temp_stream;
|
StreamType local_temp_stream;
|
||||||
Call(fun_child, nullptr, local_temp_stream, true, empty_stream);
|
Call(fun_child, nullptr, local_temp_stream, true, empty_stream);
|
||||||
|
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
CopyStreamToString(local_temp_stream, parameters[i].str);
|
||||||
parameters[i].str = local_temp_stream.Str();
|
|
||||||
#else
|
|
||||||
parameters[i].str = local_temp_stream.str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
parameters[i].res = last_res;
|
parameters[i].res = last_res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1621,42 +1673,33 @@ void Generator<StreamType>::CopyTmpStreamToOutputStreams(Item::Function & fun, S
|
||||||
{
|
{
|
||||||
if( output_frames_streams )
|
if( output_frames_streams )
|
||||||
{
|
{
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
CopyStream(ezc_out_tmp_stream, previous_stream);
|
||||||
const std::wstring & str = ezc_out_tmp_stream.Str();
|
|
||||||
#else
|
|
||||||
const std::wstring & str = ezc_out_tmp_stream.str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( !str.empty() )
|
for(size_t s=0 ; s < fun.parameters.size() ; ++s)
|
||||||
{
|
{
|
||||||
previous_stream.write(str.c_str(), str.size());
|
std::wstring & name = fun.parameters[s]->name;
|
||||||
|
auto imap = output_frames_streams->streams_map.find(name);
|
||||||
|
|
||||||
for(size_t s=0 ; s < fun.parameters.size() ; ++s)
|
if( imap == output_frames_streams->streams_map.end() )
|
||||||
{
|
{
|
||||||
std::wstring & name = fun.parameters[s]->name;
|
if( output_frames_streams->streams_map.size() < output_frames_streams->streams_tab.size() )
|
||||||
auto imap = output_frames_streams->streams_map.find(name);
|
|
||||||
|
|
||||||
if( imap == output_frames_streams->streams_map.end() )
|
|
||||||
{
|
{
|
||||||
if( output_frames_streams->streams_map.size() < output_frames_streams->streams_tab.size() )
|
/* a new stream from the pool (output_stream_tab) is taken */
|
||||||
{
|
StreamType * stream = output_frames_streams->streams_tab[ output_frames_streams->streams_map.size() ];
|
||||||
/* a new stream from the pool (output_stream_tab) is taken */
|
output_frames_streams->streams_map.insert(std::make_pair(name, stream));
|
||||||
StreamType * stream = output_frames_streams->streams_tab[ output_frames_streams->streams_map.size() ];
|
ClearStream(*stream);
|
||||||
output_frames_streams->streams_map.insert(std::make_pair(name, stream));
|
CopyStream(ezc_out_tmp_stream, *stream);
|
||||||
ClearStream(*stream);
|
|
||||||
stream->write(str.c_str(), str.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CreateMsg(L"limit of output streams in OutStreams<> has been reached");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StreamType * stream = imap->second;
|
CreateMsg(L"limit of output streams in OutStreams<> has been reached");
|
||||||
stream->write(str.c_str(), str.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StreamType * stream = imap->second;
|
||||||
|
CopyStream(ezc_out_tmp_stream, *stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1669,11 +1712,11 @@ void Generator<StreamType>::CreateMsg(const wchar_t * type, const wchar_t * arg)
|
||||||
{
|
{
|
||||||
if( plog )
|
if( plog )
|
||||||
{
|
{
|
||||||
(*plog) << pt::Log::log2 << L"Ezc: runtime error: " << type;
|
(*plog) << pt::Log::log2 << "Ezc: " << type;
|
||||||
|
|
||||||
if( arg )
|
if( arg )
|
||||||
{
|
{
|
||||||
(*plog) << arg;
|
(*plog) << ' ' << arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*plog) << pt::Log::logend;
|
(*plog) << pt::Log::logend;
|
||||||
|
@ -1804,7 +1847,7 @@ void Generator<StreamType>::MakeTextContainer(Item & item)
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextNormal(Item & item)
|
void Generator<StreamType>::MakeTextFunction(Item & item)
|
||||||
{
|
{
|
||||||
is_generating_normal = true;
|
is_generating_normal = true;
|
||||||
|
|
||||||
|
@ -1928,12 +1971,7 @@ void Generator<StreamType>::MakeTextDefine(Item & item, Var & var)
|
||||||
// call function
|
// call function
|
||||||
if( Call(fun, nullptr, stream_temp_define, true, empty_stream) )
|
if( Call(fun, nullptr, stream_temp_define, true, empty_stream) )
|
||||||
{
|
{
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
CopyStreamToString(stream_temp_define, var.str);
|
||||||
var.str += stream_temp_define.Str();
|
|
||||||
#else
|
|
||||||
var.str += stream_temp_define.str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
var.res = last_res;
|
var.res = last_res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2222,7 +2260,7 @@ void Generator<StreamType>::MakeText(Item & item)
|
||||||
|
|
||||||
if ( item.type == Item::item_text ) MakeItemText(item);
|
if ( item.type == Item::item_text ) MakeItemText(item);
|
||||||
else if( item.type == Item::item_container ) MakeTextContainer(item);
|
else if( item.type == Item::item_container ) MakeTextContainer(item);
|
||||||
else if( item.type == Item::item_function ) MakeTextNormal(item);
|
else if( item.type == Item::item_function ) MakeTextFunction(item);
|
||||||
else if( item.type == Item::item_if ) MakeTextIf(item);
|
else if( item.type == Item::item_if ) MakeTextIf(item);
|
||||||
else if( item.type == Item::item_def ) MakeTextDefine(item);
|
else if( item.type == Item::item_def ) MakeTextDefine(item);
|
||||||
else if( item.type == Item::item_def_if_not_set ) MakeTextDefineIfNotSet(item);
|
else if( item.type == Item::item_def_if_not_set ) MakeTextDefineIfNotSet(item);
|
||||||
|
|
|
@ -150,8 +150,8 @@ void OutStreams<StreamType>::ClearMap()
|
||||||
{
|
{
|
||||||
StreamType & str = *(i->second);
|
StreamType & str = *(i->second);
|
||||||
|
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||||
str.Clear();
|
str.clear();
|
||||||
#else
|
#else
|
||||||
str.str(L"");
|
str.str(L"");
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue