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 "models.h"
|
||||
#include "log/log.h"
|
||||
#include "utf8/utf8.h"
|
||||
|
||||
|
||||
|
||||
#ifdef EZC_HAS_MORM_LIBRARY
|
||||
#include "model.h"
|
||||
|
@ -288,6 +291,11 @@ private:
|
|||
void ClearEzcFrameTab();
|
||||
|
||||
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);
|
||||
|
||||
bool ConvertToBool(const std::wstring & str);
|
||||
|
@ -357,7 +365,6 @@ 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);
|
||||
void CopyStream(pt::TextStream src_stream, StreamType & dst_stream, bool should_escape);
|
||||
bool ShouldEscapeValue(std::vector<Var> parameters);
|
||||
|
||||
|
||||
|
@ -379,7 +386,7 @@ private:
|
|||
void MakeTextFor(Item & item);
|
||||
void MakeItemText(Item & item);
|
||||
void MakeTextContainer(Item & item);
|
||||
void MakeTextNormal(Item & item);
|
||||
void MakeTextFunction(Item & item);
|
||||
void MakeTextDefine(Item & item, Var & var);
|
||||
void MakeTextDefine(Item & item);
|
||||
void MakeTextDefineIfNotSet(Item & item);
|
||||
|
@ -708,14 +715,91 @@ void Generator<StreamType>::ClearForStack()
|
|||
template<class StreamType>
|
||||
void Generator<StreamType>::ClearStream(StreamType & str)
|
||||
{
|
||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||
str.Clear();
|
||||
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||
str.clear();
|
||||
#else
|
||||
str.str(L"");
|
||||
#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>
|
||||
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
|
||||
if( FindInModels(find_helper) )
|
||||
return true;
|
||||
|
||||
if( !item_fun.fields.empty() )
|
||||
{
|
||||
CreateMsg(L"unknown model", find_helper.fun_name->c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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>
|
||||
|
@ -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 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
|
||||
*
|
||||
*/
|
||||
pt::TextStream str;
|
||||
pt::WTextStream str;
|
||||
bool found = false;
|
||||
|
||||
if( parameters.empty() )
|
||||
|
@ -1168,7 +1231,7 @@ bool Generator<StreamType>::CallModel(morm::Model & model, const std::wstring &
|
|||
last_res = info.res;
|
||||
}
|
||||
|
||||
if( found )
|
||||
if( found && !str.empty())
|
||||
{
|
||||
bool should_escape = ShouldEscapeValue(parameters);
|
||||
CopyStream(str, out_stream, should_escape);
|
||||
|
@ -1320,13 +1383,7 @@ bool Generator<StreamType>::CallBlock(Item & item_block,
|
|||
|
||||
MakeText(item_block);
|
||||
|
||||
#ifdef EZC_HAS_SPECIAL_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());
|
||||
CopyStream(*output_stream, out_stream);
|
||||
// last_res is set by [return ...] statement or other last evaluated function
|
||||
|
||||
ClearStream(*output_stream);
|
||||
|
@ -1392,12 +1449,7 @@ std::vector<Var> parameters;
|
|||
StreamType local_temp_stream;
|
||||
Call(fun_child, nullptr, local_temp_stream, true, empty_stream);
|
||||
|
||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||
parameters[i].str = local_temp_stream.Str();
|
||||
#else
|
||||
parameters[i].str = local_temp_stream.str();
|
||||
#endif
|
||||
|
||||
CopyStreamToString(local_temp_stream, parameters[i].str);
|
||||
parameters[i].res = last_res;
|
||||
}
|
||||
else
|
||||
|
@ -1621,42 +1673,33 @@ void Generator<StreamType>::CopyTmpStreamToOutputStreams(Item::Function & fun, S
|
|||
{
|
||||
if( output_frames_streams )
|
||||
{
|
||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||
const std::wstring & str = ezc_out_tmp_stream.Str();
|
||||
#else
|
||||
const std::wstring & str = ezc_out_tmp_stream.str();
|
||||
#endif
|
||||
CopyStream(ezc_out_tmp_stream, previous_stream);
|
||||
|
||||
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;
|
||||
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() )
|
||||
{
|
||||
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() ];
|
||||
output_frames_streams->streams_map.insert(std::make_pair(name, stream));
|
||||
ClearStream(*stream);
|
||||
stream->write(str.c_str(), str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateMsg(L"limit of output streams in OutStreams<> has been reached");
|
||||
}
|
||||
/* a new stream from the pool (output_stream_tab) is taken */
|
||||
StreamType * stream = output_frames_streams->streams_tab[ output_frames_streams->streams_map.size() ];
|
||||
output_frames_streams->streams_map.insert(std::make_pair(name, stream));
|
||||
ClearStream(*stream);
|
||||
CopyStream(ezc_out_tmp_stream, *stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamType * stream = imap->second;
|
||||
stream->write(str.c_str(), str.size());
|
||||
CreateMsg(L"limit of output streams in OutStreams<> has been reached");
|
||||
}
|
||||
}
|
||||
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 )
|
||||
{
|
||||
(*plog) << pt::Log::log2 << L"Ezc: runtime error: " << type;
|
||||
(*plog) << pt::Log::log2 << "Ezc: " << type;
|
||||
|
||||
if( arg )
|
||||
{
|
||||
(*plog) << arg;
|
||||
(*plog) << ' ' << arg;
|
||||
}
|
||||
|
||||
(*plog) << pt::Log::logend;
|
||||
|
@ -1804,7 +1847,7 @@ void Generator<StreamType>::MakeTextContainer(Item & item)
|
|||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextNormal(Item & item)
|
||||
void Generator<StreamType>::MakeTextFunction(Item & item)
|
||||
{
|
||||
is_generating_normal = true;
|
||||
|
||||
|
@ -1928,12 +1971,7 @@ void Generator<StreamType>::MakeTextDefine(Item & item, Var & var)
|
|||
// call function
|
||||
if( Call(fun, nullptr, stream_temp_define, true, empty_stream) )
|
||||
{
|
||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||
var.str += stream_temp_define.Str();
|
||||
#else
|
||||
var.str += stream_temp_define.str();
|
||||
#endif
|
||||
|
||||
CopyStreamToString(stream_temp_define, var.str);
|
||||
var.res = last_res;
|
||||
}
|
||||
else
|
||||
|
@ -2222,7 +2260,7 @@ void Generator<StreamType>::MakeText(Item & item)
|
|||
|
||||
if ( item.type == Item::item_text ) MakeItemText(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_def ) MakeTextDefine(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);
|
||||
|
||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||
str.Clear();
|
||||
#ifdef EZC_GENERATOR_HAS_PT_STREAM
|
||||
str.clear();
|
||||
#else
|
||||
str.str(L"");
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue