added support for hex strings and binary strings

added FT::hexadecimal, FT::binary and FT::dont_use_utf8
This commit is contained in:
Tomasz Sowa 2021-05-11 22:11:31 +02:00
parent 2afe111c57
commit 009955a0fd
19 changed files with 744 additions and 515 deletions

View File

@ -1,174 +1,49 @@
# DO NOT DELETE
baseexpression.o: baseexpression.h ../../pikotools/textstream/textstream.h
baseexpression.o: ../../pikotools/space/space.h
baseexpression.o: ../../pikotools/textstream/types.h
baseexpression.o: ../../pikotools/convert/inttostr.h
baseexpression.o: ../../pikotools/date/date.h
baseexpression.o: ../../pikotools/membuffer/membuffer.h
baseexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
baseexpression.o: modeldata.h cursorhelper.h queryresult.h
baseexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
baseexpression.o: finderhelper.h fieldvaluehelper.h ft.h model.h
baseexpression.o: modelconnector.h clearer.h dbconnector.h flatconnector.h
baseexpression.o: dbexpression.h flatexpression.h ../../pikotools/utf8/utf8.h
baseexpression.o: ../../pikotools/utf8/utf8_templates.h
baseexpression.o: ../../pikotools/utf8/utf8_private.h
clearer.o: clearer.h ../../pikotools/date/date.h
clearer.o: ../../pikotools/convert/inttostr.h ../../pikotools/space/space.h
clearer.o: ../../pikotools/textstream/types.h model.h
clearer.o: ../../pikotools/textstream/textstream.h
clearer.o: ../../pikotools/membuffer/membuffer.h
clearer.o: ../../pikotools/textstream/types.h modelconnector.h dbconnector.h
clearer.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
clearer.o: queryresult.h flatconnector.h dbexpression.h baseexpression.h
clearer.o: morm_types.h modelenv.h modeldata.h cursorhelper.h finderhelper.h
clearer.o: fieldvaluehelper.h ft.h flatexpression.h
dbconnector.o: ../../pikotools/space/spaceparser.h
dbconnector.o: ../../pikotools/space/space.h
dbconnector.o: ../../pikotools/textstream/types.h
dbconnector.o: ../../pikotools/convert/inttostr.h dbconnector.h
dbconnector.o: ../../pikotools/textstream/textstream.h
dbconnector.o: ../../pikotools/space/space.h ../../pikotools/date/date.h
dbconnector.o: ../../pikotools/membuffer/membuffer.h
dbconnector.o: ../../pikotools/textstream/types.h ../../pikotools/log/log.h
dbconnector.o: ../../pikotools/log/filelog.h queryresult.h dbexpression.h
baseexpression.o: baseexpression.h morm_types.h modelenv.h modeldata.h
baseexpression.o: cursorhelper.h queryresult.h finderhelper.h
baseexpression.o: fieldvaluehelper.h ft.h model.h modelconnector.h clearer.h
baseexpression.o: dbconnector.h flatconnector.h dbexpression.h
baseexpression.o: flatexpression.h
clearer.o: clearer.h model.h modelconnector.h dbconnector.h queryresult.h
clearer.o: ft.h flatconnector.h dbexpression.h baseexpression.h morm_types.h
clearer.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
clearer.o: fieldvaluehelper.h flatexpression.h
dbconnector.o: dbconnector.h queryresult.h ft.h dbexpression.h
dbconnector.o: baseexpression.h morm_types.h modelenv.h modeldata.h
dbconnector.o: cursorhelper.h finderhelper.h fieldvaluehelper.h ft.h model.h
dbconnector.o: cursorhelper.h finderhelper.h fieldvaluehelper.h model.h
dbconnector.o: modelconnector.h clearer.h flatconnector.h flatexpression.h
dbconnector.o: ../../pikotools/utf8/utf8.h
dbconnector.o: ../../pikotools/utf8/utf8_templates.h
dbconnector.o: ../../pikotools/utf8/utf8_private.h
dbconnector.o: ../../pikotools/convert/convert.h
dbconnector.o: ../../pikotools/convert/inttostr.h
dbconnector.o: ../../pikotools/convert/patternreplacer.h
dbconnector.o: ../../pikotools/convert/strtoint.h
dbconnector.o: ../../pikotools/convert/text.h ../../pikotools/convert/misc.h
dbexpression.o: dbexpression.h baseexpression.h
dbexpression.o: ../../pikotools/textstream/textstream.h
dbexpression.o: ../../pikotools/space/space.h
dbexpression.o: ../../pikotools/textstream/types.h
dbexpression.o: ../../pikotools/convert/inttostr.h
dbexpression.o: ../../pikotools/date/date.h
dbexpression.o: ../../pikotools/membuffer/membuffer.h
dbexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
dbexpression.o: modeldata.h cursorhelper.h queryresult.h
dbexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
dbexpression.o: finderhelper.h fieldvaluehelper.h ft.h
flatconnector.o: flatconnector.h ../../pikotools/textstream/textstream.h
flatconnector.o: ../../pikotools/space/space.h
flatconnector.o: ../../pikotools/textstream/types.h
flatconnector.o: ../../pikotools/convert/inttostr.h
flatconnector.o: ../../pikotools/date/date.h
flatconnector.o: ../../pikotools/membuffer/membuffer.h
flatconnector.o: ../../pikotools/textstream/types.h flatexpression.h
flatconnector.o: baseexpression.h morm_types.h modelenv.h modeldata.h
flatconnector.o: cursorhelper.h queryresult.h ../../pikotools/log/log.h
flatconnector.o: ../../pikotools/log/filelog.h finderhelper.h
flatconnector.o: fieldvaluehelper.h ft.h model.h modelconnector.h clearer.h
flatconnector.o: dbconnector.h dbexpression.h
flatexpression.o: flatexpression.h baseexpression.h
flatexpression.o: ../../pikotools/textstream/textstream.h
flatexpression.o: ../../pikotools/space/space.h
flatexpression.o: ../../pikotools/textstream/types.h
flatexpression.o: ../../pikotools/convert/inttostr.h
flatexpression.o: ../../pikotools/date/date.h
flatexpression.o: ../../pikotools/membuffer/membuffer.h
flatexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
flatexpression.o: modeldata.h cursorhelper.h queryresult.h
flatexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
flatexpression.o: finderhelper.h fieldvaluehelper.h ft.h
jsonconnector.o: jsonconnector.h flatconnector.h
jsonconnector.o: ../../pikotools/textstream/textstream.h
jsonconnector.o: ../../pikotools/space/space.h
jsonconnector.o: ../../pikotools/textstream/types.h
jsonconnector.o: ../../pikotools/convert/inttostr.h
jsonconnector.o: ../../pikotools/date/date.h
jsonconnector.o: ../../pikotools/membuffer/membuffer.h
jsonconnector.o: ../../pikotools/textstream/types.h jsonexpression.h
dbexpression.o: dbexpression.h baseexpression.h morm_types.h modelenv.h
dbexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
dbexpression.o: fieldvaluehelper.h ft.h
flatconnector.o: flatconnector.h flatexpression.h baseexpression.h
flatconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
flatconnector.o: queryresult.h finderhelper.h fieldvaluehelper.h ft.h model.h
flatconnector.o: modelconnector.h clearer.h dbconnector.h dbexpression.h
flatexpression.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
flatexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
flatexpression.o: fieldvaluehelper.h ft.h
jsonconnector.o: jsonconnector.h flatconnector.h jsonexpression.h
jsonconnector.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
jsonconnector.o: modeldata.h cursorhelper.h queryresult.h
jsonconnector.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
jsonconnector.o: finderhelper.h fieldvaluehelper.h ft.h
jsonconnector.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
jsonconnector.o: fieldvaluehelper.h ft.h
jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.h
jsonexpression.o: ../../pikotools/textstream/textstream.h
jsonexpression.o: ../../pikotools/space/space.h
jsonexpression.o: ../../pikotools/textstream/types.h
jsonexpression.o: ../../pikotools/convert/inttostr.h
jsonexpression.o: ../../pikotools/date/date.h
jsonexpression.o: ../../pikotools/membuffer/membuffer.h
jsonexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
jsonexpression.o: modeldata.h cursorhelper.h queryresult.h
jsonexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
jsonexpression.o: finderhelper.h fieldvaluehelper.h ft.h
model.o: model.h ../../pikotools/textstream/textstream.h
model.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
model.o: ../../pikotools/convert/inttostr.h ../../pikotools/date/date.h
model.o: ../../pikotools/membuffer/membuffer.h
model.o: ../../pikotools/textstream/types.h modelconnector.h clearer.h
model.o: dbconnector.h ../../pikotools/log/log.h
model.o: ../../pikotools/log/filelog.h queryresult.h flatconnector.h
model.o: dbexpression.h baseexpression.h morm_types.h modelenv.h modeldata.h
model.o: cursorhelper.h finderhelper.h fieldvaluehelper.h ft.h
model.o: flatexpression.h
modelconnector.o: modelconnector.h clearer.h ../../pikotools/date/date.h
modelconnector.o: ../../pikotools/convert/inttostr.h
modelconnector.o: ../../pikotools/space/space.h
modelconnector.o: ../../pikotools/textstream/types.h dbconnector.h
modelconnector.o: ../../pikotools/textstream/textstream.h
modelconnector.o: ../../pikotools/membuffer/membuffer.h
modelconnector.o: ../../pikotools/textstream/types.h
modelconnector.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
modelconnector.o: queryresult.h flatconnector.h
postgresqlconnector.o: postgresqlconnector.h dbconnector.h
postgresqlconnector.o: ../../pikotools/textstream/textstream.h
postgresqlconnector.o: ../../pikotools/space/space.h
postgresqlconnector.o: ../../pikotools/textstream/types.h
postgresqlconnector.o: ../../pikotools/convert/inttostr.h
postgresqlconnector.o: ../../pikotools/date/date.h
postgresqlconnector.o: ../../pikotools/membuffer/membuffer.h
postgresqlconnector.o: ../../pikotools/textstream/types.h
postgresqlconnector.o: ../../pikotools/log/log.h
postgresqlconnector.o: ../../pikotools/log/filelog.h queryresult.h
postgresqlconnector.o: postgresqlqueryresult.h ../../pikotools/utf8/utf8.h
postgresqlconnector.o: ../../pikotools/utf8/utf8_templates.h
postgresqlconnector.o: ../../pikotools/utf8/utf8_private.h
postgresqlconnector.o: postgresqlexpression.h dbexpression.h baseexpression.h
postgresqlconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
postgresqlconnector.o: finderhelper.h fieldvaluehelper.h ft.h
postgresqlconnector.o: ../../pikotools/convert/strtoint.h
postgresqlconnector.o: ../../pikotools/convert/text.h
postgresqlconnector.o: ../../pikotools/convert/misc.h
jsonexpression.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
jsonexpression.o: queryresult.h finderhelper.h fieldvaluehelper.h ft.h
model.o: model.h modelconnector.h clearer.h dbconnector.h queryresult.h ft.h
model.o: flatconnector.h dbexpression.h baseexpression.h morm_types.h
model.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
model.o: fieldvaluehelper.h flatexpression.h
modelconnector.o: modelconnector.h clearer.h dbconnector.h queryresult.h ft.h
modelconnector.o: flatconnector.h
postgresqlconnector.o: postgresqlconnector.h dbconnector.h queryresult.h ft.h
postgresqlconnector.o: postgresqlqueryresult.h postgresqlexpression.h
postgresqlconnector.o: dbexpression.h baseexpression.h morm_types.h
postgresqlconnector.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
postgresqlconnector.o: fieldvaluehelper.h
postgresqlexpression.o: postgresqlexpression.h dbexpression.h
postgresqlexpression.o: baseexpression.h
postgresqlexpression.o: ../../pikotools/textstream/textstream.h
postgresqlexpression.o: ../../pikotools/space/space.h
postgresqlexpression.o: ../../pikotools/textstream/types.h
postgresqlexpression.o: ../../pikotools/convert/inttostr.h
postgresqlexpression.o: ../../pikotools/date/date.h
postgresqlexpression.o: ../../pikotools/membuffer/membuffer.h
postgresqlexpression.o: ../../pikotools/textstream/types.h morm_types.h
postgresqlexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
postgresqlexpression.o: ../../pikotools/log/log.h
postgresqlexpression.o: ../../pikotools/log/filelog.h finderhelper.h
postgresqlexpression.o: baseexpression.h morm_types.h modelenv.h modeldata.h
postgresqlexpression.o: cursorhelper.h queryresult.h finderhelper.h
postgresqlexpression.o: fieldvaluehelper.h ft.h
postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h
postgresqlqueryresult.o: ../../pikotools/log/log.h
postgresqlqueryresult.o: ../../pikotools/textstream/textstream.h
postgresqlqueryresult.o: ../../pikotools/space/space.h
postgresqlqueryresult.o: ../../pikotools/textstream/types.h
postgresqlqueryresult.o: ../../pikotools/convert/inttostr.h
postgresqlqueryresult.o: ../../pikotools/date/date.h
postgresqlqueryresult.o: ../../pikotools/membuffer/membuffer.h
postgresqlqueryresult.o: ../../pikotools/textstream/types.h
postgresqlqueryresult.o: ../../pikotools/log/filelog.h
queryresult.o: queryresult.h ../../pikotools/log/log.h
queryresult.o: ../../pikotools/textstream/textstream.h
queryresult.o: ../../pikotools/space/space.h
queryresult.o: ../../pikotools/textstream/types.h
queryresult.o: ../../pikotools/convert/inttostr.h ../../pikotools/date/date.h
queryresult.o: ../../pikotools/membuffer/membuffer.h
queryresult.o: ../../pikotools/textstream/types.h
queryresult.o: ../../pikotools/log/filelog.h ../../pikotools/utf8/utf8.h
queryresult.o: ../../pikotools/utf8/utf8_templates.h
queryresult.o: ../../pikotools/utf8/utf8_private.h
queryresult.o: queryresult.h

View File

@ -318,71 +318,95 @@ void BaseExpression::after_second_part_long_field_name()
void BaseExpression::before_field_value(const std::wstring &)
void BaseExpression::before_field_value(const std::wstring &, FT field_type)
{
before_field_value_string();
before_field_value_string(field_type);
}
void BaseExpression::before_field_value(const std::string &)
void BaseExpression::before_field_value(const std::string &, FT field_type)
{
before_field_value_string();
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const std::wstring &)
void BaseExpression::after_field_value(const std::wstring &, FT field_type)
{
after_field_value_string();
after_field_value_string(field_type);
}
void BaseExpression::after_field_value(const std::string &)
void BaseExpression::after_field_value(const std::string &, FT field_type)
{
after_field_value_string();
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const wchar_t *)
void BaseExpression::before_field_value(const wchar_t *, FT field_type)
{
before_field_value_string();
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const wchar_t *)
void BaseExpression::after_field_value(const wchar_t *, FT field_type)
{
after_field_value_string();
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const char *)
void BaseExpression::before_field_value(const char *, FT field_type)
{
before_field_value_string();
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const char *)
void BaseExpression::after_field_value(const char *, FT field_type)
{
after_field_value_string();
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const PT::Date &)
void BaseExpression::before_field_value(wchar_t, FT field_type)
{
before_field_value_string();
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const PT::Date &)
void BaseExpression::after_field_value(wchar_t, FT field_type)
{
after_field_value_string();
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const PT::Space &)
void BaseExpression::before_field_value(char, FT field_type)
{
before_field_value_string();
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const PT::Space &)
void BaseExpression::after_field_value(char, FT field_type)
{
after_field_value_string();
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const PT::Date &, FT field_type)
{
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const PT::Date &, FT field_type)
{
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const PT::Space &, FT field_type)
{
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const PT::Space &, FT field_type)
{
after_field_value_string(field_type);
}
@ -392,82 +416,120 @@ void BaseExpression::put_name_value_separator()
}
void BaseExpression::esc(char val, PT::TextStream & stream)
char BaseExpression::char_to_hex_part(char c)
{
stream << val;
if( c < 10 )
return c + '0';
return c - 10 + 'A';
}
void BaseExpression::esc(unsigned char val, PT::TextStream & stream)
void BaseExpression::char_to_hex(char c, PT::TextStream & stream)
{
esc(static_cast<char>(val), stream);
stream << char_to_hex_part(((unsigned char)c) >> 4);
stream << char_to_hex_part(((unsigned char)c) & 0x0f);
}
void BaseExpression::esc(wchar_t val, PT::TextStream & stream)
void BaseExpression::esc(char val, PT::TextStream & stream, FT field_type)
{
char utf8_buf[10];
size_t utf8_len = PT::IntToUTF8((int)val, utf8_buf, sizeof(utf8_buf));
for(size_t a = 0 ; a < utf8_len ; ++a)
if( field_type.is_binary() || field_type.is_hexadecimal() )
{
esc(utf8_buf[a], stream);
char_to_hex(val, stream);
}
else
{
stream << val;
}
}
void BaseExpression::esc(const std::wstring & val, PT::TextStream & stream)
void BaseExpression::esc(unsigned char val, PT::TextStream & stream, FT field_type)
{
char utf8_buf[10];
esc(static_cast<char>(val), stream, field_type);
}
for(size_t i = 0 ; i < val.size() ; ++i)
void BaseExpression::esc(wchar_t val, PT::TextStream & stream, FT field_type)
{
if( field_type.use_utf8() )
{
size_t utf8_len = PT::IntToUTF8((int)val[i], utf8_buf, sizeof(utf8_buf));
char utf8_buf[10];
size_t utf8_len = PT::IntToUTF8((int)val, utf8_buf, sizeof(utf8_buf));
for(size_t a = 0 ; a < utf8_len ; ++a)
{
esc(utf8_buf[a], stream);
esc(utf8_buf[a], stream, field_type);
}
}
else
{
esc(static_cast<char>(val), stream, field_type);
}
}
void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, PT::TextStream & stream, FT field_type)
{
if( field_type.use_utf8() )
{
char utf8_buf[10];
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
{
size_t utf8_len = PT::IntToUTF8((int)val[i], utf8_buf, sizeof(utf8_buf));
for(size_t a = 0 ; a < utf8_len ; ++a)
{
esc(utf8_buf[a], stream, field_type);
}
}
}
else
{
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
{
esc(static_cast<char>(val[i]), stream, field_type);
}
}
}
void BaseExpression::esc(const wchar_t * val, PT::TextStream & stream)
void BaseExpression::esc(const std::wstring & val, PT::TextStream & stream, FT field_type)
{
char utf8_buf[10];
for(size_t i = 0 ; val[i] != 0 ; ++i)
{
size_t utf8_len = PT::IntToUTF8((int)val[i], utf8_buf, sizeof(utf8_buf));
for(size_t a = 0 ; a < utf8_len ; ++a)
{
esc(utf8_buf[a], stream);
}
}
esc(val.c_str(), true, val.size(), stream, field_type);
}
void BaseExpression::esc(const std::string & val, PT::TextStream & stream)
void BaseExpression::esc(const wchar_t * val, PT::TextStream & stream, FT field_type)
{
esc(val, false, 0, stream, field_type);
}
void BaseExpression::esc(const std::string & val, PT::TextStream & stream, FT field_type)
{
for(size_t i = 0 ; i < val.size() ; ++i)
{
esc(val[i], stream);
esc(val[i], stream, field_type);
}
}
void BaseExpression::esc(const char * val, PT::TextStream & stream)
void BaseExpression::esc(const char * val, PT::TextStream & stream, FT field_type)
{
for(size_t i = 0 ; val[i] != 0 ; ++i)
{
esc(val[i], stream);
esc(val[i], stream, field_type);
}
}
void BaseExpression::esc(bool val, PT::TextStream & stream)
void BaseExpression::esc(bool val, PT::TextStream & stream, FT field_type)
{
if( val )
stream << "true";
@ -476,105 +538,105 @@ void BaseExpression::esc(bool val, PT::TextStream & stream)
}
void BaseExpression::esc(short val, PT::TextStream & stream)
void BaseExpression::esc(short val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned short val, PT::TextStream & stream)
void BaseExpression::esc(unsigned short val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(int val, PT::TextStream & stream)
void BaseExpression::esc(int val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned int val, PT::TextStream & stream)
void BaseExpression::esc(unsigned int val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(long val, PT::TextStream & stream)
void BaseExpression::esc(long val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned long val, PT::TextStream & stream)
void BaseExpression::esc(unsigned long val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(long long val, PT::TextStream & stream)
void BaseExpression::esc(long long val, PT::TextStream & stream, FT field_type)
{
// not implemented in PT::TextStream yet
//stream << val;
}
void BaseExpression::esc(unsigned long long val, PT::TextStream & stream)
void BaseExpression::esc(unsigned long long val, PT::TextStream & stream, FT field_type)
{
//stream << val;
}
void BaseExpression::esc(float val, PT::TextStream & stream)
void BaseExpression::esc(float val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(double val, PT::TextStream & stream)
void BaseExpression::esc(double val, PT::TextStream & stream, FT field_type)
{
stream << val;
}
void BaseExpression::esc(long double val, PT::TextStream & stream)
void BaseExpression::esc(long double val, PT::TextStream & stream, FT field_type)
{
// IMPLEMENT ME in PT::TextStream
//stream << val;
}
void BaseExpression::esc(const PT::Date & date, PT::TextStream & stream)
void BaseExpression::esc(const PT::Date & date, PT::TextStream & stream, FT field_type)
{
stream << date;
}
void BaseExpression::esc(const PT::TextStream & val, PT::TextStream & stream)
void BaseExpression::esc(const PT::TextStream & val, PT::TextStream & stream, FT field_type)
{
PT::TextStream::const_iterator i = val.begin();
for(; i != val.end() ; ++i)
{
esc(*i, stream);
esc(*i, stream, field_type);
}
}
void BaseExpression::esc(const PT::WTextStream & val, PT::TextStream & stream)
void BaseExpression::esc(const PT::WTextStream & val, PT::TextStream & stream, FT field_type)
{
PT::WTextStream::const_iterator i = val.begin();
for(; i != val.end() ; ++i)
{
esc(*i, stream);
esc(*i, stream, field_type);
}
}
void BaseExpression::esc(const PT::Space & space, PT::TextStream & stream)
void BaseExpression::esc(const PT::Space & space, PT::TextStream & stream, FT field_type)
{
PT::WTextStream tmp_stream;
space.serialize_to_space_stream(tmp_stream, true);
esc(tmp_stream, stream);
esc(tmp_stream, stream, field_type);
}
@ -687,11 +749,11 @@ void BaseExpression::esc(const PT::Space & space, PT::TextStream & stream)
//}
void BaseExpression::before_field_value_string()
void BaseExpression::before_field_value_string(FT field_type)
{
}
void BaseExpression::after_field_value_string()
void BaseExpression::after_field_value_string(FT field_type)
{
}

View File

@ -129,13 +129,13 @@ public:
if( field_type.is_primary_key() )
{
if( model_env && model_env->has_primary_key_set )
put_field_value(field_value);
put_field_value(field_value, field_type);
else
put_null_value();
}
else
{
put_field_value(field_value);
put_field_value(field_value, field_type);
}
}
@ -288,35 +288,35 @@ public:
* esc for: signed char, wchar_t, char16_t, char32_t
*
*/
virtual void esc(char val, PT::TextStream & stream);
virtual void esc(unsigned char val, PT::TextStream & stream);
virtual void esc(char val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(unsigned char val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(wchar_t val, PT::TextStream & stream);
virtual void esc(wchar_t val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const std::wstring & val, PT::TextStream & stream);
virtual void esc(const wchar_t * val, PT::TextStream & stream);
virtual void esc(const std::wstring & val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const wchar_t * val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const std::string & val, PT::TextStream & stream);
virtual void esc(const char * val, PT::TextStream & stream);
virtual void esc(const std::string & val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const char * val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(bool val, PT::TextStream & stream);
virtual void esc(short val, PT::TextStream & stream);
virtual void esc(unsigned short val, PT::TextStream & stream);
virtual void esc(int val, PT::TextStream & stream);
virtual void esc(unsigned int val, PT::TextStream & stream);
virtual void esc(long val, PT::TextStream & stream);
virtual void esc(unsigned long val, PT::TextStream & stream);
virtual void esc(long long val, PT::TextStream & stream);
virtual void esc(unsigned long long val, PT::TextStream & stream);
virtual void esc(float val, PT::TextStream & stream);
virtual void esc(double val, PT::TextStream & stream);
virtual void esc(long double val, PT::TextStream & stream);
virtual void esc(bool val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(short val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(unsigned short val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(int val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(unsigned int val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(long val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(unsigned long val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(long long val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(unsigned long long val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(float val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(double val, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(long double val, PT::TextStream & stream, FT field_type = FT::default_type);
//virtual void esc(void* val, PT::TextStream & stream);
virtual void esc(const PT::Date & date, PT::TextStream & stream);
virtual void esc(const PT::TextStream & val,PT::TextStream & stream);
virtual void esc(const PT::WTextStream & val,PT::TextStream & stream);
virtual void esc(const PT::Space & space, PT::TextStream & stream);
virtual void esc(const PT::Date & date, PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const PT::TextStream & val,PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const PT::WTextStream & val,PT::TextStream & stream, FT field_type = FT::default_type);
virtual void esc(const PT::Space & space, PT::TextStream & stream, FT field_type = FT::default_type);
virtual bool is_long_field_name(const wchar_t * field_name);
virtual bool is_long_field_name(const PT::TextStream & table_name);
@ -344,13 +344,13 @@ protected:
virtual void dump_additional_info(Model & model);
template<typename FieldValue>
void put_field_value(const FieldValue & field_value)
void put_field_value(const FieldValue & field_value, FT field_type)
{
if( out_stream )
{
before_field_value(field_value);
esc(field_value, *out_stream);
after_field_value(field_value);
before_field_value(field_value, field_type);
esc(field_value, *out_stream, field_type);
after_field_value(field_value, field_type);
}
}
@ -402,7 +402,7 @@ protected:
field_value_list_separator();
}
put_field_value(m);
put_field_value(m, FT::default_type);
is_first = false;
}
@ -641,7 +641,7 @@ protected:
field_value_list_separator();
}
put_field_value(v);
put_field_value(v, FT::default_type);
is_first = false;
}
@ -672,31 +672,37 @@ protected:
virtual void put_long_field_name(const wchar_t * field_name);
virtual void put_short_field_name(const wchar_t * field_name, ModelEnv * model_env);
virtual void before_field_value(const std::wstring &);
virtual void after_field_value(const std::wstring &);
virtual void before_field_value(const std::wstring &, FT field_type);
virtual void after_field_value(const std::wstring &, FT field_type);
virtual void before_field_value(const std::string &);
virtual void after_field_value(const std::string &);
virtual void before_field_value(const std::string &, FT field_type);
virtual void after_field_value(const std::string &, FT field_type);
virtual void before_field_value(const wchar_t *);
virtual void after_field_value(const wchar_t *);
virtual void before_field_value(const wchar_t *, FT field_type);
virtual void after_field_value(const wchar_t *, FT field_type);
virtual void before_field_value(const char *);
virtual void after_field_value(const char *);
virtual void before_field_value(const char *, FT field_type);
virtual void after_field_value(const char *, FT field_type);
virtual void before_field_value(const PT::Date &);
virtual void after_field_value(const PT::Date &);
virtual void before_field_value(wchar_t, FT field_type);
virtual void after_field_value(wchar_t, FT field_type);
virtual void before_field_value(const PT::Space &);
virtual void after_field_value(const PT::Space &);
virtual void before_field_value(char, FT field_type);
virtual void after_field_value(char, FT field_type);
virtual void before_field_value(const PT::Date &, FT field_type);
virtual void after_field_value(const PT::Date &, FT field_type);
virtual void before_field_value(const PT::Space &, FT field_type);
virtual void after_field_value(const PT::Space &, FT field_type);
template<typename FieldValue>
void before_field_value(const FieldValue &)
void before_field_value(const FieldValue &, FT field_type)
{
}
template<typename FieldValue>
void after_field_value(const FieldValue &)
void after_field_value(const FieldValue &, FT field_type)
{
}
@ -747,12 +753,14 @@ protected:
// }
private:
virtual void before_field_value_string();
virtual void after_field_value_string();
virtual void before_field_value_string(FT field_type);
virtual void after_field_value_string(FT field_type);
char char_to_hex_part(char c);
void char_to_hex(char c, PT::TextStream & stream);
void esc(const wchar_t * val, bool has_known_length, size_t len, PT::TextStream & stream, FT field_type = FT::default_type);
};

View File

@ -61,6 +61,10 @@ void Clearer::clear_value(unsigned char & field_value)
field_value = 0;
}
void Clearer::clear_value(wchar_t & field_value)
{
field_value = 0;
}
void Clearer::clear_value(std::wstring & field_value)
{

View File

@ -54,6 +54,7 @@ public:
virtual void clear_value(char & field_value);
virtual void clear_value(unsigned char & field_value);
virtual void clear_value(wchar_t & field_value);
virtual void clear_value(std::wstring & field_value);
virtual void clear_value(std::string & field_value);
virtual void clear_value(bool & field_value);

View File

@ -291,52 +291,310 @@ void DbConnector::allocate_default_expression_if_needed()
}
void DbConnector::get_value(const char * value_str, char & field_value)
char DbConnector::unescape_hex_char_part(char hex)
{
field_value = *value_str;
value_str += 1;
if( *value_str != 0 )
if( hex>='0' && hex<='9' )
{
// value has more than one charater, put some error?
return hex - '0';
}
else
if( hex>='a' && hex<='f' )
{
return hex - 'a' + 10;
}
else
if( hex>='A' && hex<='F' )
{
return hex - 'A' + 10;
}
else
{
if( log )
{
(*log) << PT::Log::log2 << "Morm: incorrect character when reading a hex string, char code: " << (int)(unsigned char)hex;
if( hex >= 32 )
{
(*log) << " '" << hex << "'";
}
(*log) << PT::Log::logend;
}
}
return 0;
}
char DbConnector::unescape_hex_char(char char1, char char2)
{
int c1 = unescape_hex_char_part(char1);
int c2 = unescape_hex_char_part(char2);
return static_cast<char>(((c1 << 4) | c2));
}
void DbConnector::unescape_hex_string(const char * str, std::string & out)
{
for(size_t i=0 ; str[i] != 0 ; i+=2 )
{
out += unescape_hex_char(str[i], str[i+1]);
}
}
void DbConnector::unescape_hex_string(const char * str, std::wstring & out, FT field_type)
{
if( field_type.use_utf8() )
{
size_t len;
wchar_t c;
while( *str != 0 && (len = unescape_hex_char(str, c, field_type)) > 0 )
{
out += c;
str += len;
}
}
else
{
for(size_t i=0 ; str[i] != 0 ; i+=2 )
{
out += static_cast<wchar_t>(static_cast<unsigned char>(unescape_hex_char(str[i], str[i+1])));
}
}
}
void DbConnector::unescape_bin_string(const char * str, std::string & out)
{
unescape_hex_string(str, out);
}
void DbConnector::unescape_bin_string(const char * str, std::wstring & out, FT field_type)
{
unescape_hex_string(str, out, field_type);
}
// returns how many characters have been provided to utf8_str buffer
// min size of utf8_str should be 5 bytes (max 4 bytes for utf8 sequence + terminating null)
size_t DbConnector::unescape_hex_char(const char * value_str, char * utf8_str, size_t utf8_str_max_len)
{
size_t value_str_index = 0;
size_t utf8_str_index = 0;
utf8_str[0] = 0;
while( utf8_str_index + 1 < utf8_str_max_len )
{
if( value_str[value_str_index] != 0 && value_str[value_str_index+1] != 0 )
{
utf8_str[utf8_str_index] = unescape_hex_char(value_str[value_str_index], value_str[value_str_index+1]);
utf8_str[utf8_str_index+1] = 0;
}
else
{
break;
}
value_str_index += 2;
utf8_str_index += 1;
}
return utf8_str_index;
}
// CHECKME need to be tested
// returns how many characters were used from value_str
size_t DbConnector::unescape_hex_char(const char * value_str, wchar_t & field_value, FT field_type)
{
size_t len = 0;
if( field_type.use_utf8() )
{
char utf8_str[4 + 1]; // max utf8 sequence length + terminating zero
size_t utf8_str_len = unescape_hex_char(value_str, utf8_str, sizeof(utf8_str) / sizeof(char));
int value_int;
bool is_correct;
len = PT::UTF8ToInt(utf8_str, utf8_str_len, value_int, is_correct);
len = len * 2;
if( is_correct )
{
field_value = static_cast<wchar_t>(value_int);
}
else
{
if( log )
{
(*log) << PT::Log::log2 << "Morm: incorrect utf-8 sequence (ignoring)" << PT::Log::logend;
}
}
}
else
{
if( value_str[0] != 0 && value_str[1] != 0 )
{
field_value = static_cast<wchar_t>(static_cast<unsigned char>(unescape_hex_char(value_str[0], value_str[1])));
len = 2;
}
else
{
if( log )
{
(*log) << PT::Log::log2 << "Morm: unexpected end of string (ignoring)" << PT::Log::logend;
}
}
}
return len;
}
size_t DbConnector::unescape_bin_char(const char * value_str, wchar_t & field_value, FT field_type)
{
return unescape_hex_char(value_str, field_value, field_type);
}
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, char & field_value, FT field_type)
{
wchar_t c;
field_value = 0;
get_value(value_str, c, field_type);
if( field_type.use_utf8() )
{
if( c <= 127 )
{
field_value = static_cast<char>(c);
}
else
{
if( log )
{
(*log) << PT::Log::log2 << "Morm: a character greater than 127 cannot be stored in char type, code point: "
<< (int)c << " '" << c << "'" << PT::Log::logend;
}
}
}
else
{
field_value = static_cast<char>(c);
}
}
void DbConnector::get_value(const char * value_str, unsigned char & field_value)
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, unsigned char & field_value, FT field_type)
{
field_value = *(const unsigned char*)value_str;
value_str += 1;
char tmp_char;
get_value(value_str, tmp_char, field_type);
if( *value_str != 0 )
field_value = static_cast<unsigned char>(tmp_char);
}
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, wchar_t & field_value, FT field_type)
{
field_value = 0;
if( field_type.is_binary() )
{
// value has more than one charater, put some error?
unescape_bin_char(value_str, field_value, field_type);
}
else
if( field_type.is_hexadecimal() )
{
unescape_hex_char(value_str, field_value, field_type);
}
else
{
if( field_type.use_utf8() )
{
int value_int;
bool is_correct;
PT::UTF8ToInt(value_str, value_int, is_correct);
if( is_correct )
{
field_value = static_cast<wchar_t>(value_int);
}
else
{
// report an error?
}
}
else
{
field_value = static_cast<wchar_t>((unsigned char)*value_str);
}
}
}
void DbConnector::get_value(const char * value_str, std::wstring & field_value)
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, std::wstring & field_value, FT field_type)
{
// CHECKME
// what about \0 in val_str?
// it is escaped somehow?
PT::UTF8ToWide(value_str, field_value);
if( field_type.is_binary() )
{
unescape_bin_string(value_str, field_value, field_type);
}
else
if( field_type.is_hexadecimal() )
{
unescape_hex_string(value_str, field_value, field_type);
}
else
{
if( field_type.use_utf8() )
{
PT::UTF8ToWide(value_str, field_value);
}
else
{
for(size_t i=0 ; value_str[i] != 0 ; ++i)
{
field_value += static_cast<wchar_t>(value_str[i]);
}
}
}
}
void DbConnector::get_value(const char * value_str, std::string & field_value)
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, std::string & field_value, FT field_type)
{
field_value = value_str;
if( field_type.is_binary() )
{
unescape_bin_string(value_str, field_value);
}
else
if( field_type.is_hexadecimal() )
{
unescape_hex_string(value_str, field_value);
}
else
{
field_value = value_str;
}
}
void DbConnector::get_value(const char * value_str, bool & field_value)
void DbConnector::get_value(const char * value_str, bool & field_value, FT field_type)
{
// IMPROVE ME
// this 't' is locale dependent
@ -344,91 +602,91 @@ void DbConnector::get_value(const char * value_str, bool & field_value)
}
void DbConnector::get_value(const char * value_str, short & field_value)
void DbConnector::get_value(const char * value_str, short & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = (short)PT::Toi(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned short & field_value)
void DbConnector::get_value(const char * value_str, unsigned short & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = (unsigned short)PT::Toui(value_str, 10);
}
void DbConnector::get_value(const char * value_str, int & field_value)
void DbConnector::get_value(const char * value_str, int & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Toi(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned int & field_value)
void DbConnector::get_value(const char * value_str, unsigned int & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Toui(value_str, 10);
}
void DbConnector::get_value(const char * value_str, long & field_value)
void DbConnector::get_value(const char * value_str, long & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Tol(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned long & field_value)
void DbConnector::get_value(const char * value_str, unsigned long & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Toul(value_str, 10);
}
void DbConnector::get_value(const char * value_str, long long & field_value)
void DbConnector::get_value(const char * value_str, long long & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Toll(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned long long & field_value)
void DbConnector::get_value(const char * value_str, unsigned long long & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Toull(value_str, 10);
}
void DbConnector::get_value(const char * value_str, float & field_value)
void DbConnector::get_value(const char * value_str, float & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = strtof(value_str, 0);
}
void DbConnector::get_value(const char * value_str, double & field_value)
void DbConnector::get_value(const char * value_str, double & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = strtod(value_str, 0);
}
void DbConnector::get_value(const char * value_str, long double & field_value)
void DbConnector::get_value(const char * value_str, long double & field_value, FT field_type)
{
// IMPROVE ME give some overflow checking
field_value = strtold(value_str, 0);
}
void DbConnector::get_value(const char * value_str, PT::Date & field_value)
void DbConnector::get_value(const char * value_str, PT::Date & field_value, FT field_type)
{
// IMPROVE ME give some log if parsing failed
field_value.Parse(value_str);
}
void DbConnector::get_value(const char * value_str, PT::Space & field_value)
void DbConnector::get_value(const char * value_str, PT::Space & field_value, FT field_type)
{
field_value.clear();
@ -443,7 +701,7 @@ void DbConnector::get_value(const char * value_str, PT::Space & field_value)
if( log )
{
(*log) << PT::Log::log1 << "Morm: I cannot correctly parse the Space struct from the datebase"
(*log) << PT::Log::log2 << "Morm: I cannot correctly parse the Space struct from the datebase"
<< ", the raw string is: " << value_str << PT::Log::logend;
}
}

View File

@ -38,6 +38,7 @@
#include "textstream/textstream.h"
#include "log/log.h"
#include "queryresult.h"
#include "ft.h"
namespace morm
@ -90,25 +91,27 @@ public:
virtual bool query_insert(const PT::TextStream & stream, QueryResult & query_result);
virtual bool query_remove(const PT::TextStream & stream, QueryResult & query_result);
virtual void get_value(const char * value_str, char & field_value);
virtual void get_value(const char * value_str, unsigned char & field_value);
virtual void get_value(const char * value_str, std::wstring & field_value);
virtual void get_value(const char * value_str, std::string & field_value);
virtual void get_value(const char * value_str, bool & field_value);
virtual void get_value(const char * value_str, short & field_value);
virtual void get_value(const char * value_str, unsigned short & field_value);
virtual void get_value(const char * value_str, int & field_value);
virtual void get_value(const char * value_str, unsigned int & field_value);
virtual void get_value(const char * value_str, long & field_value);
virtual void get_value(const char * value_str, unsigned long & field_value);
virtual void get_value(const char * value_str, long long & field_value);
virtual void get_value(const char * value_str, unsigned long long & field_value);
virtual void get_value(const char * value_str, float & field_value);
virtual void get_value(const char * value_str, double & field_value);
virtual void get_value(const char * value_str, long double & field_value);
virtual void get_value(const char * value_str, PT::Date & field_value);
virtual void get_value(const char * value_str, PT::Space & field_value);
virtual void get_value(const char * value_str, char & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned char & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, wchar_t & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, std::wstring & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, std::string & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, bool & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, short & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned short & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, int & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned int & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, long & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, long long & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long long & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, float & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, double & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, long double & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, PT::Date & field_value, FT field_type = FT::default_type);
virtual void get_value(const char * value_str, PT::Space & field_value, FT field_type = FT::default_type);
// add get_value for PT::TextStream and PT::WTextStream
template<typename FieldValue>
bool get_last_sequence(const wchar_t * sequence_table_name, FieldValue & field_value)
@ -145,6 +148,23 @@ protected:
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
virtual void unescape_hex_string(const char * str, std::string & out);
virtual void unescape_hex_string(const char * str, std::wstring & out, FT field_type);
virtual void unescape_bin_string(const char * str, std::string & out);
virtual void unescape_bin_string(const char * str, std::wstring & out, FT field_type);
virtual size_t unescape_hex_char(const char * value_str, char * utf8_str, size_t utf8_str_max_len);
virtual size_t unescape_hex_char(const char * value_str, wchar_t & field_value, FT field_type);
virtual size_t unescape_bin_char(const char * value_str, wchar_t & field_value, FT field_type);
private:
char unescape_hex_char_part(char hex);
char unescape_hex_char(char char1, char char2);
};

View File

@ -183,13 +183,13 @@ void DbExpression::put_name_value_separator()
void DbExpression::before_field_value_string()
void DbExpression::before_field_value_string(FT field_type)
{
(*out_stream) << "'";
}
void DbExpression::after_field_value_string()
void DbExpression::after_field_value_string(FT field_type)
{
(*out_stream) << "'";
}

View File

@ -81,18 +81,15 @@ protected:
int output_type;
std::vector<int> conjunctions;
bool can_field_be_generated(FT field_type);
void field_before();
void put_name_value_separator();
private:
void before_field_value_string();
void after_field_value_string();
void before_field_value_string(FT field_type);
void after_field_value_string(FT field_type);
};

View File

@ -39,7 +39,7 @@
namespace morm
{
void FlatExpression::esc(const PT::Date & date, PT::TextStream & stream)
void FlatExpression::esc(const PT::Date & date, PT::TextStream & stream, FT field_type)
{
date.SerializeISO(stream);
}

View File

@ -45,7 +45,7 @@ class FlatExpression : public BaseExpression
{
public:
void esc(const PT::Date & date, PT::TextStream & stream);
void esc(const PT::Date & date, PT::TextStream & stream, FT field_type);

View File

@ -57,6 +57,9 @@ public:
no_updatable = 16,
no_fetchable = 32, /* not supported yet */
raw_field_name = 64,
dont_use_utf8 = 128,
hexadecimal = 256,
binary = 512,
};
/*
@ -137,6 +140,22 @@ public:
return is_flag_set(raw_field_name);
}
bool use_utf8() const
{
return !is_flag_set(dont_use_utf8);
}
bool is_hexadecimal() const
{
return is_flag_set(hexadecimal);
}
bool is_binary() const
{
return is_flag_set(binary);
}
};
}

View File

@ -105,12 +105,12 @@ void JSONExpression::after_second_part_long_field_name()
}
void JSONExpression::before_field_value_string()
void JSONExpression::before_field_value_string(FT field_type)
{
(*out_stream) << "\"";
}
void JSONExpression::after_field_value_string()
void JSONExpression::after_field_value_string(FT field_type)
{
(*out_stream) << "\"";
}
@ -134,20 +134,48 @@ void JSONExpression::after_field_value_list()
}
void JSONExpression::esc(char val, PT::TextStream & stream)
void JSONExpression::esc(char val, PT::TextStream & stream, FT field_type)
{
switch( val )
if( field_type.is_hexadecimal() || field_type.is_binary() )
{
case 0: stream << '\\'; stream << '0'; break; // may to skip this character is better?
case '\r': stream << '\\'; stream << 'r'; break;
case '\n': stream << '\\'; stream << 'n'; break;
case '\t': stream << '\\'; stream << 't'; break;
case 0x08: stream << '\\'; stream << 'b'; break;
case 0x0c: stream << '\\'; stream << 'f'; break;
case '\\': stream << '\\'; stream << '\\'; break;
case '"': stream << '\\'; stream << '\"'; break;
default:
stream << val;
char_to_hex(val, stream);
}
else
{
if( (unsigned char)val < 32 )
{
char buf[10];
size_t len;
PT::Toa((unsigned char)val, buf, sizeof(buf)/sizeof(char), 16, &len);
stream << "\\u";
if( len < 4 )
{
for(size_t i=0 ; i < (4-len) ; ++i)
{
stream << '0';
}
}
stream << buf;
}
else
{
switch( val )
{
case 0: stream << '\\'; stream << '0'; break; // may to skip this character is better?
case '\r': stream << '\\'; stream << 'r'; break;
case '\n': stream << '\\'; stream << 'n'; break;
case '\t': stream << '\\'; stream << 't'; break;
case 0x08: stream << '\\'; stream << 'b'; break;
case 0x0c: stream << '\\'; stream << 'f'; break;
case '\\': stream << '\\'; stream << '\\'; break;
case '"': stream << '\\'; stream << '\"'; break;
default:
stream << val;
}
}
}
}

View File

@ -70,13 +70,13 @@ protected:
// 'morm::JSONExpression::esc' hides overloaded virtual function [-Woverloaded-virtual]
using FlatExpression::esc;
void esc(char val, PT::TextStream & stream);
void esc(char val, PT::TextStream & stream, FT field_type);
private:
void before_field_value_string();
void after_field_value_string();
void before_field_value_string(FT field_type);
void after_field_value_string(FT field_type);
};

View File

@ -232,6 +232,11 @@ protected:
field_generic(field_name, field_name, field_value, field_type);
}
void field(const wchar_t * field_name, wchar_t & field_value, FT field_type = FT::default_type)
{
field_generic(field_name, field_name, field_value, field_type);
}
void field(const wchar_t * field_name, std::wstring & field_value, FT field_type = FT::default_type)
{
field_generic(field_name, field_name, field_value, field_type);
@ -347,6 +352,11 @@ protected:
field_generic(db_field_name, flat_field_name, field_value, field_type);
}
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, wchar_t & field_value, FT field_type = FT::default_type)
{
field_generic(db_field_name, flat_field_name, field_value, field_type);
}
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::wstring & field_value, FT field_type = FT::default_type)
{
field_generic(db_field_name, flat_field_name, field_value, field_type);
@ -1224,7 +1234,7 @@ protected:
if( val_str )
{
db_connector->get_value(val_str, field_value);
db_connector->get_value(val_str, field_value, field_type);
}
}
else
@ -1271,7 +1281,7 @@ protected:
if( val_str )
{
db_connector->get_value(val_str, field_value);
db_connector->get_value(val_str, field_value, field_type);
}
}
else

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -392,128 +392,6 @@ bool PostgreSQLConnector::query_remove(const PT::TextStream & stream, QueryResul
/*
converting from a bytea
the old way (escape format)
*/
/*
int PostgreSQLConnector::CharToInt(char c)
{
return (int)(unsigned char)(c-'0');
}
bool PostgreSQLConnector::IsCorrectOctalDigit(char c)
{
return c>='0' && c<='7';
}
// moves 'i' at least once
// return -1 if there is en error
int PostgreSQLConnector::UnescapeBin(const char * str, size_t & i, size_t len)
{
if( str[i] != '\\' )
return str[i++];
i += 1;
if( i >= len )
return -1;
if( str[i] == '\\' )
return str[i++];
if( i+2 >= len )
{
i = len;
return -1;
}
if( !IsCorrectOctalDigit(str[i]) ||
!IsCorrectOctalDigit(str[i+1]) ||
!IsCorrectOctalDigit(str[i+2]) )
{
i += 3;
return -1;
}
int c = 8*8*CharToInt(str[i]) + 8*CharToInt(str[i+1]) + CharToInt(str[i+2]);
i += 3;
if( c<0 || c>255 )
return -1;
return c;
}
void PostgreSQLConnector::UnescapeBin(const char * str, size_t len, std::string & out, bool clear_out)
{
int c;
size_t i = 0;
if( clear_out )
out.clear();
while( i < len )
{
c = UnescapeBin(str, i, len);
if( c != -1 )
out += c;
}
}
*/
/*
converting from a bytea
the new way (hex format)
*/
//char PostgreSQLConnector::UnescapeBinHexToDigit(char hex)
//{
// if( hex>='0' && hex<='9' )
// return hex - '0';
//
// if( hex>='a' && hex<='z' )
// return hex - 'a' + 10;
//
// if( hex>='A' && hex<='Z' )
// return hex - 'A' + 10;
//
//return 0;
//}
//
//
//void PostgreSQLConnector::UnescapeBin(const char * str, size_t len, std::string & out, bool clear_out)
//{
// if( clear_out )
// out.clear();
//
// if( len < 2 || str[0]!='\\' || str[1]!='x' )
// {
// log << log1 << "Morm: unsupported binary format (skipping)" << logend;
// return;
// }
//
// for(size_t i=2 ; i + 1 < len ; i+=2 )
// {
// int c1 = UnescapeBinHexToDigit(str[i]);
// int c2 = UnescapeBinHexToDigit(str[i+1]);
//
// out += ((c1 << 4) | c2);
// }
//}
void PostgreSQLConnector::set_conn_param(const std::wstring & database_name, const std::wstring & user, const std::wstring & pass)
{
db_database = database_name;
@ -672,8 +550,55 @@ void PostgreSQLConnector::set_db_parameters()
}
void PostgreSQLConnector::log_unsupported_bin_format()
{
if( log )
{
(*log) << PT::Log::log1 << "Morm: unsupported binary format (skipping)" << PT::Log::logend;
}
}
size_t PostgreSQLConnector::unescape_bin_char(const char * str, wchar_t & field_value, FT field_type)
{
if( str[0]!='\\' || str[1]!='x' )
{
log_unsupported_bin_format();
return 0;
}
else
{
return unescape_hex_char(str + 2, field_value, field_type);
}
}
void PostgreSQLConnector::unescape_bin_string(const char * str, std::string & out)
{
if( str[0]!='\\' || str[1]!='x' )
{
log_unsupported_bin_format();
}
else
{
unescape_hex_string(str + 2, out);
}
}
void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & out, FT field_type)
{
if( str[0]!='\\' || str[1]!='x' )
{
log_unsupported_bin_format();
}
else
{
unescape_hex_string(str + 2, out, field_type);
}
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -98,6 +98,11 @@ protected:
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
virtual QueryResult * create_query_result();
void log_unsupported_bin_format();
size_t unescape_bin_char(const char * str, wchar_t & field_value, FT field_type);
void unescape_bin_string(const char * str, std::string & out);
void unescape_bin_string(const char * str, std::wstring & out, FT field_type);
};

View File

@ -77,34 +77,53 @@ void PostgreSQLExpression::after_second_part_long_field_name()
void PostgreSQLExpression::before_field_value_string()
void PostgreSQLExpression::before_field_value_string(FT field_type)
{
(*out_stream) << "E'";
if( field_type.is_binary() )
{
(*out_stream) << "'\\x";
}
else
if( field_type.is_hexadecimal() )
{
(*out_stream) << "'";
}
else
{
(*out_stream) << "E'";
}
}
void PostgreSQLExpression::after_field_value_string()
void PostgreSQLExpression::after_field_value_string(FT field_type)
{
(*out_stream) << "'";
}
void PostgreSQLExpression::esc(char val, PT::TextStream & stream)
void PostgreSQLExpression::esc(char val, PT::TextStream & stream, FT field_type)
{
switch( val )
if( field_type.is_hexadecimal() || field_type.is_binary() )
{
case '\\': stream << "\\\\"; break;
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
default:
if( val != 0 )
char_to_hex(val, stream);
}
else
{
switch( val )
{
stream << val;
case '\\': stream << "\\\\"; break;
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
default:
if( val != 0 )
{
stream << val;
}
}
}
}
void PostgreSQLExpression::esc(const PT::Date & date, PT::TextStream & stream)
void PostgreSQLExpression::esc(const PT::Date & date, PT::TextStream & stream, FT field_type)
{
stream << date << "+00";
}

View File

@ -45,8 +45,8 @@ class PostgreSQLExpression : public DbExpression
{
public:
void esc(char val, PT::TextStream & stream);
void esc(const PT::Date & date, PT::TextStream & stream);
void esc(char val, PT::TextStream & stream, FT field_type);
void esc(const PT::Date & date, PT::TextStream & stream, FT field_type);
DbExpression & page(PT::TextStream & stream, size_t page_number, size_t page_size);
@ -64,10 +64,8 @@ protected:
private:
void before_field_value_string();
void after_field_value_string();
void before_field_value_string(FT field_type);
void after_field_value_string(FT field_type);
};